|
Description:
The getEps function in this module returns a text string containing the original air date for the last aired and next upcoming episodes of a TV series title. It also provides the plot for the next upcoming episode, if available. The information returned is limited to what is available at IMDb, and so it may not be up to date. IMDbPY (http://imdbpy.sourceforge.net/) is used. See code for usage information and examples.
Source: Text Source
from imdb import IMDb
from imdb.helpers import sortedEpisodes
from itertools import dropwhile, ifilter, islice, takewhile
from datetime import date
from time import sleep, strptime
import locale
locale.setlocale(locale.LC_ALL,'')
def getEps(title,max_len=990,debug=False):
"""Returns a text string containing schedule info for the last aired and the next upcoming episodes for the given TV series title"""
assert isinstance(title,str), 'A string input was not provided.'
title=title.strip()
if title.lower().endswith('/noplot'):
title=title[:-len('/noplot')].rstrip()
include_plot=False
else:
include_plot=True
try:
if len(title)==0: return 'A title was not provided.'
i=IMDb()
max_attempts=3
for attempt in range(1,max_attempts+1):
try:
search_results=i.search_movie(title)
break
except:
if attempt<max_attempts:
if debug: print 'An error occurred while attempting to retrieve search results for "%s". %s attempts were made.'%(title,attempt)+'\n'
sleep(attempt*2)
else:
return 'An error occurred while attempting to retrieve search results for "%s". %s attempts were made.'%(title,attempt)
del attempt,max_attempts
search_results=ifilter(lambda s:s['kind']=='tv series',search_results)
search_results=list(islice(search_results,0,1))
if len(search_results)==0: return 'No TV series matches were found for "%s".'%title
s=search_results[0]
del search_results
i.update(s,'episodes')
s_title=s['long imdb title']
if (not s.has_key('episodes')) or len(s['episodes'])==0: return 'Episode info is unavailable for %s.'%s_title
s=sortedEpisodes(s)
if len(s)==0: return 'Episode info is unavailable for %s.'%s_title
s.reverse()
s=list(dropwhile(lambda e:e['season']=='unknown',s))+list(takewhile(lambda e:e['season']=='unknown',s))
date_today=date.today()
for ep_ind in xrange(len(s)):
if s[ep_ind].has_key('original air date'):
try:
s[ep_ind]['date']=strptime(s[ep_ind]['original air date'],'%d %B %Y')
except: pass
if s[ep_ind].has_key('date'):
s[ep_ind]['date']=date(*s[ep_ind]['date'][0:3])
s[ep_ind]['age']=(s[ep_ind]['date']-date_today).days
if s[ep_ind]['age']<0:
s[ep_ind]['has aired']=True
else:
s[ep_ind]['has aired']=False
else:
s[ep_ind]['has aired']=False
del date_today,ep_ind
if debug:
print 'Last 10 listed episodes:\nS# Epi# Age Episode Title'
for e in s[:10]: print '%s %s %s %s'%(str(e['season']).zfill(2)[:2],str(e['episode']).zfill(4),e.has_key('age') and str(e['age']).zfill(5) or ' '*5,e['title'].encode('latin-1'))
print
def getSE(e):
if not isinstance(e['season'],int): return ''
Sstr='S'+str(e['season']).zfill(2)
Estr='E'+str(e['episode']).zfill(2)
return ' ('+Sstr+Estr+')'
def getAge(e): return locale.format('%i',abs(e['age']),grouping=True)
def getDate(e): return 'i.e. on '+e['date'].strftime('%a, ')+str(e['date'].day)+e['date'].strftime(' %b %y')
e=ifilter(lambda e:e['has aired'],s)
e=list(islice(e,0,1))
if len(e)>0:
e=e[0]
e_schedule= e['age']!=-1 and ('%s days ago'%getAge(e)) or 'yesterday'
e_out='The episode that aired last for '+s_title+' is "'+e['title']+'"'+getSE(e)+'. It aired '+e_schedule+', '+getDate(e)+'. '
del e_schedule
else:
e_out=''
e=list(takewhile(lambda e:e['has aired']==False,s))
if len(e)>0:
e=e[-1]
e_out=e_out+'The next upcoming episode '+(e_out=='' and ('for '+s_title+' ') or '')+'is "'+e['title']+'"'+getSE(e)+'.'
if e.has_key('age'):
e_schedule= e['age']>1 and ('in %s days'%getAge(e)) or e['age']==1 and 'tomorrow' or e['age']==0 and 'today'
e_out=e_out+' It airs '+e_schedule+', '+getDate(e)+'.'
del e_schedule
else:
e_out=e_out+' Its air date is unavailable.'
if include_plot:
if e.has_key('plot') and e['plot']!='Related Links':
e_out=e_out+' Its plot is: '+e['plot']
elif e_out.endswith('Its air date is unavailable.'):
e_out=e_out.replace('Its air date is unavailable.','Its air date and plot are unavailable.')
else:
e_out=e_out+' Its plot is unavailable.'
else:
if e_out!='':
e_out=e_out+'No upcoming episode is scheduled.'
else:
e_out='Episode info is unavailable for %s.'%s_title
if (max_len not in [-1,0,None]) and len(e_out)>max_len-3: e_out=e_out[:max_len-3]+'...'
return e_out
except: return 'An error occurred while attempting to retrieve episode info for "%s".'%title
def getEps_test(add_noplot=False):
"""Run a set of tests"""
titles=('24',
'arrested development',
'avatar',
'big brother',
'dexter',
'future weapons',
'heroes',
'kid nation',
'kyle xy',
'las vegas',
'lost',
'my name is earl',
'nip tuck',
'numbers',
'prison break',
'scrubs',
'showtime championship boxing',
'smallville',
'south park',
'stargate atlantis',
'stargate sg1',
'supernatural',
'terminator',
'the daily show',
'the oc',
'the office',
'the universe',
'the wire',
'twilight zone',
'ufo hunters',
'weeds',
'zzkjsdfglkjfsdg')
for title in titles:
print title+':\n'
print getEps(title,debug=True)+'\n'+'_'*72+'\n'
if add_noplot:
print title+': '+getEps(title+' /noplot',debug=True)++'\n''_'*72+'\n'
if __name__=='__main__': getEps_test()
Discussion:
While TV.com may provide more accurate schedule information, IMDb was chosen here as the data source because a library for accessing it, namely IMDbPY, is available.
|