From b19aa83dc61200ec67bc6c312f40fc13aba5cd5b Mon Sep 17 00:00:00 2001 From: Mike Date: Sat, 27 Apr 2013 12:14:06 -0600 Subject: [PATCH 1/4] rewrite due to site change --- Contents/Code/__init__.py | 80 ++++++++++--------- Contents/Info.plist | 4 - Contents/Services/ServiceInfo.plist | 10 +-- .../Services/URL/PBS Kids/ServiceCode.pys | 59 +++++++------- 4 files changed, 77 insertions(+), 76 deletions(-) diff --git a/Contents/Code/__init__.py b/Contents/Code/__init__.py index e7f597a..84189eb 100644 --- a/Contents/Code/__init__.py +++ b/Contents/Code/__init__.py @@ -1,73 +1,81 @@ -VIDEO_PREFIX = "/video/pbskids" +PREFIX = "/video/pbskids" NAME = "PBS Kids" PBSKIDS_URL = "http://www.pbskids.org/video/" -PBSKIDS_SHOWS = "http://pbskids.org/everything.html" -PBS_JSON = "http://pbs.feeds.theplatform.com/ps/JSON/PortalService/2.2/getReleaseList?PID=6HSLquMebdOkNaEygDWyPOIbkPAnQ0_C&startIndex=1&endIndex=500&sortField=airdate&sortDescending=true&query=contentCustomBoolean|isClip|%s&field=airdate&field=author&field=bitrate&field=description&field=format&field=length&field=PID&field=thumbnailURL&field=title&field=URL&contentCustomField=isClip¶m=affiliate|prekPlayer&field=categories&field=expirationDate&query=categories|%s" +PBSKIDS_SHOWS = "http://pbskids.org/go/video/js/org.pbskids.shows.js" #"http://pbskids.org/everything.html" +VIDEO_LIST = "http://pbskids.org/pbsk/video/api/getVideos/?startindex=%s&endindex=%s&program=%s&category=&group=&selectedID=&status=available&type=%s&return=airdate,+expirationdate,+rating" CATEGORY_LIST = "http://pbs.feeds.theplatform.com/ps/JSON/PortalService/2.2/getCategoryList?PID=6HSLquMebdOkNaEygDWyPOIbkPAnQ0_C&query=CustomText|CategoryType|%s&query=HasReleases&field=title&field=thumbnailURL" ART = "art-default.jpg" ICON = "icon-default.png" +OFFSET = 20 + +VIDEO_URL = '%sid=%s' #################################################################################################### def Start(): - Plugin.AddPrefixHandler(VIDEO_PREFIX, MainMenu, NAME, ICON, ART) ObjectContainer.art = R(ART) ObjectContainer.title1 = NAME DirectoryObject.thumb=R(ICON) #################################################################################################### +@handler(PREFIX, NAME, ICON, ART) def MainMenu(): oc = ObjectContainer() - oc.add(DirectoryObject(key=Callback(ShowsList, categoryType="Show", title="Shows"), title="Shows")) - oc.add(DirectoryObject(key=Callback(ShowsList, categoryType="Channel", title="Topics"), title="Topics")) + content = JSON.ObjectFromURL(PBSKIDS_SHOWS) + for item in content: + title = item['title'] + thumb = item['thumbnail2URL'] + summary = String.StripTags(item['description']) + oc.add(DirectoryObject(key=Callback(ShowPage, title=title, thumb=thumb), title=title, summary=summary, + thumb=Resource.ContentsOfURLWithFallback(url=thumb))) return oc #################################################################################################### +@route(PREFIX + '/show') def ShowPage(title, thumb): oc = ObjectContainer(title2=title) - oc.add(DirectoryObject(key=Callback(VideoPage, clip='false', title=title), title="Full Episodes", thumb=Resource.ContentsOfURLWithFallback(url=thumb, fallback=ICON))) - oc.add(DirectoryObject(key=Callback(VideoPage, clip='true', title=title), title="Clips", thumb=Resource.ContentsOfURLWithFallback(url=thumb, fallback=ICON))) + oc.add(DirectoryObject(key=Callback(VideoPage, clip='Episode', title=title), title="Full Episodes", + thumb=Resource.ContentsOfURLWithFallback(url=thumb))) + oc.add(DirectoryObject(key=Callback(VideoPage, clip='Clip', title=title), title="Clips", + thumb=Resource.ContentsOfURLWithFallback(url=thumb))) - if len(oc) == 0: - return ObjectContainer(header="Empty", message="There aren't any items") - else: - return oc + return oc #################################################################################################### -def VideoPage(clip, title): +@route(PREFIX + '/videos') +def VideoPage(clip, title, offset=0): oc = ObjectContainer(title2=title) - show_title = title.replace(' ', '%20').replace('&', '%26') ### FORMATTING FIX - content = JSON.ObjectFromURL(PBS_JSON % (clip, show_title), cacheTime=CACHE_1DAY) + if offset == 0: + start = 0 + else: + start = offset + offset = offset + OFFSET + content = JSON.ObjectFromURL(VIDEO_LIST % (start, offset, String.Quote(title, usePlus=True), clip), cacheTime=CACHE_1DAY) for item in content['items']: - thumb = item['thumbnailURL'] - link = item['URL'] + series_url = item['series_url'] + if not series_url.endswith('/'): + series_url = series_url + '/' + url = VIDEO_URL % (series_url, item['id']) video_title = item['title'] summary = item['description'] - duration = item['length'] + duration = item['videos']['iphone']['length'] + try: thumb = item['images']['originalres_4x3'] + except: + try: thumb = item['images']['originalres_16x9'] + except: thumb = ICON - if clip == 'true': - oc.add(VideoClipObject(url=link, title=video_title, summary=summary, duration=int(duration), thumb=Resource.ContentsOfURLWithFallback(url=thumb, fallback=ICON))) + if clip == 'Clip': + oc.add(VideoClipObject(url=url, title=video_title, summary=summary, duration=duration, + thumb=Resource.ContentsOfURLWithFallback(thumb))) else: - oc.add(EpisodeObject(url=link, title=video_title, show=title, summary=summary, duration=int(duration), thumb=Resource.ContentsOfURLWithFallback(url=thumb, fallback=ICON))) + oc.add(EpisodeObject(url=url, title=video_title, show=title, summary=summary, duration=duration, + thumb=Resource.ContentsOfURLWithFallback(thumb))) + if int(content['matched']) > offset: + oc.add(NextPageObject(key=Callback(VideoPage, clip=clip, title=title, offset=offset), title="More")) if len(oc) == 0: return ObjectContainer(header="Empty", message="There aren't any items") else: return oc - -#################################################################################################### -def ShowsList(categoryType, title): - oc = ObjectContainer(title2=title) - content = JSON.ObjectFromURL(CATEGORY_LIST % categoryType) - for item in content['items']: - title = item['title'] - thumb = item['thumbnailURL'] - if thumb != "": - if "Channel Sample" not in title: - if categoryType == "Show": - oc.add(DirectoryObject(key=Callback(ShowPage, title=title, thumb=thumb), title=title, thumb=Resource.ContentsOfURLWithFallback(url=thumb, fallback=ICON))) - else: - oc.add(DirectoryObject(key=Callback(VideoPage, title=title, clip='true'), title=title, thumb=Resource.ContentsOfURLWithFallback(url=thumb, fallback=ICON))) - return oc diff --git a/Contents/Info.plist b/Contents/Info.plist index 66e3139..650be0d 100644 --- a/Contents/Info.plist +++ b/Contents/Info.plist @@ -10,9 +10,5 @@ * PlexFrameworkVersion 2 - PlexFrameworkFlags - - UseRealRTMP - diff --git a/Contents/Services/ServiceInfo.plist b/Contents/Services/ServiceInfo.plist index ae1d6b9..466fae5 100644 --- a/Contents/Services/ServiceInfo.plist +++ b/Contents/Services/ServiceInfo.plist @@ -6,19 +6,11 @@ PBS Kids - TestURLs - - http://release.theplatform.com/content.select\?pid=3CxvEh2lftsC1ypeLZXmKt6Vu50ksjYL%26UserName=Unknown%26affiliate=prekPlayer%26Embedded=True%26Portal=PBS%20KidsGo%20Default%20Feed%26Tracking=True - URLPatterns - http://release.theplatform.com/content.select\?pid=.+?Portal=PBS%20KidsGo.* + http://pbskids.org/.+/id=[0-9]+ - PlexFrameworkFlags - - UseRealRTMP - diff --git a/Contents/Services/URL/PBS Kids/ServiceCode.pys b/Contents/Services/URL/PBS Kids/ServiceCode.pys index 8a493e2..b5658b0 100644 --- a/Contents/Services/URL/PBS Kids/ServiceCode.pys +++ b/Contents/Services/URL/PBS Kids/ServiceCode.pys @@ -1,17 +1,25 @@ -NAMESPACES = {"a" : "http://www.w3.org/2001/SMIL20/Language", "tp" : "http://xml.theplatform.com/mps/metadata/content/custom"} - +JSON_URL = 'http://pbskids.org/pbsk/video/api/getVideos/?id=' #################################################################################################### def MetadataObjectForURL(url): - smil = XML.ElementFromURL(url + '&format=SMIL') - video = smil.xpath('//a:ref', namespaces=NAMESPACES)[0] - title = video.get('title') - duration = int(video.get('dur').strip('ms')) - - return VideoClipObject( - title = title, - thumb = R('icon-default.png'), - duration = duration - ) + details = GetJSON(url) + title = details['title'] + thumb = details['images']['originalres_4x3'] + summary = details['description'] + duration = details['videos']['ipad']['length'] + if details['type'] =='Clip': + return VideoClipObject( + title = title, + summary=summary, + thumb = Resource.ContentsOfURLWithFallback(thumb) + ) + else: + show_title = details['series_title'] + return EpisodeObject( + title = title, + show = show_title, + summary = summary, + thumb = Resource.ContentsOfURLWithFallback(thumb) + ) #################################################################################################### def MediaObjectsForURL(url): @@ -20,25 +28,22 @@ def MediaObjectsForURL(url): MediaObject( video_codec = VideoCodec.H264, audio_codec = AudioCodec.AAC, - video_resolution = 360, - parts = [PartObject(key=Callback(PlayVideo, url = url))] + protocol = 'hls', + parts = [PartObject(key=Callback(PlayVideo, url=url))], ) ] #################################################################################################### @indirect def PlayVideo(url): - - smil = XML.ElementFromURL(url + '&format=SMIL') + details = GetJSON(url) + try: redirect_url = details['videos']['ipad']['url'] + except: redirect_url = details['videos']['iphone']['url'] + m3u8_url = JSON.ObjectFromURL(redirect_url + '?format=json')['url'] + return IndirectResponse(VideoClipObject, key=HTTPLiveStreamURL(url=m3u8_url)) - rtmp_base = smil.xpath('//a:meta', namespaces=NAMESPACES)[0].get('base') - rtmp_url = smil.xpath('//a:ref', namespaces=NAMESPACES)[0].get('src') - - clip = rtmp_url - if '.mp4' in clip: - clip = 'mp4:' + clip.split('.mp4')[0] - elif '.flv' in clip: - clip = clip.split('.flv')[0] - - return IndirectResponse(VideoClipObject, key=RTMPVideoURL(url=rtmp_base, clip=clip)) - \ No newline at end of file +#################################################################################################### +def GetJSON(url): + video_id = url.split('id=')[1] + json = JSON.ObjectFromURL(JSON_URL + video_id) + return json['items'][0] \ No newline at end of file From b1aaac80fd7cbd5f630a996662f59bfb60504039 Mon Sep 17 00:00:00 2001 From: Mike Date: Sat, 27 Apr 2013 12:22:14 -0600 Subject: [PATCH 2/4] fix for thumbs --- Contents/Code/__init__.py | 5 ++--- Contents/Services/URL/PBS Kids/ServiceCode.pys | 5 ++++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Contents/Code/__init__.py b/Contents/Code/__init__.py index 84189eb..2aeed49 100644 --- a/Contents/Code/__init__.py +++ b/Contents/Code/__init__.py @@ -61,11 +61,10 @@ def VideoPage(clip, title, offset=0): video_title = item['title'] summary = item['description'] duration = item['videos']['iphone']['length'] - try: thumb = item['images']['originalres_4x3'] + try: thumb = item['images']['originalres_4x3']['url'] except: - try: thumb = item['images']['originalres_16x9'] + try: thumb = item['images']['originalres_16x9']['url'] except: thumb = ICON - if clip == 'Clip': oc.add(VideoClipObject(url=url, title=video_title, summary=summary, duration=duration, thumb=Resource.ContentsOfURLWithFallback(thumb))) diff --git a/Contents/Services/URL/PBS Kids/ServiceCode.pys b/Contents/Services/URL/PBS Kids/ServiceCode.pys index b5658b0..0c9e39a 100644 --- a/Contents/Services/URL/PBS Kids/ServiceCode.pys +++ b/Contents/Services/URL/PBS Kids/ServiceCode.pys @@ -3,7 +3,10 @@ JSON_URL = 'http://pbskids.org/pbsk/video/api/getVideos/?id=' def MetadataObjectForURL(url): details = GetJSON(url) title = details['title'] - thumb = details['images']['originalres_4x3'] + try: thumb = item['images']['originalres_4x3']['url'] + except: + try: thumb = item['images']['originalres_16x9']['url'] + except: thumb = R('icon-deafult.jpg) summary = details['description'] duration = details['videos']['ipad']['length'] if details['type'] =='Clip': From 8a54d53cc8eb278f8b049c78f0371749d4b5fd8c Mon Sep 17 00:00:00 2001 From: Mike Date: Sat, 27 Apr 2013 12:23:09 -0600 Subject: [PATCH 3/4] catch typo --- Contents/Services/URL/PBS Kids/ServiceCode.pys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Contents/Services/URL/PBS Kids/ServiceCode.pys b/Contents/Services/URL/PBS Kids/ServiceCode.pys index 0c9e39a..6a9e5d3 100644 --- a/Contents/Services/URL/PBS Kids/ServiceCode.pys +++ b/Contents/Services/URL/PBS Kids/ServiceCode.pys @@ -6,7 +6,7 @@ def MetadataObjectForURL(url): try: thumb = item['images']['originalres_4x3']['url'] except: try: thumb = item['images']['originalres_16x9']['url'] - except: thumb = R('icon-deafult.jpg) + except: thumb = R('icon-deafult.jpg') summary = details['description'] duration = details['videos']['ipad']['length'] if details['type'] =='Clip': From 6e3d7c5ea5f29a65e7e8153642d7a64a1456db35 Mon Sep 17 00:00:00 2001 From: Mike Date: Sat, 27 Apr 2013 13:38:12 -0600 Subject: [PATCH 4/4] fix formatting error --- Contents/Services/URL/PBS Kids/ServiceCode.pys | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Contents/Services/URL/PBS Kids/ServiceCode.pys b/Contents/Services/URL/PBS Kids/ServiceCode.pys index 6a9e5d3..10b66d3 100644 --- a/Contents/Services/URL/PBS Kids/ServiceCode.pys +++ b/Contents/Services/URL/PBS Kids/ServiceCode.pys @@ -4,9 +4,9 @@ def MetadataObjectForURL(url): details = GetJSON(url) title = details['title'] try: thumb = item['images']['originalres_4x3']['url'] - except: - try: thumb = item['images']['originalres_16x9']['url'] - except: thumb = R('icon-deafult.jpg') + except: + try: thumb = item['images']['originalres_16x9']['url'] + except: thumb = R('icon-deafult.jpg') summary = details['description'] duration = details['videos']['ipad']['length'] if details['type'] =='Clip':