22 Commits
2.0 ... master

Author SHA1 Message Date
3a7c6dc7b3 Sort the duplicate list 2013-09-09 19:48:38 +10:00
1fb8543c62 Sort the duplicate list 2013-09-09 19:47:25 +10:00
d185b0047e Sort the duplicate list 2013-09-09 19:45:30 +10:00
4e0060a3ce Ignore case when comparing file extensions 2013-09-09 17:16:24 +10:00
5f788998a3 fixing bug looking for non-existant directories 2013-08-01 19:16:24 +10:00
60584b4dfb fixing bug 2013-07-30 19:59:45 +10:00
eca7f5710b making looking for duplicates case insensitive 2013-07-29 09:40:35 +10:00
ac508047bd Added : as an illegal character 2013-07-28 10:12:38 +10:00
5ef02c1e8e Added a check to search the output directories for duplicate video files 2013-07-23 23:59:30 +10:00
5ae07c01e7 Removed debugging lines 2013-07-23 23:07:41 +10:00
5aa5da1a92 fixed error finding duplicate file 2013-07-22 23:43:58 +10:00
d9da2d18f7 Fixed fuzzy episode name matching logic 2013-07-22 22:34:36 +10:00
1297a07e37 fixing pylint suggestions 2013-07-21 22:35:53 +10:00
5ca6c3861e added check for pre-existing video files 2013-07-21 22:23:14 +10:00
aa514032f5 Also check for the output file without the _ in the filename to see if it exists 2013-07-21 21:50:58 +10:00
3cb3930c1c removing unneeded files 2013-07-21 09:35:53 +10:00
34e2a89066 Added unit test for email 2013-07-20 22:26:43 +10:00
f0ac96de94 Added email messaging 2013-07-20 20:58:29 +10:00
00de89d02c Added string substitutions to config and corrected logging error 2013-07-19 23:18:51 +10:00
be97271559 added logging 2013-07-19 22:36:46 +10:00
c06d43b3e7 Merge branch 'master' of https://github.com/sfrischkorn/recordingprocessing 2013-07-18 23:34:37 +10:00
48e4eae2be Ignore ? in filenames since they are illegal 2013-07-18 23:33:17 +10:00
16 changed files with 573 additions and 74 deletions

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
*.pyc
.spyderproject

5
EmailSettings.cfg Normal file
View File

@@ -0,0 +1,5 @@
SMTPServer = ""
SMTPUser = ""
SMTPPassword = ""
From = ""
To = ""

View File

@@ -10,9 +10,14 @@ import getopt
from libfilemanager import FileManager from libfilemanager import FileManager
from libsettings import Settings from libsettings import Settings
import libhandbrake import libhandbrake
import libemail
from libtvdatasource import TVData from libtvdatasource import TVData
from collections import namedtuple from collections import namedtuple
from termcolor import colored from termcolor import colored
import logging
SETTINGS = "settings.cfg"
EMAIL_SETTINGS = "EmailSettings.cfg"
def showhelp(): def showhelp():
@@ -26,6 +31,7 @@ def showhelp():
'files that will be processed without actually encoding them' 'files that will be processed without actually encoding them'
print 'TVEncoder.py -e - encode the files that have been processed' print 'TVEncoder.py -e - encode the files that have been processed'
print 'TVEncoder.py -e -l - list the files that would be encoded' print 'TVEncoder.py -e -l - list the files that would be encoded'
print 'TVEncoder.py -c - check the output directories for duplicates'
def print_shows(shows): def print_shows(shows):
@@ -69,9 +75,11 @@ def processarguments(options):
""" """
inputoptions = namedtuple("inputoptions", inputoptions = namedtuple("inputoptions",
"numfiles doencode readonly dolist") "numfiles doencode readonly dolist "
"checkduplicates")
inputoptions.readonly = False inputoptions.readonly = False
inputoptions.checkduplicates = False
for opt, arg in options: for opt, arg in options:
if opt == '-h': if opt == '-h':
@@ -85,6 +93,8 @@ def processarguments(options):
inputoptions.numfiles = arg inputoptions.numfiles = arg
elif opt == "-l": elif opt == "-l":
inputoptions.readonly = True inputoptions.readonly = True
elif opt == "-c":
inputoptions.checkduplicates = True
return inputoptions return inputoptions
@@ -94,15 +104,25 @@ def main(argv):
The main program for TVEncoder. The main program for TVEncoder.
""" """
try: try:
opts, args = getopt.getopt(argv, "hlpen:") opts, _ = getopt.getopt(argv, "hlpecn:")
except getopt.GetoptError: except getopt.GetoptError:
showhelp() showhelp()
sys.exit(2) sys.exit(2)
inputoptions = processarguments(opts) inputoptions = processarguments(opts)
settings = Settings("settings.cfg") settings = Settings(SETTINGS)
filemanager = FileManager(settings) filemanager = FileManager(settings)
if inputoptions.checkduplicates:
print "Searching for duplicates..."
duplicates = filemanager.checkexistingduplicates()
if duplicates:
for duplicate in duplicates:
print duplicate
else:
print "No duplicates found."
return
if inputoptions.readonly: if inputoptions.readonly:
if inputoptions.doencode: if inputoptions.doencode:
#Generate the list of files that would be encoded #Generate the list of files that would be encoded
@@ -116,25 +136,69 @@ def main(argv):
else: else:
if inputoptions.doencode: if inputoptions.doencode:
#Encode the files and move them to their final destination #Encode the files and move them to their final destination
showdata = filemanager.getencodingfiles(inputoptions.readonly)
logging.basicConfig(level=logging.DEBUG)
generallogger = createlogger("general", settings.generallogfile(),
logging.DEBUG)
actionlogger = createlogger("action", settings.actionlogfile(),
logging.INFO)
showdata = filemanager.getencodingfiles(inputoptions.readonly)
generallogger.info("There are {0} files to process."
.format(len(showdata)))
for show in showdata: for show in showdata:
generallogger.info("========================================")
generallogger.info("Processing {0} of {1}, {2}".format(
showdata.index(show) + 1, len(showdata), str(show)))
if filemanager.checkfileexists(show.outputfile): if filemanager.checkfileexists(show.outputfile):
print "File {0} already exists. Cannot process." \ message = "File {0} already exists. Cannot process." \
.format(show.outputfile) .format(show.outputfile)
generallogger.warning(message)
actionlogger.warning(message)
else: else:
result = libhandbrake.encode(settings.handbrakecommand(), result = libhandbrake.encode(settings.handbrakecommand(),
show.inputfile, show.inputfile,
show.outputfile) show.outputfile)
# TODO do something with the result
generallogger.info("Encode finished with result: {0}"
.format(result))
filemanager.performpostencodefileoperations( filemanager.performpostencodefileoperations(
show.inputfile, show.outputfile) show.inputfile, show.outputfile)
if filemanager.checkduplicates(show.outputfile):
actionlogger.info("There is an existing video file"
"present for {0}"
.format(show.outputfile))
generallogger.info("Processing finished.")
generallogger.info("==========================="
"=============\n\n")
libemail.sendemail(EMAIL_SETTINGS, "Encoding Complete",
"Finished encoding {0} shows."
.format(len(showdata)))
else: else:
# Process files for encoding # Process files for encoding
shows = filemanager.getfilestoprepare(inputoptions.numfiles) shows = filemanager.getfilestoprepare(inputoptions.numfiles)
print "Preparing {0} files".format(len(shows))
tvdata = TVData(settings) tvdata = TVData(settings)
tvdata.prepareepisodes(shows) tvdata.prepareepisodes(shows)
def createlogger(name, filename, level):
"""
Create a logger named <name> that will write to the file <filename>
"""
logger = logging.getLogger(name)
handler = logging.FileHandler(filename, mode='w')
formatter = logging.Formatter('%(asctime)s %(message)s')
handler.setFormatter(formatter)
handler.setLevel(level)
logger.addHandler(handler)
return logger
if __name__ == "__main__": if __name__ == "__main__":
main(sys.argv[1:]) main(sys.argv[1:])

32
libemail.py Normal file
View File

