Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- """
- tvcli
- This is a command line program to manage your favourite TV programs and output air times/program names.
- This is the first project I've created in python, feedback is welcome.
- Copyright (c) 2011
- """
- import copy, getopt, os.path, pickle, urllib, sys, time
- from datetime import date, timedelta, datetime
- from xml.dom.minidom import parse, parseString
- from colorama import init, Fore, Back, Style
- init()
- APIKEY = 'AB4A43DCDF3A99B5'
- def updateAll():
- shows = getData()
- if not shows:
- print "You have no favourite TV programs to update!"
- return 1
- for show in shows:
- print "Updating episode list for "+show['SeriesName']+"..."
- updateEpisodes(show['id'])
- def getData():
- if not os.path.isfile('data/favourites.pk'):
- return 0
- f = open('data/favourites.pk','r')
- data = pickle.load(f)
- f.close()
- return data
- def getEpData(pID):
- if not os.path.isfile('data/episodes/'+pID+'.pk'):
- return 0
- f = open('data/episodes/'+pID+'.pk','r')
- data = pickle.load(f)
- f.close()
- return data
- def listProgs(favs):
- if not favs:
- print "Your favourites list is empty :("
- return 1
- for i in range(len(favs)):
- print Fore.CYAN+Style.BRIGHT+`i+1`+': '+Style.RESET_ALL+favs[i]['SeriesName']
- return 0
- def getNextEp(pID):
- episodes = getEpData(pID)
- d = date.today()
- airDate = d.isoformat()
- offset = -99999999
- for episode in episodes:
- if 'FirstAired' in episode:
- o = int(airDate.replace('-','')) - int(episode['FirstAired'].replace('-',''))
- if o < 0 and o > offset:
- offset = o
- airDate = episode['FirstAired']
- epName = "["+episode['SeasonNumber']+"x"+episode['EpisodeNumber']+"] "+episode['EpisodeName']
- try:
- epName
- except NameError:
- epName = None
- if epName == None:
- return "No data available."
- else:
- return date.fromtimestamp(time.mktime(time.strptime(airDate,"%Y-%m-%d"))).strftime("%d %B %Y")+" - "+epName
- def showToday():
- today = date.today().strftime("%d %B %Y")
- d = getData()
- programs = []
- for i in range(len(d)):
- p = d[i]
- n = getNextEp(p['id'])
- if n.find(today) > -1:
- p['cid'] = i
- programs.append(p)
- if len(programs)==0:
- print "No programs airing today."
- return 1
- print Fore.CYAN+Style.BRIGHT+"Airing Today:"+Style.RESET_ALL
- for p in programs:
- info(p['cid']+1)
- def showTomorrow():
- t = date.today()+timedelta(days=2)
- tomorrow = t.strftime("%d %B %Y")
- d = getData()
- programs = []
- for i in range(len(d)):
- p = d[i]
- n = getNextEp(p['id'])
- if n.find(tomorrow) > -1:
- p['cid'] = i
- programs.append(p)
- if len(programs)==0:
- print "No programs airing tomorrow."
- return 1
- print Fore.CYAN+Style.BRIGHT+"Airing Tomorrow:"+Style.RESET_ALL
- for p in programs:
- info(p['cid']+1)
- def showInDays(days):
- td = date.today().isoformat()
- d = getData()
- days = int(days)
- progs = []
- for i in range(len(d)):
- p = d[i]
- episodes = getEpData(p['id'])
- for episode in episodes:
- if 'FirstAired' in episode:
- o = int(episode['FirstAired'].replace('-','')) - int(td.replace('-',''))
- if o <= days and o > 0:
- p['cid'] = i
- progs.append(p)
- if len(progs)==0:
- print "No programs airing in the next "+`days`+" days."
- return 1
- print Fore.CYAN+Style.BRIGHT+"Airing in the next "+`days`+" Days:"+Style.RESET_ALL
- for p in progs:
- info(p['cid']+1)
- def getLastEp(pID):
- episodes = getEpData(pID)
- d = date.today()
- now = d.isoformat()
- for episode in episodes:
- if 'FirstAired' in episode:
- o = int(now.replace('-','')) - int(episode['FirstAired'].replace('-',''))
- try:
- offset
- except NameError:
- offset = o
- if o > 0 and o < offset:
- offset = o
- airDate = episode['FirstAired']
- epName = "["+episode['SeasonNumber']+"x"+episode['EpisodeNumber']+"] "+episode['EpisodeName']
- try:
- airDate
- except NameError:
- airDate = None
- if airDate == None:
- return "No data available."
- else:
- return date.fromtimestamp(time.mktime(time.strptime(airDate,"%Y-%m-%d"))).strftime("%d %B %Y")+" - "+epName
- def search(program):
- sock = urllib.urlopen("http://www.thetvdb.com/api/GetSeries.php?seriesname="+program)
- f = sock.read()
- sock.close()
- dom = parseString(f)
- if len(dom.getElementsByTagName('Series')) == 0:
- print "No episodes found with that name."
- return 1
- for series in dom.getElementsByTagName('Series'):
- name = series.getElementsByTagName('SeriesName')
- ID = series.getElementsByTagName('seriesid')
- fa = series.getElementsByTagName('FirstAired')
- overview = series.getElementsByTagName('Overview')
- if len(name) < 0:
- break
- s = getSeriesData(ID[0].childNodes[0].data)
- print "\n"+Style.BRIGHT+Fore.BLUE+ID[0].childNodes[0].data+" - "+name[0].childNodes[0].data+Style.RESET_ALL
- if len(overview) > 0:
- print Style.BRIGHT+" Overview:\t"+Style.NORMAL+overview[0].childNodes[0].data[:60].rsplit(' ',1)[0]+"..."
- if len(fa) > 0:
- print Style.BRIGHT+" First Aired:\t"+Style.NORMAL+date.fromtimestamp(time.mktime(time.strptime(fa[0].childNodes[0].data,"%Y-%m-%d"))).strftime("%d %B %Y")
- if 'Genre' in s:
- genres = s['Genre'].split('|')
- print Style.BRIGHT+" Genre(s):\t"+Style.NORMAL,
- for i in range(len(genres)):
- genre = genres[i]
- if len(genre.strip()) > 0:
- sys.stdout.write(genre)
- if len(genres) != (i+2):
- print ", ",
- print
- if 'Network' in s:
- print Style.BRIGHT+" Network:\t"+Style.NORMAL+s['Network']
- if 'Rating' in s:
- print Style.BRIGHT+" Rating:\t"+Style.NORMAL+s['Rating']
- if 'Status' in s:
- print Style.BRIGHT+" Status:\t"+Style.NORMAL+s['Status']
- def updateEpisodes(pID):
- url = "http://www.thetvdb.com/api/"+APIKEY+"/series/"+pID+"/all"
- sock = urllib.urlopen(url)
- if sock.getcode() == 200:
- f = sock.read()
- else:
- return 1
- sock.close()
- dom = parseString(f)
- episode = {}
- episodes = []
- for episodeData in dom.getElementsByTagName('Episode'):
- for tag in episodeData.childNodes:
- if tag.nodeName != "#text" and tag.nodeValue !="\n":
- if len(tag.childNodes) > 0:
- episode[tag.nodeName] = tag.childNodes[0].data
- episodes.append(episode.copy())
- episode.clear()
- f = open('data/episodes/'+pID+'.pk','w')
- pickle.dump(episodes,f)
- f.close()
- def delete(pID):
- d = getData()
- print Style.BRIGHT+"Are you sure you want to delete "+d[int(pID)-1]['SeriesName']+"?"+Style.NORMAL
- i = raw_input('(y/n): ')
- if i == "n" or i=="N":
- print "Quitting..."
- sys.exit(1)
- elif i!="y" and i!="Y":
- print "Invalid."
- sys.exit(1)
- del d[int(pID)-1]
- f = open('data/favourites.pk','w')
- pickle.dump(d,f)
- f.close()
- print "Deleted."
- def getSeriesData(pID):
- url = "http://www.thetvdb.com/api/"+APIKEY+"/series/"+pID+"/all"
- sock = urllib.urlopen(url)
- if sock.getcode() == 200:
- f = sock.read()
- else:
- print "Error: Series not found or API key incorrect."
- return 1
- sock.close()
- dom = parseString(f)
- prog = {}
- for sInfo in dom.getElementsByTagName('Series'):
- for tag in sInfo.childNodes:
- if tag.nodeName != "#text" and tag.nodeValue != "\n":
- if len(tag.childNodes) > 0:
- prog[tag.nodeName] = tag.childNodes[0].data
- return prog
- def add(pID):
- print "Searching for "+pID+" in the TVDB..."
- prog = getSeriesData(pID)
- progs = []
- if os.path.isfile('data/favourites.pk'):
- current = getData()
- current.append(prog)
- progs = current
- else:
- progs = [ prog ]
- f = open('data/favourites.pk','w')
- pickle.dump(progs,f)
- f.close()
- print "Added "+prog['SeriesName']+" to favourites."
- print "Updating episodes..."
- updateEpisodes(pID)
- print "Done"
- def info(fID):
- fID = int(fID)-1
- d = getData()
- if len(d) < fID:
- print "Bad program ID. Please use the ID for the program given by the --list option."
- sys.exit(1)
- program = d[fID]
- print Fore.BLUE+Style.BRIGHT+`fID+1`+": "+program['SeriesName']+Style.RESET_ALL
- print Style.BRIGHT+" Airs: "+Style.NORMAL+program['Airs_DayOfWeek']+"s "+program['Airs_Time']+" (Network's local time)"
- print Style.BRIGHT+" Latest Episode: "+Style.NORMAL+getLastEp(program['id'])
- print Style.BRIGHT+" Next Episode: "+Style.NORMAL+getNextEp(program['id'])
- def usage():
- print "Usage: tvcli <action>"
- print " -s,\t--search=PROGRAM\tSearch for a program's ID in the TvDB."
- print " -i,\t--info=PID\t\tRetrive info for program using ID (from --list)"
- print " -a,\t--add=TVDBID\t\tAdd program (identified by TvDB ID) to favourites list."
- print " -d,\t--days=NUM\t\tList programs airing in the next NUM days."
- print " -t,\t--today\t\t\tList programs airing today."
- print " -T,\t--tomorrow\t\tList programs airing tomorrow."
- print " -u,\t--update\t\tUpdate episode lists."
- print " -l,\t--list\t\t\tList the programs being tracked."
- print " -D,\t--delete=PID\t\tDelete a program using ID from --list."
- def main(argv):
- if len(argv) == 0:
- usage()
- sys.exit(1)
- try:
- opts, args = getopt.getopt(argv, "s:i:a:d:D:tTul", ["search=","info=","add=","days=","delete=","today","tomorrow","update","list"])
- except getopt.GetoptError:
- usage()
- sys.exit(2)
- for o, a in opts:
- if o in ("-l", "--list"):
- listProgs(getData())
- if o in ("-s", "--search"):
- search(a)
- if o in ("-u", "--update"):
- updateAll()
- if o in ("-a", "--add"):
- add(a)
- if o in ("-i", "--info"):
- info(a)
- if o in ("-D", "--delete"):
- delete(a)
- if o in ("-t", "--today"):
- showToday()
- if o in ("-T", "--tomorrow"):
- showTomorrow()
- if o in ("-d", "--days"):
- showInDays(a)
- main(sys.argv[1:])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement