2011-11-20 22:23:31 +13:00
import datetime
2014-02-14 16:36:57 +13:00
2011-11-20 22:23:31 +13:00
from util import hook , http
base_url = " http://thetvdb.com/api/ "
2014-02-25 19:30:55 +13:00
api_key = " 469B73127CA0C411 "
2011-11-20 22:23:31 +13:00
2014-02-13 15:02:44 +13:00
def get_episodes_for_series ( series_name , api_key ) :
2011-11-20 22:23:31 +13:00
res = { " error " : None , " ended " : False , " episodes " : None , " name " : None }
# http://thetvdb.com/wiki/index.php/API:GetSeries
try :
2014-02-13 15:02:44 +13:00
query = http . get_xml ( base_url + ' GetSeries.php ' , seriesname = series_name )
2014-02-25 19:30:55 +13:00
except http . URLError :
2012-02-03 02:05:11 +13:00
res [ " error " ] = " error contacting thetvdb.com "
2011-11-20 22:23:31 +13:00
return res
series_id = query . xpath ( ' //seriesid/text() ' )
if not series_id :
2013-01-08 20:31:46 +13:00
res [ " error " ] = " Unknown TV series. (using www.thetvdb.com) "
2011-11-20 22:23:31 +13:00
return res
series_id = series_id [ 0 ]
try :
2014-02-25 19:30:55 +13:00
series = http . get_xml ( base_url + ' %s /series/ %s /all/en.xml ' % ( api_key , series_id ) )
except http . URLError :
2013-01-08 20:31:46 +13:00
res [ " error " ] = " Error contacting thetvdb.com. "
2011-11-20 22:23:31 +13:00
return res
series_name = series . xpath ( ' //SeriesName/text() ' ) [ 0 ]
if series . xpath ( ' //Status/text() ' ) [ 0 ] == ' Ended ' :
res [ " ended " ] = True
res [ " episodes " ] = series . xpath ( ' //Episode ' )
res [ " name " ] = series_name
return res
2012-02-16 07:18:56 +13:00
def get_episode_info ( episode , api_key ) :
2011-11-20 22:23:31 +13:00
first_aired = episode . findtext ( " FirstAired " )
try :
2014-02-13 15:02:44 +13:00
air_date = datetime . date ( * map ( int , first_aired . split ( ' - ' ) ) )
2011-11-20 22:23:31 +13:00
except ( ValueError , TypeError ) :
return None
episode_num = " S %02d E %02d " % ( int ( episode . findtext ( " SeasonNumber " ) ) ,
int ( episode . findtext ( " EpisodeNumber " ) ) )
episode_name = episode . findtext ( " EpisodeName " )
# in the event of an unannounced episode title, users either leave the
# field out (None) or fill it with TBA
if episode_name == " TBA " :
episode_name = None
2013-09-05 10:36:25 +08:00
episode_desc = ' {} ' . format ( episode_num )
2011-11-20 22:23:31 +13:00
if episode_name :
2013-09-05 10:36:25 +08:00
episode_desc + = ' - {} ' . format ( episode_name )
2014-02-13 15:02:44 +13:00
return first_aired , air_date , episode_desc
2011-11-20 22:23:31 +13:00
@hook.command
@hook.command ( ' tv ' )
2012-02-29 00:29:53 -08:00
def tv_next ( inp , bot = None ) :
2013-09-04 18:30:04 +08:00
""" tv <series> -- Get the next episode of <series>. """
2012-02-16 07:18:56 +13:00
api_key = bot . config . get ( " api_keys " , { } ) . get ( " tvdb " , None )
if api_key is None :
return " error: no api key set "
episodes = get_episodes_for_series ( inp , api_key )
2011-11-20 22:23:31 +13:00
if episodes [ " error " ] :
return episodes [ " error " ]
series_name = episodes [ " name " ]
ended = episodes [ " ended " ]
episodes = episodes [ " episodes " ]
if ended :
2013-09-05 10:36:25 +08:00
return " {} has ended. " . format ( series_name )
2011-11-20 22:23:31 +13:00
next_eps = [ ]
today = datetime . date . today ( )
for episode in reversed ( episodes ) :
2012-02-16 07:18:56 +13:00
ep_info = get_episode_info ( episode , api_key )
2011-11-20 22:23:31 +13:00
if ep_info is None :
continue
2014-02-13 15:02:44 +13:00
( first_aired , air_date , episode_desc ) = ep_info
2011-11-20 22:23:31 +13:00
2014-02-13 15:02:44 +13:00
if air_date > today :
2013-09-05 10:36:25 +08:00
next_eps = [ ' {} ( {} ) ' . format ( first_aired , episode_desc ) ]
2014-02-13 15:02:44 +13:00
elif air_date == today :
2013-09-05 10:36:25 +08:00
next_eps = [ ' Today ( {} ) ' . format ( episode_desc ) ] + next_eps
2011-11-20 22:23:31 +13:00
else :
2014-02-13 15:02:44 +13:00
# we're iterating in reverse order with newest episodes last
# so, as soon as we're past today, break out of loop
2011-11-20 22:23:31 +13:00
break
if not next_eps :
2013-09-05 10:36:25 +08:00
return " There are no new episodes scheduled for {} . " . format ( series_name )
2011-11-20 22:23:31 +13:00
if len ( next_eps ) == 1 :
2013-09-05 10:36:25 +08:00
return " The next episode of {} airs {} " . format ( series_name , next_eps [ 0 ] )
2011-11-20 22:23:31 +13:00
else :
next_eps = ' , ' . join ( next_eps )
2013-09-05 10:36:25 +08:00
return " The next episodes of {} : {} " . format ( series_name , next_eps )
2011-11-20 22:23:31 +13:00
@hook.command
@hook.command ( ' tv_prev ' )
2012-02-29 00:29:53 -08:00
def tv_last ( inp , bot = None ) :
2013-09-04 18:30:04 +08:00
""" tv_last <series> -- Gets the most recently aired episode of <series>. """
2012-02-16 07:18:56 +13:00
api_key = bot . config . get ( " api_keys " , { } ) . get ( " tvdb " , None )
if api_key is None :
return " error: no api key set "
episodes = get_episodes_for_series ( inp , api_key )
2011-11-20 22:23:31 +13:00
if episodes [ " error " ] :
return episodes [ " error " ]
series_name = episodes [ " name " ]
ended = episodes [ " ended " ]
episodes = episodes [ " episodes " ]
prev_ep = None
today = datetime . date . today ( )
for episode in reversed ( episodes ) :
2012-02-16 07:18:56 +13:00
ep_info = get_episode_info ( episode , api_key )
2011-11-20 22:23:31 +13:00
if ep_info is None :
continue
2014-02-13 15:02:44 +13:00
( first_aired , air_date , episode_desc ) = ep_info
2011-11-20 22:23:31 +13:00
2014-02-13 15:02:44 +13:00
if air_date < today :
2011-11-20 22:23:31 +13:00
#iterating in reverse order, so the first episode encountered
#before today was the most recently aired
2013-09-05 10:36:25 +08:00
prev_ep = ' {} ( {} ) ' . format ( first_aired , episode_desc )
2011-11-20 22:23:31 +13:00
break
if not prev_ep :
2013-09-05 10:36:25 +08:00
return " There are no previously aired episodes for {} . " . format ( series_name )
2011-11-20 22:23:31 +13:00
if ended :
2013-09-05 10:36:25 +08:00
return ' {} ended. The last episode aired {} . ' . format ( series_name , prev_ep )
return " The last episode of {} aired {} . " . format ( series_name , prev_ep )