@@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
"""
Created on Sat Jul 20 20:48:10 2013
@author: shanef
"""
from libsettings import EmailSettings
import smtplib
from email.mime.text import MIMEText
def sendemail(settingsfilename, subject, body):
"""
Send an email using the settings defined in settingsfilename
"""
settings = EmailSettings(settingsfilename)
msg = MIMEText(body, "plain")
msg["Subject"] = subject
msg["From"] = settings.getfromaddress()
msg["To"] = settings.gettoaddress()
smtp = smtplib.SMTP(settings.getsmtpserver())
smtp.ehlo()
smtp.starttls()
smtp.login(settings.getsmtpuser(), settings.getsmtppassword())
smtp.sendmail(settings.getfromaddress(), [settings.gettoaddress()],
msg.as_string())
smtp.quit()

View File

@@ -35,7 +35,12 @@ class EncodeData:
errors = [] errors = []
if os.path.exists(self.outputfile): if checkfileexists(self.outputfile, False):
errors.append("FILE_EXISTS")
if self.outputfile[-5:-4] == "_":
tempoutfile = self.outputfile[:-5] + self.outputfile[-4:]
if checkfileexists(tempoutfile, False):
errors.append("FILE_EXISTS") errors.append("FILE_EXISTS")
return errors return errors
@@ -107,13 +112,62 @@ class FileManager:
#will reach here if there were less than numberofFiles found #will reach here if there were less than numberofFiles found
return showstoprocess return showstoprocess
def checkexistingduplicates(self):
"""
Check the existing files in the output directories for duplicate
files, typically in different formats
"""
duplicates = []
for show in self.__settings.getshownames():
outputdir = self.__settings.getshowoutputdirectory(show)
for rootdir, dirnames, filenames in os.walk(outputdir):
for fle in filenames:
filename = os.path.join(rootdir, fle)
if os.path.splitext(fle)[1].lower() in [".avi", ".mpg", ".mpeg",
"mp4", ".mkv"]:
if self.checkduplicates(filename):
duplicates.append(filename)
return sorted(duplicates)
@staticmethod @staticmethod
def checkfileexists(filename): def checkduplicates(filename):
"""
Check to see if there are any other video files existing for the
episode
"""
dirname = os.path.dirname(filename)
filename = os.path.basename(filename)
fileseasonepisode = filename[:6]
fileextension = os.path.splitext(filename)[1]
for _, _, filenames in os.walk(dirname):
for show in filenames:
extension = os.path.splitext(show)[1]
if (extension.lower() in [".avi", ".mpg", ".mpeg", "mp4", ".mkv"] and
show[:6] == fileseasonepisode
and fileextension != extension):
return True
return False
@staticmethod
def checkfileexists(filename, casesensitive=True):
""" """
Check to see if a file currently exists Check to see if a file currently exists
""" """
if casesensitive:
return os.path.exists(filename) return os.path.exists(filename)
else:
filename = os.path.basename(filename)
for dirfile in os.listdir(os.path.dirname(filename)):
if (filename.lower() == dirfile.lower()):
return True
return False
def __getinputfilestoencode(self): def __getinputfilestoencode(self):
""" """
@@ -123,7 +177,7 @@ class FileManager:
filelist = [] filelist = []
for show in self.__settings.getshownames(): for show in self.__settings.getshownames():
for dirpath, dirnames, filenames in os.walk( for dirpath, _, filenames in os.walk(
self.__settings.getshowinputdirectory(show)): self.__settings.getshowinputdirectory(show)):
for inputfile in filenames: for inputfile in filenames:
if inputfile.endswith(".mpg"): if inputfile.endswith(".mpg"):
@@ -168,3 +222,23 @@ def findseason(path, filename, readonly):
os.makedirs(seasonpath) os.makedirs(seasonpath)
return seasonpath return seasonpath
def checkfileexists(filename, casesensitive=True):
"""
Check to see if a file currently exists
"""
dirname = os.path.dirname(filename)
if casesensitive:
return os.path.exists(filename)
else:
if not os.path.exists(dirname):
return False
basename = os.path.basename(filename)
for dirfile in os.listdir(dirname):
if (basename.lower() == dirfile.lower()):
return True
return False

View File

@@ -8,19 +8,6 @@ Created on Fri Jul 5 20:14:15 2013
from configobj import ConfigObj from configobj import ConfigObj
#==============================================================================
# class ShowSettings:
# """
# Container for the settings for a show
# """
#
# def __init__(self, name, inputdirectory, outputdirectory):
# self.name = name
# self.inputdirectory = inputdirectory
# self.outputdirectory = outputdirectory
#==============================================================================
class Settings: class Settings:
""" """
Accessor for the configuration file Accessor for the configuration file
@@ -47,6 +34,27 @@ class Settings:
return self.__config["HandbrakeCommand"] return self.__config["HandbrakeCommand"]
def illegalcharacters(self):
"""
Get a list of illegal characters for filenames
"""
return self.__config["IllegalCharacters"]
def generallogfile(self):
"""
Get the filename to save general log messages to
"""
return self.__config["Logging"]["General"]
def actionlogfile(self):
"""
Get the filename to save the action log messages to
"""
return self.__config["Logging"]["Action"]
def mythtvaddress(self): def mythtvaddress(self):
""" """
Get the MythTV/address setting Get the MythTV/address setting
@@ -206,11 +214,9 @@ class Settings:
else: else:
return show["SickbeardPrefix"] return show["SickbeardPrefix"]
# TODO check if this is actually doing anything. it seems like it
# just returns what is input
def getshow(self, showname): def getshow(self, showname):
""" """
Get the InputDirectory setting for the show, showname. Get the name of the show, showname.
""" """
showsection = self.__getshowsubsection(showname) showsection = self.__getshowsubsection(showname)
if showsection is None: if showsection is None:
@@ -231,3 +237,51 @@ class Settings:
return self.__config["Shows"][show] return self.__config["Shows"][show]
return None return None
class EmailSettings:
"""
Accessor for the email configuration file
"""
def __init__(self, settingsfile):
"""
Initialise settingsfile as a configobj
"""
self.__config = ConfigObj(settingsfile)
def getsmtpserver(self):
"""
Get the address of the smtp server
"""
return self.__config["SMTPServer"]
def getsmtpuser(self):
"""
Get the username for the smtp server
"""
return self.__config["SMTPUser"]
def getsmtppassword(self):
"""
Get the username for the smtp server
"""
return self.__config["SMTPPassword"]
def getfromaddress(self):
"""
Get the from address for emails
"""
return self.__config["From"]
def gettoaddress(self):
"""
Get the to address for emails
"""
return self.__config["To"]

View File

@@ -67,13 +67,14 @@ class Sickbeard:
jsonurl = urlopen("{0}?cmd=show.seasons&tvdbid={1}".format( jsonurl = urlopen("{0}?cmd=show.seasons&tvdbid={1}".format(
self.__getapiurl(), showid)) self.__getapiurl(), showid))
result = json.loads(jsonurl.read()) result = json.loads(jsonurl.read())
for season in result['data']: for season in result['data']:
for episode in result['data'][season]: for episode in result['data'][season]:
episodename = result['data'][season][episode]['name'] episodename = result['data'][season][episode]['name']
if name is not None and fuzz.partial_ratio(name.lower(), if name is not None and fuzz.ratio(name.lower(),
episodename) > 90: episodename.lower()) > 85:
return (season, episode, episodename) return (season, episode, episodename)
elif description is not None: elif description is not None:
descriptionqueryresult = \ descriptionqueryresult = \
@@ -84,14 +85,6 @@ class Sickbeard:
return (0, 0, '') return (0, 0, '')
#==============================================================================
# def GetEpisodeName(subtitle, showName):
# if subtitle[:len(showName)].lower() == showName.lower():
# return subtitle[len(showName + ' and the '):]
# else:
# return subtitle
#==============================================================================
def fixepisodetitle(self, showname, episodetitle): def fixepisodetitle(self, showname, episodetitle):
""" """
Check to see if there is a prefix specified for the show. If there is, Check to see if there is a prefix specified for the show. If there is,

View File

@@ -88,7 +88,7 @@ class TVData:
seasonfolder = "Season {0}".format(show.season) seasonfolder = "Season {0}".format(show.season)
season = "S{0}".format(show.season) season = "S{0}".format(show.season)
episode = "E{0}".format(show.episode) episode = "E{0}".format(show.episode)
renamedfile = "{0}{1} - {2} - SD TV_.mpg".format(season, episode, renamedfile = self.getoutputfilename(season, episode,
show.subtitle) show.subtitle)
directory = self.getdirectory(show.title, seasonfolder, directory = self.getdirectory(show.title, seasonfolder,
@@ -102,20 +102,17 @@ class TVData:
else: else:
return None return None
#============================================================================== def getoutputfilename(self, season, episode, name):
# def __determinetargetfilename(directory, filename, inputfilename): """
# """ Get the output filename, and remove any illegal characters
# Determine the filename for the input file. If the path does not """
# exist, it is created.
# """ filename = "{0}{1} - {2} - SD TV_.mpg".format(season, episode, name)
#
# inputdir = os.path.join(directory, inputfilename[:-4]) for illegalcharacter in self.__settings.illegalcharacters():
# filename = filename.replace(illegalcharacter, "")
# if not os.path.exists(inputdir):
# os.makedirs(inputdir) return filename
#
# return os.path.join(inputdir, filename)
#==============================================================================
@staticmethod @staticmethod
def processepisode(inputfile, outputfile): def processepisode(inputfile, outputfile):
@@ -137,4 +134,11 @@ class TVData:
""" """
for showdata in showsdata: for showdata in showsdata:
print "========================================"
print "Copying {0} to {1}".format(showdata.inputfile,
showdata.outputfile)
self.processepisode(showdata.inputfile, showdata.outputfile) self.processepisode(showdata.inputfile, showdata.outputfile)
print "Finished copy"
print "========================================\n\n"

3
pep8.sh Executable file
View File

@@ -0,0 +1,3 @@
#!/bin/bash
pep8 libemail.py TVEncoder.py libfilemanager.py libhandbrake.py libmythtv.py libsettings.py libsickbeard.py libtvdatasource.py libtvshow.py

3
pylint.sh Executable file
View File

@@ -0,0 +1,3 @@
#!/bin/bash
pylint TVEncoder.py libfilemanager.py libhandbrake.py libmythtv.py libsettings.py libsickbeard.py libtvdatasource.py libtvshow.py libemail.py

View File

@@ -1,5 +1,10 @@
TVRecordings = "/Volumes/TV Recordings/" TVRecordings = "/Volumes/TV Recordings/"
HandbrakeCommand = "HandBrakeCLI", "--verbose", "-i", "SUBSTITUTE WITH INPUT FILE", "-o", "SUBSTITUDE WITH OUTPUT FILE", "-f", "mkv", "-e", "x264", "-x264-preset", "slower", "-x264-tune", "animation", "-q", "20", "--loose-anamorphic", "--decomb", "--detelecine", '--denoise="2:1:2:3"', "--deblock" HandbrakeCommand = "HandBrakeCLI", "--verbose", "-i", "SUBSTITUTE WITH INPUT FILE", "-o", "SUBSTITUDE WITH OUTPUT FILE", "-f", "mkv", "-e", "x264", "-x264-preset", "slower", "-x264-tune", "animation", "-q", "20", "--loose-anamorphic", "--decomb", "--detelecine", '--denoise="2:1:2:3"', "--deblock"
IllegalCharacters = "?", ":"
[ "Logging" ]
General = "logs/encoding.log"
Action = "logs/needsaction.log"
[ "MythTV" ] [ "MythTV" ]
address = 192.168.0.2 address = 192.168.0.2
@@ -13,46 +18,55 @@ HandbrakeCommand = "HandBrakeCLI", "--verbose", "-i", "SUBSTITUTE WITH INPUT FIL
APIKey = 3678177136222bf5002be209220ccb20 APIKey = 3678177136222bf5002be209220ccb20
[ "Shows" ] [ "Shows" ]
UnknownInput = "/srv/storage2/files/VideoProcessing/Unknown/" VideoProcessingDir = "/srv/storage2/files/VideoProcessing/"
KidsTVDir = "/srv/storage2/videos/Kids/TV/"
UnknownInput = "%(VideoProcessingDir)sUnknown/"
[[ "Thomas the Tank Engine & Friends" ]] [[ "Thomas the Tank Engine & Friends" ]]
InputDirectory = "/srv/storage2/files/VideoProcessing/Thomas/Input/" InputDirectory = "%(VideoProcessingDir)sThomas/"
UnknownDirectory = "/srv/storage2/files/VideoProcessing/Unknown/Thomas/" UnknownDirectory = "%(UnknownInput)sThomas/"
OutputDirectory = "/srv/storage2/videos/Kids/TV/Thomas The Tank Engine & Friends/" OutputDirectory = "%(KidsTVDir)sThomas The Tank Engine & Friends/"
alias = "Thomas and Friends", alias = "Thomas and Friends",
MythTvEpisodePrefix = , MythTvEpisodePrefix = ,
SickbeardPrefix = "" SickbeardPrefix = ""
[[ "Chuggington" ]] [[ "Chuggington" ]]
InputDirectory = "/srv/storage2/files/VideoProcessing/Chuggington/Input/" InputDirectory = "%(VideoProcessingDir)sChuggington/"
UnknownDirectory = "/srv/storage2/files/VideoProcessing/Unknown/Chuggington/" UnknownDirectory = "%(UnknownInput)sChuggington/"
OutputDirectory = "/srv/storage2/videos/Kids/TV/Chuggington/" OutputDirectory = "%(KidsTVDir)sChuggington/"
alias = , alias = ,
MythTvEpisodePrefix = , MythTvEpisodePrefix = ,
SickbeardPrefix = "" SickbeardPrefix = ""
[[ "Mike the Knight" ]] [[ "Mike the Knight" ]]
InputDirectory = "/srv/storage2/files/VideoProcessing/MikeTheKnight/Input/" InputDirectory = "%(VideoProcessingDir)sMikeTheKnight/"
UnknownDirectory = "/srv/storage2/files/VideoProcessing/Unknown/MikeTheKnight/" UnknownDirectory = "%(UnknownInput)sMikeTheKnight/"
OutputDirectory = "/srv/storage2/videos/Kids/TV/Mike the Knight/" OutputDirectory = "%(KidsTVDir)sMike the Knight/"
alias = , alias = ,
MythTvEpisodePrefix = "Mike the Knight and the ", Mike the Knight and " MythTvEpisodePrefix = "Mike the Knight and the ", Mike the Knight and "
SickbeardPrefix = "" SickbeardPrefix = ""
[[ "Octonauts" ]] [[ "Octonauts" ]]
InputDirectory = "/srv/storage2/files/VideoProcessing/Octonauts/Input/" InputDirectory = "%(VideoProcessingDir)sOctonauts/"
UnknownDirectory = "/srv/storage2/files/VideoProcessing/Unknown/Octonauts/" UnknownDirectory = "%(UnknownInput)sOctonauts/"
OutputDirectory = "/srv/storage2/videos/Kids/TV/Octonauts/" OutputDirectory = "%(KidsTVDir)sOctonauts/"
alias = "The Octonauts", alias = "The Octonauts",
MythTvEpisodePrefix = "The Octonauts and ", MythTvEpisodePrefix = "The Octonauts and ",
SickbeardPrefix = "The" SickbeardPrefix = "The"
[[ "In the Night Garden" ]] [[ "In the Night Garden" ]]
InputDirectory = "/srv/storage2/files/VideoProcessing/InTheNightGarden/Input/" InputDirectory = "%(VideoProcessingDir)sInTheNightGarden/"
UnknownDirectory = "/srv/storage2/files/VideoProcessing/Unknown/InTheNightGarden/" UnknownDirectory = "%(UnknownInput)sInTheNightGarden/"
OutputDirectory = "/srv/storage2/videos/Kids/TV/In The Night Garden/" OutputDirectory = "%(KidsTVDir)sIn The Night Garden/"
alias = , alias = ,
MythTvEpisodePrefix = , MythTvEpisodePrefix = ,
SickbeardPrefix = "" SickbeardPrefix = ""
[[ "Raa Raa! The Noisy Lion" ]] [[ "Raa Raa! The Noisy Lion" ]]
InputDirectory = "/srv/storage2/files/VideoProcessing/RaaRaa/Input/" InputDirectory = "%(VideoProcessingDir)sRaaRaa/"
UnknownDirectory = "/srv/storage2/files/VideoProcessing/Unknown/RaaRaa/" UnknownDirectory = "%(UnknownInput)sRaaRaa/"
OutputDirectory = "/srv/storage2/videos/Kids/TV/Raa Raa the Noisy Lion/" OutputDirectory = "%(KidsTVDir)sRaa Raa the Noisy Lion/"
alias = ,
MythTvEpisodePrefix = ,
SickbeardPrefix = ""
[[ "Fireman Sam" ]]
InputDirectory = "%(VideoProcessingDir)sFiremanSam/"
UnknownDirectory = "%(UnknownInput)sFiremanSam/"
OutputDirectory = "%(KidsTVDir)sFireman Sam/"
alias = , alias = ,
MythTvEpisodePrefix = , MythTvEpisodePrefix = ,
SickbeardPrefix = "" SickbeardPrefix = ""

46
tests/TVEncodertest.py Normal file
View File

@@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
"""
Created on Sat Jul 13 20:37:47 2013
@author: shanef
"""
import unittest
import os
import sys
parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, parentdir)
import TVEncoder
class TVEncoderTest(unittest.TestCase):
def test_processarguments_encodereadonly(self):
args = []
args.append(('-e', ''))
args.append(('-l', ''))
result = TVEncoder.processarguments(args)
self.assertTrue(result.doencode)
self.assertTrue(result.readonly)
def test_processarguments_encodereadonlyreverse(self):
args = []
args.append(('-l', ''))
args.append(('-e', ''))
result = TVEncoder.processarguments(args)
self.assertTrue(result.doencode)
self.assertTrue(result.readonly)
def test_processarguments_encode(self):
args = []
args.append(('-e', ''))
result = TVEncoder.processarguments(args)
self.assertTrue(result.doencode)
self.assertFalse(result.readonly)
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(TVEncoderTest)
unittest.TextTestRunner(verbosity=2).run(suite)

33
tests/emailtest.py Normal file
View File

@@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
"""
Created on Fri Jul 19 23:31:16 2013
@author: shanef
"""
from minimock import Mock, mock
import unittest
import os
import sys
parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, parentdir)
import libemail
from libsettings import EmailSettings
import smtplib
class libemailtest(unittest.TestCase):
def test_SendEmail(self):
mock("EmailSettings.getfromaddress", returns="from@email.com")
mock("EmailSettings.gettoaddress", returns="to@email.com")
mock("EmailSettings.getsmtpserver", returns="smtp.test")
mock("EmailSettings.getsmtpuser", returns="user")
mock("EmailSettings.getsmtppassword", returns="password")
smtplib.SMTP = Mock('smtplib.SMTP')
smtplib.SMTP.mock_returns = Mock('smtp_connection')
libemail.sendemail("test", "subject", "body")
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(libemailtest)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -8,9 +8,11 @@ Created on Fri Jul 5 14:12:26 2013
import unittest import unittest
import os import os
import sys import sys
import minimock
from minimock import mock, Mock
parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, parentdir) sys.path.insert(0, parentdir)
from libfilemanager import EncodeData from libfilemanager import EncodeData, FileManager
class libfilemanagertest(unittest.TestCase): class libfilemanagertest(unittest.TestCase):
@@ -24,6 +26,92 @@ class libfilemanagertest(unittest.TestCase):
"{2}\n".format(showname, inputname, outputname) "{2}\n".format(showname, inputname, outputname)
self.assertEqual(result, expected) self.assertEqual(result, expected)
def test_EncodeDataCheckProblemsFileExists(self):
showname = "test show"
inputname = "test input"
outputname = "test_output.mkv"
data = EncodeData(showname, inputname, outputname)
mock("os.path.exists", returns=True)
result = data.checkproblems()
self.assertIn("FILE_EXISTS", result)
minimock.restore()
def test_EncodeDataCheckProblemsFile_Exists(self):
showname = "test show"
inputname = "test input"
outputname = "test_output_.mkv"
data = EncodeData(showname, inputname, outputname)
mock("os.path.exists", returns_iter=[False, True])
result = data.checkproblems()
self.assertIn("FILE_EXISTS", result)
minimock.restore()
def test_checkfileexistscaseinsensitive(self):
settings = Mock('libsettings.Settings')
filemanager = FileManager(settings)
mock("os.listdir", returns=["filename.test"])
result = filemanager.checkfileexists("/path/to/fiLename.test", False)
self.assertTrue(result)
minimock.restore()
def test_checkduplicateavi(self):
settings = Mock('libsettings.Settings')
filemanager = FileManager(settings)
os.walk = dummywalk
result = filemanager.checkduplicates("/path/to/S03E14 - Test - SD TV.mkv")
self.assertTrue(result)
minimock.restore()
def test_checkduplicatethomas(self):
settings = Mock('libsettings.Settings')
filemanager = FileManager(settings)
os.walk = thomaswalk
result = filemanager.checkduplicates("/path/to/S12E05 - Henry Gets It Wrong - SD TV.mkv")
self.assertTrue(result)
minimock.restore()
def test_checkduplicatenomatch(self):
settings = Mock('libsettings.Settings')
filemanager = FileManager(settings)
os.walk = dummywalk
result = filemanager.checkduplicates("/path/to/S03E13 - Test - SD TV.mkv")
self.assertFalse(result)
minimock.restore()
def test_checkduplicatesameextension(self):
settings = Mock('libsettings.Settings')
filemanager = FileManager(settings)
os.walk = dummywalk
result = filemanager.checkduplicates("/path/to/S03E14 - Test - SD TV.avi")
self.assertFalse(result)
minimock.restore()
def dummywalk(arg):
return [("/path/to/", [], ["S03E14 - Test - SD TV.avi"])]
def thomaswalk(arg):
return [(("/path/to/", [], ["S12E05 - Henry Gets It Wrong - Unknown.AVI"]))]
if __name__ == '__main__': if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(libfilemanagertest) suite = unittest.TestLoader().loadTestsFromTestCase(libfilemanagertest)
unittest.TextTestRunner(verbosity=2).run(suite) unittest.TextTestRunner(verbosity=2).run(suite)
minimock.restore()

View File

@@ -4,3 +4,48 @@ Created on Fri Jul 5 14:12:38 2013
@author: shanef @author: shanef
""" """
import unittest
from minimock import Mock
import os
import sys
parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, parentdir)
import libsickbeard
import urllib
class SickbeardTest(unittest.TestCase):
def test_findepisodeCloseSubtitle(self):
settings = Mock('libsettings.Settings')
settings.sickbeardaddress.mock_returns = "test"
settings.sickbeardport.mock_returns = "123"
settings.sickbeardapikey.mock_returns = "test"
urllib.urlopen = dummy_urlopen
sickbeard = libsickbeard.Sickbeard(settings)
result = sickbeard.findepisode("78949", "Splish, Splash, Splosh")
self.assertEqual("13", result[0])
self.assertEqual("15", result[1])
self.assertEqual("Splish, Splash, Splosh!", result[2])
def dummy_urlopen(arg):
class TmpClass:
def read(arg):
jsonresult = '{ "data": {"13": { "15": { "airdate": "2010-02-12", ' \
'"name": "Splish, Splash, Splosh!", "quality": "N/A", ' \
'"status": "Wanted" } } }, "message": "", ' \
'"result": "success" }'
return jsonresult
return TmpClass()
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(SickbeardTest)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
"""
Created on Thu Jul 18 23:13:15 2013
@author: shanef
"""
import unittest
from minimock import Mock
import os
import sys
parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, parentdir)
import libtvdatasource
class tvdatasourceTest(unittest.TestCase):
def test_GetOutputFilenameNoIllegals(self):
result = self._dooutputfilenametest("S01", "E02", "test name", "")
self.assertEqual(result, "S01E02 - test name - SD TV_.mpg")
def test_GetOutputFilenameOneIllegals(self):
result = self._dooutputfilenametest("S01", "E02", "test name?", "?")
self.assertEqual(result, "S01E02 - test name - SD TV_.mpg")
def test_GetOutputFilenameTwoIllegals(self):
result = self._dooutputfilenametest("S01", "E02", "tes>t name?", ["?", ">"])
self.assertEqual(result, "S01E02 - test name - SD TV_.mpg")
def _dooutputfilenametest(self, season, episode, name, illegals):
settings = Mock('libsettings.Settings')
settings.illegalcharacters.mock_returns = illegals
tvdatasource = libtvdatasource.TVData(settings)
return tvdatasource.getoutputfilename(season, episode, name)
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(tvdatasourceTest)
unittest.TextTestRunner(verbosity=2).run(suite)