Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- # Episode rename 0.8 - Copyright 2008 Stavros Korokithakis
- # Heavily modified by Rafael Fonseca
- # Released under the GNU GPL.
- # You can find the latest version at http://www.poromenos.org
- import urllib
- import urllib2
- import optparse
- import re
- import os
- import sys
- import subprocess
- import random
- import shutil
- import htmlentitydefs
- import hashlib
- from datetime import date
- class Show:
- def __init__(self, title="", rating=0):
- self.title = title
- self.attributes = {}
- self.episodes = {}
- def search_show(name):
- """Search Google for the page best matching the given show name."""
- google_url = "http://www.google.com/search?q=site%%3Aepguides.com+%s" % urllib.quote(name)
- # Bastard Google...
- request = urllib2.Request(google_url)
- request.add_header("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.1.4) Gecko/20070515 Firefox/2.0.0.4")
- page = urllib2.urlopen(request).read()
- try:
- show_id = re.search("epguides.com\/(.*?)\/", page).group(1)
- except AttributeError:
- try:
- show_id = re.search("epguides.com\/(.*?)\/", page).group(0)
- except AttributeError:
- print "Could not find show title for %s, cannot continue." % name
- sys.exit()
- return show_id
- def parse_epguides(page):
- """Parse an epguides page."""
- page = page.replace("\n", "")
- page = page.replace("'","'")
- show = Show()
- d = date.today()
- try:
- show.title = re.search("""<h1><a href="http://.*?">(.*?)</a></h1>""", page).groups()[0]
- except AttributeError:
- print "Could not find show title, cannot continue."
- sys.exit()
- matches = re.search("""<td>aired from: <em>.* (\d+)</em><br />to: <em>.*</em></td>""", page)
- try:
- year = matches.group(1)
- year = 2000 + int(year)
- if year > d.year:
- year = year - 100
- except IndexError:
- year = None
- show.attributes["year"] = year
- episodes = re.findall("\d+. +(?P<season>\d+) *\- *(?P<episode>\d+).*?(?P<day>\d+)(?:\/|\s)+(?P<month>[A-Za-z]+)(?:\/|\s)+(?P<year>\d+) +(?:<a [^>]+><img [^\r\n]+></a>)? ?<a [^>]*>(?P<name>.*?)</a>", page)
- month_dict = {"Jan": 1,
- "Feb": 2,
- "Mar": 3,
- "Apr": 4,
- "May": 5,
- "Jun": 6,
- "Jul": 7,
- "Aug": 8,
- "Sep": 9,
- "Oct": 10,
- "Nov": 11,
- "Dec": 12}
- for season, episode, day, month, year, name in episodes:
- show.episodes[(int(season), int(episode))] = {"title": name}
- #print "DEBUG: s%s e%s" % (season, episode)
- year = 2000 + int(year)
- if year > d.year:
- year = year - 100
- try:
- release_date = "%s-%02d-%02dT12:00:00Z" % (int(year),month_dict[month],int(day))
- except TypeError:
- continue
- show.episodes[(int(season), int(episode))]["year"] = release_date
- return show
- def rename_file(filename, show, file_mask, preview=False, use_ap=False, force=False):
- series_parser = [
- re.compile("^.*?s *(?P<series>\d+) *e *(?P<episode>\d+).*\.(?P<extension>.*?)$", re.IGNORECASE),
- re.compile("^.*?(?P<series>\d+)x(?P<episode>\d+).*\.(?P<extension>.*?)$", re.IGNORECASE),
- re.compile("^(?:.*?\D|)(?P<series>\d{1,2})(?P<episode>\d{2})(?:\D.*|)\.(?P<extension>.*?)$", re.IGNORECASE),
- ]
- for parser in series_parser:
- matches = parser.search(filename)
- try:
- match_dict = matches.groupdict()
- break
- except AttributeError:
- continue
- else:
- return
- series = int(match_dict["series"])
- episode = int(match_dict["episode"])
- extension = match_dict["extension"]
- info_dictionary = {"show": show.title,
- "series_num": series,
- "episode_num": episode,
- "extension": extension}
- try:
- info_dictionary.update(show.episodes[(series, episode)])
- new_filename = file_mask % info_dictionary
- except KeyError:
- print 'Episode name for "%s" not found.' % filename
- sys.exit()
- new_filename = re.sub("[\\\/\:\*\"\?\<\>\|]", "", new_filename)
- if new_filename == filename:
- if not force:
- print 'No changes to "%s".' % filename
- sys.exit()
- try:
- print "Renaming \"%s\" to \"%s\"..." % (filename, new_filename.encode("ascii", "replace"))
- except UnicodeDecodeError:
- print "Renaming \"%s\" to \"%s\"..." % (filename, new_filename)
- if not preview:
- if use_ap:
- # The temp_filename shenanigans are necessary because AP sometimes
- # chokes if it's set to overwrite the file.
- temp_filename = filename + str(random.randint(10000, 99999))
- arguments = ["AtomicParsley",
- filename,
- "-o", temp_filename,
- "--TVShowName", show.title,
- "--stik", "TV Show",
- "--TVSeasonNum", str(series),
- "--TVEpisodeNum", str(episode),
- "--TVEpisode", show.episodes[(series, episode)]["title"],
- "--title", show.episodes[(series, episode)]["title"]]
- if "year" in show.episodes[(series, episode)]:
- arguments.extend(["--year", show.episodes[(series, episode)]["year"]])
- elif "year" in show.attributes:
- arguments.extend(["--year", show.attributes["year"]])
- artwork_file = None
- if "artwork" in show.episodes[(series, episode)]:
- artwork_filename = hashlib.md5(str(random.randint(10000, 100000))).hexdigest()
- artwork_file = open(artwork_filename, "wb")
- artwork_file.write(show.episodes[(series, episode)]["artwork"])
- artwork_file.close()
- arguments.extend(["--artwork", "REMOVE_ALL", "--artwork", artwork_filename])
- elif "artwork" in show.attributes:
- artwork_filename = hashlib.md5(str(random.randint(10000, 100000))).hexdigest()
- artwork_file = open(artwork_filename, "wb")
- artwork_file.write(show.attributes["artwork"])
- artwork_file.close()
- arguments.extend(["--artwork", "REMOVE_ALL", "--artwork", artwork_filename])
- proc = subprocess.Popen(tuple(arguments))
- proc.wait()
- if artwork_file:
- os.remove(artwork_filename)
- try:
- os.rename(temp_filename, new_filename)
- except:
- print "There was an error while renaming the file."
- sys.exit()
- if new_filename != filename:
- os.remove(filename)
- else:
- try:
- os.rename(filename, new_filename)
- except:
- print "There was an error while renaming the file."
- sys.exit()
- def analyze_file(filename,options):
- # title_parser = re.compile("(?P<title>^.*)(s|\.|-)(?P<series>\d+)(e|x)(?P<episode>\d+).*\.(?P<extension>.*?)$", re.IGNORECASE)
- title_parser = [
- re.compile("^(?P<title>.*?)s *(?P<series>\d+) *e *(?P<episode>\d+).*\.(?P<extension>.*?)$", re.IGNORECASE),
- re.compile("^(?P<title>.*?)(?P<series>\d+)x(?P<episode>\d+).*\.(?P<extension>.*?)$", re.IGNORECASE),
- re.compile("^(?P<title>.*?\D|)(?P<series>\d{1,2})(?P<episode>\d{2})(?:\D.*|)\.(?P<extension>.*?)$", re.IGNORECASE),
- ]
- for parser in title_parser:
- matches = parser.search(filename)
- try:
- title_dict = matches.groupdict()
- break
- except AttributeError:
- continue
- else:
- return
- title = title_dict["title"]
- title = title.strip()
- title = title.replace('-','.')
- title = title.replace(' ','.')
- if title.endswith('.'):
- title = title.rstrip('.')
- title = title.strip()
- title = title.split('.')
- show_id = search_show("+".join(title))
- if not show_id:
- return
- page_url = "http://epguides.com/%s/" % show_id
- request = urllib2.Request(page_url)
- if options.use_cookies:
- request.add_header("Cookie","ListDisplay=tvrage.com")
- try:
- page = urllib2.urlopen(request).read()
- except urllib2.HTTPError, error:
- print "An HTTP error occurred, HTTP code %s." % error.code
- sys.exit()
- show = parse_epguides(page)
- if not show:
- sys.exit()
- rename_file(filename, show, options.mask, options.preview, options.use_atomic_parsley, options.force)
- def main():
- parser = optparse.OptionParser(usage="%prog [options] <filename>", version="Episode rename 0.8\nThis program is released under the GNU GPL.")
- parser.add_option("-p",
- "--preview",
- dest="preview",
- action="store_true",
- help="don't actually rename anything")
- parser.add_option("-a",
- "--use-atomic-parsley",
- dest="use_atomic_parsley",
- action="store_true",
- help="use AtomicParsley to fill in the files' tags")
- parser.add_option("-f",
- "--force",
- dest="force",
- action="store_true",
- help="force renaming even if filename doesn't change")
- parser.add_option("-c",
- "--cookies",
- dest="use_cookies",
- action="store_true",
- help="use site cookies for TVRage")
- parser.add_option("-m",
- "--mask",
- dest="mask",
- default="%(show)s - S%(series_num)02dE%(episode_num)02d - %(title)s.%(extension)s",
- metavar="MASK",
- action="store",
- type="string",
- help="the filename mask to use when renaming (default: \"%default\")")
- parser.set_defaults(preview=False)
- parser.set_defaults(force=False)
- parser.set_defaults(use_cookies=False)
- (options, arguments)=parser.parse_args()
- if len(arguments) != 1:
- parser.print_help()
- sys.exit(1)
- filename = arguments[0]
- filename = filename.replace('./','')
- analyze_file(filename,options)
- return sys.stdout
- if __name__ == "__main__":
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement