Permalink
Browse files

cleaned up EpGuidesSearch.py; completely rewrote automover.py (now it…

… recurisvely searches and moves); caching is a lot saner now too
  • Loading branch information...
1 parent f5ddd39 commit 824ec46658b703988fe18012c7394dab8408dce8 @sagargp committed Dec 8, 2011
Showing with 231 additions and 236 deletions.
  1. +103 −159 EpGuidesSearch.py
  2. +11 −4 README
  3. +9 −0 automover.conf
  4. +108 −73 automover.py
View
@@ -1,160 +1,104 @@
-import sgmllib, urllib, json, re, time
+import sgmllib, urllib, json, re, time, socket
from EpGuidesParser import EpGuidesParser
-
-class EpGuidesSearch(object):
- def __init__(self, title, includeSpecials=False, cachefile='cache.p', debugfile='debug.log'):
- self.__title__ = title
- self.__eps__ = None
- self.__includeSpecials__ = includeSpecials
-
- self.__debugfile__ = debugfile
- self.__debughandle__ = open(self.__debugfile__, 'a')
-
- self.DEBUG('>> Show: %s <<' % title)
-
- self.__cachefile__ = cachefile
- self.__cache__ = dict()
- self.__cacheused__ = False
- self.__cacheLoad__()
-
- def DEBUG(self, str):
- self.__debughandle__.write("%s -- %s\n" % (time.ctime(), str))
-
- def __cacheWrite__(self):
- import pickle
-
- d = 'Writing cache...'
-
- self.__cache__[self.__title__] = self.__eps__
- f = open(self.__cachefile__, 'w')
- pickle.dump(self.__cache__, f)
-
- self.DEBUG('%s done.' % d)
-
- def __cacheLoad__(self):
- import pickle
-
- d = 'Loading cache...'
-
- try:
- f = open(self.__cachefile__, 'r')
- except IOError:
- return False
-
- self.__cache__ = pickle.load(f)
-
- self.DEBUG('%s %d shows loaded.' % (d, len(self.__cache__)))
- return True
-
- def __getEpisodes__(self):
- if self.__cache__ and self.__cache__.has_key(self.__title__):
- self.DEBUG('Using cache.')
- self.__cacheused__ = True
- return self.__cache__[self.__title__]
-
- self.DEBUG('Show not found in cache, or cache not found.')
- query = {"q": "allintitle: site:epguides.com %s" % self.__title__}
- search_url = "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&%s" % urllib.urlencode(query)
-
- self.DEBUG('Searching %s' % search_url)
- f = urllib.urlopen(search_url)
- json_results = f.read()
- results = json.loads(json_results)
-
- if results['responseStatus'] == 200 and results['responseData']['cursor'].has_key('estimatedResultCount'):
- self.__epguidesUrl__ = results['responseData']['results'][0]['url']
- else:
- return None
-
- self.DEBUG('Looking for show CSV listing at %s' % self.__epguidesUrl__)
- f = urllib.urlopen(self.__epguidesUrl__)
-
- myparser = EpGuidesParser()
- myparser.parse(f.read())
- f.close()
-
- csv_link = ''
- for link in myparser.get_hyperlinks():
- if link.find("exportToCSV") > 0:
- csv_link = link
-
- self.DEBUG('Downloading show data from %s' % csv_link)
- f = urllib.urlopen(csv_link)
- myparser.reset_data()
- myparser.parse(f.read())
- f.close()
-
- eps_csv = myparser.get_eps_csv()
- if '' in eps_csv:
- eps_csv.remove('')
- eps = []
-
- for i in range(0, len(eps_csv)):
- if i == 0:
- headers = eps_csv[0].split(',')
- continue
-
- row = eps_csv[i].split(',')
- row_dict = dict()
-
- for key in range(0, len(headers)):
- row_dict[headers[key]] = row[key]
-
- eps.append(row_dict)
-
- self.DEBUG('Done downloading episode data')
- return eps
-
- def search(self, season, ep):
- return self.__search__(season, ep)
-
- def reg_search(self, query):
- pattern = re.search("s(\d+)e(\d+)", query, flags=re.IGNORECASE)
- matched = pattern.groups()
-
- season = matched[0].lstrip('0')
- ep = matched[1].lstrip('0')
-
- return self.search(season, ep)
-
- def __search__(self, season, ep):
- self.getEpisodes()
-
- append = True
- results = []
-
- for episode in self.__cache__[self.__title__]:
- if season:
- if episode['season'] == season:
- if ep:
- if ep == episode['episode']:
- append = True
- else:
- append = False
- else:
- append = True
- else:
- append = False
-
- if not self.__includeSpecials__:
- if episode['special?'] == 'y':
- append = False
-
- if append:
- results.append(episode)
-
- return results
-
- def getEpguidesURL(self):
- if not self.__epguidesUrl__:
- self.__eps__ = self.__getEpisodes__()
-
- return self.__epguidesUrl__
-
- def getEpisodes(self):
- if not self.__eps__:
- self.__eps__ = self.__getEpisodes__()
-
- if not self.__cacheused__:
- self.__cacheWrite__()
- return self.__eps__
+
+class EpGuidesSearch:
+ def __init__(self, title, debugfile='debug.log', debug=False, verbose=False):
+ self.title = title
+ self.eps = None
+
+ self.cache = dict()
+
+ if debug:
+ self.debugfile = debugfile
+ self.debughandle = open(self.debugfile, 'a')
+
+ self.doDebug = debug
+ self.verbose = verbose
+ self.debug('Show name: %s' % title)
+
+ def debug(self, str):
+ out = '%s -- %s\n' % (time.ctime(), str)
+
+ if self.doDebug:
+ self.debughandle.write(out)
+
+ if self.verbose:
+ print out,
+
+ def getEpisodes(self):
+ if self.cache.has_key(self.title):
+ self.debug('Returning cached data...')
+ return self.cache[self.title]
+
+ query = {"q": "allintitle: site:epguides.com %s" % self.title, "userip": socket.gethostbyname(socket.gethostname())}
+ search_url = "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&%s" % urllib.urlencode(query)
+
+ self.debug('Searching for show at %s' % search_url)
+
+ page = urllib.urlopen(search_url)
+ json_results = page.read()
+ results = json.loads(json_results)
+ page.close()
+
+ if results['responseStatus'] == 200 and results['responseData']['cursor'].has_key('estimatedResultCount'):
+ self.epguides_url = results['responseData']['results'][0]['url']
+ else:
+ self.debug('Show not found! Dumping search results object:')
+ self.debug(results)
+ self.debug('<<<')
+ return None
+
+ self.debug('Looking for CSV listing at %s' % self.epguides_url)
+ page = urllib.urlopen(self.epguides_url)
+
+ parser = EpGuidesParser()
+ parser.parse(page.read())
+ page.close()
+
+ csv_link = ''
+ for link in parser.get_hyperlinks():
+ if link.find('exportToCSV') > 0:
+ csv_link = link
+ break
+
+ if csv_link == '':
+ self.debug('Error! Can\'t find CSV listing for %s at %s! Bailing out...' % (self.title, self.epguides_url))
+ return None
+
+ self.debug('Downloading show data...')
+ page = urllib.urlopen(csv_link)
+ parser.reset_data()
+ parser.parse(page.read())
+ page.close()
+
+ csv = parser.get_eps_csv()
+ if '' in csv:
+ csv.remove('')
+ eps = []
+
+ for i in range(0, len(csv)):
+ if i == 0:
+ headers = csv[0].split(',')
+ continue
+
+ row = csv[i].split(',')
+ rowdict = dict()
+
+ for key in range(0, len(headers)):
+ rowdict[headers[key]] = row[key]
+
+ eps.append(rowdict)
+
+ self.debug('Done')
+ self.cache[self.title] = eps
+ return eps
+
+ def search(self, season, ep):
+ results = []
+
+ if self.getEpisodes():
+ for episode in self.cache[self.title]:
+ if episode['season'] == season and episode['episode'] == ep:
+ results.append(episode)
+
+ return results
View
@@ -1,5 +1,12 @@
-right now it outputs old name, new name pairs. eg:
+Modify the config file to your suitability, then run automover like so:
+
+ $ automover --config automover.conf --script mover.sh --verbose .
+ $ ./mover.sh
+
+Make sure to check mover.sh before running it.
+
+Future plans:
+* also output an 'undo' script that unmoves the object
+* check that we're not overwriting any destination files, if so, utter a warning and back it up
+* handle formats like modern.family.302.hdtv.xvid-lol.avi
-$ tvrenamer.py --title "Mad Men" --directory /srv/media/television/Mad\ Men/Season\ 4
-Mad.Men.S04E02.720p.WEB-DL.AAC2.0.H.264-CtrlHD.mkv "Mad Men S04E02 Christmas Comes But Once a Year.mkv"
-...
View
@@ -0,0 +1,9 @@
+[default]
+# where the files should be moved
+destination = /srv/media/television
+
+# regular expression to match the episode title format
+pattern = (.*)s(\d+)e(\d+).*(mkv|avi)
+
+# regular expression for things to avoid
+exclude = .*sample.*
Oops, something went wrong.

0 comments on commit 824ec46

Please sign in to comment.