def create_channel_item(self, channel): """ Creates a MediaItem of type 'video' for a live channel using the result_set from the regex. This method creates a new MediaItem from the Regular Expression or Json results <result_set>. The method should be implemented by derived classes and are specific to the channel. If the item is completely processed an no further data needs to be fetched the self.complete property should be set to True. If not set to True, the self.update_video_item method is called if the item is focussed or selected for playback. :param list[str]|dict channel: The result_set of the self.episodeItemRegex :return: A new MediaItem of type 'video' or 'audio' (despite the method's name). :rtype: MediaItem|None """ Logger.trace(channel) title = channel["programmeTitle"] episode = channel.get("episodeTitle", None) thumb = self.noImage channel_title = channel["displayName"] description = channel.get("longDescription") channel_id = channel["urlName"] if channel_id == "svtb": channel_id = "barnkanalen" elif channel_id == "svtk": channel_id = "kunskapskanalen" date_format = "%Y-%m-%dT%H:%M:%S" start_time = DateHelper.get_date_from_string( channel["publishingTime"][:19], date_format) end_time = DateHelper.get_date_from_string( channel["publishingEndTime"][:19], date_format) if episode: title = "%s: %s - %s (%02d:%02d - %02d:%02d)" \ % (channel_title, title, episode, start_time.tm_hour, start_time.tm_min, end_time.tm_hour, end_time.tm_min) else: title = "%s: %s (%02d:%02d - %02d:%02d)" \ % (channel_title, title, start_time.tm_hour, start_time.tm_min, end_time.tm_hour, end_time.tm_min) channel_item = MediaItem( title, "https://www.svt.se/videoplayer-api/video/ch-%s" % (channel_id.lower(), )) channel_item.type = "video" channel_item.description = description channel_item.isLive = True channel_item.isGeoLocked = True channel_item.thumb = thumb if "episodeThumbnailIds" in channel and channel["episodeThumbnailIds"]: channel_item.thumb = "https://www.svtstatic.se/image/wide/650/%s.jpg" % ( channel["episodeThumbnailIds"][0], ) return channel_item
def create_folder_item(self, result_set): """ Creates a MediaItem of type 'folder' using the result_set from the regex. This method creates a new MediaItem from the Regular Expression or Json results <result_set>. The method should be implemented by derived classes and are specific to the channel. :param list[str]|dict[str,str] result_set: The result_set of the self.episodeItemRegex :return: A new MediaItem of type 'folder'. :rtype: MediaItem|None """ Logger.trace(result_set) if self.parentItem.url.endswith(str(DateHelper.this_year())): return None url = "%s%s" % (self.baseUrl, result_set[3]) name = result_set[4] item = MediaItem(name.title(), url) day = result_set[0] month = result_set[1] month = DateHelper.get_month_from_name(month, "nl", short=False) year = result_set[2] item.set_date(year, month, day) item.complete = True return item
def create_live_channel(self, result_set): """ Creates a MediaItem of type 'video' using the result_set from the regex. This method creates a new MediaItem from the Regular Expression or Json results <result_set>. The method should be implemented by derived classes and are specific to the channel. If the item is completely processed an no further data needs to be fetched the self.complete property should be set to True. If not set to True, the self.update_video_item method is called if the item is focussed or selected for playback. :param list[str]|dict[str,str] result_set: The result_set of the self.episodeItemRegex :return: A new MediaItem of type 'video' or 'audio' (despite the method's name). :rtype: MediaItem|None """ Logger.trace(result_set) item = MediaItem(result_set[0], result_set[1]) item.type = "video" item.isGeoLocked = result_set[3].lower() == "true" date_time = DateHelper.get_date_from_posix(int(result_set[2]) * 1 / 1000) item.set_date(date_time.year, date_time.month, date_time.day, date_time.hour, date_time.minute, date_time.second) thumb = result_set[4] if not thumb.startswith("http"): thumb = "%s%s" % (self.baseUrl, thumb) item.thumb = thumb return item
def create_search_program_item(self, result_set): """ Creates a MediaItem of type 'video' using the result_set from the regex. This method creates a new MediaItem from the Regular Expression or Json results <result_set>. The method should be implemented by derived classes and are specific to the channel. If the item is completely processed an no further data needs to be fetched the self.complete property should be set to True. If not set to True, the self.update_video_item method is called if the item is focussed or selected for playback. :param list[str]|dict result_set: The result_set of the self.episodeItemRegex :return: A new MediaItem of type 'video' or 'audio' (despite the method's name). :rtype: MediaItem|None """ Logger.trace(result_set) title = result_set["Title"] # Not used: uuid = result_set["Uuid"] abstract_key = result_set["AbstractKey"] url = "http://www.rtl.nl/system/s4m/vfd/version=1/d=pc/output=json/fun=getseasons/ak={}".format( abstract_key) item = MediaItem(title, url) time_stamp = result_set["LastBroadcastDate"] # =1546268400000 date_time = DateHelper.get_date_from_posix(int(time_stamp) / 1000) item.set_date(date_time.year, date_time.month, date_time.day, date_time.hour, date_time.minute, date_time.second) return item
def __set_expire_time(self, expire_date, item): expire_date = expire_date.split("+")[0].replace("T", " ") year = expire_date.split("-")[0] if len(year) == 4 and int(year) < datetime.datetime.now().year + 50: expire_date = DateHelper.get_datetime_from_string( expire_date, date_format="%Y-%m-%d %H:%M:%S") item.set_expire_datetime(timestamp=expire_date)
def create_video_item(self, result_set): """ Creates a MediaItem of type 'video' using the result_set from the regex. This method creates a new MediaItem from the Regular Expression or Json results <result_set>. The method should be implemented by derived classes and are specific to the channel. If the item is completely processed an no further data needs to be fetched the self.complete property should be set to True. If not set to True, the self.update_video_item method is called if the item is focussed or selected for playback. :param result_set: The result_set of the self.episodeItemRegex :type result_set: list[str]|dict[str,dict[str,dict]] :return: A new MediaItem of type 'video' or 'audio' (despite the method's name). :rtype: MediaItem|None """ Logger.trace(result_set) if "fullengthSegment" in result_set and "segment" in result_set[ "fullengthSegment"]: video_id = result_set["fullengthSegment"]["segment"]["id"] geo_location = result_set["fullengthSegment"]["segment"][ "geolocation"] geo_block = False if "flags" in result_set["fullengthSegment"]["segment"]: geo_block = result_set["fullengthSegment"]["segment"][ "flags"].get("geoblock", None) Logger.trace("Found geoLocation/geoBlock: %s/%s", geo_location, geo_block) else: Logger.warning("No video information found.") return None url = "http://www.srf.ch/player/webservice/videodetail/index?id=%s" % ( video_id, ) item = MediaItem(result_set["titleFull"], url) item.type = "video" # noinspection PyTypeChecker item.thumb = result_set.get("segmentThumbUrl", None) # apparently only the 144 return the correct HEAD info # item.thumb = "%s/scale/width/288" % (item.thumb, ) # the HEAD will not return a size, so Kodi can't handle it # item.fanart = resultSet.get("imageUrl", None) item.description = result_set.get("description", "") date_value = str(result_set["time_published"]) # 2015-01-20 22:17:59" date_time = DateHelper.get_date_from_string(date_value, "%Y-%m-%d %H:%M:%S") item.set_date(*date_time[0:6]) item.icon = self.icon item.httpHeaders = self.httpHeaders item.complete = False return item
def create_episode_item_json(self, result_set): """ Creates a new MediaItem for an episode. This method creates a new MediaItem from the Regular Expression or Json results <result_set>. The method should be implemented by derived classes and are specific to the channel. :param list[str]|dict[str,str] result_set: The result_set of the self.episodeItemRegex :return: A new MediaItem of type 'folder'. :rtype: MediaItem|None """ time_stamp = result_set["created"] if time_stamp <= 1420070400: # older items don't have videos for now return None url = "https://at5news.vinsontv.com/api/news?source=web&externalid={}".format( result_set["externalId"]) item = MediaItem(result_set["title"], url) item.complete = True item.description = result_set.get("text") date_time = DateHelper.get_date_from_posix(time_stamp) item.set_date(date_time.year, date_time.month, date_time.day) # noinspection PyTypeChecker image_data = result_set.get("media", []) for image in image_data: item.thumb = image.get("imageHigh", image["image"]) return item
def create_video_item(self, result_set): """ Creates a MediaItem of type 'video' using the result_set from the regex. This method creates a new MediaItem from the Regular Expression or Json results <result_set>. The method should be implemented by derived classes and are specific to the channel. If the item is completely processed an no further data needs to be fetched the self.complete property should be set to True. If not set to True, the self.update_video_item method is called if the item is focussed or selected for playback. :param list[str]|dict[str,str] result_set: The result_set of the self.episodeItemRegex :return: A new MediaItem of type 'video' or 'audio' (despite the method's name). :rtype: MediaItem|None """ item = chn_class.Channel.create_video_item(self, result_set) if item is None: return None # 2018-02-24 07:15:00 time_stamp = DateHelper.get_date_from_string( result_set['date'], date_format="%Y-%m-%d %H:%M:%S") item.set_date(*time_stamp[0:6]) return item
def create_folder_item(self, result_set): """ Creates a MediaItem of type 'folder' using the result_set from the regex. This method creates a new MediaItem from the Regular Expression or Json results <result_set>. The method should be implemented by derived classes and are specific to the channel. :param list[str]|dict[str,str] result_set: The result_set of the self.episodeItemRegex :return: A new MediaItem of type 'folder'. :rtype: MediaItem|None """ if len(result_set) > 3 and result_set[3] != "": Logger.debug("Sub category folder found.") url = parse.urljoin( self.baseUrl, HtmlEntityHelper.convert_html_entities(result_set[3])) name = "\a.: %s :." % (result_set[4], ) item = MediaItem(name, url) item.complete = True item.type = "folder" return item url = parse.urljoin( self.baseUrl, HtmlEntityHelper.convert_html_entities(result_set[0])) name = HtmlEntityHelper.convert_html_entities(result_set[1]) helper = HtmlHelper(result_set[2]) description = helper.get_tag_content("div", {'class': 'description'}) item = MediaItem(name, "%s/RSS" % (url, )) item.type = 'folder' item.description = description.strip() date = helper.get_tag_content("div", {'class': 'date'}) if date == "": date = helper.get_tag_content("span", {'class': 'lastPublishedDate'}) if not date == "": date_parts = Regexer.do_regex(r"(\w+) (\d+)[^<]+, (\d+)", date) if len(date_parts) > 0: date_parts = date_parts[0] month_part = date_parts[0].lower() day_part = date_parts[1] year_part = date_parts[2] try: month = DateHelper.get_month_from_name(month_part, "en") item.set_date(year_part, month, day_part) except: Logger.error("Error matching month: %s", month_part, exc_info=True) item.complete = True return item
def create_video_item_new(self, result_set): """ Creates a MediaItem of type 'video' using the result_set from the regex. This method creates a new MediaItem from the Regular Expression or Json results <result_set>. The method should be implemented by derived classes and are specific to the channel. If the item is completely processed an no further data needs to be fetched the self.complete property should be set to True. If not set to True, the self.update_video_item method is called if the item is focussed or selected for playback. :param result_set: The result_set of the self.episodeItemRegex :type result_set: list[str]|dict[str,str] :return: A new MediaItem of type 'video' or 'audio' (despite the method's name). :rtype: MediaItem|None """ Logger.trace(result_set) videos = self.__get_nested_value(result_set, "Assets", "Video") if not videos: Logger.warning("No video information found.") return None video_infos = [vi for vi in videos if vi["fullLength"]] if len(video_infos) > 0: video_info = video_infos[0] else: Logger.warning("No full length video found.") return None # noinspection PyTypeChecker video_id = video_info["id"] url = "http://il.srgssr.ch/integrationlayer/1.0/ue/srf/video/play/%s.json" % ( video_id, ) item = MediaItem(result_set["title"], url) item.type = "video" item.thumb = self.__get_nested_value(video_info, "Image", "ImageRepresentations", "ImageRepresentation", 0, "url") item.description = self.__get_nested_value(video_info, "AssetMetadatas", "AssetMetadata", 0, "description") date_value = str(result_set["publishedDate"]) date_value = date_value[0:-6] # 2015-01-20T22:17:59" date_time = DateHelper.get_date_from_string(date_value, "%Y-%m-%dT%H:%M:%S") item.set_date(*date_time[0:6]) item.icon = self.icon item.httpHeaders = self.httpHeaders item.complete = False return item
def create_video_item(self, result_set, include_show_title=False): """ Creates a MediaItem of type 'video' using the result_set from the regex. This method creates a new MediaItem from the Regular Expression or Json results <result_set>. The method should be implemented by derived classes and are specific to the channel. If the item is completely processed an no further data needs to be fetched the self.complete property should be set to True. If not set to True, the self.update_video_item method is called if the item is focussed or selected for playback. :param list[str]|dict[str,str] result_set: The result_set of the self.episodeItemRegex :return: A new MediaItem of type 'video' or 'audio' (despite the method's name). :rtype: MediaItem|None """ if not result_set: return None url_format = "https://{0}/playback/videoPlaybackInfo/{{0}}".format( self.baseUrlApi) item = self.__create_generic_item(result_set, "video", url_format) if item is None: return None item.type = "video" video_info = result_set["attributes"] # type: dict if "publishStart" in video_info or "airDate" in video_info: date = video_info.get("airDate", video_info["publishStart"]) # 2018-03-20T20:00:00Z air_date = DateHelper.get_date_from_string( date, date_format="%Y-%m-%dT%H:%M:%SZ") item.set_date(*air_date[0:6]) if datetime.datetime(*air_date[0:6]) > datetime.datetime.now(): item.isPaid = True episode = video_info.get("episodeNumber", 0) season = video_info.get("seasonNumber", 0) if episode > 0 and season > 0: item.name = "s{0:02d}e{1:02d} - {2}".format( season, episode, item.name) item.set_season_info(season, episode) if include_show_title: show_id = result_set["relationships"].get("show", {}).get("data", {}).get("id") if show_id: show = self.showLookup[show_id] item.name = "{0} - {1}".format(show, item.name) if "videoDuration" in video_info: item.set_info_label(MediaItem.LabelDuration, video_info["videoDuration"] / 1000) return item
def create_json_video_item(self, result_set): """ Creates a MediaItem of type 'video' using the result_set from the regex. This method creates a new MediaItem from the Regular Expression or Json results <result_set>. The method should be implemented by derived classes and are specific to the channel. If the item is completely processed an no further data needs to be fetched the self.complete property should be set to True. If not set to True, the self.update_video_item method is called if the item is focussed or selected for playback. :param dict result_set: The result_set of the self.episodeItemRegex :return: A new MediaItem of type 'video' or 'audio' (despite the method's name). :rtype: MediaItem|None """ Logger.trace(result_set) meta = result_set["meta"] name = meta["header"]["title"] if isinstance(name, dict): name = name["text"] sub_heading = meta.get("subHeader") if sub_heading: name = "{} - {}".format(name, sub_heading) url = "{}{}".format(self.baseUrl, result_set["url"]) item = MediaItem(name, url) item.type = "video" item.description = meta.get("description") item.thumb = result_set.get("media", {}).get("image", {}).get("url") item.isGeoLocked = True date_value = meta["date"] if "." in date_value: date = DateHelper.get_date_from_string(date_value, date_format="%d.%m.%Y") else: date = DateHelper.get_date_from_string(date_value, date_format="%d/%m/%Y") item.set_date(*date[0:6]) return item
def create_recent_video_item(self, result_set): """ Creates a MediaItem of type 'video' using the result_set from the regex. This method creates a new MediaItem from the Regular Expression or Json results <result_set>. The method should be implemented by derived classes and are specific to the channel. If the item is completely processed an no further data needs to be fetched the self.complete property should be set to True. If not set to True, the self.update_video_item method is called if the item is focussed or selected for playback. :param list[str]|dict result_set: The result_set of the self.episodeItemRegex :return: A new MediaItem of type 'video' or 'audio' (despite the method's name). :rtype: MediaItem|None """ Logger.trace(result_set) show_title = result_set["abstract_name"] episode_title = result_set["title"] title = "{} - {}".format(show_title, episode_title) description = result_set.get("synopsis") uuid = result_set["uuid"] url = "https://api.rtl.nl/watch/play/api/play/xl/%s?device=web&drm=widevine&format=dash" % (uuid,) item = MediaItem(title.title(), url) item.type = "video" item.description = description item.thumb = "%s%s" % (self.posterBase, uuid,) audience = result_set.get("audience") Logger.debug("Found audience: %s", audience) item.isGeoLocked = audience == "ALLEEN_NL" # We can play the DRM stuff # item.isDrmProtected = audience == "DRM" station = result_set.get("station", None) if station: item.name = "{} ({})".format(item.name, station) icon = self.largeIconSet.get(station.lower(), None) if icon: Logger.trace("Setting icon to: %s", icon) item.icon = icon # 2018-12-05T19:30:00.000Z date_time = result_set.get("dateTime", None) if date_time: date_time = DateHelper.get_date_from_string(date_time[:-5], "%Y-%m-%dT%H:%M:%S") # The time is in UTC, and the show as at UTC+1 date_time = datetime.datetime(*date_time[:6]) + datetime.timedelta(hours=1) item.name = "{:02d}:{:02d}: {}".format(date_time.hour, date_time.minute, item.name) item.set_date(date_time.year, date_time.month, date_time.day, date_time.hour, date_time.minute, date_time.second) return item
def create_instalment_video_item(self, result_set): """ Creates a MediaItem of type 'video' using the result_set from the regex. This method creates a new MediaItem from the Regular Expression or Json results <result_set>. The method should be implemented by derived classes and are specific to the channel. If the item is completely processed an no further data needs to be fetched the self.complete property should be set to True. If not set to True, the self.update_video_item method is called if the item is focussed or selected for playback. :param list[str]|dict[str,str|dict] result_set: The result_set of the self.episodeItemRegex :return: A new MediaItem of type 'video' or 'audio' (despite the method's name). :rtype: MediaItem|None """ title = result_set["titles"]["title"] sub_title = result_set["titles"]["subtitle"] # noinspection PyTypeChecker if result_set.get("availability", {}).get("status", "available") != "available": Logger.debug("Found '%s' with a non-available status", title) return None url = "https://psapi.nrk.no/programs/{}?apiKey={}".format( result_set["prfId"], self.__api_key) item = MediaItem(title, url) item.type = 'video' item.thumb = self.__get_image(result_set["image"], "width", "url") item.fanart = self.parentItem.fanart # noinspection PyTypeChecker item.isGeoLocked = result_set.get("usageRights", {}).get( "geoBlock", {}).get("isGeoBlocked", False) if sub_title and sub_title.strip(): item.description = sub_title if "firstTransmissionDateDisplayValue" in result_set: Logger.trace("Using 'firstTransmissionDateDisplayValue' for date") day, month, year = result_set[ "firstTransmissionDateDisplayValue"].split(".") item.set_date(year, month, day) elif "usageRights" in result_set and "from" in result_set[ "usageRights"] and result_set["usageRights"][ "from"] is not None: Logger.trace("Using 'usageRights.from.date' for date") # noinspection PyTypeChecker date_value = result_set["usageRights"]["from"]["date"].split( "+")[0] time_stamp = DateHelper.get_date_from_string( date_value, date_format="%Y-%m-%dT%H:%M:%S") item.set_date(*time_stamp[0:6]) return item
def _is_paid_or_logged_on_item(self, result_set): """ Check whether an item is paid or not? :param dict result_set: :return: Indication if the item is paid? :rtype: tuple[bool,bool] """ active = set() date_format = "%Y-%m-%dT%H:%M:%SZ" availability_windows = result_set.get("attributes", {}).get("availabilityWindows") if availability_windows is not None: for availability in availability_windows: start = availability["playableStart"] start_date = DateHelper.get_datetime_from_string( start, date_format) end = availability.get("playableEnd") if end is None: end_date = datetime.datetime.max else: end_date = DateHelper.get_datetime_from_string( end, date_format) package = availability["package"].lower() if start_date < self.__now < end_date: active.add(package) else: content_packages = result_set.get("relationships", {}).get("contentPackages") if content_packages is not None: for account_info in result_set["relationships"][ "contentPackages"]["data"]: account_type = account_info.get("id", "free").lower() active.add(account_type) if "free" in active: return False, False if "registered" in active: return False, True return True, True
def create_video_item(self, result_set): """ Creates a MediaItem of type 'video' using the result_set from the regex. This method creates a new MediaItem from the Regular Expression or Json results <result_set>. The method should be implemented by derived classes and are specific to the channel. If the item is completely processed an no further data needs to be fetched the self.complete property should be set to True. If not set to True, the self.update_video_item method is called if the item is focussed or selected for playback. :param dict[str,dict|None] result_set: The result_set of the self.episodeItemRegex :return: A new MediaItem of type 'video' or 'audio' (despite the method's name). :rtype: MediaItem|None """ Logger.trace(result_set) title = result_set["title"] if "subTitle" in result_set: title = "%s - %s" % (title, result_set["subTitle"]) mgid = result_set["id"].split(":")[-1] url = "http://feeds.mtvnservices.com/od/feed/intl-mrss-player-feed" \ "?mgid=mgid:arc:episode:mtvplay.com:%s" \ "&ep=%s" \ "&episodeType=segmented" \ "&imageEp=android.playplex.mtv.%s" \ "&arcEp=android.playplex.mtv.%s" \ % (mgid, self.__backgroundServiceEp, self.__region.lower(), self.__region.lower()) item = MediaItem(title, url) item.type = "video" item.description = result_set.get("description", None) item.isGeoLocked = True images = result_set.get("images", []) if images: # mgid:file:gsp:scenic:/international/mtv.nl/playplex/dutch-ridiculousness/Dutch_Ridiculousness_Landscape.png # http://playplex.mtvnimages.com/uri/mgid:file:gsp:scenic:/international/mtv.nl/playplex/dutch-ridiculousness/Dutch_Ridiculousness_Landscape.png for image in images: if image["width"] > 500: pass # no fanart here else: item.thumb = "http://playplex.mtvnimages.com/uri/%(url)s" % image date = result_set.get("originalAirDate", None) if not date: date = result_set.get("originalPublishDate", None) if date: time_stamp = date["timestamp"] date_time = DateHelper.get_date_from_posix(time_stamp) item.set_date(date_time.year, date_time.month, date_time.day, date_time.hour, date_time.minute, date_time.second) return item
def create_video_item_hw_info(self, result_set): """ Creates a MediaItem of type 'video' using the result_set from the regex. This method creates a new MediaItem from the Regular Expression or Json results <result_set>. The method should be implemented by derived classes and are specific to the channel. If the item is completely processed an no further data needs to be fetched the self.complete property should be set to True. If not set to True, the self.update_video_item method is called if the item is focussed or selected for playback. :param list[str]|dict[str,str] result_set: The result_set of the self.episodeItemRegex :return: A new MediaItem of type 'video' or 'audio' (despite the method's name). :rtype: MediaItem|None """ xml_data = xmlhelper.XmlHelper(result_set) title = xml_data.get_single_node_content("title") # Retrieve an ID and create an URL like: http://www.youtube.com/get_video_info?hl=en_GB&asv=3&video_id=OHqu64Qnz9M url = xml_data.get_tag_attribute("enclosure", {'url': None}, {'type': 'video/youtube'}) Logger.trace(url) item = MediaItem(title, url) item.icon = self.icon item.type = 'video' # date stuff date = xml_data.get_single_node_content("pubDate") dayname, day, month, year, time, zone = date.split(' ', 6) month = DateHelper.get_month_from_name(month, language="en") hour, minute, seconds = time.split(":") Logger.trace("%s-%s-%s %s:%s", year, month, day, hour, minute) item.set_date(year, month, day, hour, minute, 0) # # description stuff description = xml_data.get_single_node_content("description") item.description = description # # thumbnail stuff item.thumb = self.noImage thumb_urls = xml_data.get_tag_attribute("enclosure", {'url': None}, {'type': 'image/jpg'}, firstOnly=False) for thumb_url in thumb_urls: if thumb_url != "" and "thumb" not in thumb_url: item.thumb = thumb_url # finish up item.complete = False return item
def create_video_item(self, result_set): """ Creates a MediaItem of type 'video' using the result_set from the regex. This method creates a new MediaItem from the Regular Expression or Json results <result_set>. The method should be implemented by derived classes and are specific to the channel. If the item is completely processed an no further data needs to be fetched the self.complete property should be set to True. If not set to True, the self.update_video_item method is called if the item is focussed or selected for playback. :param dict[str,str|dict] result_set: The result_set of the self.episodeItemRegex :return: A new MediaItem of type 'video' or 'audio' (despite the method's name). :rtype: MediaItem|None """ Logger.trace(result_set) is_serie_title = result_set["seriesTitle"] if not is_serie_title: return None if result_set["mediaType"] == "game": return None elif result_set["mediaType"] == "episode": title = "%(title)s (Episode)" % result_set else: title = result_set["title"] video_id = result_set["id"] url = "http://media.mtvnservices.com/pmt/e1/access/index.html?uri=mgid:%s:%s&configtype=edge" \ % (self.__mgid, video_id, ) item = MediaItem(title, url) item.description = result_set.get("description", None) item.type = "video" item.icon = self.icon item.fanart = self.fanart item.HttpHeaders = self.httpHeaders item.complete = False if "datePosted" in result_set: date = DateHelper.get_date_from_posix( float(result_set["datePosted"]["unixOffset"]) / 1000) item.set_date(date.year, date.month, date.day, date.hour, date.minute, date.second) if "images" in result_set: images = result_set.get("images", {}) thumbs = images.get("thumbnail", {}) item.thumb = thumbs.get("r16-9", self.noImage) return item
def create_json_video_item(self, result_set): """ Creates a MediaItem of type 'video' using the result_set from the regex. This method creates a new MediaItem from the Regular Expression or Json results <result_set>. The method should be implemented by derived classes and are specific to the channel. If the item is completely processed an no further data needs to be fetched the self.complete property should be set to True. If not set to True, the self.update_video_item method is called if the item is focussed or selected for playback. :param list[str]|dict[str,any] result_set: The result_set of the self.episodeItemRegex :return: A new MediaItem of type 'video' or 'audio' (despite the method's name). :rtype: MediaItem|None """ Logger.trace(result_set) url = "http://playapi.mtgx.tv/v3/videos/stream/%(id)s" % result_set item = MediaItem(result_set["title"], url) item.type = "video" item.thumb = self.parentItem.thumb item.icon = self.parentItem.icon item.description = result_set.get("summary", None) aired_at = result_set.get("airedAt", None) if aired_at is None: aired_at = result_set.get("publishedAt", None) if aired_at is not None: # 2016-05-20T15:05:00+00:00 aired_at = aired_at.split("+")[0].rstrip('Z') time_stamp = DateHelper.get_date_from_string( aired_at, "%Y-%m-%dT%H:%M:%S") item.set_date(*time_stamp[0:6]) item.thumb = self.__get_thumb_image(result_set.get("image")) # webvttPath / samiPath # loginRequired is_premium = result_set.get("loginRequired", False) if is_premium and AddonSettings.hide_premium_items(): Logger.debug("Found premium item, hiding it.") return None srt = result_set.get("samiPath") if not srt: srt = result_set.get("subtitles_webvtt") if srt: Logger.debug("Storing SRT/WebVTT path: %s", srt) part = item.create_new_empty_media_part() part.Subtitle = srt return item
def create_api_movie_type(self, result_set): """ Creates a new MediaItem for an program. This method creates a new MediaItem from the Regular Expression or Json results <result_set>. The method should be implemented by derived classes and are specific to the channel. :param dict result_set: The result_set of the self.episodeItemRegex :return: A new MediaItem of type 'folder'. :rtype: MediaItem|None """ title = result_set["title"] if title is None: return None url = self.__get_api_persisted_url( "programs", "b6f65688f7e1fbe22aae20816d24ca5dcea8c86c8e72d80b462a345b5b70fa41", variables={ "programTypes": "MOVIE", "guid": result_set["guid"] }) item = MediaItem(result_set["title"], url) item.description = result_set.get("description") item.type = "video" item.set_info_label("duration", int(result_set.get("duration", 0) or 0)) item.set_info_label("genre", result_set.get("displayGenre")) self.__get_artwork(item, result_set.get("imageMedia")) time_stamp = result_set["epgDate"] / 1000 date_stamp = DateHelper.get_date_from_posix(time_stamp, tz=self.__timezone_utc) date_stamp = date_stamp.astimezone(self.__timezone) if date_stamp > datetime.datetime.now(tz=self.__timezone): available = LanguageHelper.get_localized_string( LanguageHelper.AvailableFrom) item.name = "{} - [COLOR=gold]{} {:%Y-%m-%d}[/COLOR]".format( title, available, date_stamp) item.set_date(date_stamp.year, date_stamp.month, date_stamp.day) # In the main list we should set the fanart too if self.parentItem is None: item.fanart = item.thumb sources = result_set.get("sources") item.metaData["sources"] = sources subs = result_set.get("tracks") item.metaData["subtitles"] = subs return item
def create_api_episode_type(self, result_set): """ Creates a new MediaItem for an episode. This method creates a new MediaItem from the Regular Expression or Json results <result_set>. The method should be implemented by derived classes and are specific to the channel. :param dict result_set: The result_set of the self.episodeItemRegex :return: A new MediaItem of type 'folder'. :rtype: MediaItem|None """ # This URL gives the URL that contains the show info with Season ID's url = "https://graph.kijk.nl/graphql-video" if not result_set.get("sources"): return None title = result_set["title"] season_number = result_set.get("seasonNumber") episode_number = result_set.get("tvSeasonEpisodeNumber") title_format = self.parentItem.metaData.get("title_format", "s{0:02d}e{1:02d} - {2}") if title is None: serie_title = result_set["series"]["title"] title = title_format.format(season_number, episode_number, serie_title) elif season_number is not None and episode_number is not None: title = title_format.format(season_number, episode_number, title) item = MediaItem(title, url, type="video") item.description = result_set.get("longDescription", result_set.get("description")) item.set_info_label("duration", int(result_set.get("duration", 0) or 0)) item.set_info_label("genre", result_set.get("displayGenre")) self.__get_artwork(item, result_set.get("imageMedia"), mode="thumb") updated = result_set["lastPubDate"] / 1000 date_time = DateHelper.get_date_from_posix(updated) item.set_date(date_time.year, date_time.month, date_time.day, date_time.hour, date_time.minute, date_time.second) # Find the media streams item.metaData["sources"] = result_set["sources"] item.metaData["subtitles"] = result_set.get("tracks", []) # DRM only no_drm_items = [src for src in result_set["sources"] if not src["drm"]] item.isDrmProtected = len(no_drm_items) == 0 return item
def create_video_item_json(self, result_set): """ Creates a MediaItem of type 'video' using the result_set from the regex. This method creates a new MediaItem from the Regular Expression or Json results <result_set>. The method should be implemented by derived classes and are specific to the channel. If the item is completely processed an no further data needs to be fetched the self.complete property should be set to True. If not set to True, the self.update_video_item method is called if the item is focussed or selected for playback. :param dict result_set: The result_set of the self.episodeItemRegex :return: A new MediaItem of type 'video' or 'audio' (despite the method's name). :rtype: MediaItem|None """ Logger.trace(result_set) # get the title title = result_set["title"] mgid = result_set["id"] url = "http://media.mtvnservices.com/pmt/e1/access/index.html" \ "?uri=mgid:arc:video:{}:{}&configtype=edge".format(self.__country_id, mgid) item = MediaItem(title, url) item.type = "video" item.description = result_set["description"] if "images" in result_set: item.thumb = result_set["images"]["url"] air_date = int(result_set["publishDate"]) date_stamp = DateHelper.get_date_from_posix(air_date, self.__timezone_utc) item.set_date(date_stamp.year, date_stamp.month, date_stamp.day) episode = result_set.get("episode") season = result_set.get("season") if season and episode: item.set_season_info(season, episode) duration = result_set.get("duration", "0:00") duration = duration.split(":") duration = int(duration[1]) + 60 * int(duration[0]) item.set_info_label("duration", duration) # store season info item.metaData["season_id"] = result_set.get("seasonId") item.isGeoLocked = True return item
def create_json_video_item(self, result_set, prepend_serie=False): """ Creates a MediaItem of type 'video' using the result_set from the regex. This method creates a new MediaItem from the Regular Expression or Json results <result_set>. The method should be implemented by derived classes and are specific to the channel. If the item is completely processed an no further data needs to be fetched the self.complete property should be set to True. If not set to True, the self.update_video_item method is called if the item is focussed or selected for playback. :param list[str]|dict result_set: The result_set of the self.episodeItemRegex :return: A new MediaItem of type 'video' or 'audio' (despite the method's name). :rtype: MediaItem|None """ Logger.trace(result_set) if not result_set.get("available", True): Logger.warning("Item not available: %s", result_set) return None item = self.create_json_episode_item(result_set) if item is None: return None if prepend_serie and 'seriesTitle' in result_set: item.name = "{0} - {1}".format(item.name, result_set['seriesTitle']) elif 'seriesTitle' in result_set: item.name = result_set['seriesTitle'] item.type = "video" # Older URL item.url = "https://embed.kijk.nl/api/video/%(id)s?id=kijkapp&format=DASH&drm=CENC" % result_set # New URL # item.url = "https://embed.kijk.nl/video/%(id)s" % result_set if 'subtitle' in result_set: item.name = "{0} - {1}".format(item.name, result_set['subtitle']) if "date" in result_set: date = result_set["date"].split("+")[0] # 2016-12-25T17:58:00+01:00 time_stamp = DateHelper.get_date_from_string( date, "%Y-%m-%dT%H:%M:%S") item.set_date(*time_stamp[0:6]) return item
def __set_expire_time(self, expire_date, item): """ Parses and sets the correct expire date. :param str expire_date: The expire date value :param MediaItem item: The item to update """ expire_date = expire_date.split("+")[0] # .replace("T", " ") year = expire_date.split("-", 1)[0] if len(year) == 4 and int(year) < datetime.datetime.now().year + 50: expire_date = DateHelper.get_datetime_from_string(expire_date) item.set_expire_datetime(timestamp=expire_date)
def create_video_item(self, result_set): """ Creates a MediaItem of type 'video' using the result_set from the regex. This method creates a new MediaItem from the Regular Expression or Json results <result_set>. The method should be implemented by derived classes and are specific to the channel. If the item is completely processed an no further data needs to be fetched the self.complete property should be set to True. If not set to True, the self.update_video_item method is called if the item is focussed or selected for playback. :param dict[str,str|dict] result_set: The result_set of the self.episodeItemRegex :return: A new MediaItem of type 'video' or 'audio' (despite the method's name). :rtype: MediaItem|None """ Logger.trace(result_set) title = result_set["title"] if title is None: Logger.warning("Found item with all <null> items. Skipping") return None if "subtitle" in result_set and result_set['subtitle'].lower( ) not in title.lower(): title = "%(title)s - %(subtitle)s" % result_set url = "http://m.schooltv.nl/api/v1/afleveringen/%(mid)s.json" % result_set item = MediaItem(title, url) item.description = result_set.get("description", "") age_groups = result_set.get('ageGroups', ['Onbekend']) item.description = "%s\n\nLeeftijden: %s" % (item.description, ", ".join(age_groups)) item.thumb = result_set.get("image", "") item.icon = self.icon item.type = 'video' item.fanart = self.fanart item.complete = False item.set_info_label("duration", result_set['duration']) if "publicationDate" in result_set: broadcast_date = DateHelper.get_date_from_posix( int(result_set['publicationDate'])) item.set_date(broadcast_date.year, broadcast_date.month, broadcast_date.day, broadcast_date.hour, broadcast_date.minute, broadcast_date.second) return item
def create_json_video_item(self, result_set): """ Creates a MediaItem of type 'video' using the result_set from the regex. This method creates a new MediaItem from the Regular Expression or Json results <result_set>. The method should be implemented by derived classes and are specific to the channel. If the item is completely processed an no further data needs to be fetched the self.complete property should be set to True. If not set to True, the self.update_video_item method is called if the item is focussed or selected for playback. :param dict[str,str|None] result_set: The result_set of the self.episodeItemRegex :return: A new MediaItem of type 'video' or 'audio' (despite the method's name). :rtype: MediaItem|None """ Logger.trace(result_set) url = result_set["url"] if not url.startswith("http"): url = "{}{}".format(self.baseUrl, url) title = result_set["title"] item = MediaItem(title, url) item.description = result_set.get("synopsis", None) item.thumb = result_set.get("photo", self.noImage) item.type = "video" if "publicationTimeString" in result_set: try: # publicationTimeString=7 jun 2018 17:20 uur date_parts = result_set["publicationTimeString"].split(" ") day = int(date_parts[0]) month = DateHelper.get_month_from_name(date_parts[1], language="nl", short=True) year = int(date_parts[2]) hours, minutes = date_parts[3].split(":") hours = int(hours) minutes = int(minutes) item.set_date(year, month, day, hours, minutes, 0) except: Logger.warning("Error parsing date %s", result_set["publicationTimeString"], exc_info=True) item.complete = False return item
def __set_expire_time(self, expire_date, item): """ Sets the expire time :param str expire_date: :param MediaItem item: """ try: if expire_date.endswith("z"): valid_to = DateHelper.get_datetime_from_string( expire_date, "%Y-%m-%dT%H:%M:%SZ", "UTC") valid_to = valid_to.astimezone(self.__timezone) item.set_expire_datetime(timestamp=valid_to) else: expire_date = expire_date.split("+")[0].replace("T", " ") year = expire_date.split("-")[0] if len(year) == 4 and int( year) < datetime.datetime.now().year + 50: expire_date = DateHelper.get_datetime_from_string( expire_date, date_format="%Y-%m-%d %H:%M:%S") item.set_expire_datetime(timestamp=expire_date) except: Logger.warning("Error setting expire date from: %s", expire_date)
def create_epg_item(self, result_set): """ Creates a MediaItem of type 'video' using the result_set from the regex. This method creates a new MediaItem from the Regular Expression or Json results <result_set>. The method should be implemented by derived classes and are specific to the channel. If the item is completely processed an no further data needs to be fetched the self.complete property should be set to True. If not set to True, the self.update_video_item method is called if the item is focussed or selected for playback. :param dict[str,] result_set: The result_set of the self.episodeItemRegex :return: A new MediaItem of type 'video' or 'audio' (despite the method's name). :rtype: MediaItem|None """ if "video_node" not in result_set: return None # Could be: title = result_set['episodeTitle'] program_title = result_set['program_title'] episode_title = result_set['episode_title'] time_value = result_set["time_string"] if episode_title: title = "{}: {} - {}".format(time_value, program_title, episode_title) else: title = "{}: {}".format(time_value, program_title) video_info = result_set["video_node"] url = "{}{}".format(self.baseUrl, video_info["url"]) item = MediaItem(title, url) item.type = "video" item.description = video_info["description"] item.thumb = video_info["image"] item.isGeoLocked = result_set.get("isProtected") item.set_info_label("duration", video_info["duration"]) # 2021-01-27 time_stamp = DateHelper.get_date_from_string(result_set["date_string"], date_format="%Y-%m-%d") item.set_date(*time_stamp[0:6]) item.set_info_label("duration", result_set["duration"]) if "episode_nr" in result_set and "season" in result_set and "-" not in result_set["season"]: item.set_season_info(result_set["season"], result_set["episode_nr"]) return item
def create_json_video(self, result_set): """ Creates a MediaItem of type 'video' using the result_set from the regex. This method creates a new MediaItem from the Regular Expression or Json results <result_set>. The method should be implemented by derived classes and are specific to the channel. If the item is completely processed an no further data needs to be fetched the self.complete property should be set to True. If not set to True, the self.update_video_item method is called if the item is focussed or selected for playback. :param dict[str,any|None] result_set: The result_set of the self.episodeItemRegex :return: A new MediaItem of type 'video' or 'audio' (despite the method's name). :rtype: MediaItem|None """ video_id = result_set['id'] # Categories to use # category = result_set["maincategory"].title() # subcategory = result_set["subcategory"].title() url = "https://api.nos.nl/mobile/video/%s/phone.json" % (video_id, ) item = MediaItem(result_set['title'], url, type="video") item.icon = self.icon if 'image' in result_set: images = result_set['image']["formats"] matched_image = images[-1] for image in images: if image["width"] >= 720: matched_image = image break item.thumb = matched_image["url"].values()[0] item.description = result_set["description"] item.complete = False item.isGeoLocked = result_set.get("geoprotection", False) # set the date and time date = result_set["published_at"] time_stamp = DateHelper.get_date_from_string( date, date_format="%Y-%m-%dT%H:%M:%S+{0}".format(date[-4:])) item.set_date(*time_stamp[0:6]) return item
def create_video_item_json(self, result_set): """ Creates a MediaItem of type 'video' using the result_set from the regex. This method creates a new MediaItem from the Regular Expression or Json results <result_set>. The method should be implemented by derived classes and are specific to the channel. If the item is completely processed an no further data needs to be fetched the self.complete property should be set to True. If not set to True, the self.update_video_item method is called if the item is focussed or selected for playback. :param dict result_set: The result_set of the self.episodeItemRegex :return: A new MediaItem of type 'video' or 'audio' (despite the method's name). :rtype: MediaItem|None """ Logger.trace(result_set) image_data = result_set.get("media", []) thumb = None url = None for image in image_data: thumb = image.get("imageHigh", image["image"]) url = image.get("url") item = MediaItem(result_set["title"], url) item.type = "video" item.icon = self.icon item.thumb = thumb or self.noImage item.complete = True item.description = result_set.get("text") part = item.create_new_empty_media_part() M3u8.update_part_with_m3u8_streams(part, url, proxy=self.proxy, channel=self) # Let's not do the time now time_stamp = result_set["created"] date_time = DateHelper.get_date_from_posix(time_stamp) item.set_date(date_time.year, date_time.month, date_time.day, date_time.hour, date_time.minute, date_time.second) return item