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 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 CreateVideoItem(self, resultSet): """Creates a MediaItem of type 'video' using the resultSet from the regex. Arguments: resultSet : tuple (string) - the resultSet of the self.videoItemRegex Returns: A new MediaItem of type 'video' or 'audio' (despite the method's name) 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. 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.UpdateVideoItem method is called if the item is focussed or selected for playback. """ Logger.Trace(resultSet) title = resultSet["title"] if title is None: Logger.Warning("Found item with all <null> items. Skipping") return None if "subtitle" in resultSet and resultSet['subtitle'].lower( ) not in title.lower(): title = "%(title)s - %(subtitle)s" % resultSet url = "http://m.schooltv.nl/api/v1/afleveringen/%(mid)s.json" % resultSet item = mediaitem.MediaItem(title, url) item.description = resultSet.get("description", "") ageGroups = resultSet.get('ageGroups', ['Onbekend']) item.description = "%s\n\nLeeftijden: %s" % (item.description, ", ".join(ageGroups)) item.thumb = resultSet.get("image", "") item.icon = self.icon item.type = 'video' item.fanart = self.fanart item.complete = False item.SetInfoLabel("duration", resultSet['duration']) if "publicationDate" in resultSet: broadcastDate = DateHelper.GetDateFromPosix( int(resultSet['publicationDate'])) item.SetDate(broadcastDate.year, broadcastDate.month, broadcastDate.day, broadcastDate.hour, broadcastDate.minute, broadcastDate.second) 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 CreateVideoItemNonMobile(self, resultSet): """Creates a MediaItem of type 'video' using the resultSet from the regex. Arguments: resultSet : tuple (string) - the resultSet of the self.videoItemRegex Returns: A new MediaItem of type 'video' or 'audio' (despite the method's name) 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. 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.UpdateVideoItem method is called if the item is focussed or selected for playback. """ Logger.Trace(resultSet) name = resultSet["Title"].strip() videoId = resultSet["WhatsOnId"] description = resultSet["Description"] item = mediaitem.MediaItem(name, videoId) item.icon = self.icon item.type = 'video' item.complete = False item.description = description item.thumb = resultSet["Image"].replace("s174/c174x98", "s348/c348x196") if item.thumb.startswith("//"): item.thumb = self.noImage if "Premium" in resultSet and resultSet["Premium"]: item.isPaid = True try: if "Year" in resultSet: year = resultSet["Year"] if "MonthName" in resultSet: month = DateHelper.GetMonthFromName(resultSet["MonthName"], "nl") else: month = resultSet["Month"] day = resultSet["Day"] hour = resultSet.get("Hour", "0") minute = resultSet.get("Minutes", "0") item.SetDate(year, month, day, hour, minute, 0) except: Logger.Warning("Could not set date", exc_info=True) return item
def CreateVideoItem(self, resultSet): """Creates a MediaItem of type 'video' using the resultSet from the regex. Arguments: resultSet : tuple (string) - the resultSet of the self.videoItemRegex Returns: A new MediaItem of type 'video' or 'audio' (despite the method's name) 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. 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.UpdateVideoItem method is called if the item is focussed or selected for playback. """ Logger.Trace(resultSet) thumbUrl = resultSet[0] episodeUrl = resultSet[1] if not episodeUrl.startswith("http"): episodeUrl = "%s%s" % (self.baseUrl, episodeUrl) episodeId = resultSet[2] programTitle = resultSet[3] episodeTitle = resultSet[4] day = resultSet[5] month = resultSet[6] month = DateHelper.GetMonthFromName(month, language="en") year = resultSet[7] hour = resultSet[8] minute = resultSet[9] title = episodeTitle if programTitle: title = "%s - %s" % (programTitle, episodeTitle) url = "http://www.538.nl/static/VdaGemistBundle/Feed/xml/idGemist/%s|%s" % (episodeId, episodeUrl) item = mediaitem.MediaItem(title, url) item.type = 'video' item.SetDate(year, month, day, hour, minute, 0) item.description = episodeTitle item.thumb = thumbUrl item.icon = self.icon item.complete = False 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 CreateVideoItem(self, resultSet): """Creates a MediaItem of type 'video' using the resultSet from the regex. Arguments: resultSet : tuple (string) - the resultSet of the self.videoItemRegex Returns: A new MediaItem of type 'video' or 'audio' (despite the method's name) 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. 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.UpdateVideoItem method is called if the item is focussed or selected for playback. """ Logger.Trace(resultSet) # vid = resultSet[1] thumbUrl = resultSet[2] title = resultSet[3].strip() if "http" not in thumbUrl: thumbUrl = "%s%s" % (self.baseUrl, thumbUrl) url = "%s/%s" % (self.baseUrl, resultSet[0]) item = mediaitem.MediaItem(title, url) item.thumb = thumbUrl item.icon = self.icon item.type = 'video' item.complete = False # try to parse a date (for Journaal) try: dateParts = resultSet[0].split("/")[-1].split("+") Logger.Trace(dateParts) day = dateParts[1] monthName = dateParts[2] year = dateParts[3] month = DateHelper.GetMonthFromName(monthName, "nl") hour = dateParts[5][:2] minutes = dateParts[5][-2:] item.SetDate(year, month, day, hour, minutes, 0) except: Logger.Warning("Error parsing date", exc_info=True) return item
def CreateJsonVideo(self, resultSet): """Creates a MediaItem of type 'video' using the resultSet from the regex. Arguments: resultSet : tuple (string) - the resultSet of the self.videoItemRegex Returns: A new MediaItem of type 'video' or 'audio' (despite the method's name) 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. 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.UpdateVideoItem method is called if the item is focussed or selected for playback. """ # Logger.Trace(JsonHelper.DictionaryToString(resultSet)) videoId = resultSet['id'] # category = resultSet["maincategory"].title() # subcategory = resultSet["subcategory"].title() url = "https://api.nos.nl/mobile/video/%s/phone.json" % (videoId, ) item = mediaitem.MediaItem(resultSet['title'], url, type="video") item.icon = self.icon if 'image' in resultSet: images = resultSet['image']["formats"] matchedImage = images[-1] for image in images: if image["width"] >= 720: matchedImage = image break item.thumb = matchedImage["url"].values()[0] item.description = resultSet["description"] item.complete = False item.isGeoLocked = resultSet.get("geoprotection", False) # set the date and time date = resultSet["published_at"] timeStamp = DateHelper.GetDateFromString( date, dateFormat="%Y-%m-%dT%H:%M:%S+{0}".format(date[-4:])) item.SetDate(*timeStamp[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
def CreateProgramFolder(self, resultSet): """Creates a MediaItem of type 'folder' using the resultSet from the regex. Arguments: resultSet : tuple(strig) - the resultSet of the self.folderItemRegex 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"] seriesId = resultSet.get("seriesId") if seriesId is None: return None categoryId = resultSet.get("categoryId", None) parentCategoryId = self.parentItem.metaData.get(self.__metaDataIndexCategory, None) if parentCategoryId is not None and parentCategoryId != categoryId: return None item = mediaitem.MediaItem(title, "%s/series/%s" % (self.baseUrl, seriesId)) item.icon = self.icon item.type = 'folder' item.fanart = self.fanart item.description = resultSet.get("description", "") item.HttpHeaders = self.httpHeaders imageId = resultSet.get("seriesImageId", None) if imageId is not None: item.thumb = "http://m.nrk.no/img?kaleidoId=%s&width=720" % (imageId, ) item.fanart = "http://m.nrk.no/img?kaleidoId=%s&width=1280" % (imageId, ) if "usageRights" in resultSet: item.isGeoLocked = resultSet["usageRights"].get("geoblocked", False) if "availableFrom" in resultSet["usageRights"]: timeStamp = int(resultSet["usageRights"]["availableFrom"]) / 1000 if 0 < timeStamp < sys.maxint: date = DateHelper.GetDateFromPosix(timeStamp) item.SetDate(date.year, date.month, date.day, date.hour, date.minute, date.second) 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 CreateVideoItemJson(self, resultSet): Logger.Trace(resultSet) title = resultSet['title'] url = "https://vod.medialaan.io/vod/v2/videos/%(id)s" % resultSet item = MediaItem(title, url, type="video") item.description = resultSet.get('text') item.thumb = self.parentItem.thumb if 'image' in resultSet: item.thumb = resultSet['image'].get("full", None) created = DateHelper.GetDateFromPosix(resultSet['created']) item.SetDate(created.year, created.month, created.day, created.hour, created.minute, created.second) return item
def CreateLiveChannel(self, resultSet): Logger.Trace(resultSet) item = mediaitem.MediaItem(resultSet[0], resultSet[1]) item.type = "video" item.isGeoLocked = resultSet[3].lower() == "true" dateTime = DateHelper.GetDateFromPosix(int(resultSet[2]) * 1 / 1000) item.SetDate(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute, dateTime.second) thumb = resultSet[4] if not thumb.startswith("http"): thumb = "%s%s" % (self.baseUrl, thumb) item.thumb = thumb return item
def CreateVideoItem(self, resultSet): Logger.Trace(resultSet) title = resultSet["title"] if "subTitle" in resultSet: title = "%s - %s" % (title, resultSet["subTitle"]) mgid = resultSet["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.MediaItem(title, url) item.type = "video" item.icon = self.icon item.description = resultSet.get("description", None) item.thumb = self.parentItem.thumb item.fanart = self.parentItem.fanart item.isGeoLocked = True images = resultSet.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 = resultSet.get("originalAirDate", None) if not date: date = resultSet.get("originalPublishDate", None) if date: timeStamp = date["timestamp"] dateTime = DateHelper.GetDateFromPosix(timeStamp) item.SetDate(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute, dateTime.second) return item
def CreateVideoItem(self, resultSet): """Creates a MediaItem of type 'video' using the resultSet from the regex. Arguments: resultSet : tuple (string) - the resultSet of the self.videoItemRegex Returns: A new MediaItem of type 'video' or 'audio' (despite the method's name) 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. 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.UpdateVideoItem method is called if the item is focussed or selected for playback. """ Logger.Trace(resultSet) # vid = resultSet[1] thumbUrl = resultSet[2] title = resultSet[3].strip() if "http" not in thumbUrl: thumbUrl = "%s%s" % (self.baseUrl, thumbUrl) url = "%s/%s" % (self.baseUrl, resultSet[0]) item = mediaitem.MediaItem(title, url) item.thumb = thumbUrl item.icon = self.icon item.type = 'video' item.complete = False day = resultSet[4] month = resultSet[5] month = DateHelper.GetMonthFromName(month, language="nl") year = resultSet[6] hour = resultSet[7] minute = resultSet[8] item.SetDate(year, month, day, hour, minute, 0) return item
def CreateVideoItem(self, resultSet): """Creates a MediaItem of type 'video' using the resultSet from the regex. Arguments: resultSet : tuple (string) - the resultSet of the self.videoItemRegex Returns: A new MediaItem of type 'video' or 'audio' (despite the method's name) 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. 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.UpdateVideoItem method is called if the item is focussed or selected for playback. """ Logger.Trace(resultSet) url = resultSet["url"] if not url.startswith("http"): url = "%s%s" % (self.baseUrl, url) name = resultSet["title"] item = mediaitem.MediaItem(name, url) # item.description = resultSet["description"] item.type = 'video' item.icon = self.icon item.thumb = self.noImage month = resultSet["month"] month = DateHelper.GetMonthFromName(month, "en", False) day = resultSet["day"] year = resultSet["year"] item.SetDate(year, month, day) 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 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) # All of vier.be video's seem GEO locked. item.isGeoLocked = True # Set the correct url # videoId = resultSet["videoid"] # item.url = "https://api.viervijfzes.be/content/%s" % (videoId, ) time_stamp = result_set.get("timestamp") if time_stamp: date_time = DateHelper.get_date_from_posix( int(result_set["timestamp"])) item.set_date(date_time.year, date_time.month, date_time.day, date_time.hour, date_time.minute, date_time.second) if not item.thumb and "thumburl2" in result_set and result_set[ "thumburl2"]: item.thumb = result_set["thumburl2"] if item.thumb and item.thumb != self.noImage: item.thumb = HtmlEntityHelper.strip_amp(item.thumb) 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 item # http://www.rtbf.be/auvio/embed/media?id=2101078&autoplay=1 if "videoId" in result_set: item.url = "%s/auvio/embed/media?id=%s" % (self.baseUrl, result_set["videoId"]) elif "liveId" in result_set: item.name = "%s - %s" % (result_set["channel"].strip(), item.name) item.url = "%s/auvio/embed/direct?id=%s" % (self.baseUrl, result_set["liveId"]) item.isLive = True if "date" in result_set: # 2016-05-14T20:00:00+02:00 -> strip the hours time_stamp = DateHelper.get_date_from_string( result_set["date"].rsplit("+")[0], "%Y-%m-%dT%H:%M:%S") item.set_date(*time_stamp[0:6]) 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 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 "title" not in result_set or result_set["title"] is None: result_set["title"] = result_set.pop("subtitle") result_set["title"] = result_set["title"].strip() item = chn_class.Channel.create_video_item(self, result_set) if item is None: return None item.description = result_set.get("subtitle", None) if "day" in result_set and result_set["day"]: if len(result_set.get("year", "")) < 4: result_set["year"] = None item.set_date(result_set["year"] or DateHelper.this_year(), result_set["month"], result_set["day"]) if item.thumb.startswith("//"): item.thumb = "https:%s" % (item.thumb, ) self.__hasAlreadyVideoItems = True item.fanart = self.parentItem.fanart 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 = result_set["url"] if not url.startswith("http"): url = "%s%s" % (self.baseUrl, url) name = result_set["title"] item = MediaItem(name, url) item.type = 'video' item.icon = self.icon item.thumb = self.noImage month = result_set["month"] month = DateHelper.get_month_from_name(month, "en", False) day = result_set["day"] year = result_set["year"] item.set_date(year, month, day) item.complete = False return item
def CreateVideoItem(self, resultSet): item = chn_class.Channel.CreateVideoItem(self, resultSet) if item is None: return item # http://www.rtbf.be/auvio/embed/media?id=2101078&autoplay=1 if "videoId" in resultSet: item.url = "%s/auvio/embed/media?id=%s" % (self.baseUrl, resultSet["videoId"]) elif "liveId" in resultSet: item.name = "%s - %s" % (resultSet["channel"].strip(), item.name) item.url = "%s/auvio/embed/direct?id=%s" % (self.baseUrl, resultSet["liveId"]) item.isLive = True if "date" in resultSet: # 2016-05-14T20:00:00+02:00 -> strip the hours timeStamp = DateHelper.GetDateFromString( resultSet["date"].rsplit("+")[0], "%Y-%m-%dT%H:%M:%S") item.SetDate(*timeStamp[0:6]) return item
def CreateVideoItem(self, resultSet): resultSet["title"] = resultSet["title"].strip() if "url" not in resultSet: if self.__hasAlreadyVideoItems: Logger.Debug("Found a 'single' item, but we have more. So this is a duplicate") return None # this only happens once with single video folders resultSet["url"] = self.parentItem.url item = chn_class.Channel.CreateVideoItem(self, resultSet) if item is None: return None if "day" in resultSet and resultSet["day"]: item.SetDate(resultSet["year"] or DateHelper.ThisYear(), resultSet["month"], resultSet["day"]) if item.thumb.startswith("//"): item.thumb = "https:%s" % (item.thumb, ) self.__hasAlreadyVideoItems = True item.fanart = self.parentItem.fanart return item
def CreateVideoItem(self, resultSet): """Creates a MediaItem of type 'video' using the resultSet from the regex. Arguments: resultSet : tuple (string) - the resultSet of the self.videoItemRegex Returns: A new MediaItem of type 'video' or 'audio' (despite the method's name) 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. 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.UpdateVideoItem method is called if the item is focussed or selected for playback. """ item = chn_class.Channel.CreateVideoItem(self, resultSet) if "date" in resultSet: day, month, year = resultSet["date"].split("/") item.SetDate(year, month, day) # All of vier.be video's seem GEO locked. item.isGeoLocked = True # Set the correct url # videoId = resultSet["videoid"] # item.url = "https://api.viervijfzes.be/content/%s" % (videoId, ) if "timestamp" in resultSet: dateTime = DateHelper.GetDateFromPosix(int(resultSet["timestamp"])) item.SetDate(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute, dateTime.second) return item
def __set_date(self, result_set, item): if "usageRights" in result_set and "availableFrom" in result_set["usageRights"] \ and result_set["usageRights"]["availableFrom"] is not None: Logger.trace("Using 'usageRights.availableFrom' for date") # availableFrom=/Date(1540612800000+0200)/ epoch_stamp = result_set["usageRights"]["availableFrom"][6:16] available_from = DateHelper.get_date_from_posix(int(epoch_stamp)) item.set_date(available_from.year, available_from.month, available_from.day) elif "episodeNumberOrDate" in result_set and result_set[ "episodeNumberOrDate"] is not None: Logger.trace("Using 'episodeNumberOrDate' for date") date_parts = result_set["episodeNumberOrDate"].split(".") if len(date_parts) == 3: item.set_date(date_parts[2], date_parts[1], date_parts[0]) elif "programUrlMetadata" in result_set and result_set[ "programUrlMetadata"] is not None: Logger.trace("Using 'programUrlMetadata' for date") date_parts = result_set["programUrlMetadata"].split("-") if len(date_parts) == 3: item.set_date(date_parts[2], date_parts[1], date_parts[0]) return
def CreateJsonVideoItem(self, resultSet): Logger.Trace(resultSet) url = "http://playapi.mtgx.tv/v3/videos/stream/%(id)s" % resultSet item = mediaitem.MediaItem(resultSet["title"], url) item.type = "video" item.thumb = self.parentItem.thumb item.icon = self.parentItem.icon item.description = resultSet.get("summary", None) airedAt = resultSet.get("airedAt", None) if airedAt is None: airedAt = resultSet.get("publishedAt", None) if airedAt is not None: # 2016-05-20T15:05:00+00:00 airedAt = airedAt.split("+")[0].rstrip('Z') timeStamp = DateHelper.GetDateFromString(airedAt, "%Y-%m-%dT%H:%M:%S") item.SetDate(*timeStamp[0:6]) item.thumb = self.__GetThumbImage(resultSet.get("image")) # webvttPath / samiPath # loginRequired isPremium = resultSet.get("loginRequired", False) if isPremium and AddonSettings.HidePremiumItems(): Logger.Debug("Found premium item, hiding it.") return None srt = resultSet.get("samiPath") if not srt: srt = resultSet.get("subtitles_webvtt") if srt: Logger.Debug("Storing SRT/WebVTT path: %s", srt) part = item.CreateNewEmptyMediaPart() part.Subtitle = srt 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) item.thumb = self.parentItem.thumb item.fanart = self.parentItem.fanart 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 log_on(self): """ Logs on to a website, using an url. First checks if the channel requires log on. If so and it's not already logged on, it should handle the log on. That part should be implemented by the specific channel. More arguments can be passed on, but must be handled by custom code. After a successful log on the self.loggedOn property is set to True and True is returned. :return: indication if the login was successful. :rtype: bool """ api_key = "3_qhEcPa5JGFROVwu5SWKqJ4mVOIkwlFNMSKwzPDAh8QZOtHqu6L4nD5Q7lk0eXOOG" # Do we still have a valid short living token (1 hour)? If so, we have an active session. short_login_cookie = UriHandler.get_cookie("X-VRT-Token", ".vrt.be") if short_login_cookie is not None: # The old X-VRT-Token expired after 1 year. We don't want that old cookie short_login_cookie_can_live_too_long = \ DateHelper.get_date_from_posix(short_login_cookie.expires) > datetime.datetime.now() + datetime.timedelta(hours=4) if not short_login_cookie_can_live_too_long: Logger.debug("Using existing VRT.be session.") return True # Do we still have a valid long living token? If so, try to extend the session. We need the # original UIDSignature value for that. The 'vrtlogin-rt' and all other related cookies # are valid for a same period (1 year). long_login_cookie = UriHandler.get_cookie("vrtlogin-rt", ".vrt.be") if long_login_cookie is not None: # if we stored a valid user signature, we can use it, together with the 'gmid' and # 'ucid' cookies to extend the session and get new token data data = UriHandler.open("https://token.vrt.be/refreshtoken", proxy=self.proxy, no_cache=True) if "vrtnutoken" in data: Logger.debug("Refreshed the VRT.be session.") return True Logger.warning("Failed to extend the VRT.be session.") username = self._get_setting("username") if not username: Logger.warning("No username configured for VRT.nu") return None v = Vault() password = v.get_channel_setting(self.guid, "password") if not password: Logger.warning("Found empty password for VRT user") # Get a 'gmid' and 'ucid' cookie by logging in. Valid for 10 years Logger.debug("Using: %s / %s", username, "*" * len(password)) url = "https://accounts.vrt.be/accounts.login" data = { "loginID": username, "password": password, "sessionExpiration": "-1", "targetEnv": "jssdk", "include": "profile,data,emails,subscriptions,preferences,", "includeUserInfo": "true", "loginMode": "standard", "lang": "nl-inf", "APIKey": api_key, "source": "showScreenSet", "sdk": "js_latest", "authMode": "cookie", "format": "json" } logon_data = UriHandler.open(url, data=data, proxy=self.proxy, no_cache=True) user_id, signature, signature_time_stamp = self.__extract_session_data( logon_data) if user_id is None or signature is None or signature_time_stamp is None: return False # We need to initialize the token retrieval which will redirect to the actual token UriHandler.open( "https://token.vrt.be/vrtnuinitlogin?provider=site&destination=https://www.vrt.be/vrtnu/", proxy=self.proxy, no_cache=True) # Now get the actual VRT tokens (X-VRT-Token....). Valid for 1 hour. So we call the actual # perform_login url which will redirect and get cookies. token_data = { "UID": user_id, "UIDSignature": signature, "signatureTimestamp": signature_time_stamp, "client_id": "vrtnu-site", "submit": "submit" } UriHandler.open("https://login.vrt.be/perform_login", proxy=self.proxy, data=token_data, no_cache=True) return True
def create_show_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,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) start_date = result_set['start'] # 2017-01-01T00:00:00+01:00 start_time_stamp = DateHelper.get_date_from_string( start_date.split("+")[0], "%Y-%m-%dT%H:%M:%S") end_date = result_set['end'] end_time_stamp = DateHelper.get_date_from_string( end_date.split("+")[0], "%Y-%m-%dT%H:%M:%S") title = "%02d:%02d - %02d:%02d: %s" % ( start_time_stamp.tm_hour, start_time_stamp.tm_min, end_time_stamp.tm_hour, end_time_stamp.tm_min, result_set['title']) item = MediaItem(title, "", type="video") item.description = result_set.get("description") item.thumb = self.noImage if "image" in result_set: if not item.description: item.description = result_set["image"].get("alt", None) item.thumb = "https://static.538.nl/%s" % ( result_set["image"]['src'], ) item.icon = self.icon item.set_date(*start_time_stamp[0:6]) item.description = result_set.get('description') if "playbackUrls" in result_set and result_set["playbackUrls"]: title_format = "%%02d:%%02d - %s" % (result_set['title'], ) item.complete = True hour = start_time_stamp.tm_hour for stream in result_set["playbackUrls"]: if stream.startswith("//"): stream = "https:%s" % (stream, ) part = item.create_new_empty_media_part() part.Name = title_format % (hour, start_time_stamp.tm_min) part.append_media_stream(stream, 0) hour += 1 elif "showUrl" in result_set and result_set["showUrl"]: title_format = "%%02d:%%02d - %s" % (result_set['title'], ) stream = result_set["showUrl"] item.complete = True hour = start_time_stamp.tm_hour if stream.startswith("//"): stream = "https:%s" % (stream, ) part = item.create_new_empty_media_part() part.Name = title_format % (hour, start_time_stamp.tm_min) part.append_media_stream(stream, 0) hour += 1 else: Logger.warning("Found item without streams: %s", item) return None return item