1818
1919try : import json
2020except ImportError : import simplejson as json
21- import logging , datetime , re , urllib .request , xbmc , xbmcaddon
21+ import datetime , re , urllib .request , xbmc , xbmcaddon
2222#import web_pdb
2323#web_pdb.set_trace()
2424
2525# -- Constants ----------------------------------------------
2626ADDON_ID = 'plugin.video.tagesschau'
27-
28- logger = logging .getLogger ("plugin.video.tagesschau.api" )
2927base_url = "https://www.tagesschau.de/api2u/"
3028
3129addon = xbmcaddon .Addon (id = ADDON_ID )
3230showage = addon .getSettingBool ('ShowAge' )
3331tt_listopt = addon .getSetting ('tt_list' )
32+ ts20_count = int (addon .getSetting ('ts20_count' ))
3433hide_europadruck = addon .getSettingBool ('hide_europadruck' )
3534hide_wolkenfilm = addon .getSettingBool ('hide_wolkenfilm' )
3635
@@ -176,13 +175,23 @@ def parse_broadcast(self, jsonbroadcast, title="" ):
176175
177176 def parse_livestream (self , jsonlivestream ):
178177 """Parses the video JSON into a VideoContent object."""
179- tsid = "livestream"
180- title = "Livestream"
181- timestamp = None
178+ tsid = jsonlivestream ["sophoraId" ]
179+ title = jsonlivestream ["title" ]
180+
181+ if ( "date" in jsonlivestream ):
182+ timestamp = self ._parse_date (jsonlivestream ["date" ])
183+ else :
184+ timestamp = datetime .datetime .now ()
185+
186+ if ( title .lower () == "tagesschau" ):
187+ title = title + timestamp .strftime (' vom %d.%m.%Y %H:%M' )
188+
182189 imageurls = {}
183190 imageurls = self ._parse_image_urls (jsonlivestream ["teaserImage" ]["imageVariants" ])
184191 videourls = self .parse_video_urls (jsonlivestream ["streams" ])
185- return VideoContent (tsid , title , timestamp , videourls , imageurls )
192+ duration = int (jsonlivestream ["tracking" ][1 ]["length" ])
193+ description = title
194+ return VideoContent (tsid , title , timestamp , videourls , imageurls , duration , description )
186195
187196 def parse_video_urls (self , jsonvariants ):
188197 """Parses the video mediadata JSON into a dict mapping variant name to URL."""
@@ -210,24 +219,23 @@ def _parse_image_urls(self, jsonvariants):
210219class VideoContentProvider (object ):
211220 """Provides access to the VideoContent offered by the tagesschau JSON API."""
212221
213- def __init__ (self , jsonsource ):
214- self ._jsonsource = jsonsource
222+ def __init__ (self ):
215223 self ._parser = VideoContentParser ()
216- self ._logger = logging .getLogger ("plugin.video.tagesschau.api.VideoContentProvider" )
217224
218225 def livestreams (self ):
219226 """Retrieves the livestream(s) currently on the air.
220227
221228 Returns:
222229 A list of VideoContent object for livestream(s) on the air.
223230 """
224- self ._logger .info ("retrieving livestream(s)" )
225231 videos = []
226- data = self ._jsonsource .livestreams ()
232+
233+ url = base_url + "channels"
234+ data = json .loads ( urllib .request .urlopen (url ).read () )
235+
227236 for jsonstream in data ["channels" ]:
228- if ( not "date" in jsonstream ): # livestream has no date
229- video = self ._parser .parse_livestream (jsonstream )
230- videos .append (video )
237+ video = self ._parser .parse_livestream (jsonstream )
238+ videos .append (video )
231239
232240 return videos
233241
@@ -237,10 +245,11 @@ def latest_videos(self):
237245 Returns:
238246 A list of VideoContent items.
239247 """
240- self ._logger .info ("retrieving videos" )
241-
242248 videos = []
243- data = self ._jsonsource .latest_videos ()
249+
250+ url = base_url + "news"
251+ data = json .loads ( urllib .request .urlopen (url ).read () )
252+
244253 for jsonvideo in data ["news" ]:
245254 try :
246255 if ( (jsonvideo ["type" ] == "video" ) and (jsonvideo ["tracking" ][0 ]["src" ] == "tagesschau" ) ):
@@ -252,9 +261,8 @@ def latest_videos(self):
252261 video = self ._parser .parse_video (jsonvideo )
253262 videos .append (video )
254263 except :
255- self . _logger . info ( "ignoring" )
264+ pass
256265
257- self ._logger .info ("found " + str (len (videos )) + " videos" )
258266 return videos
259267
260268 def latest_broadcasts (self ):
@@ -263,18 +271,19 @@ def latest_broadcasts(self):
263271 Returns:
264272 A list of VideoContent items.
265273 """
266- self ._logger .info ("retrieving broadcasts" )
267274 videos = []
268- data = self ._jsonsource .latest_broadcasts ()
275+
276+ url = base_url + "channels"
277+ data = json .loads ( urllib .request .urlopen (url ).read () )
278+
269279 for jsonbroadcast in data ["channels" ]:
270280 try :
271281 if ( ("date" in jsonbroadcast ) and ("title" in jsonbroadcast ) ): # Filter out livestream which has no date
272282 video = self ._parser .parse_broadcast (jsonbroadcast )
273283 videos .append (video )
274284 except :
275- self . _logger . info ( "ignoring" )
285+ pass
276286
277- self ._logger .info ("found " + str (len (videos )) + " videos" )
278287 return videos
279288
280289 def tagesschau_20 (self ):
@@ -283,20 +292,24 @@ def tagesschau_20(self):
283292 Returns:
284293 A list of VideoContent items.
285294 """
286- self ._logger .info ("retrieving tagesschau 20:00" )
287295 videos = []
288- data = self ._jsonsource .tagesschau_20 ()
289- for jsonvideo in data ["searchResults" ]:
290- try :
291- if ( jsonvideo ["type" ] == "video" ):
292- length = int (jsonvideo ["tracking" ][1 ]["length" ])
293- if ( (length >= 890 ) and (length <= 910 ) ):
294- video = self ._parser .parse_broadcast (jsonvideo , "Tagesschau" )
295- videos .append (video )
296- except :
297- self ._logger .info ("ignoring" )
296+
297+ page = 0
298+ while (len (videos ) < ts20_count ) and (page < 10 ):
299+ url = base_url + "search/?searchText=Tagesschau+20+Uhr&pageSize=30&resultPage=" + str (page )
300+ data = json .loads ( urllib .request .urlopen (url ).read () )
301+ page += 1
302+
303+ for jsonvideo in data ["searchResults" ]:
304+ try :
305+ if ( jsonvideo ["type" ] == "video" ):
306+ length = int (jsonvideo ["tracking" ][1 ]["length" ])
307+ if ( (length >= 890 ) and (length <= 910 ) ):
308+ video = self ._parser .parse_broadcast (jsonvideo , "Tagesschau" )
309+ videos .append (video )
310+ except :
311+ pass
298312
299- self ._logger .info ("found " + str (len (videos )) + " videos" )
300313 return videos
301314
302315 def tagesthemen (self ):
@@ -305,55 +318,27 @@ def tagesthemen(self):
305318 Returns:
306319 A list of VideoContent items.
307320 """
308- self ._logger .info ("retrieving tagesthemen" )
309321 videos = []
310- data = self ._jsonsource .tagesthemen ()
311- for jsonvideo in data ["searchResults" ]:
312- try :
313- if ( jsonvideo ["type" ] == "video" ):
314- length = int (jsonvideo ["tracking" ][1 ]["length" ])
315- video = self ._parser .parse_broadcast (jsonvideo )
316322
317- if ( tt_listopt == "0" ):
318- if ( length >= 1100 ):
323+ for page in range (2 ):
324+ url = base_url + "search/?searchText=tagesthemen&pageSize=50&resultPage=" + str (page )
325+ data = json .loads ( urllib .request .urlopen (url ).read () )
326+
327+ for jsonvideo in data ["searchResults" ]:
328+ try :
329+ if ( jsonvideo ["type" ] == "video" ):
330+ length = int (jsonvideo ["tracking" ][1 ]["length" ])
331+ video = self ._parser .parse_broadcast (jsonvideo )
332+
333+ if ( tt_listopt == "0" ):
334+ if ( length >= 1100 ):
335+ videos .append (video )
336+ elif ( tt_listopt == "1" ):
337+ if ( length < 1100 ):
338+ videos .append (video )
339+ else :
319340 videos .append (video )
320- elif ( tt_listopt == "1" ):
321- if ( length < 1100 ):
322- videos .append (video )
323- else :
324- videos .append (video )
325- except :
326- self ._logger .info ("ignoring" )
341+ except :
342+ pass
327343
328- self ._logger .info ("found " + str (len (videos )) + " videos" )
329344 return videos
330-
331-
332- class JsonSource (object ):
333- """Provides access to the raw objects parsed from the TS JSON API.
334- Can be replaced for unittesting purposes."""
335-
336- def livestreams (self ):
337- """Returns the parsed JSON structure for livestreams."""
338- handle = urllib .request .urlopen (base_url + "channels" )
339- return json .loads (handle .read ())
340-
341- def latest_videos (self ):
342- """Returns the parsed JSON structure for the latest videos."""
343- handle = urllib .request .urlopen (base_url + "news" )
344- return json .loads (handle .read ())
345-
346- def latest_broadcasts (self ):
347- """Returns the parsed JSON structure for the latest broadcasts."""
348- handle = urllib .request .urlopen (base_url + "channels" )
349- return json .loads (handle .read ())
350-
351- def tagesschau_20 (self ):
352- """Returns the parsed JSON structure for 20:00 tagesschau"""
353- handle = urllib .request .urlopen (base_url + "search/?searchText=Tagesschau+20+Uhr" )
354- return json .loads (handle .read ())
355-
356- def tagesthemen (self ):
357- """Returns the parsed JSON structure for tagesthemen"""
358- handle = urllib .request .urlopen (base_url + "search/?searchText=tagesthemen" )
359- return json .loads (handle .read ())
0 commit comments