nachdem ich letztes Wochenende über das "Google's Python Class" (wer es nicht kennt einfach mal nach googeln) Videotutorial gestolpert bin und es mir angeschaut sowie die Übungen durchgearbeitet habe, wollte ich euch nun die Umsetzung meines ersten Projekts präsentieren.
Das Script dient dazu alle, in dem an das Script übergebenen Verzeichnis befindlichen Dateien umzubenennen.
Hier ein paar Beispiele:
bones.S05E19.720p.X264-DIMENSION.mkv --> Bones - 103 - 05x19 - The Rocker in the Rinse Cycle.mkv
Game.of.Thrones.S01E05.720p.HDTV.X264.mkv --> Game of Thrones - 005 - 01x05 - The Wolf and the Lion.mkv
Glee.S01E20.720p.HDTV.X264-ctu.mkv --> Glee - 020 - 01x20 - Theatricality.mkv
the.mentalist.S03E07.720p.HDTV.X264-DIMENSION.mkv --> The Mentalist - 053 - 03x07 - Red Hot.mkv
Das Script tut genau das was es soll, da es sich hierbei aber um meine ersten Gehversuche in Sachen Python handelt und ich gerne dazu lernen möchte, würde ich mich über konstruktive Kritik wie man das Script noch optimieren könnte, freuen.
Gruß waldbaer
Das Script:
Code: Alles auswählen
#!/usr/local/bin/python
# -*- mode: python; coding: utf-8; -*-
# Copyright 2011 Markus Hoffmann
from xml.etree import ElementTree as et
import urllib2
import sys
import os
import re
import glob
import shutil
def get_filenames(dir):
filenames = glob.glob(dir + '\*.*')
return filenames
def build_rename_queue(filenames, dir):
queue = []
for filename in filenames:
analysed_filename = analyse_filename(filename, dir)
showid = get_showid(analysed_filename, dir)
episodename = get_episodename(showid, dir)
new_filename = generate_new_filename(episodename)
tuple = (new_filename['old_filename'], dir + '\\' + clear_filename(new_filename['new_filename']))
queue.append(tuple)
return queue
def analyse_filename(filename, dir):
analysed_filename = {}
analysed_filename['old_filename'] = filename
result = re.search(r'([\w.]+)s(\d\d)e(\d\d)[\w.-]+(\.\w\w\w)', filename.replace(dir + '\\', '').lower())
if result:
analysed_filename['showname'] = result.group(1)[:-1].replace('.' , ' ')
analysed_filename['season'] = int(result.group(2))
analysed_filename['episode'] = int(result.group(3))
analysed_filename['extension'] = result.group(4)
else:
print "Couldn't analyse filename"
return
return analysed_filename
def get_showid(analysed_filename, dir):
if not os.path.exists(os.path.abspath(os.path.join(dir + '\\tmp', 'tmp_showid_' + analysed_filename['showname'] + '.xml'))):
generate_xmlshowid(analysed_filename, dir)
xml_feed = open(os.path.abspath(os.path.join(dir + '\\tmp', 'tmp_showid_' + analysed_filename['showname'] + '.xml')), 'rU')
tree = et.parse(xml_feed)
xml_feed.close
shows = tree.findall('show')
for show in shows:
tmp_showid = show.find("showid").text
tmp_showname = show.find("name").text
if tmp_showname.lower() == analysed_filename['showname']:
analysed_filename['showname'] = tmp_showname
analysed_filename['showid'] = tmp_showid
return analysed_filename
def generate_xmlshowid(analysed_filename, dir):
stripped_showname = analysed_filename['showname'].replace('the ', '')
xml_url = r'http://services.tvrage.com/feeds/search.php?show=' + stripped_showname
if not os.path.exists(os.path.abspath(dir + '\\tmp')):
os.mkdir(os.path.abspath(dir + '\\tmp'))
xml_feed = urllib2.urlopen(xml_url).read()
f = open(os.path.abspath(os.path.join(dir + '\\tmp', 'tmp_showid_' + analysed_filename['showname'] + '.xml')), 'w')
f.write(xml_feed)
f.close
def get_episodename(showid, dir):
if not os.path.exists(os.path.abspath(os.path.join(dir + '\\tmp', 'tmp_series_' + showid['showname'] + '.xml'))):
generate_xmlseries(showid, dir)
xml_feed = open(os.path.abspath(os.path.join(dir + '\\tmp', 'tmp_series_' + showid['showname'] + '.xml')), 'rU')
tree = et.parse(xml_feed)
xml_feed.close
seasons = tree.findall('Episodelist/Season')
if seasons:
for season in seasons:
if int(season.get('no')) == showid['season']:
episodes = season.findall('episode')
for episode in episodes:
if int(episode.find('seasonnum').text) == showid['episode']:
showid['episodename'] = episode.find('title').text
showid['absolut_number'] = episode.find('epnum').text
else:
print "Couldn't parse XML file - " + os.path.abspath(os.path.join(dir + '\\tmp', 'tmp_series_' + showid['showname'] + '.xml'))
return showid
def generate_xmlseries(analysed_filename, dir):
xml_url = r'http://services.tvrage.com/feeds/episode_list.php?sid=' + analysed_filename['showid']
if not os.path.exists(os.path.abspath(dir + '\\tmp')):
os.mkdir(os.path.abspath(dir + '\\tmp'))
xml_feed = urllib2.urlopen(xml_url).read()
f = open(os.path.abspath(os.path.join(dir + '\\tmp', 'tmp_series_' + analysed_filename['showname'].lower() + '.xml')), 'w')
f.write(xml_feed)
f.close
def generate_new_filename(episodename):
episodename['new_filename'] = episodename['showname'] + ' - ' + '%0*d' % (3, int(episodename['absolut_number'])) + ' - ' + '%0*d' % (2, episodename['season']) + 'x' + '%0*d' % (2, episodename['episode']) + ' - ' + episodename['episodename'] + episodename['extension']
return episodename
def clear_filename(filename):
bad_chars = ['\\', '\/', '\?', '\:', '\*', '\"', '\<', '\>', '\|']
clean_filename = filename
for bad_char in bad_chars:
clean_filename = clean_filename.replace(bad_char, ' ')
return clean_filename
def propose_rename_queue(queue, dir):
print
print 'Rename Proposal:'
print '================'
print
for tuple in queue:
print tuple[0].replace(dir + '\\', '') + ' -->\n' + tuple[1].replace(dir + '\\', '')
print
choice = raw_input('Execute rename? (y)es or (n)o --> ')
return choice
def execute_rename_queue(choice, queue):
if choice == 'y':
for names in queue:
if names[1] != 'Episode not available':
os.rename(names[0], names[1])
elif choice == 'n':
print 'Proposal rejected'
return
else:
print 'You have to enter y or n'
return
def main():
if len(sys.argv) != 2:
print 'usage: xmlparser.py dir'
sys.exit(1)
dir = sys.argv[1]
filenames = get_filenames(dir)
queue = build_rename_queue(filenames, dir)
choice = propose_rename_queue(queue, dir)
execute_rename_queue(choice, queue)
shutil.rmtree(os.path.abspath(os.path.join(dir + '\\tmp')))
return
if __name__ == '__main__':
main()
Code: Alles auswählen
<?xml version="1.0" encoding="UTF-8" ?>
<Results>
<show><showid>8159</showid><name>The Game</name><link>http://www.tvrage.com/The_Game</link><country>US</country><started>2006</started><ended>0</ended><seasons>5</seasons><status>Returning Series</status><classification>Scripted</classification><genres><genre>Comedy</genre><genre>Sports</genre></genres></show>
<show><showid>24493</showid><name>Game of Thrones</name><link>http://www.tvrage.com/Game_of_Thrones</link><country>US</country><started>2010</started><ended>0</ended><seasons>1</seasons><status>Returning Series</status><classification>Scripted</classification><genres><genre>Action</genre><genre>Drama</genre><genre>Fantasy</genre></genres></show>
<show><showid>14649</showid><name>Wicked Wicked Games</name><link>http://www.tvrage.com/Wicked_Wicked_Games</link><country>US</country><started>2006</started><ended>2007</ended><seasons>1</seasons><status>Canceled/Ended</status><classification>Scripted</classification><genres><genre>Soaps</genre></genres></show>
</Results>
Code: Alles auswählen
<?xml version="1.0" encoding="UTF-8" ?>
<Show>
<name>Game of Thrones</name>
<totalseasons>1</totalseasons>
<Episodelist>
<Season no="1">
<episode><epnum>1</epnum><seasonnum>01</seasonnum><prodnum></prodnum><airdate>2011-04-17</airdate><link>http://www.tvrage.com/Game_of_Thrones/episodes/1065008299</link><title>Winter is Coming</title></episode>
<episode><epnum>2</epnum><seasonnum>02</seasonnum><prodnum></prodnum><airdate>2011-04-24</airdate><link>http://www.tvrage.com/Game_of_Thrones/episodes/1065023912</link><title>The Kingsroad</title></episode>
<episode><epnum>3</epnum><seasonnum>03</seasonnum><prodnum></prodnum><airdate>2011-05-01</airdate><link>http://www.tvrage.com/Game_of_Thrones/episodes/1065027990</link><title>Lord Snow</title></episode>
<episode><epnum>4</epnum><seasonnum>04</seasonnum><prodnum></prodnum><airdate>2011-05-08</airdate><link>http://www.tvrage.com/Game_of_Thrones/episodes/1065029350</link><title>Cripples, Bastards, and Broken Things</title></episode>
<episode><epnum>5</epnum><seasonnum>05</seasonnum><prodnum></prodnum><airdate>2011-05-15</airdate><link>http://www.tvrage.com/Game_of_Thrones/episodes/1065036402</link><title>The Wolf and the Lion</title></episode>
<episode><epnum>6</epnum><seasonnum>06</seasonnum><prodnum></prodnum><airdate>2011-05-22</airdate><link>http://www.tvrage.com/Game_of_Thrones/episodes/1065036403</link><title>A Golden Crown</title></episode>
<episode><epnum>7</epnum><seasonnum>07</seasonnum><prodnum></prodnum><airdate>2011-05-29</airdate><link>http://www.tvrage.com/Game_of_Thrones/episodes/1065036404</link><title>You Win or You Die</title></episode>
<episode><epnum>8</epnum><seasonnum>08</seasonnum><prodnum></prodnum><airdate>2011-06-05</airdate><link>http://www.tvrage.com/Game_of_Thrones/episodes/1065039305</link><title>The Pointy End</title></episode>
<episode><epnum>9</epnum><seasonnum>09</seasonnum><prodnum></prodnum><airdate>2011-06-12</airdate><link>http://www.tvrage.com/Game_of_Thrones/episodes/1065039306</link><title>Baelor</title></episode>
<episode><epnum>10</epnum><seasonnum>10</seasonnum><prodnum></prodnum><airdate>2011-06-19</airdate><link>http://www.tvrage.com/Game_of_Thrones/episodes/1065039307</link><title>Fire and Blood</title></episode>
</Season>
<Special>
<episode><season>1</season><airdate>2010-12-05</airdate><link>http://www.tvrage.com/Game_of_Thrones/episodes/1064997231</link><title>Inside Game of Thrones</title></episode>
<episode><season>1</season><airdate>2011-04-03</airdate><link>http://www.tvrage.com/Game_of_Thrones/episodes/1065027989</link><title>15-Minute Preview</title></episode>
</Special>
</Episodelist>
</Show>