Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- #encoding:utf-8
- import urllib
- import xml.dom.minidom
- import re
- import time
- import os
- import sys
- import string
- from tvdb_api import (tvdb_error, tvdb_shownotfound, tvdb_seasonnotfound,
- tvdb_episodenotfound, tvdb_episodenotfound, tvdb_attributenotfound, tvdb_userabort)
- from tvdb_api import Tvdb
- ######
- # TV #
- ######
- __author__ = "minimad/Neil"
- __version__ = "0.88"
- ################################### MEGA IMPORTANT ##################################################
- #
- # This script also requires the tvdb_api from http://github.com/dbr/tvdb_api/tree/master
- # you will require ALL the files (well, maybe not the setup.py) and they need to be in the same dir
- # as this script
- #
- # Expected Show format is (Showname/Season XX/Showname - SxxExx - Episodename.ext e.g.
- # House/Season 02/House - S02E01 - Autopsy.avi
- #
- ################################### MEGA IMPORTANT ##################################################
- ################################### CHANGE LOG ######################################################
- #
- # 090103 1600 Now uses SAB 0.4.6 illegal character replacement behaviour
- #
- # 090112 2300 Uses tvdb_api to validate show name
- #
- # 090114 2300 Cleaned up the code, used re.pattern in print statements where possible
- # and tried to limit number of places to change for new formats by using vars
- #
- # 090117 2300 Fixed bug - Queued name is meant to be original report, NOT reformated version
- #
- # 090117 2330 Added required video format functionality
- #
- # 090117 2345 Moved Season/Episode regex formats to user config area
- #
- # 090120 2045 Added Debug setting for 'print' statements
- # Fixed IsMissing regex to look for both cases of S and E i.e. s and S
- # Fixed season_to_check variable
- # A few wording changes
- #
- # 090121 2330 Made 'Smart' queue optional
- # Removing Illegal Chars at end of cleanSeriesName if Win32
- # Moved Format check into isWanted. Check format before checking for show.
- # Should reduce processing time by not checking all shows then finding out that format isn't wanted
- # Removed sum_file_size function as not
- #
- # 090122 0015 Added 'extra' debug messages
- # Fixed 'Smart' Queue
- # Moved Change Log to Top of Script
- # Added 'Known Issues'
- # Made Code more consistant
- #
- # 090122 2200 Fixed 'isMissing', left a test string in place, so it always thought you needed the episode
- # Also it 'bombed' out because I left an icorrectly anmed variable in
- #
- # 090123 2200 Added option to choose SABnzbd style or tvnamer.py style, illegal character replacement
- # Added option to force Windows compliant names, useful if you run this on a linux box but access via windows
- # Now we reformat a NewzBin into the same format as a 'non' newzbin feed, Smart Queue should work better now
- # Added an 'Aliases' function to trasnlate known 'Aliases' into proper show names, at least until the tvdb_api has
- # this functionality which is due in the next few weeks
- #
- # 090124 0015 'Smart' queue wasn't being smart, it was still checking filename against a reformated string, now fixed
- # However the script is considerably slower due to the number of calls to tvdb_api, now once per queue entry per queue check
- #
- # 090124 2300 Fixed NewzBin adding to queue, was trying to add entire url (thanks markus101).
- #
- # 090125 0935 New Function, isInHistorySmart (ONLY 0.5.0 onwards), checks the history for the show, episode
- # NOT COMPLETE, NOT ACTIVE IN CODE
- #
- # 090125 2200 0.80 NEW FEATURE - Per Show AND Season Format Matching. Only get the format specified for the show and season
- #
- # 090126 1430 0.81 Should find files in ANY supported format (supported formats in Importnat Info section), no need to rename files
- #
- # 090126 2330 MAJOR Code Cleanup. Most probably broke everything.
- #
- # 090127 1100 0.82 Fixed - MATCH FOUND now returns the Season & Episode rather than the regex pattern that found it
- # (regex pattern looks like gibberish
- # Fixed - General Format Matching - I had changed the regex, now back to what it was.
- #
- # 090128 2220 0.84 Multiple Feed Functionality, Script now smart enough to know a newzbin feed
- # Fixed - NewzBin format check
- #
- # 090206 2050 0.88 Changed way isWanted looks for a show, it now loops through the tvdirs checking a lowercase
- # dir against a lowercase series_title
- #
- #
- ################################### CHANGE LOG ######################################################
- ################################### KNOWN ISSUES ####################################################
- #
- # Script is too fast and gets 'Trying to fetch NZB from.....' in the Queue. 'Smart' queue and 'Normal' Queue
- # are unable to check show, episode or filename in this instance so they assume it isn't in the queue.
- #
- # This script is UNABLE to process feeds that are gzip'd, TVBINZ etc are now using gzip'd feeds
- # Use www.feedburner.com to turn them back into 'raw' feeds.
- #
- # Seems to have a problem with shows that have a : (colon) in them e.g. CSI: Miami, CSI: NY etc
- #
- ################################### KNOWN ISSUES ####################################################
- ################################### TO DO (NOT IN ORDER) ############################################
- #
- # Improve script speed, All those tvdb_api calls, REALLY slows it down, maybe cache the answers????
- # Have config settings in another file.
- #
- ################################### TO DO ###########################################################
- ################################### IMPORTANT INFO ##################################################
- # To ignore a whole season, create a file or directory in the directory for your show with this name
- # ignore Season x
- # e.g. c:\tv\lost\ignore Season 1
- #
- # To use Per Show and Season format matching, create a file or directory in the SHOW directory with
- # name format Sxx.yyyy.format
- # Where xx is the season number
- # Where yyyy is the format, either xvid or x264
- # e.g. S01.xvid.format
- # S02.x264.format
- #
- # Supported File Naming Formats:-
- #
- # seriesname.s01e02.dsr.nf.avi
- # seriesname.S01E02.PROPER.dsr.nf.avi
- # seriesname.s01.e02.avi
- # seriesname-s01e02.avi
- # seriesname-s01e02.the.wrong.ep.name.avi
- # seriesname - [01x02].avi
- # seriesname - [01x002].avi
- # seriesname-[01x02].avi
- # seriesname [01x02].avi
- # seriesname [01x02] epname.avi
- # seriesname [01x02] - the wrong ep name.avi
- # seriesname - [01x02] - the wrong ep name.avi
- # seriesname.01x02.epname.avi
- # seriesname.102.epname.avi
- # seriesname_s1e02_epname.avi
- # seriesname - s01e02 - dsr.nf.avi
- # seriesname - s01e02 - the wrong ep name.avi
- # seriesname - s01e02 - the_wrong_ep_name!.avi
- #
- ################################### IMPORTANT INFO ##################################################
- #################################### CHANGE TO YOUR OWN VALUES ######################################
- #
- # set this to the location of your downloads. the first entry must be your live download area
- if sys.platform == "win32":
- tv_dirs=[ "Z:" ]
- else:
- tv_dirs=[ "/share/Qmultimedia/TV_Shows" ]
- # the RSS link to your search
- nzbfeeds=[
- "http://myfeed.rss",
- "http://feeds.feedburner.com/minimad-csi"
- ]
- # your SABNZB address
- my_SAB="http://192.168.1.200:8800"
- # /sabnzbd is added below
- # additional SAB parameters to e.g. specify the category, and/or script to run. see http://sabnzbd.wikidot.com/automation-support
- my_SAB_params="&cat=tv"
- # Use NewzBin feed
- # Changes several sections to use NewzBin specific functionality
- # NO LONGER USED, Script is Mart enough to know a NewzBin feed when it sees it
- # becuase the feed has newzbin in the url e.g. http://www.newzbin.com
- #NewzBin = False
- # theTVDB api
- # Set tvdb_interactive=True to select shows returned, otherwise it takes first show returned (usually the right one)
- tvdb_interactive=False
- # Required video formats
- # for x264 enter 'x264'
- # for xvid enter 'xvid'
- # for 720p enter '720p'
- # for 1080p enter '1080'
- # for multiple formats put | between them and brackets around each group e.g.
- # ([x264])|([xvid])
- #
- video_formats='x264'
- # Season/Episode Formats
- # Standard Regex with brackets around each format and seperated by |
- season_formats="([sS][0-9][0-9])|([0-9]?[0-9][xX])"
- episode_formats="([eE][0-9][0-9])|([xX][0-9][0-9])"
- # DEBUG
- # Set debug to True, to see what this scrip is doing
- debug = True
- # theTVDB api
- # Set tvdb_debug=True to see debug info from theTVDB api
- tvdb_debug=False
- # 'Smart' Queue checking
- # Set to True to use 'Smart' Queue checking
- # Looks for the Show, Episode in Queue rather than the filename
- useSmartQueue = True
- # SABnzbd or tvnamer.py style illegal char replaement
- # Set to True to use SABnzbd Style
- SABnzbdIllegalCharsStyle = False
- # Force Windows Compliant Names
- # Set to True to force script to use windows compliant names
- force_windows_compliant_filenames = True
- ################################### CHANGE TO YOUR OWN VALUES #####################################
- config = {}
- reportdict = {}
- config['valid_filename_chars'] = """0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@£$%^&*()_+=-[]:{}"'.,<>`~? """
- config['with_ep_name'] = '%(seriesname)s - S%(seasno)02dE%(epno)02d - %(epname)s'
- # Force the stripping of invalid Windows characters, even if the current
- # platform is not detected as Windows
- config['force_windows_compliant_filenames'] = True
- if sys.platform == "win32" or config['force_windows_compliant_filenames']:
- # " * : < > ? | \ are all invalid on Windows
- config['valid_filename_chars'] = config['valid_filename_chars'].replace("\"*:<>?|\\","")
- config['valid_filename_chars_regex'] = re.escape(config['valid_filename_chars'])
- # Regex's to parse filenames with. Must have 3 groups, seriesname, season number
- # and episode number. Use (?: optional) non-capturing groups if you need others.
- # taken from tvnamer.py script
- config['name_parse'] = [
- # foo_[s01]_[e01]
- re.compile('''^([%s]+?)[ \._\-]\[[Ss]([0-9]+?)\]_\[[Ee]([0-9]+?)\]?([%s]+)[^\\/]*$''' % (config['valid_filename_chars_regex'], config['valid_filename_chars_regex']) ),
- # foo.1x09*
- re.compile('''^([%s]+?)[ \._\-]\[?([0-9]+)x([0-9]+)([%s]+)[^\\/]*$''' % (config['valid_filename_chars_regex'], config['valid_filename_chars_regex']) ),
- # foo.s01e01.title
- re.compile('''^([%s]+?)[ \._\-][Ss]([0-9]+)[\.\- ]?[Ee]([0-9]+)[ \._\-]([%s]+)[^\\/]*$''' % (config['valid_filename_chars_regex'], config['valid_filename_chars_regex']) ),
- # foo.s01.e01, foo.s01_e01, foo.s01e01
- re.compile('''^([%s]+?)[ \._\-][Ss]([0-9]+)[\.\- ]?[Ee]([0-9]+)([%s]+)[^\\/]*$''' % (config['valid_filename_chars_regex'], config['valid_filename_chars_regex']) ),
- # foo.103*
- re.compile('''^([%s]+)[ \._\-]([0-9]{1})([0-9]{2})[\._ -]([%s]+)[^\\/]*$''' % (config['valid_filename_chars_regex'], config['valid_filename_chars_regex']) ),
- # foo.0103*
- re.compile('''^([%s]+)[ \._\-]([0-9]{2})([0-9]{2,3})[\._ -]([%s]+)[^\\/]*$''' % (config['valid_filename_chars_regex'], config['valid_filename_chars_regex']) ),
- ]
- # Class to allow an exception to be raised
- # if format is not wanted
- class FormatNotWanted:
- pass
- class formatError:
- pass
- # SABnzbd style illegal chars
- illegal = r'\/<>?*:;|"'
- legal = r'++{}!@--#`'
- translate_table = string.maketrans(illegal, legal)
- #Directory Seperator Character (default linux)
- ds="/"
- #If Win32 then double backslash
- if sys.platform == "win32":
- ds="\\"
- already=[]
- #RegEx Compiles
- daily=re.compile("([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9])|([0-9][0-9][0-9][0-9]\.[0-9][0-9]\.[0-9][0-9])")
- season_re = re.compile( season_formats )
- episode_re = re.compile( episode_formats )
- video_formats_re = re.compile( video_formats, re.IGNORECASE )
- #### SimpleCache Start - jason.fisher@gmail.com
- class SimpleCache:
- def __init__(self, filename="simplecache.pyd", debug=1, safe=1):
- self.file = os.path.join(os.path.dirname(sys.argv[0]),filename)
- self.debug = debug
- self.safe = safe
- self.init = 0
- self.msg("loading " + self.file + " .. ")
- try:
- cache = open(self.file,"r")
- except IOError, EOFError:
- try:
- self.msg("new cache file: " + self.file)
- cache = open(self.file,"w")
- self.data = {'evalcacheversion_creation':'20090212a-jmf'}
- self.msg(self.data)
- pickle.dump(self.data, cache)
- cache.close()
- self.msg(".. created.")
- cache = open(self.file,"r")
- except IOError, EOFError:
- self.msg("cannot open/create " + self.file)
- return 0
- self.data = pickle.load(cache)
- self.msg(".. done.")
- self.msg(self.data)
- cache.close()
- def msg(self, val):
- if self.debug:
- print val
- def save(self):
- self.msg("saving " + self.file)
- self.msg(self.data)
- try:
- cache = open(self.file,"w")
- pickle.dump(self.data, cache)
- cache.close()
- except IOError:
- self.msg("error")
- self.msg(".. done.")
- def read(self, key):
- self.msg("looking for " + str(key))
- if str(key) in self.data:
- if self.debug:
- self.msg("hit: " + str(key) + " = " + str(self.data[str(key)]))
- return self.data[str(key)]
- self.msg("not cached.")
- return 0
- def write(self, key, value):
- self.msg("storing " + str(key))
- self.data[str(key)] = str(value)
- if self.debug and self.data[str(key)]:
- self.msg(".. done: " + str(self.data[str(key)]))
- if self.safe:
- self.save()
- return self.data[str(key)]
- #### Simple Caching End
- import pickle
- cache = SimpleCache()
- ####
- def removeIllegalChars(origstring):
- if SABnzbdIllegalCharsStyle:
- try:
- return str(origstring).translate(translate_table)
- except:
- return origstring
- else:
- try:
- # convert unicode to ASCII
- newstring = origstring.encode('ascii', 'ignore')
- # replace illegal chars with nothing
- return re.sub("[*:<>|]", "", newstring).strip()
- except:
- return origstring
- #end if SABnzbdIllegalStyle
- #end def removeIllegalChars
- def isInQueue(download_title):
- queue=xml.dom.minidom.parse(urllib.urlopen(my_SAB+"/sabnzbd/api?mode=qstatus&output=xml"))
- for job in queue.getElementsByTagName("job"):
- filename=job.getElementsByTagName("filename")[0].childNodes[0].data
- regex_download_title_string = removeIllegalChars(download_title)
- regex_download_title = re.compile(regex_download_title_string, re.IGNORECASE)
- if re.match(regex_download_title, filename):
- if debug:
- print("IS IN QUEUE: " + regex_download_title.pattern)
- #end if debug
- return 1
- #end if re.match
- #end for job
- if debug:
- print("IS NOT IN QUEUE: " + regex_download_title.pattern)
- #end if debug
- return 0
- #end def isInQueue
- def isInQueueSmart(series, season, episode):
- print("ENTERED isInQueueSmart")
- # Compile the regex
- regex_download_title = re.compile(series + " - S" + season + "E" + episode, re.IGNORECASE)
- # Get the Queue
- queue=xml.dom.minidom.parse(urllib.urlopen(my_SAB+"/sabnzbd/api?mode=qstatus&output=xml"))
- # Process each job in Queue
- for job in queue.getElementsByTagName("job"):
- filename=job.getElementsByTagName("filename")[0].childNodes[0].data
- try:
- if debug:
- print("CHECK QUEUE: " + filename)
- #end if debug
- filename = formatReport(filename)
- series,epstr,eptitle=filename.split(' - ')
- series=cleanSeriesName(series)
- filename=series + " - " + epstr + " - " + eptitle
- if debug:
- print("CHECK REFORMAT QUEUE: " + filename)
- #end if debug
- if re.search(regex_download_title, filename):
- if debug:
- print("IS IN QUEUE: " + regex_download_title.pattern)
- #end if debug
- return 1
- #end if re.match
- except:
- # Queue Check Failed, so assume it's not in Queue
- pass
- #end for job
- if debug:
- print("IS NOT IN QUEUE: " + regex_download_title.pattern)
- #end if debug
- return 0
- #end def isInQueue
- def isInHistorySmart(series, season, episode):
- # Compile the regex
- regex_download_title = re.compile(series + " - S" + season + "E" + episode, re.IGNORECASE)
- # Get the Histroy
- queue=xml.dom.minidom.parse(urllib.urlopen(my_SAB+"/sabnzbd/api?mode=history&output=xml"))
- # Process each job in Queue
- for job in queue.getElementsByTagName("slot"):
- jobname=job.getElementsByTagName("name")[0].childNodes[0].data
- try:
- if debug:
- print("CHECK HISTORY: " + jobname)
- #end if debug
- jobname=reformatReport(filename)
- series,epstr,eptitle=jobname.split(' - ')
- series=cleanSeriesName(series)
- jobname=series + " - " + epstr + " - " + eptitle
- if debug:
- print("CHECK REFORMAT HISTORY: " + jobname)
- #end if debug
- if re.search(regex_download_title, jobname):
- if debug:
- print("IS IN HISTORY: " + regex_download_title.pattern)
- #end if debug
- return 1
- #end if re.match
- except:
- # Queue Check Failed, so assume it's not in Queue
- pass
- #end for job
- if debug:
- print("IS NOT IN HISTORY: " + regex_download_title.pattern)
- #end if debug
- return 0
- #end def isInHistorySmart
- def isWanted(series_title):
- if debug:
- print("CHECK WANTED: " + series_title)
- #end if debug
- for dir in tv_dirs:
- for filename in os.listdir(dir):
- print("DEBUG: " + filename.lower() )
- print("DEBUG: " + series_title.lower() )
- if debug:
- print("LOOKING FOR: " + dir + ds + series_title)
- #end if debug
- if filename.lower() == series_title.lower():
- if debug:
- print("SHOW WANTED: " + series_title)
- #end if debug
- return 1
- #end if os.path
- #end for filename
- #end for dir
- if debug:
- print("SHOW NOT WANTED: " + series_title)
- #end if debug
- return 0
- #end def isWanted
- def isFormatWanted(series_title, report, season, feed_type):
- # Override Format checking for NewzBin feeds
- if feed_type == 'NewzBin':
- if debug:
- print("NEWZBIN FORMAT OVERRIDE: " + report)
- #end if debug
- return 1
- #end if feed_type
- # Allow per Show/Season Format OverRide
- for dir in tv_dirs:
- if os.path.exists(dir + ds + series_title):
- for filename in os.listdir(dir + ds + series_title):
- if filename[9:] == 'format':
- if filename[1:3] == season:
- if re.search(filename[4:8], report , re.IGNORECASE):
- if debug:
- print("SHOW FORMAT WANTED: " + report)
- #end if debug
- return 1
- else:
- if debug:
- print("SHOW FORMAT NOT WANTED: " + report)
- #end if debug
- return 0
- #end if re.search
- #end if file[1:3]
- #end if file[9:]
- #end for file
- #end if os.path
- #end for dir
- # General Format Wanted
- # Used if Show/Season not specified
- format_object = video_formats_re.search( report , re.IGNORECASE)
- if format_object:
- if debug:
- print("FORMAT WANTED: " + report)
- #end if debug
- return 1
- #end if format_object
- if debug:
- print("FORMAT NOT WANTED: " + video_formats_re.pattern + " " + report)
- #end if debug
- raise FormatNotWanted
- #end def isFormatWanted
- def isMissing(series_title, season_number, episode_number):
- print("LOOKING: " + "Season " + str(season_number) + ", Episode " + str(episode_number))
- for dir in tv_dirs:
- series_path=dir + ds + showToFolder(series_title) + ds + "Season " + season_number
- print("CHECK: " + series_title + " for seasons to IGNORE")
- # ignore this season if told to do so (existence of file or directory called ignore Season x)
- if os.path.exists(dir + ds + showToFolder(series_title) + ds + "ignore Season " + season_number):
- if debug:
- print("IGNORE: Season " + season_number)
- #end if debug
- return 0
- else:
- if debug:
- print("PROCESS: Season " + season_number)
- #end if debug
- #end if os.path.exists
- if os.path.exists(series_path):
- if debug:
- print("EXIST: " + series_path)
- #end if debug
- for tested_episode in os.listdir(series_path):
- if debug:
- print("CHECK: " + tested_episode)
- #end if debug
- for r in config['name_parse']:
- match = r.match(tested_episode)
- if match:
- seriesname, seasno, epno, epname = match.groups()
- if re.search(series_title, seriesname, re.IGNORECASE):
- if seasno == season_number:
- if epno == episode_number:
- if debug:
- print("MATCH FOUND: " + "Season " + season_number + ", Episode " + episode_number)
- #end if debug
- return 0
- #end if epno
- #end if seasno
- #end if seriesname
- #end if match
- #end for r
- #end for tested_episode
- else:
- if debug:
- print("NOT EXIST: " + series_path)
- #end if debug
- #end if os.path.exists
- if debug:
- print("MISSING: " + "Season " + season_number + ", Episode " + episode_number)
- #end if debug
- #end for dir
- return 1
- #end def isMissing
- def download(report_id):
- print "ADD QUEUE: " + time.strftime("%Y-%m-%d %H:%M:%S")+": "+ report_id
- # Check report_id, if it starts http, its not a NewzBin id
- if report_id[:4] == 'http':
- #'Other' NZB RSS
- urllib.urlopen(my_SAB+"/sabnzbd/api?mode=addurl&name="+report_id+my_SAB_params)
- else:
- #NewzBin Style
- urllib.urlopen(my_SAB+"/sabnzbd/api?mode=addid&name="+report_id+my_SAB_params)
- #end if NewzBin
- #end def download
- def cleanSeriesName(series_title):
- global cache
- theTVDB = Tvdb(debug = tvdb_debug, interactive = tvdb_interactive)
- good_series_title = removeIllegalChars(series_title)
- good_series_title = good_series_title.replace("(", "\(").replace(")", "\)")
- good_series_title = re.sub('\.|_', ' ', good_series_title)
- if debug:
- print "NZB: ", good_series_title
- #end if debug
- try:
- good_series_title = showAlias(good_series_title)
- if cache.read(good_series_title.lower()):
- good_series_title = cache.read(good_series_title.lower())
- else:
- good_series_title = cache.write(good_series_title.lower(),theTVDB[good_series_title]['seriesname'])
- if debug:
- print "TVDB: ", good_series_title
- #end if debug
- except tvdb_shownotfound:
- # Didn't find the show @ theTVDB,
- # most likely has 'and' and theTVDB has '&'
- try:
- if cache.read(re.sub(' [aA]nd ', ' & ', good_series_title.lower())):
- good_series_title = cache.read(re.sub(' [aA]nd ', ' & ', good_series_title.lower()))
- else:
- good_series_title = cache.write(good_series_title.strtolower(),theTVDB[re.sub(' [aA]nd ', ' & ', good_series_title.strtolower())]['seriesname'])
- if debug:
- print "TVDB: ", good_series_title
- #end if debug
- except tvdb_shownotfound:
- # Well, didn't find it a second time, even using '&'
- # return cleaned good_series_title
- good_series_title = good_series_title
- if debug:
- print "TVDB NOT FOUND: ", good_series_title
- #end if debug
- #If Win32 then remove illegal chars
- if sys.platform == "win32" or force_windows_compliant_filenames:
- good_series_title = removeIllegalChars(good_series_title)
- #end if sys.platform
- return good_series_title
- #end def cleanSeriesName
- def formatReport( report ):
- # format into ' - ' seperated parts
- # showname - seasonepisode - title
- for r in config['name_parse']:
- match = r.match( report )
- if match:
- seriesname, seasno, epno, epname = match.groups()
- # Remove any space dash space that might be left over
- # We're going to put them in anyway but need to make sure we don't 'double' them
- reportdict['seriesname'] = re.sub("\s\-\s|\s\-", "", seriesname)
- reportdict['seasno'] = int(seasno)
- reportdict['epno'] = int(epno)
- reportdict['epname'] = re.sub("\s\-\s|\s\-", "", epname)
- # Format the report name
- report = config['with_ep_name'] % (reportdict)
- return report
- #end if match
- #end for r
- raise formatError
- #end def formatReport
- def showAlias(showname):
- # Takes a showname and matches it to an alias
- # e.g. CSI should map to CSI: Crime Scene Investigation and not CSI: NY
- # as returned by theTVDB api
- if re.match('CSI.+?N?.+?Y', showname, re.IGNORECASE):
- print("MATCHED CSI: NY")
- return "CSI: NY"
- #end if re.match
- if re.match("CSI Miami", showname, re.IGNORECASE):
- print("MATCHED CSI Miami")
- return "CSI: Miami"
- #end if re.match
- if re.match("CSI", showname, re.IGNORECASE):
- print("MATCHED CSI")
- return "CSI: Crime Scene Investigation"
- #end if re.match
- if re.match("DEMONS", showname, re.IGNORECASE):
- print("MATCHED DEMONS")
- return "Demons"
- #end if re.match
- # Didn't match anything so return the passed showname
- return showname
- #def showAlias
- def showToFolder(showname):
- # Takes a showname and returns the foldername associated
- # e.g. CSI NY could return CSI New York
- if re.match('CSI.+?N?.+?Y', showname, re.IGNORECASE):
- print("MATCHED CSI: NY")
- return "CSI NY"
- #end if re.match
- # Didn't match anything so return the passed showname
- return showname
- #def showToFolder
- def Main():
- for feed in nzbfeeds:
- print("PROCESS NZB FEED: " + feed)
- # Set feed type
- # NewzBin feeds have different 'titles'
- if re.search('newzbin', feed, re.IGNORECASE):
- feed_type = 'NewzBin'
- if debug:
- print("FEED: " + feed_type)
- #end if debug
- else:
- feed_type = 'Other'
- if debug:
- print("FEED: " + feed_type)
- #end if debug
- #end if re.search
- dom=xml.dom.minidom.parse(urllib.urlopen(feed))
- for node in dom.getElementsByTagName("item"):
- report=node.getElementsByTagName("title")[0].childNodes[0].data
- report_original=report
- print "PROCESSING:"+report
- #try-catch block because some of this stuff fails hard when it gets a weird report, and pythons default behavior is to terminate
- try:
- report=formatReport(report)
- #Split report into 3 parts
- series,epstr,title=report.split(' - ')
- if daily.match(epstr):
- year,month,date=epstr.split("-")
- season=year+"-"+month
- episode=date
- else:
- season=epstr[1:3]
- episode=epstr[4:]
- #end if daily.match
- # Clean series name here (reduces number of times the same code is called)
- series=cleanSeriesName(series)
- toDownload = False
- if not useSmartQueue:
- if isWanted(series, report, season, feed_type) and isMissing(series, season, episode, feed_type) and (not isInQueue(report_original)):
- toDownload = True
- else:
- toDownload = False
- #end if isWanted(series)
- else:
- if isWanted(series):
- if isFormatWanted(series, report, season, feed_type):
- if isMissing(series, season, episode):
- if not isInQueueSmart(series, season, episode):
- toDownload = True
- #end if not isInQueueSmart
- #end if isMissing
- #end if isWanted(seies)
- #end if not useSmartQueue
- if toDownload:
- if feed_type == 'NewzBin':
- msgid=node.getElementsByTagName("report:id")[0].childNodes[0].data
- else:
- msgid=node.getElementsByTagName("link")[0].childNodes[0].data
- #end if NewzBin
- msgid=urllib.quote(msgid)
- download(msgid)
- #end if toDownload
- except:
- print("FAILED PROCESSING: " + report)
- pass
- #end try:
- #end for node
- #end for feed
- #end def Main
- if __name__ == '__main__':
- Main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement