def create_episode_item(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[str,str|dict] result_set: The result_set of the self.episodeItemRegex :return: A new MediaItem of type 'folder'. :rtype: MediaItem|None """ Logger.trace(result_set) url = "http://m.schooltv.nl/api/v1/programmas/%s/afleveringen.json?size=%s&sort=Nieuwste" % ( result_set['mid'], self.__PageSize) item = MediaItem(result_set['title'], url) item.thumb = result_set.get('image', self.noImage) item.icon = self.icon item.description = result_set.get('description', None) age_groups = result_set.get('ageGroups', ['Onbekend']) item.description = "%s\n\nLeeftijden: %s" % (item.description, ", ".join(age_groups)) return item
def create_episode_item(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[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) title = result_set["title"] description = result_set.get("description", "") description_nl = result_set.get("introduction_lan1", "") thumb = result_set["image_full"] url = "https://www.24classics.com/app/core/server_load.php?" \ "r=default&page=luister&serial=&subserial=&hook=%s" % (result_set["hook"],) item = MediaItem(title, url) item.icon = self.icon item.thumb = thumb item.description = "%s\n\n%s" % (description_nl, description) item.description = item.description.strip() item.complete = True return item
def create_movie(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) movie_id = result_set['id'] url = "%s/movies/%s" % (self.baseUrl, movie_id) item = MediaItem(result_set["name"], url) item.icon = self.icon item.thumb = result_set["thumb"].replace("nocropthumb/[format]/", "") item.complete = True item.HttpHeaders = self.httpHeaders if self.scheduleData: Logger.debug("Adding schedule data") schedule_data = [s for s in self.scheduleData if s['movieId'] == movie_id] schedule = "" day = "" for s in schedule_data: start = s['start'] day, start = start.split("T") hour, minute, ignore = start.split(":", 2) start = "%s:%s" % (hour, minute) end = s['end'] ignore, end = end.split("T") hour, minute, ignore = end.split(":", 2) end = "%s:%s" % (hour, minute) schedule = "%s%s-%s, " % (schedule, start, end) item.description = "%s\n\n%s: %s" % (item.description, day, schedule.strip(', ')) item.description = "%s\n\n%s" % (item.description, result_set.get('teaser', "")) if not item.description.endswith('.'): item.description = "%s." % (item.description, ) if "releaseDate" in result_set: item.description = "%s\n\nRelease datum: %s" % (item.description, result_set["releaseDate"]) # Dates? # date = result_set.get('releaseDate', None) # if date is not None: # year, month, day = date.split("-") # item.set_date(year, month, day) item.description = item.description.strip() 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) 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_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 """ # 0 1 2 3 #<a class="item" href="([^"]+)"[^=]+="([^"]+)" alt="([^"]+)[^:]+<div class="date">([^<]+) item = MediaItem(result_set[2], result_set[0], type='video') item.icon = self.icon item.description = result_set[2] item.thumb = result_set[1] try: month = datehelper.DateHelper.get_month_from_name(result_set[4], "nl") item.set_date(result_set[5], month, result_set[3], result_set[6], result_set[7], 0) except: Logger.error("Error matching month: %s", result_set[4].lower(), exc_info=True) item.complete = False return item
def create_episode_item(self, result_set, append_subtitle=True): """ 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 :param bool append_subtitle: Should we append a subtitle? :return: A new MediaItem of type 'folder'. :rtype: MediaItem|None """ Logger.trace(result_set) url = result_set['href'] if not url.startswith("http"): url = "{}{}".format(self.baseUrl, url) title = result_set["title"] if title is None: title = self.parentItem.name elif append_subtitle and "subtitle" in result_set: title = "{} - {}".format(title, result_set["subtitle"]) item = MediaItem(title, url) item.description = result_set.get('synopsis', item.description) image_template = result_set.get("imageTemplate") item.fanart = image_template.replace("{recipe}", "1920x1080") item.thumb = image_template.replace("{recipe}", "608x342") return item
def create_episode_item_new(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 """ Logger.trace(result_set) url = "http://il.srgssr.ch/integrationlayer/1.0/ue/srf/assetSet/listByAssetGroup/%s.json?pageSize=100" % ( result_set["id"], ) item = MediaItem(result_set["title"], url) item.description = result_set.get("description", "") item.icon = self.icon item.httpHeaders = self.httpHeaders item.thumb = self.__get_nested_value(result_set, "Image", "ImageRepresentations", "ImageRepresentation", 0, "url") item.complete = True 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 """ # Logger.Trace(resultSet) title = result_set["title"] url = "%s/%s" % (self.baseUrl, result_set["url"]) thumb = "https://assets.ur.se/id/%(id)s/images/1_l.jpg" % result_set item = MediaItem(title, url) item.type = "video" item.thumb = thumb item.description = result_set["description"] item.fanart = self.parentItem.fanart item.icon = self.icon item.complete = False self.__videoItemFound = True return item
def create_json_tag_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 result_set: The result_set of the self.episodeItemRegex :return: A new MediaItem of type 'folder'. :rtype: MediaItem|None """ Logger.trace(result_set) url = "https://www.svtplay.se/api/cluster_titles_and_episodes?cluster={}".format( result_set['slug']) genre = MediaItem(result_set['name'], url) genre.icon = self.icon genre.description = result_set.get('description') genre.fanart = result_set.get( 'backgroundImage') or self.parentItem.fanart genre.fanart = self.__get_thumb(genre.fanart, thumb_size="/extralarge/") genre.thumb = result_set.get('thumbnailImage') or self.noImage genre.thumb = self.__get_thumb(genre.thumb) return genre
def create_json_genre(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 result_set: The result_set of the self.episodeItemRegex :return: A new MediaItem of type 'folder'. :rtype: MediaItem|None """ genres = [] for cluster in result_set['clusters']: Logger.trace(cluster) url = "%s%s" % (self.baseUrl, cluster['contentUrl']) genre = MediaItem(cluster['name'], url) genre.icon = self.icon genre.description = cluster.get('description') genre.fanart = cluster.get( 'backgroundImage') or self.parentItem.fanart genre.fanart = self.__get_thumb(genre.fanart, thumb_size="/extralarge/") genre.thumb = cluster.get('thumbnailImage') or self.noImage genre.thumb = self.__get_thumb(genre.thumb) genres.append(genre) return genres
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): """ 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.icon = self.icon item.thumb = self.noImage 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_single_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 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 self.__hasAlreadyVideoItems: # we already have items, so don't show this one, it will be a duplicate return None result_set = result_set.replace('\\x27', "'") json_data = JsonHelper(result_set) url = self.parentItem.url title = json_data.get_value("name") description = HtmlHelper.to_text(json_data.get_value("description")) item = MediaItem(title, url, type="video") item.description = description item.thumb = self.parentItem.thumb item.fanart = self.parentItem.fanart return item
def create_music_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 """ Logger.trace(result_set) title = "%(composers)s - %(title)s" % result_set url = "https://www.24classics.com/app/ajax/auth.php?serial=%(serial)s" % result_set item = MediaItem(title, url) item.icon = self.icon item.type = "video" # seems to not really work well with track numbers (not showing) # item.type = "audio" item.thumb = self.parentItem.thumb item.complete = False item.description = "Composers: %(composers)s\nPerformers: %(performers)s" % result_set item.set_info_label("TrackNumber", result_set["order"]) item.set_info_label("AlbumArtist", result_set["composers"].split(",")) item.set_info_label("Artist", result_set["performers"].split(",")) return item
def create_json_episode_item(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 result_set: The result_set of the self.episodeItemRegex :return: A new MediaItem of type 'folder'. :rtype: MediaItem|None """ Logger.trace(result_set) if "titleArticleId" in result_set: return None url = "%s%s" % (self.baseUrl, result_set['contentUrl'],) if "/video/" in url: return None item = MediaItem(result_set['programTitle'], url) item.icon = self.icon item.isGeoLocked = result_set.get('onlyAvailableInSweden', False) item.description = result_set.get('description') thumb = self.noImage if "poster" in result_set: thumb = result_set["poster"] thumb = self.__get_thumb(thumb or self.noImage) item.thumb = thumb return item
def create_episode_item(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 """ Logger.trace(result_set) url = "http://il.srgssr.ch/integrationlayer/1.0/ue/srf/assetSet/listByAssetGroup/%s.json" % ( result_set["id"], ) item = MediaItem(result_set["title"], url) item.description = result_set.get("description", "") item.icon = self.icon item.httpHeaders = self.httpHeaders # the 0005 seems to be a quality thing: 0001, 0003, 0004, 0005 # http://www.srf.ch/webservice/picture/videogroup/c60026b7-2ed0-0001-b4b1-1f801a6355d0/0005 # http://www.srfcdn.ch/piccache/vis/videogroup/c6/00/c60026b7-2ed0-0001-b4b1-1f801a6355d0_0005_w_h_m.jpg # item.thumb = "http://www.srf.ch/webservice/picture/videogroup/%s/0005" % (resultSet["id"],) item.thumb = "http://www.srfcdn.ch/piccache/vis/videogroup/%s/%s/%s_0005_w_h_m.jpg" \ % (result_set["id"][0:2], result_set["id"][2:4], result_set["id"],) # item.thumb = resultSet.get("thumbUrl", None) # item.thumb = "%s/scale/width/288" % (item.thumb, ) # apparently only the 144 return the correct HEAD info # item.fanart = resultSet.get("imageUrl", None) $# the HEAD will not return a size, so Kodi can't handle it item.complete = True return item
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["channelName"] description = channel.get("description") channel_id = channel["channel"].lower() if channel_id == "svtbarn": channel_id = "barnkanalen" 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 "titlePageThumbnailIds" in channel and channel[ "titlePageThumbnailIds"]: channel_item.thumb = "https://www.svtstatic.se/image/wide/650/%s.jpg" % ( channel["titlePageThumbnailIds"][0], ) return channel_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 create_json_genre_item(self, result_set): """ Creates a MediaItem of type 'folder/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. :param list[str]|dict result_set: The result_set of the self.episodeItemRegex :return: A new MediaItem of type 'folder'. :rtype: MediaItem|None """ if "__typename" not in result_set: return None item_type = result_set["__typename"].lower() if item_type not in ("episode", "single", "clip", "tvseries") or "name" not in result_set: return None Logger.trace("%s->%s", item_type, result_set) title = result_set["name"] if item_type == 'episode' and "parent" in result_set: # noinspection PyTypeChecker parent_data = self.__apollo_data[result_set["parent"]["id"]] parent_title = parent_data["name"] title = "{} - {}".format(parent_title, title) if item_type == "clip": url = "https://www.svtplay.se/klipp/{}/".format(result_set["id"]) elif "urls" in result_set: # noinspection PyTypeChecker url_data = self.__apollo_data[result_set["urls"]["id"]] url = url_data["svtplay"] url = "{}{}".format(self.baseUrl, url) else: Logger.debug("No url found for: %s", title) return None item = MediaItem(title, url) item.description = result_set.get("longDescription") item.fanart = self.parentItem.fanart item.type = "video" if item_type != "tvseries" else "folder" if "image" in result_set: # noinspection PyTypeChecker image = result_set["image"]["id"] image_data = self.__apollo_data[image] image_url = "https://www.svtstatic.se/image/medium/520/{id}/{changed}".format(**image_data) item.thumb = image_url if "restrictions" in result_set: # noinspection PyTypeChecker restrictions = self.__apollo_data[result_set["restrictions"]["id"]] item.isGeoLocked = restrictions.get('onlyAvailableInSweden', False) return item
def StievieCreateEpgItems(self, epg): Logger.Trace(epg) Logger.Debug("Processing EPG for channel %s", epg["id"]) items = [] summerTime = time.localtime().tm_isdst now = datetime.datetime.now() for resultSet in epg["items"]: # if not resultSet["parentSeriesOID"]: # continue # Does not always work # videoId = resultSet["epgId"].replace("-", "_") # url = "https://vod.medialaan.io/vod/v2/videos/%s_Stievie_free" % (videoId, ) videoId = resultSet["programOID"] url = "https://vod.medialaan.io/vod/v2/videos?episodeIds=%s&limit=10&offset=0&sort=broadcastDate&sortDirection=asc" % (videoId, ) title = resultSet["title"] if resultSet["episode"] and resultSet["season"]: title = "%s - s%02de%02d" % (title, resultSet["season"], resultSet["episode"]) if "startTime" in resultSet and resultSet["startTime"]: dateTime = resultSet["startTime"] dateValue = DateHelper.GetDateFromString(dateTime, dateFormat="%Y-%m-%dT%H:%M:%S.000Z") # Convert to Belgium posix time stamp dateValue2 = time.mktime(dateValue) + (1 + summerTime) * 60 * 60 # Conver the posix to a time stamp startTime = DateHelper.GetDateFromPosix(dateValue2) title = "%02d:%02d - %s" % (startTime.hour, startTime.minute, title) # Check for items in their black-out period if "blackout" in resultSet and resultSet["blackout"]["enabled"]: blackoutDuration = resultSet["blackout"]["duration"] blackoutStart = startTime + datetime.timedelta(seconds=blackoutDuration) if blackoutStart < now: Logger.Debug("Found item in Black-out period: %s (started at %s)", title, blackoutStart) continue # else: # startTime = self.parentItem.metaData["airDate"] item = MediaItem(title, url) item.type = "video" item.isGeoLocked = resultSet["geoblock"] item.description = resultSet["shortDescription"] # item.SetDate(startTime.year, startTime.month, startTime.day) if "images" in resultSet and resultSet["images"] and "styles" in resultSet["images"][0]: images = resultSet["images"][0]["styles"] # if "1520x855" in images: # item.fanart = images["1520x855"] if "400x225" in images: item.thumb = images["400x225"] items.append(item) return items
def create_series_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 """ title = result_set["title"] sub_title = result_set.get("episodeTitle", None) if sub_title: title = "{} - {}".format(title, sub_title) if not result_set["usageRights"].get("hasRightsNow", True): Logger.debug("Found '%s' without 'usageRights'", title) return None url = "https://psapi.nrk.no/programs/{}?apiKey={}".format( result_set["id"], self.__api_key) item = MediaItem(title, url) item.type = 'video' # noinspection PyTypeChecker item.thumb = self.__get_image(result_set["image"]["webImages"], "pixelWidth", "imageUrl") item.description = result_set.get("longDescription", "") if not item.description: item.description = result_set.get("shortDescription", "") item.isGeoLocked = result_set.get("usageRights", {}).get("isGeoBlocked", False) self.__set_date(result_set, item) 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_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 """ # Logger.Trace(result_set) xml_data = XmlHelper(result_set) title = xml_data.get_single_node_content("title") url = xml_data.get_single_node_content("link") description = xml_data.get_single_node_content("description") description = description.replace("<![CDATA[ ", "").replace("]]>", "").replace( "<p>", "").replace("</p>", "\n") item = MediaItem(title, url) item.type = 'video' item.complete = False item.description = description item.thumb = self.noImage item.icon = self.icon date = xml_data.get_single_node_content("pubDate") date_result = Regexer.do_regex(r"\w+, (\d+) (\w+) (\d+)", date)[-1] day = date_result[0] month_part = date_result[1].lower() year = date_result[2] try: month_lookup = [ "jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec" ] month = month_lookup.index(month_part) + 1 item.set_date(year, month, day) except: Logger.error("Error matching month: %s", result_set[4].lower(), exc_info=True) 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 """ Logger.trace(result_set) # Validate the input and raise errors if not isinstance(result_set, dict): Logger.critical( "No Dictionary as a result_set. Implement a custom create_video_item" ) raise NotImplementedError( "No Dictionary as a result_set. Implement a custom create_video_item" ) elif "title" not in result_set or "url" not in result_set: Logger.warning("No ?P<title> or ?P<url> in result_set") raise LookupError("No ?P<title> or ?P<url> in result_set") # The URL url = self._prefix_urls(result_set["url"]) # The title if "subtitle" in result_set and result_set["subtitle"]: # noinspection PyStringFormat title = "%(title)s - %(subtitle)s" % result_set else: title = result_set["title"] if title.isupper(): title = title.title() item = MediaItem(title, url) item.thumb = self._prefix_urls(result_set.get("thumburl", "")) item.description = result_set.get("description", "") item.icon = self.icon item.type = 'video' item.fanart = self.fanart item.HttpHeaders = self.httpHeaders item.complete = False 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.thumb = self.noImage 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.thumb = self.noImage 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_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 CreateEpisodeItemJson(self, resultSet): """Creates a new MediaItem for an episode Arguments: resultSet : list[string] - the resultSet of the self.episodeItemRegex Returns: A new MediaItem of type 'folder' This method creates a new MediaItem from the Regular Expression or Json results <resultSet>. The method should be implemented by derived classes and are specific to the channel. """ Logger.Trace(resultSet) title = resultSet['title'] if resultSet["parent_series_oid"] is None: return None # if not resultSet["is_featured"]: # # most of them are empty anyways # return None # if resultSet.get("archived", False): # return None url = "https://vod.medialaan.io/api/1.0/list?" \ "app_id=%s&parentSeriesOID=%s" % (self.__app, resultSet['parent_series_oid']) item = MediaItem(title, url) item.fanart = self.fanart item.thumb = self.noImage item.description = resultSet.get('body', None) if item.description: # Clean HTML item.description = item.description.replace("<br />", "\n\n") item.description = self.__cleanRegex.sub("", item.description) if 'images' in resultSet and 'image' in resultSet['images']: item.thumb = resultSet['images']['image'].get('full', self.noImage) 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 """ Logger.trace(result_set) url = "%s%s" % (self.baseUrl, result_set["url"]) if self.parentItem.url not in url: return None name = result_set["title"] desc = result_set.get("description", "") thumb = result_set["thumburl"] if thumb and not thumb.startswith("http://"): thumb = "%s%s" % (self.baseUrl, thumb) item = MediaItem(name, url) item.thumb = thumb item.description = desc item.icon = self.icon item.type = 'video' item.complete = False try: name_parts = name.rsplit("/", 3) if len(name_parts) == 3: Logger.debug("Found possible date in name: %s", name_parts) year = name_parts[2] if len(year) == 2: year = 2000 + int(year) month = name_parts[1] day = name_parts[0].rsplit(" ", 1)[1] Logger.trace("%s - %s - %s", year, month, day) item.set_date(year, month, day) except: Logger.warning("Apparently it was not a date :)") return item
def __ShowEmptyInformation(self, items, favs=False): """ Adds an empty item to a list or just shows a message. @type favs: boolean indicating that we are dealing with favourites @param items: the list of items @rtype : boolean indicating succes or not """ if self.channelObject: Statistics.RegisterError(self.channelObject) if favs: title = LanguageHelper.GetLocalizedString(LanguageHelper.NoFavsId) else: title = LanguageHelper.GetLocalizedString(LanguageHelper.ErrorNoEpisodes) behaviour = AddonSettings.GetEmptyListBehaviour() Logger.Debug("Showing empty info for mode (favs=%s): [%s]", favs, behaviour) if behaviour == "error": # show error ok = False elif behaviour == "dummy" and not favs: # We should add a dummy items, but not for favs emptyListItem = MediaItem("- %s -" % (title.strip("."), ), "", type='video') emptyListItem.icon = self.channelObject.icon emptyListItem.thumb = self.channelObject.noImage emptyListItem.fanart = self.channelObject.fanart emptyListItem.dontGroup = True emptyListItem.description = "This listing was left empty intentionally." emptyListItem.complete = True emptyListItem.fanart = self.channelObject.fanart # add funny stream here? # part = emptyListItem.CreateNewEmptyMediaPart() # for s, b in YouTube.GetStreamsFromYouTube("", self.channelObject.proxy): # part.AppendMediaStream(s, b) # if we add one, set OK to True ok = True items.append(emptyListItem) else: ok = True XbmcWrapper.ShowNotification(LanguageHelper.GetLocalizedString(LanguageHelper.ErrorId), title, XbmcWrapper.Error, 2500) return ok