def root(plugin, content_type="video"): """ :param Route plugin: The plugin parent object. :param str content_type: The type of content been listed e.g. video, music. This is passed in from kodi and we have no use for it as of yet. """ yield Listitem.recent(recent_videos) yield Listitem.from_dict(top_videos, plugin.localize(TOP_VIDEOS)) yield Listitem.from_dict(watching_now, plugin.localize(WATCHING_NOW)) yield Listitem.search(video_list) # Fetch HTML Source url = url_constructor("/mobile/category.html") resp = urlquick.get(url, headers={"Cookie": "COOKIE_DEVICE=mobile"}) root_elem = resp.parse(u"ul", attrs={"id": "category_listing"}) for elem in root_elem.iterfind("li"): a_tag = elem.find("a") item = Listitem() # Set label with video count added item.label = "%s (%s)" % (a_tag.text, elem.find("span").text) item.set_callback(video_list, cat=a_tag.get("href")) yield item # Add the video items here so that show at the end of the listing yield Listitem.from_dict(play_video, plugin.localize(VIDEO_OF_THE_DAY), params={"url": "index.html"}) yield Listitem.from_dict(party_play, plugin.localize(PARTY_MODE), params={"url": "randomizer.php"})
def video_list(_, url): """ :param Route _: The plugin parent object. :param unicode url: The url resource containing recent videos. """ # Fetch HTML Source url = url_constructor(url) resp = urlquick.get(url) root_elem = resp.parse("div", attrs={"class": "primary-content"}) for elem in root_elem.find("ul").iterfind("./li/div"): item = Listitem() item.art["thumb"] = elem.find(".//img").get("src") item.info["plot"] = elem.find("p").text.strip() # Find duration node = elem.find("span/span/span") if node is not None and "pm-label-duration" in node.get("class"): item.info["duration"] = node.text.strip() # View count views = elem.find("./div/span[@class='pm-video-attr-numbers']/small").text item.info["count"] = views.split(" ", 1)[0].strip() # Date of video date = elem.find(".//time[@datetime]").get("datetime") date = date.split("T", 1)[0] item.info.date(date, "%Y-%m-%d") # 2018-10-19 # Url to video & name a_tag = elem.find("h3/a") url = a_tag.get("href") item.label = a_tag.text # Extract the artist name from the title item.info["artist"] = [a_tag.text.split("-", 1)[0].strip()] item.context.related(related, url=url) item.set_callback(play_video, url=url) yield item # Fetch next page url next_tag = root_elem.find("./div[@class='pagination pagination-centered']/ul") if next_tag is not None: next_tag = next_tag.findall("li[@class='']/a") next_tag.reverse() for node in next_tag: if node.text == u"\xbb": yield Listitem.next_page(url=node.get("href"), callback=video_list) break
def video_list(plugin, url): """ List all video for given url. site: http://www.watchmojo.com/shows/Top%2010 :param Route plugin: Tools related to Route callbacks. :param unicode url: The url to a list of videos. :return: A generator of listitems. """ url = url_constructor(url) source = urlquick.get(url) lbl_tags = plugin.localize(TAGS) # Parse all the video elements root_elem = source.parse() for line in root_elem.iterfind(".//div[@class='owl-carousel margin-bottom']"): for elem in line.iterfind(".//div[@class='item']"): yield extract_videos(lbl_tags, elem, "%b %d, %Y") # Add link to next page if available next_page = root_elem.find(".//div[@class='cat-next']") if next_page is not None: url = next_page.find("a").get("href") yield Listitem.next_page(url=url)
def watching_now(_): # Fetch HTML Source url = url_constructor("/index.html") resp = urlquick.get(url) root_elem = resp.parse("ul", attrs={"id": "mycarousel"}) for elem in root_elem.iterfind("li"): a_tag = elem.find(".//a[@title]") item = Listitem() # Fetch label & thumb item.label = a_tag.text item.art["thumb"] = elem.find(".//img").get("src") url = a_tag.get("href") item.context.related(related, url=url) item.set_callback(play_video, url=url) yield item
def related(_, url): """ :param Route _: The plugin parent object. :param unicode url: The url of a video. """ # Fetch HTML Source url = url_constructor(url) resp = urlquick.get(url) root_elem = resp.parse("div", attrs={"id": "bestincategory"}) for elem in root_elem.iterfind("ul/li/div"): img = elem.find(".//img") item = Listitem() # The image tag contains both the image url and title item.label = img.get("alt") item.art["thumb"] = img.get("src") # Find duration node = elem.find("span/span/span") if node is not None and "pm-label-duration" in node.get("class"): item.info["duration"] = node.text.strip() # View count item.info["count"] = elem.find("div/span/small").text.split(" ")[0].strip() url = elem.find("span/a").get("href") item.context.related(related, url=url) item.set_callback(play_video, url=url) yield item
def recent_videos(_, url="newvideos.php"): """ :param Route _: The plugin parent object. :param unicode url: The url resource containing recent videos. """ # Fetch HTML Source url = url_constructor(url) resp = urlquick.get(url) root_elem = resp.parse("div", attrs={"id": "browse_main"}) node = root_elem.find("./div[@id='newvideos_results']")[0] for elem in node.iterfind("./tr"): if not elem.attrib: item = Listitem() item.art["thumb"] = elem.find(".//img").get("src") artist = elem[1].text track = elem[1][0][0].text item.label = "%s - %s" % (artist, track) item.info["artist"] = [artist] url = elem.find(".//a").get("href") item.context.related(related, url=url) item.set_callback(play_video, url=url) yield item # Fetch next page url next_tag = root_elem.findall("./div[@class='pagination']/a") if next_tag and next_tag[-1].text.startswith("next"): yield Listitem.next_page(url=next_tag[-1].get("href"))
def root(_): """ Lists all categories and link's to 'Shows', 'MsMojo' and 'All videos'. site: http://www.watchmojo.com :param Route _: Tools related to callback. :return: A generator of listitems. """ # Add links to watchmojo youtube channels yield Listitem.youtube("UCaWd5_7JhbQBe4dknZhsHJg") # WatchMojo yield Listitem.youtube("UCMm0YNfHOCA-bvHmOBSx-ZA", label="WatchMojo UK") yield Listitem.youtube("UC3rLoj87ctEHCcS7BuvIzkQ", label="MsMojo") url = url_constructor("/") source = urlquick.get(url) root_elem = source.parse() # Parse only the show category elements menu_elem = root_elem.find(".//ul[@class='top-ul left']") for elem in menu_elem.iterfind(".//a"): url = elem.get("href") if url and elem.text and elem.text != "MsMojo": item = Listitem() item.label = elem.text item.set_callback(video_list, url=url) yield item
def watching_now(_): # Fetch HTML Source url = url_constructor("/index.html") resp = urlquick.get(url, max_age=0) try: root_elem = resp.parse("ul", attrs={"id": "pm-ul-wn-videos"}) except RuntimeError: pass else: for elem in root_elem.iterfind("li/div"): img = elem.find(".//img") item = Listitem() # The image tag contains both the image url and title item.label = img.get("alt") item.art["thumb"] = img.get("src") url = elem.find("span/a").get("href") item.context.related(related, url=url) item.set_callback(play_video, url=url) yield item
def tags(plugin, url): """ List tags for a video. site: https://www.watchmojo.com/video/id/19268/ :param Route plugin: Tools related to Route callbacks. :param unicode url: The url to a video. :return: A generator of listitems. """ plugin.category = plugin.localize(TAGS) url = url_constructor(url) source = urlquick.get(url) # Parse all video tags root_elem = source.parse("div", attrs={"id": "tags"}) for elem in root_elem.iterfind("a"): item = Listitem() item.label = elem.text.title() item.set_callback(video_list, url="%s1" % elem.get("href")) yield item
def recent(plugin): """ List all recent videos from the rss feed. :param Route plugin: Tools related to Route callbacks. :return: A generator of listitems. """ url = "http://feeds.feedburner.com/johnlockerv3" source = plugin.request.get(url) # Pars all the videos root_elem = source.xml() for elem in root_elem.iterfind("./channel/item"): item = Listitem() date = elem.findtext("pubDate") item.info.date(date[:date.find("+") - 1], "%a, %d %b %Y %H:%M:%S") item.info["genre"] = elem.findall("category")[0].text # Split title into label and plot title, _, plot = elem.findtext("title").partition("\u2013") item.info["plot"] = plot.split("(", 1)[0].strip() item.label = title.split("(", 1)[0].strip() item.set_callback(play_video, url=elem.findtext("comments")) yield item
def search_results(_, search_query): """ List search results :param Route _: Tools related to Route callbacks. :param search_query: The search term to find results for. """ url = url_constructor("/search/search_1018.php?q={}&query=like".format(search_query)) source = urlquick.get(url) root_elem = source.parse() for elem in root_elem.iterfind(".//li"): item = Listitem() atag = elem.find("a") item.art["thumb"] = url_constructor(atag.find("img").get("src")) # Extrac all title segments and join title = [atag.text] for i in atag: title.append(i.text) title.append(i.tail) item.label = "".join(filter(None, title)) # Extract plot plot_node = elem.find("div") plots = [plot_node.text] for node in plot_node: plots.append(node.text) plots.append(node.tail) item.info["plot"] = "".join(text.strip() for text in plots if text is not None) url = atag.get("href") item.set_callback(play_video, url=url) yield item
def related(_, url): """ :param Route _: The plugin parent object. :param unicode url: The url of a video. """ # Fetch HTML Source url = url_constructor(url) resp = urlquick.get(url) root_elem = resp.parse("div", attrs={"id": "tabs_related"}) # Parse the xml for elem in root_elem.iterfind(u"div"): a_tag = elem.find("./a[@class='song_name']") item = Listitem() item.label = a_tag.text item.art["thumb"] = elem.find("./a/img").get("src") url = a_tag.get("href") item.context.related(related, url=url) item.set_callback(play_video, url=url) yield item
def root(plugin): """ Lists all categories and link's to 'Shows', 'MsMojo' and 'All videos'. site: http://johnlocker.com :param Route plugin: Tools related to callback. :return: A generator of listitems. """ url = url_constructor("/us") source = plugin.request.get(url) # Add link to recent videos yield Listitem.recent(recent) # Parse the categories root_elem = source.parse("ul", attrs={"id": "menu-category-items primary-menu"}) for elem in root_elem.iterfind("./li/a"): item = Listitem() item.label = elem.text item.set_callback(video_list, url=elem.get("href")) yield item
def tags(plugin, url): """ List tags for a video. site: https://www.watchmojo.com/video/id/19268/ :param Route plugin: Tools related to Route callbacks. :param unicode url: The url to a video. """ plugin.category = plugin.localize(TAGS) url = url_constructor(url) source = urlquick.get(url) # Parse all video tags root_elem = source.parse("div", attrs={"id": "tags"}) for elem in root_elem.iterfind("a"): url = elem.get("href") urlparams = utils.parse_qs(url) if "q" in urlparams: search_term = urlparams["q"] item = Listitem() item.label = elem.text.title() item.set_callback(search_results, search_term) yield item
def extract_videos(lbl_tags, elem, date_format): item = Listitem() item.label = elem.findtext(".//div[@class='hptitle']").replace("\t", " ").strip() item.art["thumb"] = url_constructor(elem.find(".//img").get("src")) duration = elem.find(".//img[@class='hpplay']") if duration is not None and duration.tail: item.info["duration"] = duration.tail.strip(";") url = elem.find("a").get("href") item.info.date(elem.findtext(".//div[@class='hpdate']").strip(), date_format) item.context.container(tags, lbl_tags, url=url) item.context.related(related, url=url) item.set_callback(play_video, url=url) return item
def video_list(plugin, url=None, cat=None, search_query=None): """ :param Route plugin: The plugin parent object. :param unicode url: The url resource containing lists of videos or next page. :param unicode cat: A category url e.g. Alternative, Folk Metal. :param unicode search_query: The video search term to use for searching. """ if search_query: url = url_constructor("search.php?keywords=%s&btn=Search" % search_query) elif cat: sortby = (u"date.html", u"artist.html", u"rating.html", u"views.html")[plugin.setting.get_int("sort")] base, _ = url_constructor(cat).rsplit("-", 1) url = "-".join((base, sortby)) else: url = url_constructor(url) resp = urlquick.get(url) root_elem = resp.parse("div", attrs={"id": "browse_main"}) for elem in root_elem.iterfind(u".//div[@class='video_i']"): item = Listitem() item.art["thumb"] = elem.find(".//img").get("src") # Extract url and remove first 'a' tag section # This makes it easir to extract 'artist' and 'song' name later a_tag = elem.find("a") url = a_tag.get("href") elem.remove(a_tag) # Fetch title span_tags = tuple(node.text for node in elem.findall(".//span")) item.label = "%s - %s" % span_tags item.info["artist"] = [span_tags[0]] # Add related video context item item.context.related(related, url=url) item.set_callback(play_video, url=url) yield item # Fetch next page url next_tag = root_elem.findall(".//div[@class='pagination']/a") if next_tag and next_tag[-1].text.startswith("next"): yield Listitem.next_page(url=next_tag[-1].get("href"))
def top_videos(plugin): """:param Route plugin: The plugin parent object.""" # Fetch HTML Source plugin.cache_to_disc = True url = url_constructor("/topvideos.html") resp = urlquick.get(url) titles = [] urls = [] # Parse categories root_elem = resp.parse("select", attrs={"name": "categories"}) for group in root_elem.iterfind("optgroup"): for elem in group: urls.append(elem.get("value")) titles.append(elem.text.strip()) # Display list for Selection dialog = xbmcgui.Dialog() ret = dialog.select(plugin.localize(SELECT_TOP), titles) if ret >= 0: # Fetch HTML Source url = urls[ret] resp = urlquick.get(url) root_elem = resp.parse("div", attrs={"id": "topvideos_results"}) for elem in root_elem.iterfind(".//tr"): if not elem.attrib: item = Listitem() a_tag = elem[3][0] artist = elem[2].text item.label = "%s %s - %s" % (elem[0].text, artist, a_tag.text) item.art["thumb"] = elem.find(".//img").get("src") item.info["count"] = elem[4].text.replace(",", "") item.info["artist"] = [artist] url = a_tag.get("href") item.context.related(related, url=url) item.set_callback(play_video, url=url) yield item else: yield False
def video_list(plugin, url): """ List all videos for given url. site: http://johnlocker.com/category/science-tech/ :param Route plugin: Tools related to Route callbacks. :param unicode url: The url to a list of videos. :return: A generator of listitems. """ url = url_constructor(url) source = plugin.request.get(url) # Parse video content root_elem = source.parse("main", attrs={"id": "main"}) for elem in root_elem.iterfind("./div/article"): a_tag = elem.find(".//a[@rel='bookmark']") item = Listitem() item.label = a_tag.text.split("(", 1)[0].strip() url = a_tag.get("href") date = elem.find(".//time[@datetime]").get("datetime") item.info.date(date[:date.find("+")], "%Y-%m-%dT%H:%M:%S") item.info["count"] = elem.find(".//span[@class='entry-view']").text.split(" ", 1)[0].replace(",", "") # Extract video source url using post id to help with search post_id = elem.get("id").split("-", 1)[-1] iframe_node = elem.find("./div[@id='entry-video-%s']//iframe" % post_id) if iframe_node is not None: url = iframe_node.get("src") thumb = elem.find("./a/img") if thumb is not None: item.art["thumb"] = thumb.get("src") item.set_callback(play_video, url=url) yield item next_page = root_elem.find(".//nav/a[@class='next page-numbers']") if next_page is not None: yield Listitem.next_page(url=next_page.get("href"))
def root(plugin): """:type plugin: Route""" # Set context parameters based on default view setting if plugin.setting.get_int("defaultview") == 0: context_label = plugin.localize(LIST_AUDIO) context_type = "segment" item_type = "video" else: context_label = plugin.localize(LIST_VIDEO) context_type = "video" item_type = "segment" # Fetch HTML Source url = "https://www.sciencefriday.com/explore/" html = urlquick.get(url) # Parse for the content root_elem = html.parse("form", attrs={"class": "searchandfilter"}) sfid = root_elem.get("data-sf-form-id") # Add Youtube & Recent Content yield Listitem.youtube("UCDjGU4DP3b-eGxrsipCvoVQ") # Add Recent Videos link yield Listitem.from_dict(content_lister, plugin.localize(RECENT_VIDEOS), params={"sfid": sfid, "ctype": "video"}) # Add Recent Audio link yield Listitem.from_dict(content_lister, plugin.localize(RECENT_AUDIO), params={"sfid": sfid, "ctype": "segment"}) # List all topics for elem in root_elem.iterfind(".//option[@data-sf-cr]"): item = Listitem() item.label = elem.text # Add context item to link to the opposite content type. e.g. audio if video is default item.context.container(content_lister, context_label, topic=elem.attrib["value"], sfid=sfid, ctype=context_type) item.set_callback(content_lister, topic=elem.attrib["value"], ctype=item_type, sfid=sfid) yield item
def buildSearch(self, callback): return Listitem().search(**{ "callback": self.callbackRefs.get("tray_list"), })
def open_json_page(plugin, page, base_url): items = json.loads(page) for i in items['channels']: item = Listitem() if 'details' in i and isinstance(i['details'], dict): if 'poster' in i['details']: item.art.poster = i['details']['poster'] if 'released' in i['details']: item.info.premiered = i['details']['released'] if 'background-image' in items: item.art.landscape = items['background-image'] item.label = remove_html_tags(i['title']) if 'logo_30x30' in i: item.art.thumb = i['logo_30x30'] if 'description' in i: item.info.plot = remove_html_tags(i['description']) if 'search_on' in i: print("search method user") item.set_callback(do_input_page, url=i['playlist_url'], base_url=base_url) elif 'playlist_url' in i: print("dir method user") item.set_callback(open_page, url=i['playlist_url'], base_url=base_url) elif 'stream_url' in i: print("stream method user") if 'youtube.com' or 'youtu.be' in i['stream_url']: item.set_callback(play_youtubedl_url, url=i['stream_url']) else: item.set_path(path=i['stream_url']) yield item
def list_programs(plugin, item_id, next_url, **kwargs): resp = urlquick.get(next_url) json_parser = json.loads(resp.text) if 'strates' in json_parser: program_title = json_parser['currentPage']['displayName'] for strate in json_parser["strates"]: if strate["type"] == "contentRow" or strate["type"] == "contentGrid": strate_title = program_title + ' - ' + strate["title"] item = Listitem() item.label = strate_title item.set_callback( list_sub_programs, item_id=item_id, next_url=next_url, strate_title=strate_title) item_post_treatment(item) yield item elif 'episodes' in json_parser: program_title = json_parser['currentPage']['displayName'] for video_datas in json_parser["episodes"]['contents']: video_title = program_title + ' - ' + video_datas['title'] video_image = video_datas['URLImage'] video_plot = '' if 'summary' in video_datas: video_plot = video_datas['summary'] if 'contentAvailability' in video_datas: video_url = video_datas["contentAvailability"]["availabilities"]["stream"]["URLMedias"] else: video_url = video_datas["URLMedias"] item = Listitem() item.label = video_title item.art['thumb'] = item.art['landscape'] = video_image item.info['plot'] = video_plot item.set_callback( get_video_url, item_id=item_id, next_url=video_url) item_post_treatment(item, is_playable=True, is_downloadable=True) yield item if json_parser["episodes"]["paging"]["hasNextPage"]: yield Listitem.next_page(item_id=item_id, next_url=json_parser["episodes"]["paging"]["URLPage"]) elif 'detail' in json_parser: if 'seasons' in json_parser['detail']: for seasons_datas in json_parser['detail']['seasons']: if 'seasonNumber' in seasons_datas: season_title = seasons_datas['onClick']['displayName'] + \ ' (Saison ' + str(seasons_datas["seasonNumber"]) + ')' else: season_title = seasons_datas['onClick']['displayName'] season_url = seasons_datas['onClick']['URLPage'] item = Listitem() item.label = season_title item.set_callback( list_videos, item_id=item_id, next_url=season_url) item_post_treatment(item) yield item else: # Case just one video program_title = json_parser['currentPage']['displayName'] video_datas = json_parser['detail']['informations'] if 'subtitle' in video_datas: video_title = program_title + ' - ' + video_datas['title'] + ' - ' + video_datas['subtitle'] else: video_title = program_title + ' - ' + video_datas['title'] video_image = video_datas['URLImage'] video_plot = '' if 'summary' in video_datas: video_plot = video_datas['summary'] if 'contentAvailability' in video_datas: video_url = video_datas["contentAvailability"]["availabilities"]["stream"]["URLMedias"] else: video_url = video_datas["URLMedias"] item = Listitem() item.label = video_title item.art['thumb'] = item.art['landscape'] = video_image item.info['plot'] = video_plot item.set_callback( get_video_url, item_id=item_id, next_url=video_url) item_post_treatment(item, is_playable=True, is_downloadable=True) yield item elif 'contents' in json_parser: for content_datas in json_parser['contents']: if content_datas["type"] != 'article': if 'subtitle' in content_datas: content_title = content_datas['title'] + \ ' - ' + content_datas['subtitle'] else: content_title = content_datas['title'] content_image = content_datas['URLImage'] content_url = content_datas['onClick']['URLPage'] item = Listitem() item.label = content_title item.art['thumb'] = item.art['landscape'] = content_image item.set_callback( list_programs, item_id=item_id, next_url=content_url) item_post_treatment(item) yield item
def list_videos_programs(plugin, item_id, next_url, page, **kwargs): resp = urlquick.get(next_url) program_id_values = re.compile(r'\/program\.(.*?)\/prepare').findall( resp.text) if len(program_id_values) > 0: if DESIRED_LANGUAGE == 'FR': resp2 = urlquick.get( eval('URL_ROOT_%s' % DESIRED_LANGUAGE) + '/listing/program.%s/prepare/idi-listing/10/%s' % (program_id_values[0], page)) root = resp2.parse("div", attrs={"data-role": "content"}) for video_datas in root.iterfind(".//div[@data-role='item']"): video_title = video_datas.find( ".//span[@class='st-idi-episode-card__title']").text.strip( ) video_image_datas = video_datas.find( ".//span[@class='st-idi-episode-card__image']").get( 'style') video_image = re.compile(r'url\((.*?)\)').findall( video_image_datas)[0] video_url = video_datas.find('.//a').get('href') video_plot = video_datas.find( ".//span[@class='st-idi-episode-card__summary']" ).text.strip() item = Listitem() item.label = video_title item.art['thumb'] = video_image item.info['plot'] = video_plot item.set_callback(get_video_url, item_id=item_id, video_label=LABELS[item_id] + ' - ' + item.label, video_url=video_url) item_post_treatment(item, is_playable=True, is_downloadable=True) yield item elif DESIRED_LANGUAGE == 'EN': resp2 = urlquick.get( eval('URL_ROOT_%s' % DESIRED_LANGUAGE) + '/listing/program.%s/prepare/latestepisodes/10/%s' % (program_id_values[0], page)) try: root = resp2.parse( "ul", attrs={"class": "card-rows js-listing__list"}) except Exception: root = None if root is not None: for video_datas in root.iterfind(".//li"): video_title = video_datas.find(".//img").get('alt') video_image = video_datas.find(".//img").get('data-src') video_url = eval('URL_ROOT_%s' % DESIRED_LANGUAGE ) + video_datas.find('.//a').get('href') video_plot = video_datas.find( ".//div[@class='card__summary ']").text.strip() item = Listitem() item.label = video_title item.art['thumb'] = video_image item.info['plot'] = video_plot item.set_callback(get_video_url, item_id=item_id, video_label=LABELS[item_id] + ' - ' + item.label, video_url=video_url) item_post_treatment(item, is_playable=True, is_downloadable=True) yield item yield Listitem.next_page(item_id=item_id, next_url=next_url, page=str(int(page) + 1)) else: if DESIRED_LANGUAGE == 'FR': root = resp.parse( "ul", attrs={"class": "telecast-list js-listing__list"}) for video_datas in root.iterfind(".//li"): video_title = video_datas.find('.//img').get('alt') video_image = video_datas.find('.//img').get('data-src') video_url = eval( 'URL_ROOT_%s' % DESIRED_LANGUAGE) + video_datas.find('.//a').get('href') video_plot = video_datas.find( ".//p[@class='card__summary ']").text.strip() item = Listitem() item.label = video_title item.art['thumb'] = video_image item.info['plot'] = video_plot item.set_callback(get_video_url, item_id=item_id, video_label=LABELS[item_id] + ' - ' + item.label, video_url=video_url) item_post_treatment(item, is_playable=True, is_downloadable=True) yield item elif DESIRED_LANGUAGE == 'EN': root = resp.parse("ul", attrs={"class": "card-rows js-listing__list"}) for video_datas in root.iterfind(".//li"): video_title = video_datas.find('.//img').get('alt') video_image = video_datas.find('.//img').get('data-src') video_url = eval( 'URL_ROOT_%s' % DESIRED_LANGUAGE) + video_datas.find('.//a').get('href') video_plot = video_datas.find( ".//div[@class='card__summary ']").text.strip() item = Listitem() item.label = video_title item.art['thumb'] = video_image item.info['plot'] = video_plot item.set_callback(get_video_url, item_id=item_id, video_label=LABELS[item_id] + ' - ' + item.label, video_url=video_url) item_post_treatment(item, is_playable=True, is_downloadable=True) yield item
def list_videos_bonus(plugin, item_id, category_url, page, **kwargs): resp = urlquick.get(category_url + '/page/%s' % str(page)) root = resp.parse() at_least_one_item = False video_integral = root.find(".//div[@class='col-md-6']") if video_integral is not None: at_least_one_item = True item = Listitem() item.label = video_integral.find('.//img').get('alt') video_url = URL_ROOT(video_integral.find('.//a').get('href')) item.art['thumb'] = item.art['landscape'] = video_integral.find('.//img').get('src') item.set_callback(get_video_url, item_id=item_id, video_url=video_url) item_post_treatment(item, is_playable=True, is_downloadable=True) yield item for video in root.iterfind(".//div[@class='col-md-3']"): at_least_one_item = True item = Listitem() item.label = video.find('.//img').get('alt') video_url = URL_ROOT(video.find('.//a').get('href')) item.art['thumb'] = item.art['landscape'] = video.find('.//img').get('src') item.set_callback(get_video_url, item_id=item_id, video_url=video_url) item_post_treatment(item, is_playable=True, is_downloadable=True) yield item if page is not None and at_least_one_item: # More videos... yield Listitem.next_page(item_id=item_id, category_url=category_url, page=page + 1) else: plugin.notify(plugin.localize(30718), '') yield False
def get_video_url(plugin, item_id, next_url, download_mode=False, **kwargs): if 'tokenCMS' in next_url: if get_kodi_version() < 18: xbmcgui.Dialog().ok('Info', plugin.localize(30602)) return False is_helper = inputstreamhelper.Helper('mpd', drm='widevine') if not is_helper.check_inputstream(): return False if download_mode: xbmcgui.Dialog().ok('Info', plugin.localize(30603)) return False # Get DeviceId (not a good device ID => TODO find the good one to fix to get licence key) header_device_id = { 'referer': 'https://secure-player.canal-plus.com/one/prod/v2/', } resp_device_id = urlquick.get(URL_DEVICE_ID, headers=header_device_id, max_age=-1) device_id_first = re.compile( r'deviceId\"\:\"(.*?)\"').findall(resp_device_id.text)[0] # Get Portail Id session_requests = requests.session() resp_app_config = session_requests.get(URL_REPLAY % item_id) json_app_config = re.compile('window.app_config=(.*?)};').findall( resp_app_config.text)[0] json_app_config_parser = json.loads(json_app_config + ('}')) portail_id = json_app_config_parser["api"]["pass"][ "portailIdEncrypted"] # Get PassToken payload = { 'deviceId': device_id_first, 'vect': 'INTERNET', 'media': 'PC', 'portailId': portail_id } resp_token_mycanal = session_requests.post(URL_TOKEN, data=payload) json_token_parser = json.loads(resp_token_mycanal.text) pass_token = json_token_parser["response"]["passToken"] device_id = json_token_parser["response"]["userData"]["deviceId"].split(':')[0] video_id = next_url.split('/')[-1].split('.json')[0] headers = { 'Accept': 'application/json, text/plain, */*', 'Authorization': 'PASS Token="%s"' % pass_token, 'Content-Type': 'application/json; charset=UTF-8', 'XX-DEVICE': 'pc %s' % device_id, 'XX-DOMAIN': 'cpfra', 'XX-OPERATOR': 'pc', 'XX-Profile-Id': '0', 'XX-SERVICE': 'mycanal', 'User-Agent': web_utils.get_random_ua() } value_datas_json = session_requests.get(URL_VIDEO_DATAS % video_id, headers=headers) value_datas_jsonparser = json.loads(value_datas_json.text) comMode_value = '' contentId_value = '' distMode_value = '' distTechnology_value = '' drmType_value = '' functionalType_value = '' hash_value = '' idKey_value = '' quality_value = '' if 'available' not in value_datas_jsonparser: # Some videos required an account # Get error return False is_video_drm = True for stream_datas in value_datas_jsonparser["available"]: if 'stream' in stream_datas['distTechnology']: if 'DRM' not in stream_datas['drmType']: comMode_value = stream_datas['comMode'] contentId_value = stream_datas['contentId'] distMode_value = stream_datas['distMode'] distTechnology_value = stream_datas['distTechnology'] drmType_value = stream_datas['drmType'] functionalType_value = stream_datas['functionalType'] hash_value = stream_datas['hash'] idKey_value = stream_datas['idKey'] quality_value = stream_datas['quality'] is_video_drm = False if is_video_drm: for stream_datas in value_datas_jsonparser["available"]: if 'stream' in stream_datas['distTechnology']: if 'Widevine' in stream_datas['drmType']: comMode_value = stream_datas['comMode'] contentId_value = stream_datas['contentId'] distMode_value = stream_datas['distMode'] distTechnology_value = stream_datas['distTechnology'] drmType_value = stream_datas['drmType'] functionalType_value = stream_datas['functionalType'] hash_value = stream_datas['hash'] idKey_value = stream_datas['idKey'] quality_value = stream_datas['quality'] payload = { 'comMode': comMode_value, 'contentId': contentId_value, 'distMode': distMode_value, 'distTechnology': distTechnology_value, 'drmType': drmType_value, 'functionalType': functionalType_value, 'hash': hash_value, 'idKey': idKey_value, 'quality': quality_value } payload = json.dumps(payload) headers = { 'Accept': 'application/json, text/plain, */*', 'Authorization': 'PASS Token="%s"' % pass_token, 'Content-Type': 'application/json; charset=UTF-8', 'XX-DEVICE': 'pc %s' % device_id, 'XX-DOMAIN': 'cpfra', 'XX-OPERATOR': 'pc', 'XX-Profile-Id': '0', 'XX-SERVICE': 'mycanal', 'User-Agent': web_utils.get_random_ua() } resp_stream_datas = session_requests.put( URL_STREAM_DATAS, data=payload, headers=headers) jsonparser_stream_datas = json.loads(resp_stream_datas.text) resp_real_stream_datas = session_requests.get( jsonparser_stream_datas['@medias'], headers=headers) jsonparser_real_stream_datas = json.loads( resp_real_stream_datas.text) subtitle_url = '' item = Listitem() if 'VM' in jsonparser_real_stream_datas: item.path = jsonparser_real_stream_datas["VM"][0]["media"][0]["distribURL"] + '/manifest' if plugin.setting.get_boolean('active_subtitle'): for asset in jsonparser_real_stream_datas["VM"][0]["files"]: if 'vtt' in asset["mimeType"]: subtitle_url = asset['distribURL'] else: item.path = jsonparser_real_stream_datas["VF"][0]["media"][0]["distribURL"] + '/manifest' if plugin.setting.get_boolean('active_subtitle'): for asset in jsonparser_real_stream_datas["VF"][0]["files"]: if 'vtt' in asset["mimeType"]: subtitle_url = asset['distribURL'] item.label = get_selected_item_label() item.art.update(get_selected_item_art()) item.info.update(get_selected_item_info()) item.property['inputstreamaddon'] = 'inputstream.adaptive' item.property['inputstream.adaptive.manifest_type'] = 'ism' if 'http' in subtitle_url: item.subtitles.append(subtitle_url) if 'Widevine' in drmType_value: # DRM Message (TODO to find a way to get licence key) Script.notify("INFO", plugin.localize(30702), Script.NOTIFY_INFO) return False item.property['inputstream.adaptive.license_type'] = 'com.widevine.alpha' item.property[ 'inputstream.adaptive.license_type'] = 'com.widevine.alpha' value_pass_token = 'PASS Token="%s"' % pass_token headers2 = { 'Accept': 'application/json, text/plain, */*', 'Authorization': value_pass_token, 'Content-Type': 'text/plain', 'User-Agent': web_utils.get_random_ua(), 'Origin': 'https://www.mycanal.fr', 'XX-DEVICE': 'pc %s' % device_id, 'XX-DOMAIN': 'cpfra', 'XX-OPERATOR': 'pc', 'XX-Profile-Id': '0', 'XX-SERVICE': 'mycanal', } # Return HTTP 200 but the response is not correctly interpreted by inputstream (https://github.com/peak3d/inputstream.adaptive/issues/267) item.property['inputstream.adaptive.license_key'] = jsonparser_stream_datas['@licence'] + '?drmConfig=mkpl::false' + '|%s|R{SSM}|' % urlencode(headers2) return item else: resp = urlquick.get( next_url, headers={'User-Agent': web_utils.get_random_ua()}, max_age=-1) json_parser = json.loads(resp.text) return json_parser["detail"]["informations"]["playsets"]["available"][0]["videoURL"]
def list_videos(plugin, item_id, program_id, sub_category_id, **kwargs): url = '' if sub_category_id is None: url = URL_VIDEOS2 % program_id else: url = URL_VIDEOS % (program_id, sub_category_id) resp = urlquick.get(url, headers={ 'User-Agent': web_utils.get_random_ua(), 'x-customer-name': 'rtlbe' }) json_parser = json.loads(resp.text) # TO DO Playlist More one 'clips' at_least_one_item = False for video in json_parser: video_id = str(video['id']) title = video['title'] duration = video['clips'][0]['duration'] description = '' if 'description' in video: description = video['description'] try: aired = video['clips'][0]['product']['last_diffusion'] aired = aired aired = aired[:10] # year = aired[:4] # date : string (%d.%m.%Y / 01.01.2009) # aired : string (2008-12-07) # day = aired.split('-')[2] # mounth = aired.split('-')[1] # year = aired.split('-')[0] # date = '.'.join((day, mounth, year)) except Exception: aired = '' # year = '' # date = '' img = '' program_imgs = video['clips'][0]['images'] program_img = '' for img in program_imgs: if img['role'] == 'vignette': external_key = img['external_key'] program_img = URL_IMG % (external_key) item = Listitem() at_least_one_item = True item.label = title item.info['plot'] = description item.info['duration'] = duration item.art['thumb'] = item.art['landscape'] = program_img item.art['fanart'] = program_img try: item.info.date(aired, '%Y-%m-%d') except Exception: pass is_downloadable = False if get_kodi_version() < 18: is_downloadable = True item.set_callback(get_video_url, item_id=item_id, video_id=video_id) item_post_treatment(item, is_playable=True, is_downloadable=is_downloadable) yield item if not at_least_one_item: plugin.notify(plugin.localize(30718), '') yield False
def get_live_url(plugin, item_id, video_id, **kwargs): resp = urlquick.get(URL_LIVE_JSON % item_id[:3]) json_parser = json.loads(resp.text) live_id = '' for live_datas in json_parser["teaser"]: if live_datas["channelName"] in LIVE_LIVE_CHANNEL_NAME[item_id]: live_id = live_datas["id"] if live_id is None: # Add Notification return False resp2 = urlquick.get(URL_INFO_VIDEO % (item_id[:3], live_id)) json_parser2 = json.loads(resp2.text) # build stream_url stream_url = '' is_drm = False for stream_datas in json_parser2["chapterList"]: if live_id in stream_datas["id"]: for stream_datas_url in stream_datas["resourceList"]: if 'drmList' in stream_datas_url: is_drm = True if is_drm: if get_kodi_version() < 18: xbmcgui.Dialog().ok('Info', plugin.localize(30602)) return False is_helper = inputstreamhelper.Helper('mpd', drm='widevine') if not is_helper.check_inputstream(): return False licence_drm_url = '' for stream_datas in json_parser2["chapterList"]: if live_id in stream_datas["id"]: for stream_datas_url in stream_datas["resourceList"]: stream_url = stream_datas_url["url"] for licence_drm_datas in stream_datas_url["drmList"]: if 'WIDEVINE' in licence_drm_datas["type"]: licence_drm_url = licence_drm_datas["licenseUrl"] item = Listitem() item.path = stream_url item.property['inputstreamaddon'] = 'inputstream.adaptive' item.property['inputstream.adaptive.manifest_type'] = 'mpd' item.property[ 'inputstream.adaptive.license_type'] = 'com.widevine.alpha' item.property[ 'inputstream.adaptive.license_key'] = licence_drm_url + '|Content-Type=&User-Agent=Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3041.0 Safari/537.36&Host=srg.live.ott.irdeto.com|R{SSM}|' item.label = get_selected_item_label() item.art.update(get_selected_item_art()) item.info.update(get_selected_item_info()) return item else: for stream_datas in json_parser2["chapterList"]: if live_id in stream_datas["id"]: for stream_datas_url in stream_datas["resourceList"]: if 'HD' in stream_datas_url["quality"] and \ 'mpegURL' in stream_datas_url["mimeType"]: stream_url = stream_datas_url["url"] break else: if 'mpegURL' in stream_datas_url["mimeType"]: stream_url = stream_datas_url["url"] acl_value = '/i/%s/*' % ( re.compile(r'\/i\/(.*?)\/').findall(stream_url)[0]) token_datas = urlquick.get(URL_TOKEN % acl_value, max_age=-1) token_jsonparser = json.loads(token_datas.text) token = token_jsonparser["token"]["authparams"] if '?' in stream_url: final_video_url = stream_url + '&' + token else: final_video_url = stream_url + '?' + token return final_video_url
def list_videos(plugin, item_id, program_url, **kwargs): if 'api/context' in program_url: resp = urlquick.get(program_url) json_parser = json.loads(resp.text) for video_datas in json_parser['items']: video_title = video_datas['meta']['header']['title'] video_image = video_datas['media']['image']['url'] video_plot = video_datas['meta']['description'] # TODO add duration / date video_url = URL_ROOT + video_datas['url'] item = Listitem() item.label = video_title item.art['thumb'] = video_image item.info['plot'] = video_plot item.set_callback(get_video_url, item_id=item_id, video_url=video_url) item_post_treatment(item, is_playable=True, is_downloadable=True) yield item if json_parser['loadMore'] is not None: new_program_url = URL_ROOT + json_parser['loadMore']['url'] yield Listitem.next_page(item_id=item_id, program_url=new_program_url) else: resp = urlquick.get(program_url) json_value = re.compile(r'window\.__DATA__ \= (.*?)\}\;').findall( resp.text)[0] json_parser = json.loads(json_value + '}') for main_contents_datas in json_parser['children']: if 'MainContainer' in main_contents_datas['type']: for video_child in main_contents_datas['children']: if video_child['type'] is not None: if 'LineList' in video_child['type']: video_props = video_child['props'] if 'video-guide' in video_props['type']: for video_datas in video_props['items']: video_title = video_datas['meta'][ 'header']['title'] video_image = video_datas['media'][ 'image']['url'] video_plot = video_datas['meta'][ 'description'] # TODO add duration / date video_url = URL_ROOT + video_datas['url'] item = Listitem() item.label = video_title item.art['thumb'] = video_image item.info['plot'] = video_plot item.set_callback(get_video_url, item_id=item_id, video_url=video_url) item_post_treatment(item, is_playable=True, is_downloadable=True) yield item if 'loadMore' in video_props: new_program_url = URL_ROOT + video_props[ 'loadMore']['url'] yield Listitem.next_page( item_id=item_id, program_url=new_program_url)
def get_live_url(plugin, item_id, video_id, **kwargs): if get_kodi_version() < 18: xbmcgui.Dialog().ok('Info', plugin.localize(30602)) return False resp_js_id = urlquick.get(URL_GET_JS_ID_API_KEY) js_id = re.compile(r'client\-(.*?)\.bundle\.js').findall( resp_js_id.text)[0] resp = urlquick.get(URL_API_KEY % js_id) api_key = re.compile(r'login.rtl.be\"\,key\:\"(.*?)\"').findall( resp.text)[0] if plugin.setting.get_string('rtlplaybe.login') == '' or\ plugin.setting.get_string('rtlplaybe.password') == '': xbmcgui.Dialog().ok( 'Info', plugin.localize(30604) % ('RTLPlay (BE)', 'https://www.rtlplay.be')) return False # Build PAYLOAD payload = { "loginID": plugin.setting.get_string('rtlplaybe.login'), "password": plugin.setting.get_string('rtlplaybe.password'), "apiKey": api_key, "format": "jsonp", "callback": "gigya.callback" } # LOGIN resp2 = urlquick.post(URL_COMPTE_LOGIN, data=payload, headers={ 'User-Agent': web_utils.get_random_ua(), 'referer': 'https://www.rtlplay.be/connexion' }) json_parser = json.loads( resp2.text.replace('gigya.callback(', '').replace(');', '')) if "UID" not in json_parser: plugin.notify('ERROR', 'RTLPlay (BE) : ' + plugin.localize(30711)) return False account_id = json_parser["UID"] account_timestamp = json_parser["signatureTimestamp"] account_signature = json_parser["UIDSignature"] is_helper = inputstreamhelper.Helper('mpd', drm='widevine') if not is_helper.check_inputstream(): return False # Build PAYLOAD headers payload_headers = { 'x-auth-gigya-signature': account_signature, 'x-auth-gigya-signature-timestamp': account_timestamp, 'x-auth-gigya-uid': account_id, 'User-Agent': web_utils.get_random_ua(), 'x-customer-name': 'rtlbe' } channel = 'rtlbe_' + item_id token_json = urlquick.get(URL_TOKEN_DRM % (account_id, 'dashcenc_%s' % (channel)), headers=payload_headers, max_age=-1) token_jsonparser = json.loads(token_json.text) token = token_jsonparser["token"] video_json = urlquick.get(URL_LIVE_JSON % (channel), headers={ 'User-Agent': web_utils.get_random_ua(), 'x-customer-name': 'rtlbe' }, max_age=-1) json_parser = json.loads(video_json.text) if not json_parser[channel]: plugin.notify('ERROR', plugin.localize(30712)) return False video_assets = json_parser[channel][0]['live']['assets'] if not video_assets: plugin.notify('INFO', plugin.localize(30716)) return False subtitle_url = '' if plugin.setting.get_boolean('active_subtitle'): for asset in video_assets: if 'subtitle_vtt' in asset["type"]: subtitle_url = asset['full_physical_path'] for asset in video_assets: if 'delta_dashcenc_h264' in asset["type"]: item = Listitem() item.path = asset['full_physical_path'] if 'http' in subtitle_url: item.subtitles.append(subtitle_url) item.property['inputstreamaddon'] = 'inputstream.adaptive' item.property['inputstream.adaptive.manifest_type'] = 'mpd' item.property[ 'inputstream.adaptive.license_type'] = 'com.widevine.alpha' item.property[ 'inputstream.adaptive.license_key'] = URL_LICENCE_KEY % token item.label = get_selected_item_label() item.art.update(get_selected_item_art()) item.info.update(get_selected_item_info()) return item return False
def get_live_url(plugin, item_id, video_id, item_dict, **kwargs): if item_id == 'fun_radio' or \ item_id == 'rtl2' or \ item_id == 'mb': if item_id == 'mb': video_json = urlquick.get( URL_LIVE_JSON % (item_id.upper()), headers={'User-Agent': web_utils.get_random_ua()}, max_age=-1) json_parser = json.loads(video_json.text) video_assets = json_parser[item_id.upper()][0]['live']['assets'] else: video_json = urlquick.get( URL_LIVE_JSON % (item_id), headers={'User-Agent': web_utils.get_random_ua()}, max_age=-1) json_parser = json.loads(video_json.text) video_assets = json_parser[item_id][0]['live']['assets'] if not video_assets: plugin.notify('INFO', plugin.localize(30716)) return False subtitle_url = '' if plugin.setting.get_boolean('active_subtitle'): for asset in video_assets: if 'subtitle_vtt' in asset["type"]: subtitle_url = asset['full_physical_path'] for asset in video_assets: if 'delta_hls_h264' in asset["type"]: item = Listitem() item.path = asset['full_physical_path'] if 'http' in subtitle_url: item.subtitles.append(subtitle_url) if 'label' in item_dict: item.label = item_dict['label'] if 'info' in item_dict: item.info.update(item_dict['info']) if 'art' in item_dict: item.art.update(item_dict['art']) return item return False else: if cqu.get_kodi_version() < 18: xbmcgui.Dialog().ok('Info', plugin.localize(30602)) return False resp_js_id = urlquick.get(URL_GET_JS_ID_API_KEY) js_id = re.compile(r'client\-(.*?)\.bundle\.js').findall( resp_js_id.text)[0] resp = urlquick.get(URL_API_KEY % js_id) api_key = re.compile(r'\"eu1.gigya.com\"\,key\:\"(.*?)\"').findall( resp.text)[0] if plugin.setting.get_string('6play.login') == '' or\ plugin.setting.get_string('6play.password') == '': xbmcgui.Dialog().ok( 'Info', plugin.localize(30604) % ('6play', 'https://www.6play.fr')) return False # Build PAYLOAD payload = { "loginID": plugin.setting.get_string('6play.login'), "password": plugin.setting.get_string('6play.password'), "apiKey": api_key, "format": "jsonp", "callback": "jsonp_3bbusffr388pem4" } # LOGIN resp2 = urlquick.post(URL_COMPTE_LOGIN, data=payload, headers={ 'User-Agent': web_utils.get_random_ua(), 'referer': 'https://www.6play.fr/connexion' }) json_parser = json.loads( resp2.text.replace('jsonp_3bbusffr388pem4(', '').replace(');', '')) if "UID" not in json_parser: plugin.notify('ERROR', '6play : ' + plugin.localize(30711)) return False account_id = json_parser["UID"] account_timestamp = json_parser["signatureTimestamp"] account_signature = json_parser["UIDSignature"] is_helper = inputstreamhelper.Helper('mpd', drm='widevine') if not is_helper.check_inputstream(): return False # Build PAYLOAD headers payload_headers = { 'x-auth-gigya-signature': account_signature, 'x-auth-gigya-signature-timestamp': account_timestamp, 'x-auth-gigya-uid': account_id, 'x-customer-name': 'm6web' } if item_id == '6ter': token_json = urlquick.get(URL_TOKEN_DRM % (account_id, 'dashcenc_%s' % '6T'), headers=payload_headers, max_age=-1) else: token_json = urlquick.get( URL_TOKEN_DRM % (account_id, 'dashcenc_%s' % item_id.upper()), headers=payload_headers, max_age=-1) token_jsonparser = json.loads(token_json.text) token = token_jsonparser["token"] if item_id == '6ter': video_json = urlquick.get( URL_LIVE_JSON % '6T', headers={'User-Agent': web_utils.get_random_ua()}, max_age=-1) json_parser = json.loads(video_json.text) video_assets = json_parser['6T'][0]['live']['assets'] else: video_json = urlquick.get( URL_LIVE_JSON % (item_id.upper()), headers={'User-Agent': web_utils.get_random_ua()}, max_age=-1) json_parser = json.loads(video_json.text) video_assets = json_parser[item_id.upper()][0]['live']['assets'] if not video_assets: plugin.notify('INFO', plugin.localize(30716)) return False subtitle_url = '' if plugin.setting.get_boolean('active_subtitle'): for asset in video_assets: if 'subtitle_vtt' in asset["type"]: subtitle_url = asset['full_physical_path'] for asset in video_assets: if 'delta_dashcenc_h264' in asset["type"]: item = Listitem() item.path = asset['full_physical_path'] if 'http' in subtitle_url: item.subtitles.append(subtitle_url) item.property['inputstreamaddon'] = 'inputstream.adaptive' item.property['inputstream.adaptive.manifest_type'] = 'mpd' item.property[ 'inputstream.adaptive.license_type'] = 'com.widevine.alpha' item.property[ 'inputstream.adaptive.license_key'] = URL_LICENCE_KEY % token if item_dict: if 'label' in item_dict: item.label = item_dict['label'] if 'info' in item_dict: item.info.update(item_dict['info']) if 'art' in item_dict: item.art.update(item_dict['art']) else: item.label = LABELS[item_id] item.art["thumb"] = "" item.art["icon"] = "" item.art["fanart"] = "" item.info["plot"] = LABELS[item_id] return item return False
def get_video_url(plugin, item_id, video_id, item_dict=None, download_mode=False, video_label=None, **kwargs): if cqu.get_kodi_version() < 18: video_json = urlquick.get(URL_JSON_VIDEO % video_id, headers={ 'User-Agent': web_utils.get_random_ua(), 'x-customer-name': 'm6web' }, max_age=-1) json_parser = json.loads(video_json.text) video_assets = json_parser['clips'][0]['assets'] if video_assets is None: plugin.notify('ERROR', plugin.localize(30721)) return False final_video_url = '' all_datas_videos_quality = [] all_datas_videos_path = [] for asset in video_assets: if 'http_h264' in asset["type"]: all_datas_videos_quality.append(asset["video_quality"]) all_datas_videos_path.append(asset['full_physical_path']) elif 'h264' in asset["type"]: manifest = urlquick.get( asset['full_physical_path'], headers={'User-Agent': web_utils.get_random_ua()}, max_age=-1) if 'drm' not in manifest.text: all_datas_videos_quality.append(asset["video_quality"]) all_datas_videos_path.append(asset['full_physical_path']) if len(all_datas_videos_quality) == 0: xbmcgui.Dialog().ok('Info', plugin.localize(30602)) return False elif len(all_datas_videos_quality) == 1: final_video_url = all_datas_videos_path[0] else: if DESIRED_QUALITY == "DIALOG": seleted_item = xbmcgui.Dialog().select( plugin.localize(LABELS['choose_video_quality']), all_datas_videos_quality) if seleted_item == -1: return False return all_datas_videos_path[seleted_item] elif DESIRED_QUALITY == "BEST": url_best = '' i = 0 for data_video in all_datas_videos_quality: if 'lq' not in data_video: url_best = all_datas_videos_path[i] i = i + 1 final_video_url = url_best else: final_video_url = all_datas_videos_path[0] if download_mode: return download.download_video(final_video_url, video_label) return final_video_url else: resp_js_id = urlquick.get(URL_GET_JS_ID_API_KEY) js_id = re.compile(r'client\-(.*?)\.bundle\.js').findall( resp_js_id.text)[0] resp = urlquick.get(URL_API_KEY % js_id) api_key = re.compile(r'\"eu1.gigya.com\"\,key\:\"(.*?)\"').findall( resp.text)[0] if plugin.setting.get_string('6play.login') == '' or\ plugin.setting.get_string('6play.password') == '': xbmcgui.Dialog().ok( 'Info', plugin.localize(30604) % ('6play', 'https://www.6play.fr')) return False # Build PAYLOAD payload = { "loginID": plugin.setting.get_string('6play.login'), "password": plugin.setting.get_string('6play.password'), "apiKey": api_key, "format": "jsonp", "callback": "jsonp_3bbusffr388pem4" } # LOGIN resp2 = urlquick.post(URL_COMPTE_LOGIN, data=payload, headers={ 'User-Agent': web_utils.get_random_ua(), 'referer': 'https://www.6play.fr/connexion' }) json_parser = json.loads( resp2.text.replace('jsonp_3bbusffr388pem4(', '').replace(');', '')) if "UID" not in json_parser: plugin.notify('ERROR', '6play : ' + plugin.localize(30711)) return False account_id = json_parser["UID"] account_timestamp = json_parser["signatureTimestamp"] account_signature = json_parser["UIDSignature"] is_helper = inputstreamhelper.Helper('mpd', drm='widevine') if not is_helper.check_inputstream(): return False # Build PAYLOAD headers payload_headers = { 'x-auth-gigya-signature': account_signature, 'x-auth-gigya-signature-timestamp': account_timestamp, 'x-auth-gigya-uid': account_id, 'x-customer-name': 'm6web' } token_json = urlquick.get(URL_TOKEN_DRM % (account_id, video_id), headers=payload_headers, max_age=-1) token_jsonparser = json.loads(token_json.text) token = token_jsonparser["token"] video_json = urlquick.get(URL_JSON_VIDEO % video_id, headers={ 'User-Agent': web_utils.get_random_ua(), 'x-customer-name': 'm6web' }, max_age=-1) json_parser = json.loads(video_json.text) video_assets = json_parser['clips'][0]['assets'] if video_assets is None: plugin.notify('ERROR', plugin.localize(30721)) return False subtitle_url = '' if plugin.setting.get_boolean('active_subtitle'): for asset in video_assets: if 'subtitle_vtt' in asset["type"]: subtitle_url = asset['full_physical_path'] for asset in video_assets: if 'usp_dashcenc_h264' in asset["type"]: item = Listitem() item.path = asset['full_physical_path'] if 'http' in subtitle_url: item.subtitles.append(subtitle_url) item.label = item_dict['label'] item.info.update(item_dict['info']) item.art.update(item_dict['art']) item.property['inputstreamaddon'] = 'inputstream.adaptive' item.property['inputstream.adaptive.manifest_type'] = 'mpd' item.property[ 'inputstream.adaptive.license_type'] = 'com.widevine.alpha' item.property[ 'inputstream.adaptive.license_key'] = URL_LICENCE_KEY % token return item for asset in video_assets: if 'http_h264' in asset["type"]: if "hd" in asset["video_quality"]: item = Listitem() item.path = asset['full_physical_path'] if 'http' in subtitle_url: item.subtitles.append(subtitle_url) item.label = item_dict['label'] item.info.update(item_dict['info']) item.art.update(item_dict['art']) return item return False
def list_categories(plugin, item_id, **kwargs): """ Build categories listing - Tous les programmes - Séries - Informations - ... """ CATEGORIES_VIDEOS = eval('CATEGORIES_VIDEOS_%s' % DESIRED_LANGUAGE) for category_url, category_title in CATEGORIES_VIDEOS.items(): if 'magazines' in category_url or 'shows' in category_url: item = Listitem() item.label = category_title item.set_callback(list_programs, item_id=item_id, next_url=category_url) item_post_treatment(item) yield item elif 'documentaires' in category_url: item = Listitem() item.label = category_title item.set_callback(list_videos_documentaries, item_id=item_id, next_url=category_url, page='0') item_post_treatment(item) yield item elif 'videos' in category_url: item = Listitem() item.label = category_title item.set_callback(list_videos, item_id=item_id, page='0') item_post_treatment(item) yield item
def root(plugin, content_type="video"): item = Listitem() item.label = "nserv.host [supported]" item.set_callback(open_page, url="/", base_url="http://nserv.host:5300") yield item item = Listitem() item.label = "filmix.red [partically supported]" item.set_callback(open_page, url="/", base_url="http://filmix.red") yield item item = Listitem() item.label = "spiderxml search [partically supported][untested]" item.set_callback(do_input_page, url="/search", base_url="http://spiderxml.com") yield item item = Listitem() item.label = "cooltv.info [supported][untested]" item.set_callback(open_page, url="/start", base_url="http://cltv.club") yield item
def get_live_url(plugin, item_id, **kwargs): if get_kodi_version() < 18: xbmcgui.Dialog().ok('Info', plugin.localize(30602)) return False is_helper = inputstreamhelper.Helper('mpd', drm='widevine') if not is_helper.check_inputstream(): return False headers = {'X-Requested-With': 'XMLHttpRequest'} resp_token = urlquick.get(URL_TOKEN_API, headers=headers, max_age=-1) session_token = resp_token.cookies['npo_session'] json_parser_token = json.loads(resp_token.text) api_token = json_parser_token['token'] resp = urlquick.get(URL_LIVE_ID % item_id, max_age=-1) video_id = '' list_media_id = re.compile(r'media-id\=\"(.*?)\"').findall(resp.text) for media_id in list_media_id: if 'LI_' in media_id: video_id = media_id # Build PAYLOAD payload = {"_token": api_token} cookies = {"npo_session": session_token} resp2 = urlquick.post(URL_TOKEN_ID % video_id, cookies=cookies, data=payload, max_age=-1) json_parser = json.loads(resp2.text) token_id = json_parser['token'] resp3 = urlquick.get(URL_STREAM % (video_id, token_id), max_age=-1) json_parser2 = json.loads(resp3.text) if "html" in json_parser2 and "Vanwege uitzendrechten is het niet mogelijk om deze uitzending buiten Nederland te bekijken." in json_parser2[ "html"]: plugin.notify('ERROR', plugin.localize(30713)) return False licence_url = json_parser2["stream"]["keySystemOptions"][0]["options"][ "licenseUrl"] licence_url_header = json_parser2["stream"]["keySystemOptions"][0][ "options"]["httpRequestHeaders"] xcdata_value = licence_url_header["x-custom-data"] item = Listitem() item.path = json_parser2["stream"]["src"] item.label = get_selected_item_label() item.art.update(get_selected_item_art()) item.info.update(get_selected_item_info()) if plugin.setting.get_boolean('active_subtitle'): item.subtitles.append(URL_SUBTITLE % video_id) item.property[INPUTSTREAM_PROP] = 'inputstream.adaptive' item.property['inputstream.adaptive.manifest_type'] = 'mpd' item.property['inputstream.adaptive.license_type'] = 'com.widevine.alpha' item.property['inputstream.adaptive.manifest_update_parameter'] = 'full' item.property[ 'inputstream.adaptive.license_key'] = licence_url + '|Content-Type=&User-Agent=Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3041.0 Safari/537.36&x-custom-data=%s|R{SSM}|' % xcdata_value return item
def open_xml_page(page, base_url): items = dict({'channels': []}) items_et = fromstring(page.encode("utf-8")) for item in list(items_et.iterfind("channel")): i = Listitem() if item.find('title') is not None: i.label = item.find('title').text if item.find('description') is not None: i.info.plot = remove_html_tags(item.find('description').text) if item.find('logo_30x30') is not None: i.art.thumb = remove_html_tags(item.find('logo_30x30').text) if item.find('search_on') is not None: i.set_callback(do_input_page, url=item.find('playlist_url').text, base_url=base_url) elif item.find('playlist_url') is not None: i.set_callback(open_page, url=item.find('playlist_url').text, base_url=base_url) elif item.find('stream_url') is not None: if 'youtube.com' or 'youtu.be' in item.find('stream_url').text: i.set_callback(play_youtubedl_url, url=item.find('stream_url').text) else: i.set_path(item.find('stream_url').text, is_folder=False, is_playable=True) yield i
def list_videos_cat(plugin, item_id, program_part_url, **kwargs): item = Listitem() item.label = "Replay" item.set_callback(list_videos, item_id=item_id, program_part_url=program_part_url, filter_value='only-replay') item_post_treatment(item) yield item item = Listitem() item.label = "Extrait" item.set_callback(list_videos, item_id=item_id, program_part_url=program_part_url, filter_value='only-extract') item_post_treatment(item) yield item item = Listitem() item.label = "Autres Videos" item.set_callback(list_videos_other, item_id=item_id, program_part_url=program_part_url) item_post_treatment(item) yield item
def list_videos(plugin, item_id, next_url): resp = urlquick.get(next_url) root = resp.parse() if root.find(".//ul[@class='vrtnu-list']") is not None: list_videos_datas = root.find(".//ul[@class='vrtnu-list']").findall( './/li') for video_datas in list_videos_datas: video_title = video_datas.find('.//h3').text.strip() video_image = 'https:' + video_datas.find('.//img').get( 'srcset').split('1x')[0].strip() video_plot = '' if video_datas.find('.//p').text is not None: video_plot = video_datas.find('.//p').text.strip() video_url = URL_ROOT + video_datas.find('.//a').get('href') item = Listitem() item.label = video_title item.art['thumb'] = video_image item.info['plot'] = video_plot item.context.script(get_video_url, plugin.localize(LABELS['Download']), item_id=item_id, video_url=video_url, video_label=LABELS[item_id] + ' - ' + item.label, download_mode=True) item.set_callback(get_video_url, item_id=item_id, video_url=video_url) yield item else: if root.find(".//div[@class='nui-content-area']") is not None: video_datas = root.find(".//div[@class='nui-content-area']") video_title = video_datas.find('.//h1').text.strip() video_image = 'https:' + video_datas.find('.//img').get( 'srcset').strip() video_plot = video_datas.find( ".//div[@class='content__shortdescription']").text.strip() video_url = re.compile(r'page_url":"(.*?)"').findall(resp.text)[0] item = Listitem() item.label = video_title item.art['thumb'] = video_image item.info['plot'] = video_plot item.context.script(get_video_url, plugin.localize(LABELS['Download']), item_id=item_id, video_url=video_url, video_label=LABELS[item_id] + ' - ' + item.label, download_mode=True) item.set_callback(get_video_url, item_id=item_id, video_url=video_url) yield item
def list_videos_search(plugin, item_id, search_query, page=0, **kwargs): has_item = False while not has_item: url_search = "https://vwdlashufe-dsn.algolia.net/1/indexes/yatta_prod_contents/" resp = urlquick.get(url_search, params={ 'page': page, 'filters': "class:video", 'query': search_query }, headers=HEADERS_YATTA) json_parser = json.loads(resp.text) nb_pages = json_parser['nbPages'] for show in json_parser['hits']: item_id_found = False for channel in show['channels']: if channel['url'] == item_id: item_id_found = True break if not item_id_found: continue has_item = True title = show['title'] label = "" program_name = None if "program" in show: program_name = show['program']['label'] label += program_name + " - " # What about "teaser" and "resume"? # E.g. http://api-front.yatta.francetv.fr/standard/publish/taxonomies/france-3_plus-belle-la-vie/contents/?size=20&page=0&sort=begin_date:desc&filter=with-no-vod,only-visible if show['type'] == "extrait": label += "[extrait] " label += title headline = show['headline_title'] plot = "" if headline: plot += headline + "\n" plot += show['text'] last_publication_date = show['dates']['last_publication_date'] publication_date = time.strftime( "%Y-%m-%d", time.localtime(last_publication_date)) image_400 = "" image_1024 = "" if "image" in show: image_400 = show['image']['formats']['vignette_16x9']['urls'][ 'w:400'] image_1024 = show['image']['formats']['vignette_16x9']['urls'][ 'w:1024'] rating = None if 'rating_csa_code' in show and show['rating_csa_code']: rating = show['rating_csa_code'] # Add a dash before the numbers, instead of e.g. "TP", # to simulate the CSA logo instead of having the long description if rating.isdigit(): rating = "-" + rating item = Listitem() item.label = label item.info['title'] = label item.info['tvshowtitle'] = program_name item.art['fanart'] = URL_API(image_1024) item.art['thumb'] = URL_API(image_400) item.info.date(publication_date, "%Y-%m-%d") item.info['plot'] = plot item.info['duration'] = show['duration'] item.info['director'] = show['director'] item.info['season'] = show['season_number'] item.info['mpaa'] = rating if "episode_number" in show and show['episode_number']: item.info['mediatype'] = "episode" item.info['episode'] = show['episode_number'] actors = [] if "casting" in show and show['casting']: actors = [ actor.strip() for actor in show['casting'].split(",") ] elif "presenter" in show and show['presenter']: actors.append(show['presenter']) item.info['cast'] = actors if "characters" in show and show['characters']: characters = [ role.strip() for role in show['characters'].split(",") ] if len(actors) > 0 and len(characters) > 0: item.info['castandrole'] = list( zip_longest(actors, characters)) item.set_callback(get_video_url, item_id=item_id, id_yatta=show['id']) item_post_treatment(item, is_playable=True, is_downloadable=True) yield item page = page + 1 # More videos... if page != nb_pages - 1: yield Listitem.next_page(search_query=search_query, item_id=item_id, page=page + 1)
def list_videos(plugin, item_id, program_id): resp = urlquick.get(URL_LIST_SHOW % (get_api_key(), program_id), headers={'User-Agent': web_utils.get_random_ua}) json_parser = json.loads(resp.text) for show in json_parser['res']: # media_id = show['media_id'] # program_title = show['program_title'] # cat_id = show['cat_id'] # program_id = show['program_id'] fanart = show['program_image'] thumb = show['episode_image'] episode_title = show['episode_title'] episode_number = show['episode_number'] season_number = show['season_number'] # total_episodes_in_season = show['total_episodes_in_season'] video_url = show['url_streaming'] # url_streaming = show['url_streaming'] short_desc = show['short_desc'] note = float(show['note']) * 2 date_debut = show['date_debut'] # "2017-02-03 00:00:00" year = int(date_debut[:4]) day = date_debut[8:10] month = date_debut[5:7] date = '.'.join((day, month, str(year))) aired = '-'.join((str(year), month, day)) item = Listitem() item.label = episode_title item.info['episode'] = episode_number item.info['season'] = season_number item.info['plot'] = short_desc item.info['rating'] = note item.info['date'] = date item.info['aired'] = aired item.info['year'] = year item.art["thumb"] = thumb item.art["fanart"] = fanart item.context.script(get_video_url, plugin.localize(LABELS['Download']), item_id=item_id, video_url=video_url, video_label=LABELS[item_id] + ' - ' + item.label, download_mode=True) item.set_callback(get_video_url, item_id=item_id, video_url=video_url) yield item
def content_lister(plugin, sfid, ctype, topic=None, page_count=1): """ :type plugin: Route :type sfid: unicode :type ctype: unicode :type topic: unicode :type page_count: int """ # Add link to Alternitve Listing if page_count == 1 and topic: params = {"_updatelisting_": True, "sfid": sfid, "topic": topic, "ctype": u"segment" if ctype == u"video" else u"video"} label = plugin.localize(LIST_AUDIO) if ctype == u"video" else plugin.localize(LIST_VIDEO) item_dict = {"label": label, "callback": content_lister, "params": params} yield Listitem.from_dict(**item_dict) # Create content url if topic: url = "https://www.sciencefriday.com/wp-admin/admin-ajax.php?action=get_results&paged=%(next)s&" \ "sfid=%(sfid)s&post_types=%(ctype)s&_sft_topic=%(topic)s" % \ {"sfid": sfid, "ctype": ctype, "topic": topic, "next": page_count} else: url = "https://www.sciencefriday.com/wp-admin/admin-ajax.php?action=get_results&paged=%(next)s&" \ "sfid=%(sfid)s&post_types=%(ctype)s" % \ {"sfid": sfid, "ctype": ctype, "next": page_count} # Fetch & parse HTML Source ishd = bool(plugin.setting.get_int("video_quality", addon_id="script.module.youtube.dl")) root_elem = urlquick.get(url).parse() # Fetch next page next_url = root_elem.find(".//a[@rel='next']") if next_url is not None: # pragma: no branch yield Listitem.next_page(sfid=sfid, ctype=ctype, page_count=page_count+1) # Parse the elements for element in root_elem.iterfind(".//article"): tag_a = element.find(".//a[@rel='bookmark']") item = Listitem() item.label = tag_a.text item.stream.hd(ishd) # Fetch plot & duration tag_p = element.findall(".//p") if tag_p and tag_p[0].get("class") == "run-time": item.info["duration"] = tag_p[0].text item.info["plot"] = tag_p[1].text elif tag_p: # pragma: no branch item.info["plot"] = tag_p[0].text # Fetch image if exists img = element.find(".//img[@data-src]") if img is not None: item.art["thumb"] = img.get("data-src") # Fetch audio/video url tag_audio = element.find(".//a[@data-audio]") if tag_audio is not None: audio_url = tag_audio.get("data-audio") item.set_callback(audio_url) else: item.set_callback(play_video, url=tag_a.get("href")) yield item
def root(plugin, content_type="video"): """ :param Route plugin: The plugin parent object. :param str content_type: The type of content been listed e.g. video, music. This is passed in from kodi and we have no use for it as of yet. """ yield Listitem.recent(video_list, url="newvideos.html") yield Listitem.from_dict(top_videos, bold(plugin.localize(TOP_VIDEOS))) yield Listitem.from_dict(watching_now, bold(plugin.localize(WATCHING_NOW))) yield Listitem.search(search_videos) # Fetch HTML Source url = url_constructor("/browse.html") resp = urlquick.get(url) root_elem = resp.parse("div", attrs={"id": "primary"}) for elem in root_elem.iterfind("ul/li"): img = elem.find(".//img") item = Listitem() # The image tag contains both the image url and title item.label = img.get("alt") item.art["thumb"] = img.get("src") url = elem.find("div/a").get("href") item.set_callback(video_list, url=url) yield item # Add the video items here so that show at the end of the listing bold_text = bold(plugin.localize(VIDEO_OF_THE_DAY)) yield Listitem.from_dict(play_video, bold_text, params={"url": "/index.html"}) yield Listitem.from_dict(party_play, plugin.localize(PARTY_MODE), params={"url": "/randomizer.php"})
def list_videos(plugin, item_id, program_url): resp = urlquick.get(program_url) root = resp.parse() if root.find(".//div[@class='tv5-pagerTop tv5-pagerTop--green']") is None: video_datas = root.find(".//div[@class='tv5-player']") video_title = video_datas.find('.//h1').text.strip() video_image = re.compile(r'image\" content=\"(.*?)\"').findall( resp.text)[0] video_plot = video_datas.find( ".//div[@class='tv5-desc to-expand u-mg-t--m u-mg-b--s']").get( 'data-originaltext') item = Listitem() item.label = video_title item.art['thumb'] = video_image item.info['plot'] = video_plot item.context.script(get_video_url, plugin.localize(LABELS['Download']), item_id=item_id, video_url=program_url, video_label=LABELS[item_id] + ' - ' + item.label, download_mode=True) item.set_callback(get_video_url, item_id=item_id, video_url=program_url) yield item else: list_seasons = root.find( ".//div[@class='tv5-pagerTop tv5-pagerTop--green']").findall( './/a') if len(list_seasons) > 1: for season in list_seasons: season_title = 'Saison ' + season.text season_url = URL_TV5MAF_ROOT + season.get('href') item = Listitem() item.label = season_title item.set_callback(list_videos_season, item_id=item_id, season_url=season_url) yield item else: list_videos_datas = root.findall( ".//div[@class='grid-col-12 grid-col-m-4']") for video_datas in list_videos_datas: video_title = video_datas.find('.//h2/span').text.strip() video_image = video_datas.find('.//img').get('src') video_url = URL_TV5MAF_ROOT + video_datas.find('.//a').get( 'href') item = Listitem() item.label = video_title item.art['thumb'] = video_image item.context.script(get_video_url, plugin.localize(LABELS['Download']), item_id=item_id, video_url=video_url, video_label=LABELS[item_id] + ' - ' + item.label, download_mode=True) item.set_callback(get_video_url, item_id=item_id, video_url=video_url) yield item
def buildTray(self, items, nextPageUrl=None): for eachItem in items: yield Listitem().from_dict(**self._buildItem(eachItem)) if nextPageUrl: yield Listitem().next_page(url=nextPageUrl)
def list_programs(plugin, item_id, next_url, **kwargs): """ Build programs listing - Les feux de l'amour - ... """ resp = urlquick.get(next_url) if DESIRED_LANGUAGE == 'FR': root = resp.parse("ul", attrs={"class": "media-rows"}) for program_datas in root.iterfind("li"): program_title = program_datas.find('.//img').get('alt') program_url = program_datas.find('.//a').get('href') program_image = program_datas.find('.//img').get('data-src') program_plot = program_datas.find('.//p').text item = Listitem() item.label = program_title item.art['thumb'] = program_image item.info['plot'] = program_plot item.set_callback(list_videos_programs, item_id=item_id, next_url=program_url, page='0') item_post_treatment(item) yield item elif DESIRED_LANGUAGE == 'EN': root = resp.parse("ul", attrs={"class": "card-rows"}) for program_datas in root.iterfind("li"): program_title = program_datas.find('.//img').get('alt') program_url = eval( 'URL_ROOT_%s' % DESIRED_LANGUAGE) + program_datas.find('.//a').get('href') program_image = program_datas.find('.//img').get('data-src') item = Listitem() item.label = program_title item.art['thumb'] = program_image item.set_callback(list_videos_programs, item_id=item_id, next_url=program_url, page='0') item_post_treatment(item) yield item
def list_categories(plugin, item_id, **kwargs): """ Build categories listing - actualités & société - vie quotidienne - jeux & divertissement - ... """ # URL example: http://api-front.yatta.francetv.fr/standard/publish/channels/france-2/categories/ # category_part_url example: actualites-et-societe url_categories = "standard/publish/channels/%s/categories/" % item_id resp = urlquick.get(URL_API(url_categories)) json_parser = json.loads(resp.text) for category in json_parser['result']: item = Listitem() item.label = category['label'] category_part_url = category['url'] item.set_callback(list_programs, item_id=item_id, category_part_url=category_part_url) item_post_treatment(item) yield item """ Seems to be broken in current CodeQuick version yield Listitem.recent( list_videos_last, item_id = item_id) """ item = Listitem() item.label = "Recent" item.set_callback(list_videos_last, item_id=item_id) item_post_treatment(item) yield item item = Listitem.search(list_videos_search, item_id=item_id) item_post_treatment(item) yield item
def buildPlay(self, data, label=""): if data.get("vendor") == "hotstar": return Listitem().from_dict(**{ "label": label, "callback": data.get("playbackUrl"), "properties": { "IsPlayable": True, "inputstreamaddon": "inputstream.adaptive", "inputstream.adaptive.stream_headers": urlencode(data.get("headers", {})), "inputstream.adaptive.manifest_type": data.get("playbackProto"), } }) elif data.get("vendor") == "Sony Pictures": if data.get("licenceUrl"): is_helper = inputstreamhelper.Helper( "mpd", drm="com.widevine.alpha") if is_helper.check_inputstream(): Script.log("licenceUrl %s" % data.get("licenceUrl"), lvl=Script.INFO) return Listitem().from_dict(**{ "label": label, "callback": data.get("playbackUrl"), "properties": { "IsPlayable": True, "inputstreamaddon": is_helper.inputstream_addon, "inputstream.adaptive.manifest_type": data.get("playbackProto"), "inputstream.adaptive.license_type": "com.widevine.alpha", "inputstream.adaptive.license_key": data.get("licenceUrl") + "||R{SSM}|", } }) return Listitem().from_dict(**{ "label": label, "callback": data.get("playbackUrl"), "properties": { "IsPlayable": True, "inputstreamaddon": "inputstream.adaptive", "inputstream.adaptive.manifest_type": data.get("playbackProto"), } }) elif data.get("ext"): return Listitem().from_dict(**{ "label": label, "callback": data.get("ext") + hexlify(dumps({"contentId": data.get("contentId")})), }) else: Script.log("licenceUrl %s" % data.get("licenceUrl"), lvl=Script.INFO) is_helper = inputstreamhelper.Helper( "mpd", drm="com.widevine.alpha") if is_helper.check_inputstream(): return Listitem().from_dict(**{ "label": label, "callback": data.get("playbackUrl"), "subtitles": data.get("subtitles"), "properties": { "IsPlayable": True, "inputstreamaddon": is_helper.inputstream_addon, "inputstream.adaptive.stream_headers": urlencode(data.get("headers", {})), "inputstream.adaptive.manifest_type": data.get("playbackProto"), "inputstream.adaptive.license_type": "com.widevine.alpha", "inputstream.adaptive.license_key": data.get("licenseUrl"), } }) return False
def list_videos_replays(plugin, item_id, program_url, page, **kwargs): resp = urlquick.get(program_url + '?page=%s' % (page)) root = resp.parse() if root.find(".//div[@class='row replaynessma-cats row-eq-height ']" ) is not None: root2 = resp.parse( "div", attrs={"class": "row replaynessma-cats row-eq-height "}) for video_datas in root2.iterfind(".//article"): video_title = video_datas.find('.//h3/a').text video_image = video_datas.find('.//img').get('src') video_url = video_datas.find('.//a').get('href') item = Listitem() item.label = video_title item.art['thumb'] = item.art['landscape'] = video_image item.set_callback(get_video_url, item_id=item_id, video_url=video_url) item_post_treatment(item, is_playable=True, is_downloadable=True) yield item else: for video_datas in root.iterfind(".//div[@class='col-sm-3']"): video_title = video_datas.find('.//img').get('alt') video_image = video_datas.find('.//img').get('src') video_url = video_datas.find('.//a').get('href') item = Listitem() item.label = video_title item.art['thumb'] = item.art['landscape'] = video_image item.set_callback(get_video_url, item_id=item_id, video_url=video_url) item_post_treatment(item, is_playable=True, is_downloadable=True) yield item yield Listitem.next_page(item_id=item_id, program_url=program_url, page=str(int(page) + 1))
def list_videos(plugin, item_id, program_title, program_url, **kwargs): resp = urlquick.get(program_url) root = resp.parse() if len(root.findall(".//figure[@class='thumbnailReplay-visual']")) > 0: for video_datas in root.findall( ".//figure[@class='thumbnailReplay-visual']"): video_title = program_title + ' - ' + video_datas.find( './/img').get('alt') video_url = URL_ROOT + video_datas.find('.//a').get('href') video_image = '' if video_datas.find('.//source').get('data-srcset') is not None: video_image = video_datas.find('.//source').get('data-srcset') else: video_image = video_datas.find('.//source').get('srcset') item = Listitem() item.label = video_title item.art['thumb'] = video_image item.set_callback(get_video_url, item_id=item_id, video_url=video_url) yield item else: video_title = root.find(".//div[@class='nrjVideo-player']").find( './/meta').get('alt') video_url = program_url video_image = root.find(".//div[@class='nrjVideo-player']").find( './/meta').get('content') item = Listitem() item.label = video_title item.art['thumb'] = video_image item.set_callback(get_video_url, item_id=item_id, video_url=video_url) item_post_treatment(item, is_playable=True, is_downloadable=True) yield item
def list_videos_franchise(plugin, item_id, program_url, **kwargs): if 'page=' in program_url: resp = urlquick.get(program_url + '&ApiKey=%s' % (API_KEY)) json_parser = json.loads(resp.text) for video_datas in json_parser["items"]: if 'title' not in video_datas: continue if not video_datas['title']: continue subtitle = '' if 'seasonNumber' in video_datas and 'episodeNumber' in video_datas: if video_datas['seasonNumber'] is not None and video_datas[ 'episodeNumber'] is not None: subtitle = " - S%sE%s" % ( str(video_datas['seasonNumber']), str(video_datas['episodeNumber'])) video_title = video_datas["title"] + subtitle if 'header' in video_datas["images"]: video_image = URL_IMAGE % video_datas["images"]["header"]["id"] else: video_image = '' video_plot = video_datas["description"] video_id = video_datas["id"] video_duration = video_datas["duration"] date_value = video_datas['broadcastDate'].split('T')[0] item = Listitem() item.label = video_title item.art['thumb'] = item.art['landscape'] = video_image item.info['plot'] = video_plot item.info['duration'] = video_duration item.info.date(date_value, "%Y-%m-%d") item.set_callback(get_video_url, item_id=item_id, video_id=video_id) item_post_treatment(item, is_playable=True, is_downloadable=False) yield item if 'next' in json_parser["_links"]: yield Listitem.next_page( item_id=item_id, program_url=json_parser["_links"]['next']['href']) else: resp = urlquick.get( program_url.replace('/router', '') + '?ApiKey=%s' % API_KEY) json_parser = json.loads(resp.text) for video_datas in json_parser["components"][2]["data"]["items"]: try: video_title = str(video_datas["title"] + " - S%sE%s" % (str(video_datas['seasonNumber']), str(video_datas['episodeNumber']))) except Exception: video_title = str(video_datas["title"]) if 'header' in video_datas["images"]: video_image = URL_IMAGE % video_datas["images"]["header"]["id"] else: video_image = '' video_plot = video_datas["description"] video_id = video_datas["id"] video_duration = video_datas["duration"] date_value = video_datas['broadcastDate'].split('T')[0] item = Listitem() item.label = video_title item.art['thumb'] = item.art['landscape'] = video_image item.info['plot'] = video_plot item.info['duration'] = video_duration item.info.date(date_value, "%Y-%m-%d") item.set_callback(get_video_url, item_id=item_id, video_id=video_id) item_post_treatment(item, is_playable=True, is_downloadable=False) yield item if 'next' in json_parser["components"][2]["data"]["_links"]: yield Listitem.next_page(item_id=item_id, program_url=json_parser["components"][2] ["data"]["_links"]['next']['href'])
def list_lives(plugin, item_id, **kwargs): resp = urlquick.get(URL_FRANCETV_SPORT % 'directs', max_age=-1) json_parser = json.loads(resp.text) if 'lives' in json_parser["page"]: for live_datas in json_parser["page"]["lives"]: live_title = live_datas["title"] live_image = '' if 'image' in live_datas: live_image = live_datas["image"]["large_16_9"] id_diffusion = live_datas["sivideo-id"] try: live_date_plot = time.strftime( '%d/%m/%Y %H:%M', time.localtime(live_datas["start"])) date_value = time.strftime('%Y-%m-%d', time.localtime(live_datas["start"])) except Exception: live_date_plot = '' date_value = '' live_plot = 'Live starts at ' + live_date_plot item = Listitem() item.label = live_title item.art['thumb'] = live_image item.info['plot'] = live_plot item.info.date(date_value, '%Y-%m-%d') item.set_callback(get_live_url, item_id=item_id, id_diffusion=id_diffusion) yield item for live_datas in json_parser["page"]["upcoming-lives"]: live_title = 'Prochainement - ' + live_datas["title"] try: live_image = live_datas["image"]["large_16_9"] except KeyError: live_image = '' try: live_date_plot = time.strftime('%d/%m/%Y %H:%M', time.localtime(live_datas["start"])) date_value = time.strftime('%Y-%m-%d', time.localtime(live_datas["start"])) except Exception: live_date_plot = '' date_value = '' live_plot = 'Live starts at ' + live_date_plot item = Listitem() item.label = live_title item.art['thumb'] = live_image item.info['plot'] = live_plot item.info.date(date_value, '%Y-%m-%d') yield item
def root(_): """ Lists all categories and link's to 'Shows', 'MsMojo' and 'All videos'. site: http://www.watchmojo.com """ # Add links to watchmojo youtube channels yield Listitem.youtube("UCaWd5_7JhbQBe4dknZhsHJg") # WatchMojo yield Listitem.search(search_results) yield Listitem.youtube("UCMm0YNfHOCA-bvHmOBSx-ZA", label="WatchMojo UK") yield Listitem.youtube("UC9_eukrzdzY91jjDZm62FXQ", label="MojoTravels") yield Listitem.youtube("UC4HnC-AS714lT2TCTJ-A1zQ", label="MojoPlays") yield Listitem.youtube("UC88y_sxutS1mnoeBDroS74w", label="MojoTalks") yield Listitem.youtube("UC3rLoj87ctEHCcS7BuvIzkQ", label="MsMojo") yield Listitem.youtube("UCYJyrEdlwxUu7UwtFS6jA_Q", label="UnVeiled") source = urlquick.get(BASE_URL) root_elem = source.parse() # Find each category and fetch the image for the first video in the list for elem in root_elem.iterfind("./body/section/div[@class='line']"): # If we have a 'link' tag with class=more, then we are in the right section tag = elem.find("a[@class='more']") if tag is not None: url = tag.get("href") # Only list category entrys if url.startswith("/categories"): item = Listitem() item.label = elem.find("h2").text.strip().title() item.art["thumb"] = url_constructor(elem.find(".//img").get("src")) item.set_callback(video_list, url=url) yield item # Add link to exclusive watchmojo video yield Listitem.from_dict(video_list, "Exclusive", params={"url": "/exclusive/1"}, art={"thumb": "https://www.watchmojo.com/uploads/blipthumbs/Fi-M-Top10-Well-" "Regarded-Controversial-Films_R7D2Y7-720p30-C_480.jpg"})
def get_video_url(plugin, item_id, video_id, download_mode=False, **kwargs): if get_kodi_version() < 18: xbmcgui.Dialog().ok('Info', plugin.localize(30602)) return False is_helper = inputstreamhelper.Helper('mpd', drm='widevine') if not is_helper.check_inputstream(): return False headers = {'X-Requested-With': 'XMLHttpRequest'} resp_token = urlquick.get(URL_TOKEN_API, headers=headers, max_age=-1) session_token = resp_token.cookies['npo_session'] json_parser_token = json.loads(resp_token.text) api_token = json_parser_token['token'] # Build PAYLOAD payload = {"_token": api_token} cookies = {"npo_session": session_token} resp2 = urlquick.post(URL_TOKEN_ID % video_id, cookies=cookies, data=payload, max_age=-1) json_parser = json.loads(resp2.text) token_id = json_parser['token'] resp3 = urlquick.get(URL_STREAM % (video_id, token_id), max_age=-1) json_parser2 = json.loads(resp3.text) if "html" in json_parser2 and "Dit programma mag niet bekeken worden vanaf jouw locatie (33)." in json_parser2[ "html"]: plugin.notify('ERROR', plugin.localize(30713)) return False if "html" in json_parser2 and "Dit programma is niet (meer) beschikbaar (15)." in json_parser2[ "html"]: plugin.notify('ERROR', plugin.localize(30710)) return False licence_url = json_parser2["stream"]["keySystemOptions"][0]["options"][ "licenseUrl"] licence_url_header = json_parser2["stream"]["keySystemOptions"][0][ "options"]["httpRequestHeaders"] xcdata_value = licence_url_header["x-custom-data"] item = Listitem() item.path = json_parser2["stream"]["src"] item.label = get_selected_item_label() item.art.update(get_selected_item_art()) item.info.update(get_selected_item_info()) if plugin.setting.get_boolean('active_subtitle'): item.subtitles.append(URL_SUBTITLE % video_id) item.property[INPUTSTREAM_PROP] = 'inputstream.adaptive' item.property['inputstream.adaptive.manifest_type'] = 'mpd' item.property['inputstream.adaptive.license_type'] = 'com.widevine.alpha' item.property[ 'inputstream.adaptive.license_key'] = licence_url + '|Content-Type=&User-Agent=Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3041.0 Safari/537.36&x-custom-data=%s|R{SSM}|' % xcdata_value return item