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)

        genres = result_set[0]
        if self.__genre and self.__genre not in genres:
            Logger.debug("Item '%s' filtered due to genre: %s", result_set[2], genres)
            return None

        url = result_set[1]
        if "&" in url:
            url = HtmlEntityHelper.convert_html_entities(url)

        if not url.startswith("http:"):
            url = "%s%s" % (self.baseUrl, url)

        # get the ajax page for less bandwidth
        url = "%s?sida=1&amp;sort=tid_stigande&embed=true" % (url, )

        item = MediaItem(result_set[2], url)
        item.complete = True
        item.isGeoLocked = True
        return item
Пример #2
0
    def create_api_single_type(self, result_set):
        """ Creates a MediaItem of type 'video' using the result_set from the API.

        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

        This works for:
            __typename=Episode

        """

        title = result_set['name']
        url = '{}{}'.format(self.baseUrl, result_set['urls']['svtplay'])

        item = MediaItem(title, url)
        item.type = "video"
        item.description = result_set.get('longDescription')

        image_info = result_set.get("image")
        if image_info:
            item.thumb = self.__get_thumb(image_info, width=720)
            item.fanart = self.__get_thumb(image_info)
        item.isGeoLocked = result_set['restrictions']['onlyAvailableInSweden']
        return item
Пример #3
0
    def create_api_tvshow_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 list[str]|dict result_set: The result_set of the self.episodeItemRegex

        :return: A new MediaItem of type 'folder'.
        :rtype: MediaItem|None

        This works for:
            __typename=TvShow, KidsTvShow, Single

        """

        url = result_set["urls"]["svtplay"]
        item = MediaItem(result_set['name'], "#program_item")
        item.metaData["slug"] = url
        item.icon = self.icon
        item.isGeoLocked = result_set.get('restrictions',
                                          {}).get('onlyAvailableInSweden',
                                                  False)
        item.description = result_set.get('description')
        image_info = result_set.get("image")
        if image_info:
            item.thumb = self.__get_thumb(image_info)
        return item
Пример #4
0
    def create_live_channel_item(self, result_set):
        """ Creates a MediaItem of type 'video' for live 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,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

        """

        # noinspection PyTypeChecker
        url = "{}{}?apiKey={}".format(self.baseUrl, result_set["_links"]["manifest"]["href"], self.__api_key)

        live_data = result_set["_embedded"]["playback"]  # type: dict
        item = MediaItem(live_data["title"], url)
        item.type = "video"
        item.isLive = True
        item.isGeoLocked = live_data.get("isGeoBlocked")

        # noinspection PyTypeChecker
        self.__get_image(live_data["posters"][0]["image"]["items"], "pixelWidth", "url")
        return item
Пример #5
0
    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_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 dict result_set:   The result_set of the self.episodeItemRegex

        :return: A new MediaItem of type 'folder'.
        :rtype: MediaItem|None

        """

        Logger.trace(result_set)
        meta = result_set["meta"]
        name = meta["header"]["title"]
        url = "{}{}".format(self.baseUrl, result_set["url"])

        item = MediaItem(name, url)
        item.description = meta.get("description")
        item.isGeoLocked = True
        media_info = result_set.get("media")
        if media_info is not None:
            item.thumb = media_info.get("image", {}).get("url")
        return item
Пример #7
0
    def create_episode_item_api(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] result_set: The result_set of the self.episodeItemRegex

        :return: A new MediaItem of type 'folder'.
        :rtype: MediaItem|None

        """

        if not isinstance(result_set, dict):
            json_data = result_set[1].replace("&quot;", "\"")
            result_set = JsonHelper(json_data)
            result_set = result_set.json

        brand = result_set["brand"]
        if brand != self.__channel_brand:
            return None

        title = result_set["title"]
        url = "{}{}".format(self.baseUrl, result_set["link"])
        item = MediaItem(title, url)
        item.description = result_set["description"]
        item.isGeoLocked = True

        images = result_set["images"]
        item.poster = HtmlEntityHelper.convert_html_entities(images.get("poster"))
        item.thumb = HtmlEntityHelper.convert_html_entities(images.get("teaser"))
        return item
Пример #8
0
    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
Пример #9
0
    def get_live_items(self, data):
        """ Adds live stream items.

        The return values should always be instantiated in at least ("", []).

        :param str data: The retrieve data that was loaded for the current item and URL.

        :return: A tuple of the data and a list of MediaItems that were generated.
        :rtype: tuple[str|JsonHelper,list[MediaItem]]

        """

        Logger.info("Fetching episode items")
        items = []

        live_items = MediaItem("\a.: Live TV :.", "")
        items.append(live_items)

        live_base = "http://il.srgssr.ch/integrationlayer/1.0/ue/srf/video/play/%s.json"
        live_channels = {
            "SRF 1 live": ("c4927fcf-e1a0-0001-7edd-1ef01d441651", "srf1.png"),
            "SRF zwei live":
            ("c49c1d64-9f60-0001-1c36-43c288c01a10", "srf2.png"),
            "SRF info live":
            ("c49c1d73-2f70-0001-138a-15e0c4ccd3d0", "srfinfo.png")
        }
        for live_item in live_channels.keys():
            item = MediaItem(live_item,
                             live_base % (live_channels[live_item][0], ))
            item.thumb = self.get_image_location(live_channels[live_item][1])
            item.isGeoLocked = True
            item.type = "video"
            live_items.items.append(item)

        return data, items
Пример #10
0
    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
Пример #11
0
    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
Пример #12
0
    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(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)

        thumb_url = result_set[0]
        if thumb_url.startswith("//"):
            thumb_url = "http:%s" % (thumb_url, )
        elif not thumb_url.startswith("http"):
            thumb_url = "%s%s" % (self.baseUrl, thumb_url)
        Logger.trace(thumb_url)

        season = result_set[1]
        if season:
            name = "%s - %s" % (season, result_set[2])
        else:
            name = result_set[2]

        video_id = result_set[4]
        url = "http://www.oppetarkiv.se/video/%s?output=json" % (video_id, )
        item = MediaItem(name, url)
        item.type = 'video'
        item.icon = self.icon
        item.thumb = thumb_url

        date = result_set[5]
        date_key = 'datetime="'
        if date_key in date:
            date = date[date.index(date_key) + len(date_key):date.index("T")]
            date = date.split("-")
            year = date[0]
            month = date[1]
            day = date[2]
            Logger.trace("%s - %s-%s-%s", date, year, month, day)
            item.set_date(year, month, day)
        else:
            Logger.debug("No date found")

        item.complete = False
        item.isGeoLocked = True
        return item
Пример #14
0
    def __create_json_episode_item(self, result_set, check_channel=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 dict[str,any] result_set: The result_set of the self.episodeItemRegex
        :param bool check_channel:       Compare channel ID's and ignore that that do not match.

        :return: A new MediaItem of type 'folder'.
        :rtype: MediaItem|None

        """

        Logger.trace(result_set)

        # make sure we use ID as GUID
        if "id" in result_set:
            result_set["guid"] = result_set["id"]

        if check_channel and self.channelId is not None:
            channels = [int(c["guid"]) for c in result_set.get("channels", [])]
            valid_channel_found = any(
                [c for c in channels if c in self.channelId])
            if not valid_channel_found:
                Logger.trace("Found item for wrong channel %s instead of %s",
                             channels, self.channelId)
                return None

        # For now we keep using the API, otherwise we need to do more complex VideoItem parsing
        if self.useNewPages:
            raise NotImplementedError("The 'slug' part is no longer working")
            # So this no longer works
            # category_slug = self.__categories[result_set["category"]]["guid"]
            # url = "%s/%s/%s" % (self.baseUrl, category_slug, result_set['slug'])
        else:
            url = "http://playapi.mtgx.tv/v3/videos?format=%(guid)s&order=-airdate&type=program" % result_set
        item = MediaItem(result_set['title'], url)

        # Find the possible images
        if "images" in result_set and "landscape" in result_set["images"]:
            image_url = result_set["images"]["landscape"]["href"]
            item.thumb = self.__get_thumb_image(image_url)
            item.fanart = self.__get_thumb_image(image_url, True)

        elif "image" in result_set:
            item.thumb = self.__get_thumb_image(result_set["image"])

        elif "_links" in result_set and "image" in result_set["_links"]:
            thumb_data = result_set["_links"]["image"]
            item.thumb = self.__get_thumb_image(thumb_data['href'])
            item.fanart = self.__get_thumb_image(thumb_data['href'], True)

        item.isGeoLocked = result_set.get('onlyAvailableInSweden', False)
        return item
Пример #15
0
    def create_generic_item(self, result_set, program_type):
        """ Creates a MediaItem of type 'video' or 'folder' using the result_set from the regex and
        a basic set of values.

        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"]

        if not result_set.get("hasOndemandRights", True):
            Logger.debug("Item '%s' has no on-demand rights", title)
            return None

        item_id = result_set["id"]
        if program_type == "programme":
            url = "https://psapi.nrk.no/programs/{}?apiKey={}".format(item_id, self.__api_key)
            item = MediaItem(title, url)
            item.type = 'video'
        else:
            use_old_series_api = False
            if use_old_series_api:
                url = "https://psapi.nrk.no/series/{}?apiKey={}".format(item_id, self.__api_key)
            else:
                url = "https://psapi.nrk.no/tv/catalog/series/{}?apiKey={}".format(item_id, self.__api_key)

            item = MediaItem(title, url)
            item.type = 'folder'

        item.isGeoLocked = result_set.get("isGeoBlocked", result_set.get("usageRights", {}).get("isGeoBlocked", False))

        description = result_set.get("description")
        if description and description.lower() != "no description":
            item.description = description

        if "image" not in result_set or "webImages" not in result_set["image"]:
            return item

        # noinspection PyTypeChecker
        item.thumb = self.__get_image(result_set["image"]["webImages"], "pixelWidth", "imageUrl")

        # see if there is a date?
        self.__set_date(result_set, item)
        return item
Пример #16
0
    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
Пример #17
0
    def create_api_clip_type(self, result_set):
        """ Creates a MediaItem of type 'video' using the result_set from the API.

        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

        This works for:
            __typename=Episode

        """

        if not self.__show_videos:
            return None

        if not self.__show_videos:
            return None

        title = result_set['name']
        svt_video_id = result_set.get("videoSvtId",
                                      result_set.get("svtId", None))
        if svt_video_id:
            # API style
            url = "https://api.svt.se/videoplayer-api/video/{}".format(
                svt_video_id)
        else:
            # HTML style
            url = "{}{}".format(self.baseUrl, result_set['urls']['svtplay'])

        item = MediaItem(title, url)
        item.type = "video"
        item.description = result_set.get('longDescription')
        item.isGeoLocked = result_set['restrictions']['onlyAvailableInSweden']

        image_info = result_set.get("image")
        if image_info:
            item.thumb = self.__get_thumb(image_info)

        duration = int(result_set.get("duration", 0))
        item.set_info_label("duration", duration)

        return item
Пример #18
0
    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
Пример #19
0
    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_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
Пример #21
0
    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
Пример #22
0
    def __create_generic_item(self, result_set, expected_item_type, url_format):
        video_info = result_set["attributes"]
        name = video_info["name"]

        if expected_item_type != result_set["type"]:
            Logger.warning("Not %s, excluding %s", expected_item_type, name)
            return None

        channel_id = int(result_set["relationships"]["primaryChannel"]["data"]["id"])
        if self.primaryChannelId is not None and channel_id != self.primaryChannelId:
            return None

        item_id = result_set["id"]
        # Show the slug?
        # showSlug = video_info["alternateId"]

        url = url_format.format(item_id)
        item = MediaItem(name, url)
        item.description = video_info.get("description")

        geo_info = video_info.get("geoRestrictions", {"countries": ["world"]})
        item.isGeoLocked = "world" not in geo_info.get("countries")

        # set the images
        if "images" in result_set["relationships"]:
            thumb_id = result_set["relationships"]["images"]["data"][0]["id"]
            item.thumb = self.imageLookup.get(thumb_id, self.noImage)
            if item.thumb == self.noImage:
                Logger.warning("No thumb found for %s", thumb_id)

        # paid or not?
        if "contentPackages" in result_set["relationships"]:
            item.isPaid = not any(
                filter(
                    lambda p: p["id"].lower() == "free", result_set["relationships"]["contentPackages"]["data"]
                )
            )
        else:
            item.isPaid = False

        return item
Пример #23
0
    def create_video_item_api(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

        """

        # Could be: title = result_set['episodeTitle']
        title = result_set['title']
        url = "https://api.viervijfzes.be/content/{}".format(
            result_set['videoUuid'])
        item = MediaItem(title, url)
        item.type = "video"
        item.description = HtmlHelper.to_text(
            result_set.get("description").replace(">\r\n", ">"))
        item.thumb = result_set["image"]
        item.isGeoLocked = result_set.get("isProtected")

        date_time = DateHelper.get_date_from_posix(result_set["createdDate"])
        item.set_date(date_time.year, date_time.month, date_time.day,
                      date_time.hour, date_time.minute, date_time.second)

        item.set_info_label("duration", result_set["duration"])
        if "epsiodeNumber" in result_set and "seasonNumber" in result_set:
            item.set_season_info(result_set["seasonNumber"],
                                 result_set["epsiodeNumber"])
        return item
