From 0e3e1a2b14e0b750e478c228351c888830915b16 Mon Sep 17 00:00:00 2001 From: Shane Frischkorn Date: Fri, 12 Jul 2013 00:02:42 +1000 Subject: [PATCH] fixing for pylint and pep8 recommendatins --- TVEncoder.py | 19 ++-- libfilemanager.py | 16 ++-- libmythtv.py | 12 +-- libsettings.py | 105 ++++++++++++++++++++++ libsickbeard.py | 118 +++++++++++++++---------- libtvdatasource.py | 212 ++++++++++++++++++++++----------------------- libtvshow.py | 19 ++-- 7 files changed, 317 insertions(+), 184 deletions(-) diff --git a/TVEncoder.py b/TVEncoder.py index ab01972..d80a1a4 100644 --- a/TVEncoder.py +++ b/TVEncoder.py @@ -27,24 +27,15 @@ def showhelp(): print 'TVEncoder.py -e -l - list the files that would be encoded' -def print_shows_to_encode(shows): +def print_shows(shows): """ - Prints he details of the shows that have been selected for encoding. + Prints he details of the shows. """ for showdata in shows: print showdata -def print_shows_to_prepare(shows): - """ - Prints he details of the shows that have been selected for preparation. - """ - - for showdata in shows: - showdata.Print() - - def processarguments(options): """ Determine the actions required from the input flags @@ -90,12 +81,12 @@ def main(argv): if inputoptions.doencode: #Generate the list of files that would be encoded showdata = filemanager.getencodingfiles(inputoptions.readonly) - print_shows_to_encode(showdata) + print_shows(showdata) else: # Generate the list of files to process shows = filemanager.getfilestoprepare(inputoptions.numfiles) print "num results: {0}".format(len(shows)) - print_shows_to_prepare(shows) + print_shows(shows) else: if inputoptions.doencode: #Encode the files and move them to their final destination @@ -116,7 +107,7 @@ def main(argv): # Process files for encoding shows = filemanager.getfilestoprepare(inputoptions.numfiles) tvdata = TVData(settings) - tvdata.PrepareEpisodes(shows) + tvdata.prepareepisodes(shows) if __name__ == "__main__": diff --git a/libfilemanager.py b/libfilemanager.py index 4b13837..efe0d11 100644 --- a/libfilemanager.py +++ b/libfilemanager.py @@ -35,7 +35,7 @@ class FileManager: """ def __init__(self, settings): - self.settings = settings + self.__settings = settings def getencodingfiles(self, readonly=True): """ @@ -70,7 +70,7 @@ class FileManager: return the details of the number available. """ - path = self.settings.TVRecordingDirectory() + path = self.__settings.tvrecordingdirectory() potentialfiles = glob.glob("{0}*.mpg".format(path)) potentialfiles = sorted(potentialfiles, key=os.path.getctime) potentialfiles = [potentialfile for potentialfile in potentialfiles @@ -82,10 +82,10 @@ class FileManager: i = 0 print "Found {0} potential files".format(len(potentialfiles)) - tvdata = TVData(self.settings) + tvdata = TVData(self.__settings) for potentialfile in potentialfiles: - showdata = tvdata.RetrieveEpisodeData(potentialfile) + showdata = tvdata.retrieveepisodedata(potentialfile) if showdata: showstoprocess.append(showdata) i = i + 1 @@ -110,9 +110,9 @@ class FileManager: filelist = [] - for show in self.settings.GetShowNames(): + for show in self.__settings.getshownames(): for dirpath, dirnames, filenames in os.walk( - self.settings.GetShowInputDirectory(show)): + self.__settings.getshowinputdirectory(show)): for inputfile in filenames: if inputfile.endswith(".mpg"): data = EncodeData(show, os.path.join( @@ -128,7 +128,7 @@ class FileManager: infile = os.path.basename(inputfile) outfilename = infile[:-3]+"mkv" - outpath = findseason(self.settings.GetShowOutputDirectory( + outpath = findseason(self.__settings.GetShowOutputDirectory( showname), outfilename, readonly) return os.path.join(outpath, outfilename) @@ -139,7 +139,7 @@ class FileManager: final directory in it's path. """ - return os.path.join(self.settings.TVRecordingDirectory(), + return os.path.join(self.__settings.TVRecordingDirectory(), os.path.dirname(filename).split("/")[-1] + ".mpg") diff --git a/libmythtv.py b/libmythtv.py index 0036b08..a65cd7d 100644 --- a/libmythtv.py +++ b/libmythtv.py @@ -15,16 +15,16 @@ class MythTV: """ def __init__(self, settings): - self.settings = settings + self.__settings = settings def retrieveepisodedata(self, inputfile): """ Retrieve the data that mythtv knows about the recorded file. """ - con = mdb.connect(self.settings.MythTVAddress(), - self.settings.MythTVUser(), - self.settings.MythTVPassword(), - self.settings.MythTVDatabase()) + con = mdb.connect(self.__settings.mythtvaddress(), + self.__settings.mythtvuser(), + self.__settings.mythtvpassword(), + self.__settings.mythtvdatabase()) with con: cur = con.cursor(mdb.cursors.DictCursor) @@ -45,7 +45,7 @@ class MythTV: prefixes are listed in the configuration file. """ - for prefix in self.settings.GetShowMythTVEpisodePrefix(showname): + for prefix in self.__settings.getshowmythtvepisodeprefix(showname): if episodetitle.lower().startswith(prefix.lower()): return episodetitle[len(prefix):] diff --git a/libsettings.py b/libsettings.py index 21394aa..598b729 100644 --- a/libsettings.py +++ b/libsettings.py @@ -27,39 +27,90 @@ class Settings: """ def __init__(self, settingsfile): + """ + Initialise settingsfile as a configobj + """ + self.__config = ConfigObj(settingsfile) def tvrecordingdirectory(self): + """ + Get the TVRecordings setting + """ + return self.__config["TVRecordings"] def handbrakecommand(self): + """ + Get the HandbrakeCommand setting + """ + return self.__config["HandbrakeCommand"] def mythtvaddress(self): + """ + Get the MythTV/address setting + """ + return self.__config["MythTV"]["address"] def mythtvuser(self): + """ + Get the MythTV/user setting + """ + return self.__config["MythTV"]["user"] def mythtvpassword(self): + """ + Get the MythTV/password setting + """ + return self.__config["MythTV"]["password"] def mythtvdatabase(self): + """ + Get the MythTV/database setting + """ + return self.__config["MythTV"]["database"] def sickbeardaddress(self): + """ + Get the Sickbeard/address setting + """ + return self.__config["Sickbeard"]["address"] def sickbeardport(self): + """ + Get the Sickbeard/port setting + """ + return int(self.__config["Sickbeard"]["port"]) def sickbeardapikey(self): + """ + Get the Sickbeard/APIKey setting + """ + return self.__config["Sickbeard"]["APIKey"] def unknowndirectory(self): + """ + Get the Shows/UnknownInput directory. It is the directory used for + episodes where nothing is known about it + """ + return self.__config["Shows"]["UnknownInput"] def getshownames(self, includealias=False): + """ + Get a list of the names of the shows that are specified in the + settings file. If includealias is True, it will also include any + defined aliases in the list. + """ + shows = self.__config["Shows"].sections result = shows[:] if includealias: @@ -68,7 +119,30 @@ class Settings: result.append(alias) return result + def findshownameforalias(self, aliasname): + """ + Find the name of the show. If the supplied aliasname is an alias, it + will return the show name. If aliasname is the name of a show, it will + return aliasname + """ + + if aliasname in self.getshownames(): + # aliasname is the name of an actual show + return aliasname + + # search for the show that the alias belongs to + for showsettings in self.__config["Shows"]: + if aliasname in showsettings["alias"]: + return showsettings.name + + # Could not find it anywhere + return None + def getshowinputdirectory(self, showname): + """ + Get the InputDirectory setting for the show, showname. + """ + show = self.__getshowsubsection(showname) if show is None: return "" @@ -76,6 +150,11 @@ class Settings: return show["InputDirectory"] def getshowunknowndirectory(self, showname): + """ + Get the UnknownDirectory setting for the show, showname. It is used + when the show is known, but the season or episode are not. + """ + show = self.__getshowsubsection(showname) if show is None: return "" @@ -83,6 +162,10 @@ class Settings: return show["UnknownDirectory"] def getshowoutputdirectory(self, showname): + """ + Get the OutputDirectory setting for the show, showname. + """ + show = self.__getshowsubsection(showname) if show is None: return "" @@ -90,6 +173,11 @@ class Settings: return show["OutputDirectory"] def getshowalias(self, showname): + """ + Get the alias setting for the show, showname. It returns a list of + aliases. + """ + show = self.__getshowsubsection(showname) if show is None: return "" @@ -97,6 +185,10 @@ class Settings: return show["alias"] def getshowmythtvepisodeprefix(self, showname): + """ + Get the MythTVEpisodePrefix setting for the show, showname. + """ + show = self.__getshowsubsection(showname) if show is None: return "" @@ -104,13 +196,22 @@ class Settings: return show["MythTvEpisodePrefix"] def getshowsickbearsepisodeprefix(self, showname): + """ + Get the SickbeardPrefix setting for the show, showname. + """ + show = self.__getshowsubsection(showname) if show is None: return "" else: return show["SickbeardPrefix"] + # TODO check if this is actually doing anything. it seems like it + # just returns what is input def getshow(self, showname): + """ + Get the InputDirectory setting for the show, showname. + """ showsection = self.__getshowsubsection(showname) if showsection is None: return None @@ -118,6 +219,10 @@ class Settings: return showsection.name def __getshowsubsection(self, showname): + """ + Get the configuration options for the show, showname. + """ + if showname in self.getshownames(): return self.__config["Shows"][showname] else: # check liases diff --git a/libsickbeard.py b/libsickbeard.py index b8dd583..a1b4abb 100644 --- a/libsickbeard.py +++ b/libsickbeard.py @@ -12,29 +12,29 @@ from operator import itemgetter class Sickbeard: + """ + Contains operations used to interact with sickbeard + """ + def __init__(self, settings): self.__settings = settings - self.__address = settings.SickbeardAddress() - self.__port = settings.SickbeardPort() - self.__apikey = settings.SickbeardAPIKey() + self.__address = settings.sickbeardaddress() + self.__port = settings.sickbeardport() + self.__apikey = settings.sickbeardapikey() - def __GetApiURL(self): - return "http://{0}:{1}/api/{2}/".format(self.__address, self.__port, - self.__apikey) + def findshowid(self, showname): + """ + Get the tvdb show id for the show + """ - def FindShowId(self, showName): - jsonurl = urlopen(self.__GetApiURL()+"?cmd=shows") + jsonurl = urlopen(self.__getapiurl()+"?cmd=shows") result = json.loads(jsonurl.read()) - # TODO find a better way to do this - if showName == "Thomas and Friends": - showName = "Thomas The Tank Engine & Friends" - elif showName == "The Octonauts": - showName = "Octonauts" + showname = self.__settings.findshownameforalias(showname) shows = [] for show in result['data']: - shows.append((show, fuzz.partial_ratio(showName.lower(), + shows.append((show, fuzz.partial_ratio(showname.lower(), result['data'][show] ['show_name'].lower()))) @@ -43,32 +43,30 @@ class Sickbeard: if shows[0][1] > 85: return shows[0][0] - def FindEpisodeByDescription(self, showId, season, episode, description): - jsonepisodeurl = urlopen("{0}?cmd=episode&tvdbid={1}&season={2}" - "&episode={3}".format(self.__GetApiURL(), - showId, season, episode)) - episoderesult = json.loads(jsonepisodeurl.read()) + def findepisodename(self, showid, season, episode): + """ + Get the name of an episode, given it's season and episode numbers + """ - sickbearddescription = episoderesult['data']['description'] - - if fuzzystringcompare(sickbearddescription, description): - return (season, episode, episoderesult['data']['name']) - - return None - - def FindEpisodeName(self, showId, season, episode): jsonurl = urlopen("{0}?cmd=episode&tvdbid={1}&season={2}" - "&episode={3}".format(self.__GetApiURL(), showId, - int(season), int(episode))) + "&episode={3}".format(self.__getapiurl(), showid, + int(season), int(episode))) + result = json.loads(jsonurl.read()) + if result['result'] == 'error': return "" else: return result['data']['name'] - def FindEpisode(self, showId, name=None, description=None): + def findepisode(self, showid, name=None, description=None): + """ + Find an episode, either by it's name or it's description. This is used + when the season and episode numbers are not known + """ + jsonurl = urlopen("{0}?cmd=show.seasons&tvdbid={1}".format( - self.__GetApiURL(), showId)) + self.__getapiurl(), showid)) result = json.loads(jsonurl.read()) for season in result['data']: @@ -78,11 +76,11 @@ class Sickbeard: episodename) > 90: return (season, episode, episodename) elif description is not None: - descriptionQueryResult = \ - self.FindEpisodeByDescription(showId, season, - episode, description) - if descriptionQueryResult is not None: - return descriptionQueryResult + descriptionqueryresult = \ + self.__findepisodebydescription(showid, season, + episode, description) + if descriptionqueryresult is not None: + return descriptionqueryresult return (0, 0, '') @@ -94,16 +92,48 @@ class Sickbeard: # return subtitle #============================================================================== - def FixEpisodeTitle(self, showName, episodeTitle): - sickbeardPrefix = \ - self.__settings.GetShowSickbeardEpisodePrefix(showName) + def fixepisodetitle(self, showname, episodetitle): + """ + Check to see if there is a prefix specified for the show. If there is, + add the prefix to the start of the episode title + """ - if sickbeardPrefix != "": - if not episodeTitle.lower.startswith(sickbeardPrefix.lower()): - return "{0} {1}".format(sickbeardPrefix.rstrip(), - episodeTitle.lstrip()) + sickbeardprefix = \ + self.__settings.GetShowSickbeardEpisodePrefix(showname) - return episodeTitle + if sickbeardprefix != "": + if not episodetitle.lower.startswith(sickbeardprefix.lower()): + return "{0} {1}".format(sickbeardprefix.rstrip(), + episodetitle.lstrip()) + + return episodetitle + + def __getapiurl(self): + """ + Get the url of the sickbeard api, substituting the values from the + settings + """ + + return "http://{0}:{1}/api/{2}/".format(self.__address, self.__port, + self.__apikey) + + def __findepisodebydescription(self, showid, season, episode, description): + """ + Find the details of an episode by searching for it's description + """ + + jsonepisodeurl = urlopen("{0}?cmd=episode&tvdbid={1}&season={2}" + "&episode={3}".format(self.__getapiurl(), + showid, season, + episode)) + episoderesult = json.loads(jsonepisodeurl.read()) + + sickbearddescription = episoderesult['data']['description'] + + if fuzzystringcompare(sickbearddescription, description): + return (season, episode, episoderesult['data']['name']) + + return None def fuzzystringcompare(string1, string2, matchvalue=85, casesensitive=False): diff --git a/libtvdatasource.py b/libtvdatasource.py index f68364a..e19fd2c 100644 --- a/libtvdatasource.py +++ b/libtvdatasource.py @@ -10,131 +10,131 @@ from libsickbeard import Sickbeard import os import shutil -# TODO Move these to settings -#PROCESSDIR="/srv/storage2/files/VideoProcessing/" -#THOMAS="Thomas" -#CHUGGINGTON="Chuggington" -#MIKE="MikeTheKnight" -#OCTONAUTS="Octonauts" -#NIGHTGARDEN="InTheNightGarden" -#RAARAA="RaaRaa" -#INPUTDIR="Input" + +def fixepisodeseasonnumber(number): + """ + If the number is single digit, return a string with 0 in front of it. + """ + + if len(number) == 1: + return "0{0}".format(number) + else: + return number + class TVData: + """ + Class contains logic for processing information about tv episodes + """ + def __init__(self, settings): - self.settings = settings - - def FixEpisodeSeasonNumber(self, number): - if len(number) == 1: - return "0{0}".format(number) - else: - return number - - def GetDirectory(self, title, seasonFolder, season, episode): - show = self.settings.GetShow(title) + self.__settings = settings + + def getdirectory(self, title, seasonfolder, season, episode): + """ + Get the directory where prepared episodes will be located. + """ + + show = self.__settings.getshow(title) if not show or show == "": print "Couldn't find show for {0}".format(title) - return self.settings.UnknownDirectory() + return self.__settings.unknowndirectory() elif season == "S00" or episode == "E00": - return self.settings.GetShowUnknownDirectory(show) + return self.__settings.getshowunknowndirectory(show) else: - return os.path.join(self.settings.GetShowInputDirectory(show), seasonFolder) -#============================================================================== -# if title == "Thomas and Friends" or title == "Thomas the Tank Engine & Friends": -# directory = THOMAS -# elif title == "Chuggington": -# directory = CHUGGINGTON -# elif title == "Mike the Knight": -# directory = MIKE -# elif title == "Octonauts" or title == "The Octonauts": -# directory = OCTONAUTS -# elif title == "In the Night Garden": -# directory = NIGHTGARDEN -# elif title == "Raa Raa! The Noisy Lion": -# directory = RAARAA -# else: -# print "Didn't match" -#============================================================================== - -# return os.path.join(PROCESSDIR, directory, INPUTDIR, season) - - def RetrieveEpisodeData(self, inputFile): - file = os.path.basename(inputFile) - - mythTv = MythTV(self.settings) - show = mythTv.RetrieveEpisodeData(file) - - showsToProcess = self.settings.GetShowNames(True) - - if show.title and show.title in showsToProcess: - show.title = self.settings.GetShow(show.title) - + return os.path.join(self.__settings.getshowinputdirectory(show), + seasonfolder) + + def retrieveepisodedata(self, inputfile): + """ + Retrieve the details of an episode. It first looks up the details that + mythtv recorded about it, then looks up sickbeard to attempt to find + any missing details. Finally it determined the output file for it. + """ + + inputfilename = os.path.basename(inputfile) + + mythtv = MythTV(self.__settings) + show = mythtv.retrieveepisodedata(inputfilename) + + showstoprocess = self.__settings.getshownames(True) + + if show.title and show.title in showstoprocess: + show.title = self.__settings.getshow(show.title) + if (show.season == "0" or show.episode == "0"): - sickbeard = Sickbeard(self.settings) - showId = sickbeard.FindShowId(show.title) - + sickbeard = Sickbeard(self.__settings) + showid = sickbeard.findshowid(show.title) + if show.subtitle is not None and show.subtitle: - show.subtitle = mythTv.FixMythTVEpisodeName(show.title, show.subtitle) - show.subtitle = sickbeard.FixEpisodeTitle(show.title, show.subtitle) - - result = sickbeard.FindEpisode(showId, show.subtitle, show.description) + show.subtitle = mythtv.fixmythtvepisodename(show.title, + show.subtitle) + show.subtitle = sickbeard.fixepisodetitle(show.title, + show.subtitle) + + result = sickbeard.findepisode(showid, show.subtitle, + show.description) show.season = str(result[0]) show.episode = str(result[1]) show.subtitle = result[2] - + if show.subtitle is None or show.subtitle == "": - show.subtitle = sickbeard.FindEpisodeName(showId, show.season, show.episode) - - #if show.season != "0" and show.episode != "0": - show.season = self.FixEpisodeSeasonNumber(show.season) - show.episode = self.FixEpisodeSeasonNumber(show.episode) - - seasonFolder = "Season {0}".format(show.season) + show.subtitle = sickbeard.findepisodename(showid, show.season, + show.episode) + + show.season = fixepisodeseasonnumber(show.season) + show.episode = fixepisodeseasonnumber(show.episode) + + seasonfolder = "Season {0}".format(show.season) season = "S{0}".format(show.season) episode = "E{0}".format(show.episode) - renamedFile = "{0}{1} - {2} - SD TV_.mpg".format(season, episode, show.subtitle) - - directory = self.GetDirectory(show.title, seasonFolder, season, episode) - - show.outputFile = os.path.join(directory, file[:-4], renamedFile) - show.inputFile = inputFile - + renamedfile = "{0}{1} - {2} - SD TV_.mpg".format(season, episode, + show.subtitle) + + directory = self.getdirectory(show.title, seasonfolder, + season, episode) + + show.outputfile = os.path.join(directory, inputfilename[:-4], + renamedfile) + show.inputfile = inputfile + return show else: return None - + #============================================================================== -# def CheckTitleIsInList(serverAddress, user, password, database, inputFile): -# """Check that inputFile is a recording of a show that is to be processed.""" -# file = os.path.basename(inputFile) -# show = MythTV.RetrieveEpisodeData('localhost', 'script', 'script', 'mythconverg', file) -# -# # TODO get this from settings -# if show.title in ["Thomas and Friends", "Thomas the Tank Engine & Friends", -# "Chuggington", "Mike the Knight", "Octonauts", -# "The Octonauts", "In the Night Garden", -# "Raa Raa! The Noisy Lion"]: -# return True -# else: -# return False +# def __determinetargetfilename(directory, filename, inputfilename): +# """ +# Determine the filename for the input file. If the path does not +# exist, it is created. +# """ +# +# inputdir = os.path.join(directory, inputfilename[:-4]) +# +# if not os.path.exists(inputdir): +# os.makedirs(inputdir) +# +# return os.path.join(inputdir, filename) #============================================================================== - - def DetermineTargetFilename(directory, filename, inputFilename): - dir = os.path.join(directory, inputFilename[:-4]) - - if not os.path.exists(dir): - os.makedirs(dir) - - return os.path.join(dir, filename) - - - def ProcessEpisode(self, inputFile, outputFile): - outputdir = os.path.dirname(outputFile) + + @staticmethod + def processepisode(inputfile, outputfile): + """ + Copy inputfile to outputfile, creating the path for outputfile if + required. + """ + + outputdir = os.path.dirname(outputfile) if not os.path.exists(outputdir): os.makedirs(outputdir) - - shutil.copyfile(inputFile, outputFile) - - def PrepareEpisodes(self, showsData): - for showData in showsData: - self.ProcessEpisode(showData.inputFile, showData.outputFile) \ No newline at end of file + + shutil.copyfile(inputfile, outputfile) + + def prepareepisodes(self, showsdata): + """ + Copy the files in showsdata from their input directory to their output + directory. + """ + + for showdata in showsdata: + self.processepisode(showdata.inputfile, showdata.outputfile) diff --git a/libtvshow.py b/libtvshow.py index 1fbb8a1..55ae750 100644 --- a/libtvshow.py +++ b/libtvshow.py @@ -5,15 +5,22 @@ Created on Sat Jul 6 20:26:22 2013 @author: shanef """ + class TVShow(object): - def __init__(self, episode, season, title, subtitle, description, inputFile='', outputFile=''): + """ + Describes the details of a tv episode + """ + + def __init__(self, episode, season, title, subtitle, description, + inputfile='', outputfile=''): self.episode = str(episode) self.season = str(season) self.title = title self.subtitle = subtitle self.description = description - self.inputFile = inputFile - self.outputFile = outputFile - - def Print(self): - print "Input: {0} -> Output: {1}".format(self.inputFile, self.outputFile) \ No newline at end of file + self.inputfile = inputfile + self.outputfile = outputfile + + def __str__(self): + return "Input: {0} -> Output: {1}".format(self.inputfile, + self.outputfile)