Пример #24
0
    def __create_generic_item(self, result_set, expected_item_type,
                              url_format):
        video_info = result_set["attributes"]
        name = video_info["name"]

        if expected_item_type != result_set["type"]:
            Logger.warning("Not %s, excluding %s", expected_item_type, name)
            return None

        channel_id = int(
            result_set["relationships"]["primaryChannel"]["data"]["id"])
        if self.primaryChannelId is not None and channel_id != self.primaryChannelId:
            return None

        item_id = result_set["id"]
        # Show the slug?
        # showSlug = video_info["alternateId"]

        url = url_format.format(item_id)
        item = MediaItem(name, url)
        item.description = video_info.get("description")

        geo_info = video_info.get("geoRestrictions", {"countries": ["world"]})
        item.isGeoLocked = "world" not in geo_info.get("countries")

        # set the images
        if "images" in result_set["relationships"]:
            thumb_id = result_set["relationships"]["images"]["data"][0]["id"]
            item.thumb = self.imageLookup.get(thumb_id, self.noImage)
            if item.thumb == self.noImage:
                Logger.warning("No thumb found for %s", thumb_id)

        # paid or not?
        item.isPaid, logon_required = self._is_paid_or_logged_on_item(
            result_set)
        if logon_required:
            item.metaData[self.__REQUIRES_LOGIN] = True

        return item
Пример #25
0
    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

        """

        Logger.trace('starting FormatVideoItem for %s', self.channelName)
        # Logger.Trace(result_set)

        # the vmanProgramId (like 1019976) leads to http://anytime.tv4.se/webtv/metafileFlash.smil?p=1019976&bw=1000&emulate=true&sl=true
        program_id = result_set["id"]
        # Logger.Debug("ProgId = %s", programId)

        # We can either use M3u8 or Dash
        # url = "https://playback-api.b17g.net/media/%s?service=tv4&device=browser&protocol=hls" % (program_id,)
        url = "https://playback-api.b17g.net/media/%s?service=tv4&device=browser&protocol=dash" % (
            program_id, )
        name = result_set["title"]
        season = result_set.get("season", 0)
        episode = result_set.get("episode", 0)
        is_episodic = 0 < season < 1900 and not episode == 0
        if is_episodic:
            episode_text = None
            if " del " in name:
                name, episode_text = name.split(" del ", 1)
                episode_text = episode_text.lstrip("0123456789")

            if episode_text:
                episode_text = episode_text.lstrip(" -")
                name = "{} - s{:02d}e{:02d} - {}".format(
                    name, season, episode, episode_text)
            else:
                name = "{} - s{:02d}e{:02d}".format(name, season, episode)

        item = MediaItem(name, url)
        item.description = result_set["description"]
        if item.description is None:
            item.description = item.name

        if is_episodic:
            item.set_season_info(season, episode)

        # premium_expire_date_time=2099-12-31T00:00:00+01:00
        expire_date = result_set.get("expire_date_time")
        if bool(expire_date):
            self.__set_expire_time(expire_date, item)

        date = result_set["broadcast_date_time"]
        (date_part, time_part) = date.split("T")
        (year, month, day) = date_part.split("-")
        (hour, minutes, rest1, zone) = time_part.split(":")
        item.set_date(year, month, day, hour, minutes, 00)
        broadcast_date = datetime.datetime(int(year), int(month), int(day),
                                           int(hour), int(minutes))

        item.fanart = result_set.get("program_image", self.parentItem.fanart)
        thumb_url = result_set.get("image", result_set.get("program_image"))
        # some images need to come via a proxy:
        if thumb_url and "://img.b17g.net/" in thumb_url:
            item.thumb = "https://imageproxy.b17g.services/?format=jpg&shape=cut" \
                         "&quality=90&resize=520x293&source={}"\
                .format(HtmlEntityHelper.url_encode(thumb_url))
        else:
            item.thumb = thumb_url

        availability = result_set["availability"]
        # noinspection PyTypeChecker
        free_period = availability["availability_group_free"]
        # noinspection PyTypeChecker
        premium_period = availability["availability_group_premium"]

        now = datetime.datetime.now()
        if False and not premium_period == "0":
            # always premium
            free_expired = now - datetime.timedelta(days=99 * 365)
        elif free_period == "30+" or free_period is None:
            free_expired = broadcast_date + datetime.timedelta(days=99 * 365)
        else:
            free_expired = broadcast_date + datetime.timedelta(
                days=int(free_period))
        Logger.trace(
            "Premium info for: %s\nPremium state: %s\nFree State:    %s\nBroadcast %s vs Expired %s",
            name, premium_period, free_period, broadcast_date, free_expired)

        if now > free_expired:
            item.isPaid = True

        item.type = "video"
        item.complete = False
        item.isGeoLocked = result_set["is_geo_restricted"]
        item.isDrmProtected = result_set["is_drm_protected"]
        item.isLive = result_set.get("is_live", False)
        if item.isLive:
            item.name = "{}:{} - {}".format(hour, minutes, name)
            item.url = "{0}&is_live=true".format(item.url)
        if item.isDrmProtected:
            item.url = "{}&drm=widevine&is_drm=true".format(item.url)

        item.set_info_label("duration", int(result_set.get("duration", 0)))
        return item
Пример #26
0
    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 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)

        # Channel data
        channel_title = channel["name"]
        channel_id = channel["id"]
        if channel_id == "svtb":
            channel_id = "barnkanalen"
        elif channel_id == "svtk":
            channel_id = "kunskapskanalen"

        # Running data
        running = channel["running"]
        title = running["name"]
        episode = running.get("subHeading", None)
        thumb = self.__get_thumb(running["image"], width=720)
        date_format = "%Y-%m-%dT%H:%M:%S"
        start_time = DateHelper.get_date_from_string(running["start"][:19], date_format)
        end_time = DateHelper.get_date_from_string(running["end"][:19], date_format)
        description = running.get("description")

        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)
            description = "{:02d}:{:02d} - {:02d}:{:02d}: {} - {}\n\n{}".format(
                start_time.tm_hour, start_time.tm_min, end_time.tm_hour, end_time.tm_min,
                title, episode or "", description)
        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)
            description = "{:02d}:{:02d} - {:02d}:{:02d}: {}\n\n{}".format(
                start_time.tm_hour, start_time.tm_min, end_time.tm_hour, end_time.tm_min,
                title, description)

        channel_item = MediaItem(
            title,
            "https://www.svt.se/videoplayer-api/video/%s" % (channel_id.lower(),)
        )
        channel_item.type = "video"
        channel_item.isLive = True
        channel_item.isGeoLocked = True
        channel_item.description = description

        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
Пример #27
0
    def create_api_episode_type(self, result_set, add_parent_title=False):
        """ Creates a MediaItem of type 'video' using the result_set from the API.

        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
        :param bool add_parent_title: Should the parent's title be included?

        :return: A new MediaItem of type 'video' or 'audio' (despite the method's name).
        :rtype: MediaItem|None

        This works for:
            __typename=Episode

        """

        svt_video_id = result_set.get("videoSvtId",
                                      result_set.get("svtId", None))
        if svt_video_id:
            # API style
            url = "https://api.svt.se/videoplayer-api/video/{}".format(
                svt_video_id)
        else:
            # HTML style
            url = "{}{}".format(self.baseUrl, result_set['urls']['svtplay'])

        title = result_set.get("name", "")
        if "parent" in result_set and add_parent_title:
            title = "{} - {}".format(result_set["parent"]["name"], title)

        item = MediaItem(title, url)
        item.description = result_set.get("longDescription")
        item.type = "video"
        item.set_info_label("duration", int(result_set.get("duration", 0)))
        item.isGeoLocked = result_set.get("restrictions",
                                          {}).get("onlyAvailableInSweden",
                                                  False)

        parent_images = result_set.get(self.__parent_images)
        if bool(parent_images):
            item.fanart = self.__get_thumb(parent_images)

        if "image" in result_set:
            item.thumb = self.__get_thumb(result_set["image"], width=720)
            if not bool(item.fanart):
                item.fanart = self.__get_thumb(result_set["image"])

        valid_to = result_set.get("validTo", None)
        if valid_to:
            self.__set_expire_time(valid_to, item)

        live_data = result_set.get("live")
        if live_data:
            is_live_now = live_data["liveNow"]
            if is_live_now:
                item.name = "{} [COLOR gold](live)[/COLOR]".format(item.name)

            start = live_data["start"]
            if start.endswith("Z"):
                start_time = DateHelper.get_datetime_from_string(
                    start, "%Y-%m-%dT%H:%M:%SZ", "UTC")
                start_time = start_time.astimezone(self.__timezone)
                item.set_date(start_time.year, start_time.month,
                              start_time.day, start_time.hour,
                              start_time.minute, start_time.second)
                hour = start_time.hour
                minute = start_time.minute
            else:
                start = start.split('.')[0].split("+")[0]
                start_time = DateHelper.get_date_from_string(
                    start, "%Y-%m-%dT%H:%M:%S")
                item.set_date(*start_time[0:6])
                hour = start_time.tm_hour
                minute = start_time.tm_min

            item.name = "{:02}:{:02} - {}".format(hour, minute, item.name)

        return item
Пример #28
0
    def load_programs(self, data):
        """ Performs pre-process actions for data processing.

        Accepts an data from the process_folder_list method, BEFORE the items are
        processed. Allows setting of parameters (like title etc) for the channel.
        Inside this method the <data> could be changed and additional items can
        be created.

        The return values should always be instantiated in at least ("", []).

        :param str data: The retrieve data that was loaded for the current item and URL.

        :return: A tuple of the data and a list of MediaItems that were generated.
        :rtype: tuple[str|JsonHelper,list[MediaItem]]

        """

        items = []

        # fetch al pages
        p = 1
        url_format = "https://{0}/content/shows?" \
                     "include=images" \
                     "&page%5Bsize%5D=100&page%5Bnumber%5D={{0}}".format(self.baseUrlApi)
        # "include=images%2CprimaryChannel" \
        url = url_format.format(p)
        data = UriHandler.open(url, proxy=self.proxy)
        json = JsonHelper(data)
        pages = json.get_value("meta", "totalPages")
        programs = json.get_value("data") or []

        # extract the images
        self.__update_image_lookup(json)

        for p in range(2, pages + 1, 1):
            url = url_format.format(p)
            Logger.debug("Loading: %s", url)

            data = UriHandler.open(url, proxy=self.proxy)
            json = JsonHelper(data)
            programs += json.get_value("data") or []

            # extract the images
            self.__update_image_lookup(json)

        Logger.debug("Found a total of %s items over %s pages", len(programs),
                     pages)

        for p in programs:
            item = self.create_program_item(p)
            if item is not None:
                items.append(item)

        if self.recentUrl:
            recent_text = LanguageHelper.get_localized_string(
                LanguageHelper.Recent)
            recent = MediaItem("\b.: {} :.".format(recent_text),
                               self.recentUrl)
            recent.dontGroup = True
            items.append(recent)

        # live items
        if self.liveUrl:
            live = MediaItem("\b.: Live :.", self.liveUrl)
            live.type = "video"
            live.dontGroup = True
            live.isGeoLocked = True
            live.isLive = True
            items.append(live)

        search = MediaItem("\a.: S&ouml;k :.", "searchSite")
        search.type = "folder"
        search.dontGroup = True
        items.append(search)

        return data, items
Пример #29
0
    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,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)

        drm_locked = False
        geo_blocked = result_set["is_geo_blocked"]

        title = result_set["title"]
        if ("_links" not in result_set or "stream" not in result_set["_links"]
                or "href" not in result_set["_links"]["stream"]):
            Logger.warning("No streams found for %s", title)
            return None

        # the description
        description = result_set["description"].strip()  # The long version
        summary = result_set["summary"].strip()  # The short version
        # Logger.Trace("Comparing:\nDesc: %s\nSumm:%s", description, summary)
        if not description.startswith(summary):
            # the descripts starts with the summary. Don't show
            description = "%s\n\n%s" % (summary, description)

        video_type = result_set["type"]
        if not video_type == "program":
            title = "%s (%s)" % (title, video_type.title())

        elif result_set["format_position"][
                "is_episodic"]:  # and resultSet["format_position"]["episode"] != "0":
            # make sure we show the episodes and seaso
            season = result_set["format_position"].get("season", 0)
            episode = int(result_set["format_position"]["episode"] or "0")

            # Was it a webisode?
            # webisode = result_set.get("webisode", False)

            # if the name had the episode in it, translate it
            if episode > 0 and season > 0:  # and not webisode:
                description = "%s\n\n%s" % (title, description)
                title = "{0} - s{1:02d}e{2:02d}".format(
                    result_set["format_title"], season, episode)
            else:
                Logger.debug(
                    "Found episode '0' or websido '%s': using name instead of episode number",
                    title)

        mpx_guid = result_set.get('mpx_guid')
        if mpx_guid is None:
            url = result_set["_links"]["stream"]["href"]
        else:
            # we can use mpx_guid and https://viafree.mtg-api.com/stream-links/viafree/web/se/clear-media-guids/{}/streams
            url = "https://viafree.mtg-api.com/stream-links/viafree/web/{}/clear-media-guids/{}/streams".format(
                self.language, mpx_guid)
        item = MediaItem(title, url)

        date_info = None
        date_format = "%Y-%m-%dT%H:%M:%S"
        if "broadcasts" in result_set and len(result_set["broadcasts"]) > 0:
            date_info = result_set["broadcasts"][0]["air_at"]
            Logger.trace("Date set from 'air_at'")

            if "playable_from" in result_set["broadcasts"][0]:
                start_date = result_set["broadcasts"][0]["playable_from"]
                playable_from = DateHelper.get_date_from_string(
                    start_date[0:-6], date_format)
                playable_from = datetime.datetime(*playable_from[0:6])
                if playable_from > datetime.datetime.now():
                    drm_locked = True

        elif "publish_at" in result_set:
            date_info = result_set["publish_at"]
            Logger.trace("Date set from 'publish_at'")

        if date_info is not None:
            # publish_at=2007-09-02T21:55:00+00:00
            info = date_info.split("T")
            date_info = info[0]
            time_info = info[1]
            date_info = date_info.split("-")
            time_info = time_info.split(":")
            item.set_date(date_info[0], date_info[1], date_info[2],
                          time_info[0], time_info[1], 0)

        item.type = "video"
        item.complete = False
        item.isGeoLocked = geo_blocked
        item.isDrmProtected = drm_locked

        thumb_data = result_set['_links'].get('image', None)
        if thumb_data is not None:
            # Older version
            # item.thumbUrl = thumb_data['href'].replace("{size}", "thumb")
            item.thumb = self.__get_thumb_image(thumb_data['href'])

        item.description = description
        # unpublish_at=2099-12-31T00:00:00+01:00
        expire_date = result_set["unpublish_at"]
        if bool(expire_date):
            self.__set_expire_time(expire_date, item)

        srt = result_set.get("sami_path")
        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

        item.set_info_label("duration", int(result_set.get("duration", 0)))
        return item
Пример #30
0
    def add_live_channels_and_folders(self, data):
        """ Performs pre-process actions for data processing.

        Accepts an data from the process_folder_list method, BEFORE the items are
        processed. Allows setting of parameters (like title etc) for the channel.
        Inside this method the <data> could be changed and additional items can
        be created.

        The return values should always be instantiated in at least ("", []).

        :param str data: The retrieve data that was loaded for the current item and URL.

        :return: A tuple of the data and a list of MediaItems that were generated.
        :rtype: tuple[str|JsonHelper,list[MediaItem]]

        """

        Logger.info("Generating Live channels")
        items = []

        live_channels = [
            {"name": "BBC 1 HD", "code": "bbc_one_hd", "image": "bbc1large.png"},
            {"name": "BBC 2 HD", "code": "bbc_two_hd", "image": "bbc2large.png"},
            {"name": "BBC 3 HD", "code": "bbc_three_hd", "image": "bbc3large.png"},
            {"name": "BBC 4 HD", "code": "bbc_four_hd", "image": "bbc4large.png"},
            {"name": "CBBC", "code": "cbbc_hd", "image": "cbbclarge.png"},
            {"name": "CBeebies", "code": "cbeebies_hd", "image": "cbeebieslarge.png"},
            {"name": "BBC News Channel", "code": "bbc_news24", "image": "bbcnewslarge.png"},
            {"name": "BBC Parliament", "code": "bbc_parliament", "image": "bbcparliamentlarge.png"},
            {"name": "Alba", "code": "bbc_alba", "image": "bbcalbalarge.png"},

            {"name": "S4C", "code": "s4cpbs", "image": "bbchdlarge.png"},
            {"name": "BBC One London", "code": "bbc_one_london", "image": "bbchdlarge.png"},
            {"name": "BBC One Scotland", "code": "bbc_one_scotland_hd", "image": "bbchdlarge.png"},
            {"name": "BBC One Northern Ireland", "code": "bbc_one_northern_ireland_hd", "image": "bbchdlarge.png"},
            {"name": "BBC One Wales", "code": "bbc_one_wales_hd", "image": "bbchdlarge.png"},
            {"name": "BBC Two Scotland", "code": "bbc_two_scotland", "image": "bbchdlarge.png"},
            {"name": "BBC Two Northern Ireland", "code": "bbc_two_northern_ireland_digital", "image": "bbchdlarge.png"},
            {"name": "BBC Two Wales", "code": "bbc_two_wales_digital", "image": "bbchdlarge.png"},
        ]

        live = MediaItem("Live Channels", "")
        live.dontGroup = True
        live.type = "folder"
        items.append(live)

        for channel in live_channels:
            url = "http://a.files.bbci.co.uk/media/live/manifesto/audio_video/simulcast/hds/uk/pc/ak/%(code)s.f4m" % channel
            item = MediaItem(channel["name"], url)
            item.isGeoLocked = True
            item.isLive = True
            item.type = "video"
            item.complete = False
            item.thumb = self.get_image_location(channel["image"])
            live.items.append(item)

        extra = MediaItem("Shows (A-Z)", "#alphalisting")
        extra.complete = True
        extra.description = "Alphabetical show listing of BBC shows"
        extra.dontGroup = True
        items.append(extra)

        return data, items