示例#1
0
    def __init__(self, channel_info):
        """ Initialisation of the class.

        All class variables should be instantiated here and this method should not
        be overridden by any derived classes.

        :param ChannelInfo channel_info: The channel info object to base this channel on.

        """

        chn_class.Channel.__init__(self, channel_info)

        # ============== Actual channel setup STARTS here and should be overwritten from derived classes ===============

        if self.channelCode == "ketnet":
            self.noImage = "ketnetimage.jpg"
            self.mainListUri = "https://www.ketnet.be/kijken"
            self.baseUrl = "https://www.ketnet.be"
            self.mediaUrlRegex = r'playerConfig\W*=\W*(\{[\w\W]{0,2000}?);(?:.vamp|playerConfig)'

        elif self.channelCode == "cobra":
            self.noImage = "cobraimage.png"
            self.mainListUri = "http://www.cobra.be/cm/cobra/cobra-mediaplayer"
            self.baseUrl = "http://www.cobra.be"

        self.swfUrl = "%s/html/flash/common/player.swf" % (self.baseUrl, )

        episode_regex = r'<a[^>]+href="(?<url>/kijken[^"]+)"[^>]*>\W*<img[^>]+src="' \
                        r'(?<thumburl>[^"]+)"[^>]+alt="(?<title>[^"]+)"'
        episode_regex = Regexer.from_expresso(episode_regex)
        self._add_data_parser(self.mainListUri,
                              match_type=ParserData.MatchExact,
                              parser=episode_regex,
                              creator=self.create_episode_item)

        self._add_data_parser("*", preprocessor=self.select_video_section)

        video_regex = Regexer.from_expresso(
            r'<a title="(?<title>[^"]+)" href="(?<url>[^"]+)"[^>]*>'
            r'\W+<img src="(?<thumburl>[^"]+)"[^<]+<span[^<]+[^<]+'
            r'[^>]+></span>\W+(?<description>[^<]+)')
        self._add_data_parser("*",
                              parser=video_regex,
                              creator=self.create_video_item,
                              updater=self.update_video_item)

        folder_regex = Regexer.from_expresso(
            r'<span class="more-of-program" rel="/(?<url>[^"]+)">')
        self._add_data_parser("*",
                              parser=folder_regex,
                              creator=self.create_folder_item)

        #===============================================================================================================
        # non standard items

        #===============================================================================================================
        # Test cases:

        # ====================================== Actual channel setup STOPS here =======================================
        return
    def __init__(self, channel_info):
        """ Initialisation of the class.

        All class variables should be instantiated here and this method should not
        be overridden by any derived classes.

        :param ChannelInfo channel_info: The channel info object to base this channel on.

        """

        chn_class.Channel.__init__(self, channel_info)

        # ============== Actual channel setup STARTS here and should be overwritten from derived classes ===============
        self.noImage = "eenimage.png"

        # setup the urls
        self.mainListUri = "https://www.een.be/programmas"
        self.baseUrl = "http://www.een.be"

        # setup the main parsing data
        self._add_data_parser(self.mainListUri, preprocessor=self.extract_json, json=True,
                              parser=["data", ], creator=self.create_show_item)

        video_parser = r'<a class="card-teaser"[^>][^>]*href="(?<url>[^"]+)"[^>]*>\W+<div[^>]+' \
                       r'style="background-image: url\(\'(?<thumburl>[^\']+/(?<year>\d{4})/' \
                       r'(?<month>\d{2})/(?<day>\d{2})/[^\']+)\'[^>]*>\W+<div[^>]+_play[\w\W+]' \
                       r'{0,2000}?<div[^>]*>(?<_title>[^>]*)</div>\W*<h3[^>]*>(?<title>[^<]+)' \
                       r'</h3>\W+<div[^>]*>\W+(?:<span[^>]*>[^<]*</span>)?(?<description>[^<]+)'
        video_parser = Regexer.from_expresso(video_parser)
        self._add_data_parser("*", name="Links to teasers of videos (Card teaser)",
                              parser=video_parser, creator=self.create_video_item,
                              updater=self.update_video_item)

        video_parser = r'<a[^>]*class="[^"]+-teaser"[^>]*background-image: url\(\'(?<thumburl>' \
                       r'[^\']+/(?<year>\d{4})/(?<month>\d{2})/(?<day>\d{2})/[^\']+)\'[^>]*href="' \
                       r'(?<url>[^"]+)"[^>]*>\W+<div[^>]+_play[\w\W+]{0,2000}?<div[^>]*>' \
                       r'(?<_title>[^>]*)</div>\W*<h3[^>]*>(?<title>[^<]+)</h3>\W+<div[^>]*>\W+' \
                       r'(?:<span[^>]*>[^<]*</span>)?(?<description>[^<]+)'
        video_parser = Regexer.from_expresso(video_parser)
        self._add_data_parser("*", name="Links to teasers of videos (Image Teaser)",
                              parser=video_parser, creator=self.create_video_item,
                              updater=self.update_video_item)

        single_video_parser = r'>(?<title>[^<]+)</h1>[\w\W]{0,2000}?(?:<h2>?<description>[^<]+)?' \
                              r'[\w\W]{0,1000}?data-video="(?<url>[^"]+)"[\w\W]{0,500}data-analytics' \
                              r'=\'{&quot;date&quot;:&quot;(?<year>\d+)-(?<month>\d+)-(?<day>\d+)'
        single_video_parser = Regexer.from_expresso(single_video_parser)
        self._add_data_parser("*", name="Pages that contain only a single video",
                              parser=single_video_parser, creator=self.create_video_item)

        #===============================================================================================================
        # non standard items

        #===============================================================================================================
        # Test cases:

        # ====================================== Actual channel setup STOPS here =======================================
        return
示例#3
0
    def __init__(self, channel_info):
        """ Initialisation of the class.

        All class variables should be instantiated here and this method should not
        be overridden by any derived classes.

        :param ChannelInfo channel_info: The channel info object to base this channel on.

        """

        chn_class.Channel.__init__(self, channel_info)

        # ============== Actual channel setup STARTS here and should be overwritten from derived classes ===============
        self.noImage = "vtmimage.jpg"

        # setup the urls
        self.mainListUri = "http://nieuws.vtm.be/herbekijk"
        self.baseUrl = "http://nieuws.vtm.be"

        # setup the main parsing data
        self.episodeItemRegex = '<li><a[^>]+href="/([^"]+)" class="level-1[^>]+>([^<]+)</a>'
        self._add_data_parser(self.mainListUri,
                              creator=self.create_episode_item,
                              parser=self.episodeItemRegex)

        video_item_regex = r'<article[^<]+has-video"[^>]*>\W*<a href="(?<Url>[^<"]+)"[^>]*>\W+' \
                           r'<div[^<]+<img[^>]+src="(?<Thumb>[^"]+)"[^>]*>[\w\W]{0,500}?<h3[^>]*>' \
                           r'(?:\W+<span[^>]*>[^>]*>)?(?<Title>[^<]+)</h3>\W+<div[^<]+<time[^>]+' \
                           r'datetime="(?<DateTime>[^"]+)"[^<]+</time>\W*</div>\W*<p[^>]+>*' \
                           r'(?<Description>[^<]+)'
        video_item_regex = Regexer.from_expresso(video_item_regex)
        self._add_data_parser("*",
                              creator=self.create_video_item,
                              parser=video_item_regex,
                              updater=self.update_video_item)

        stadion_regex = r'<article[^>]*>\W*<div class="image is-video">\W*<a href="(?<Url>[^"]+)' \
                        r'[^>]*>\W*<img[^>]+src="(?<Thumb>[^"]+)"[\w\W]{0,1000}?<h3 class=' \
                        r'"pagemanager-item-title">\W*<span>\W*<a[^>]*>(?<Title>[^<]+)[\w\W]' \
                        r'{0,1000}?<div class="teaser">\W*<a[^>]+>(?<Description>[^<]+)'
        stadion_regex = Regexer.from_expresso(stadion_regex)
        self._add_data_parser("http://nieuws.vtm.be/stadion",
                              parser=stadion_regex,
                              creator=self.create_video_item,
                              updater=self.update_video_item)

        self.pageNavigationRegex = ''
        self.pageNavigationRegexIndex = 0

        #===============================================================================================================
        # non standard items

        #===============================================================================================================
        # Test cases:

        # ====================================== Actual channel setup STOPS here =======================================
        return
示例#4
0
    def __init__(self, channel_info):
        """ Initialisation of the class.

        All class variables should be instantiated here and this method should not
        be overridden by any derived classes.

        :param ChannelInfo channel_info: The channel info object to base this channel on.

        """

        chn_class.Channel.__init__(self, channel_info)

        # ============== Actual channel setup STARTS here and should be overwritten from derived classes ===============
        self.noImage = "l1image.png"

        # setup the urls
        self.mainListUri = "https://l1.nl/gemist/"
        self.baseUrl = "https://l1.nl"

        # setup the main parsing data
        episode_regex = r'<li>\W*<a[^>]*href="(?<url>/[^"]+)"[^>]*>(?<title>[^<]+)</a>\W*</li>'
        episode_regex = Regexer.from_expresso(episode_regex)
        self._add_data_parser(self.mainListUri,
                              preprocessor=self.pre_process_folder_list,
                              parser=episode_regex,
                              creator=self.create_episode_item)

        # live stuff
        self._add_data_parsers(["#livetv", "#liveradio"],
                               updater=self.update_live_stream)

        video_regex = r'<a[^>]*class="mediaItem"[^>]*href="(?<url>[^"]+)"[^>]*title="(?<title>' \
                      r'[^"]+)"[^>]*>[\w\W]{0,500}?<img[^>]+src="/(?<thumburl>[^"]+)'
        video_regex = Regexer.from_expresso(video_regex)
        self._add_data_parser("*",
                              parser=video_regex,
                              creator=self.create_video_item,
                              updater=self.update_video_item)

        page_regex = r'<a[^>]+href="https?://l1.nl/([^"]+?pagina=)(\d+)"'
        page_regex = Regexer.from_expresso(page_regex)
        self.pageNavigationRegexIndex = 1
        self._add_data_parser("*",
                              parser=page_regex,
                              creator=self.create_page_item)

        #===============================================================================================================
        # non standard items

        #===============================================================================================================
        # Test cases:

        # ====================================== Actual channel setup STOPS here =======================================
        return
    def __init__(self, channel_info):
        """ Initialisation of the class.

        All class variables should be instantiated here and this method should not
        be overridden by any derived classes.

        :param ChannelInfo channel_info: The channel info object to base this channel on.

        """

        chn_class.Channel.__init__(self, channel_info)

        # ============== Actual channel setup STARTS here and should be overwritten from derived classes ===============
        self.videoType = None
        self.noImage = "eredivisieimage.jpg"

        # setup the urls
        self.baseUrl = "https://www.foxsports.nl"
        self.mainListUri = "https://www.foxsports.nl/videos/"
        self.swfUrl = "https://static.eredivisielive.nl/static/swf/edPlayer-1.6.2.plus.swf"

        # setup the main parsing data
        # self.episodeItemRegex = '<option[^>]+value="([^"]+)"[^=>]+(?:data-season="([^"]+)")?[^=>]*>([^<]+)</option>'
        # self.videoItemJson = ("item",)
        self._add_data_parser(
            self.mainListUri,
            parser=Regexer.from_expresso(
                '<a [hd][^>]*ata-(?<Type>area|sport)="(?<Url>[^"]+)[^>]*>'
                '(?<Title>[^<]+)</a>'),
            creator=self.create_folder_item)

        self._add_data_parser(
            self.mainListUri,
            parser=Regexer.from_expresso(
                r'<a[^>]+href="/video/(?<Type>filter|meest_bekeken)/?'
                r'(?<Url>[^"]*)">[^<]*</a>\W+<h1[^>]*>(?<Title>[^<;]+)'
                r'(?:&#39;s){0,1}</h1>'),
            creator=self.create_folder_item)

        self._add_data_parser(
            "https://www.foxsports.nl/video/filter/fragments/",
            preprocessor=self.add_pages,
            parser=Regexer.from_expresso(
                r'<img[^>]+src=\'(?<Thumb>[^\']+)\'[^>]*>\W+</picture>\W+'
                r'<span class="[^"]+play[\w\W]{0,500}?<h1[^>]*>\W+<a href="'
                r'(?<Url>[^"]+)"[^>]*>(?<Title>[^<]+)</a>\W+</h1>\W+<span'
                r'[^>]*>(?<Date>[^>]+)</span>'),
            creator=self.create_video_item)

        self._add_data_parser("*", updater=self.update_video_item)

        # ====================================== Actual channel setup STOPS here =======================================
        return
    def __update_video_from_brightcove(self, item, data,
                                       use_adaptive_with_encryption):
        """ Updates an existing MediaItem with more data based on an MPD stream.

        :param str data:                            Stream info retrieved from BrightCove.
        :param bool use_adaptive_with_encryption:   Do we use the Adaptive InputStream add-on?
        :param MediaItem item:                      The original MediaItem that needs updating.

        :return: The original item with more data added to it's properties.
        :rtype: MediaItem

        """

        part = item.create_new_empty_media_part()
        # Then try the new BrightCove JSON
        bright_cove_regex = '<video[^>]+data-video-id="(?<videoId>[^"]+)[^>]+data-account="(?<videoAccount>[^"]+)'
        bright_cove_data = Regexer.do_regex(
            Regexer.from_expresso(bright_cove_regex), data)
        if not bright_cove_data:
            Logger.warning("Error updating using BrightCove data: %s", item)
            return item

        Logger.info("Found new BrightCove JSON data")
        bright_cove_url = 'https://edge.api.brightcove.com/playback/v1/accounts/' \
                          '%(videoAccount)s/videos/%(videoId)s' % bright_cove_data[0]
        headers = {
            "Accept":
            "application/json;pk=BCpkADawqM3ve1c3k3HcmzaxBvD8lXCl89K7XEHiKutxZArg2c5RhwJHJANOwPwS_4o7UsC4RhIzXG8Y69mrwKCPlRkIxNgPQVY9qG78SJ1TJop4JoDDcgdsNrg"
        }

        bright_cove_data = UriHandler.open(bright_cove_url,
                                           additional_headers=headers)
        bright_cove_json = JsonHelper(bright_cove_data)
        streams = [
            d for d in bright_cove_json.get_value("sources")
            if d["container"] == "M2TS"
        ]
        # Old filter
        # streams = filter(lambda d: d["container"] == "M2TS", bright_cove_json.get_value("sources"))
        if not streams:
            Logger.warning("Error extracting streams from BrightCove data: %s",
                           item)
            return item

        # noinspection PyTypeChecker
        stream_url = streams[0]["src"]

        # these streams work better with the the InputStreamAddon because it removes the
        # "range" http header
        if use_adaptive_with_encryption:
            Logger.info("Using InputStreamAddon for playback of HLS stream")
            strm = part.append_media_stream(stream_url, 0)
            M3u8.set_input_stream_addon_input(strm)
            item.complete = True
            return item

        for s, b in M3u8.get_streams_from_m3u8(stream_url):
            item.complete = True
            part.append_media_stream(s, b)
        return item
    def add_search_and_genres(self, data):
        """ Performs pre-process actions for data processing and adds a search option and genres.

        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("Performing Pre-Processing")
        items = []

        if self.parentItem is not None and "genre" in self.parentItem.metaData:
            self.__genre = self.parentItem.metaData["genre"]
            Logger.debug("Parsing a specific genre: %s", self.__genre)
            return data, items

        search_item = MediaItem("\a.: S&ouml;k :.", "searchSite")
        search_item.complete = True
        search_item.thumb = self.noImage
        search_item.dontGroup = True
        search_item.fanart = self.fanart
        # search_item.set_date(2099, 1, 1, text="")
        # -> No items have dates, so adding this will force a date sort in Retrospect
        items.append(search_item)

        genres_item = MediaItem("\a.: Genrer :.", "")
        genres_item.complete = True
        genres_item.thumb = self.noImage
        genres_item.dontGroup = True
        genres_item.fanart = self.fanart
        items.append(genres_item)

        # find the actual genres
        genre_regex = '<li[^>]+genre[^>]*><button[^>]+data-value="(?<genre>[^"]+)"[^>]*>' \
                      '(?<title>[^>]+)</button></li>'
        genre_regex = Regexer.from_expresso(genre_regex)
        genres = Regexer.do_regex(genre_regex, data)
        for genre in genres:
            if genre["genre"] == "all":
                continue
            genre_item = MediaItem(genre["title"], self.mainListUri)
            genre_item.complete = True
            genre_item.thumb = self.noImage
            genre_item.fanart = self.fanart
            genre_item.metaData = {"genre": genre["genre"]}
            genres_item.items.append(genre_item)

        Logger.debug("Pre-Processing finished")
        return data, items
示例#8
0
    def __init__(self, channel_info):
        """ Initialisation of the class.

        All class variables should be instantiated here and this method should not
        be overridden by any derived classes.

        :param ChannelInfo channel_info: The channel info object to base this channel on.

        """

        chn_class.Channel.__init__(self, channel_info)

        # ============== Actual channel setup STARTS here and should be overwritten from derived classes ===============
        self.noImage = "twitimage.png"

        # setup the urls
        self.mainListUri = "https://twit.tv/shows"
        self.baseUrl = "https://twit.tv"

        # setup the main parsing data
        self.episodeItemRegex = r'<img[^>]+src="(?<thumburl>[^"]+)"[^>]*></a>\W+<div[^>]+>\W+' \
                                r'<h2[^>]*><a[^>]+href="/(?<url>shows/[^"]+)"[^>]*>(?<title>[^<]+)' \
                                r'</a></h2>\W+<div[^>]*>(?<description>[^<]+)'
        self.episodeItemRegex = Regexer.from_expresso(self.episodeItemRegex)
        self._add_data_parser(self.mainListUri,
                              preprocessor=self.add_live_stream,
                              match_type=ParserData.MatchExact,
                              parser=self.episodeItemRegex,
                              creator=self.create_episode_item)

        self.videoItemRegex = r'<div[^>]+class="episode item"[^>]*>\W+<a[^>]+href="(?<url>[^"]+)" ' \
                              r'title="(?<title>[^"]+)">[\w\W]{0,500}?<img[^>]+src="' \
                              r'(?<thumburl>[^"]+)"[^>]+>[\w\W]{0,500}?<span[^>]+class="date"' \
                              r'[^>]*>(?<month>\w+) (?<day>\d+)\w+ (?<year>\d+)'
        self.videoItemRegex = Regexer.from_expresso(self.videoItemRegex)
        self._add_data_parser("*",
                              parser=self.videoItemRegex,
                              creator=self.create_video_item,
                              updater=self.update_video_item)

        self.mediaUrlRegex = r'<a href="([^"]+_(\d+).mp4)"[^>]+download>'

        # ====================================== Actual channel setup STOPS here =======================================
        return
    def __init__(self, channel_info):
        """ Initialisation of the class.

        All class variables should be instantiated here and this method should not
        be overridden by any derived classes.

        :param ChannelInfo channel_info: The channel info object to base this channel on.

        """

        chn_class.Channel.__init__(self, channel_info)

        # ============== Actual channel setup STARTS here and should be overwritten from derived classes ===============
        # setup the urls
        self.baseUrl = "https://www.kijkbijons.nl"
        self.mainListUri = "https://www.kijkbijons.nl/programmas"

        # Setup textures
        self.noImage = "onsimage.png"

        # Define parsers
        episode_regex = r'<a class="clipItem"[^>]*href="(?<url>[^"]+)[^>]*>\s*<span class="clipItemImage">\s*<img[^>]*src="(?<thumburl>[^"]+)"[^>]+alt="(?<title>[^"]+)"[^>]*>'
        self._add_data_parser(self.mainListUri,
                              name="Main Programlist",
                              parser=Regexer.from_expresso(episode_regex),
                              creator=self.create_episode_item)

        video_regex = r'<a class="clipItem"\s+href="(?<url>[^"]+item\?(?<id>[^"]+))"[^>]+>\s+<[^>]+>\s*<img src="(?<thumb>[^"]+)[^>]*>\s*(?:[^>]+>\s*){4}(?<title>[^\n\r<]+)'
        self._add_data_parser("*",
                              name="Main Video parsers",
                              parser=Regexer.from_expresso(video_regex),
                              creator=self.create_video_item,
                              updater=self.update_video_item)

        #===============================================================================================================
        # non standard items

        return
    def __init__(self, channel_info):
        """ Initialisation of the class.

        All class variables should be instantiated here and this method should not
        be overridden by any derived classes.

        :param ChannelInfo channel_info: The channel info object to base this channel on.

        """

        chn_class.Channel.__init__(self, channel_info)

        # configure login stuff
        # setup the urls
        self.noImage = "flevoimage.png"
        self.mainListUri = "https://www.omroepflevoland.nl/block/missed/list?category=Gemist&page=1"
        self.baseUrl = "https://www.omroepflevoland.nl"
        self.channelBitrate = 780

        video_item_regex = r'<a[^>]+href="(?<url>[^"]+)"(?:[^>]+>\W*){2}<picture[^>]+>\s*' \
                           r'<source[^>]+srcset="(?<thumburl>[^"]+)"[^>]*>\s*(?:[^>]+>){9}\s*<h5>' \
                           r'(?<title>[^<]+)<[^>]*>\s*(?<date>\d+-\d+-\d+\s+\d+:\d+)(?:[^>]+>)' \
                           r'{11}\W*(?<description>[^<]+)</p>'
        video_item_regex = Regexer.from_expresso(video_item_regex)

        self._add_data_parser(self.mainListUri,
                              preprocessor=self.add_live_streams,
                              parser=video_item_regex,
                              creator=self.create_video_item)

        self._add_data_parser("https://[^/]*.cloudfront.net/live/",
                              updater=self.update_live_urls,
                              match_type=ParserData.MatchRegex)

        self._add_data_parser("*",
                              preprocessor=self.add_live_streams,
                              parser=video_item_regex,
                              creator=self.create_video_item,
                              updater=self.update_video_item)

        #===============================================================================================================
        # non standard items

        #===============================================================================================================
        # Test cases:

        # ====================================== Actual channel setup STOPS here =======================================
        return
示例#11
0
    def __init__(self, channel_info):
        """ Initialisation of the class.

        All class variables should be instantiated here and this method should not
        be overridden by any derived classes.

        :param ChannelInfo channel_info: The channel info object to base this channel on.

        """

        chn_class.Channel.__init__(self, channel_info)

        # setup the main parsing data
        if self.channelCode == "vijfbe":
            self.noImage = "vijfimage.png"
            self.mainListUri = "https://www.vijf.be/"
            self.baseUrl = "https://www.vijf.be"

        elif self.channelCode == "zesbe":
            self.noImage = "zesimage.png"
            self.mainListUri = "https://www.zestv.be/"
            self.baseUrl = "https://www.zestv.be"

        else:
            self.noImage = "vierimage.png"
            self.mainListUri = "https://www.vier.be/"
            self.baseUrl = "https://www.vier.be"

        episode_regex = '<a class="program-overview__link" href="(?<url>[^"]+)">\s+<span class="program-overview__title">\s+(?<title>[^<]+)</span>.*?</a>'
        episode_regex = Regexer.from_expresso(episode_regex)
        self._add_data_parser(self.mainListUri,
                              match_type=ParserData.MatchExact,
                              parser=episode_regex,
                              creator=self.create_episode_item)

        self._add_data_parser("*",
                              match_type=ParserData.MatchExact,
                              name="Json video items",
                              json=True,
                              preprocessor=self.extract_hero_data,
                              parser=["data", "playlists", 0, "episodes"],
                              creator=self.create_video_item_api)

        video_regex = r'<a(?:[^>]+data-background-image="(?<thumburl>[^"]+)")?[^>]+href="' \
                      r'(?<url>/video/[^"]+)"[^>]*>(?:\s+<div[^>]+>\s+<div [^>]+' \
                      r'data-background-image="(?<thumburl2>[^"]+)")?[\w\W]{0,1000}?' \
                      r'<h3[^>]*>(?:<span>)?(?<title>[^<]+)(?:</span>)?</h3>(?:\s+' \
                      r'(?:<div[^>]*>\s+)?<div[^>]*>[^<]+</div>\s+<div[^>]+data-timestamp=' \
                      r'"(?<timestamp>\d+)")?'
        video_regex = Regexer.from_expresso(video_regex)
        self._add_data_parser("*",
                              match_type=ParserData.MatchExact,
                              name="Normal video items",
                              parser=video_regex,
                              creator=self.create_video_item)

        # Generic updater with login
        self._add_data_parser("https://api.viervijfzes.be/content/",
                              updater=self.update_video_item_with_id)
        self._add_data_parser("*", updater=self.update_video_item)

        # ==========================================================================================
        # Channel specific stuff
        self.__idToken = None
        self.__meta_playlist = "current_playlist"
        self.__no_clips = False

        # ==========================================================================================
        # Test cases:
        # Documentaire: pages (has http://www.canvas.be/tag/.... url)
        # Not-Geo locked: Kroost

        # ====================================== Actual channel setup STOPS here ===================
        return
    def __init__(self, channel_info):
        """ Initialisation of the class.

        All class variables should be instantiated here and this method should not
        be overridden by any derived classes.

        :param ChannelInfo channel_info: The channel info object to base this channel on.

        """

        chn_class.Channel.__init__(self, channel_info)

        # ============== Actual channel setup STARTS here and should be overwritten from derived classes ===============
        self.noImage = "vrtnuimage.png"
        self.mainListUri = "https://www.vrt.be/vrtnu/a-z/"
        self.baseUrl = "https://www.vrt.be"

        # first regex is a bit tighter than the second one.
        episode_regex = r'<nui-tile href="(?<url>/vrtnu[^"]+)"[^>]*>\s*<h3[^>]*>\s*<a[^>]+>' \
                        r'(?<title>[^<]+)</a>\s*</h3>\s*<div[^>]+>(?:\s*<p>)?(?<description>' \
                        r'[\w\W]{0,2000}?)(?:</p>)?\W*</div>\s*(?:<p[^>]*' \
                        r'data-brand="(?<channel>[^"]+)"[^>]*>[^<]+</p>)?\s*(?:<img[\w\W]{0,100}?' \
                        r'data-responsive-image="(?<thumburl>//[^" ]+)")?'
        episode_regex = Regexer.from_expresso(episode_regex)
        self._add_data_parser(self.mainListUri, name="Main A-Z listing",
                              preprocessor=self.add_categories,
                              match_type=ParserData.MatchExact,
                              parser=episode_regex, creator=self.create_episode_item)

        self._add_data_parser("#channels", name="Main channel name listing",
                              preprocessor=self.list_channels)

        self._add_data_parser("https://search.vrt.be/suggest?facets[categories]",
                              name="JSON Show Parser", json=True,
                              parser=[], creator=self.create_show_item)

        self._add_data_parser("https://services.vrt.be/videoplayer/r/live.json", json=True,
                              name="Live streams parser",
                              parser=[], creator=self.create_live_stream)
        self._add_data_parsers(["http://live.stream.vrt.be/", "https://live-vrt.akamaized.net"],
                               name="Live streams updater",
                               updater=self.update_live_video)
        self._add_data_parser(r"https://live-[^/]+\.vrtcdn\.be",
                              match_type=ParserData.MatchRegex,
                              name="Live streams updater",
                              updater=self.update_live_video)

        self._add_data_parser("https://www.vrt.be/vrtnu/categorieen.model.json", name="Category parser",
                              json=True,
                              match_type=ParserData.MatchExact,
                              parser=[":items", "par", ":items", "categories", "items"],
                              creator=self.create_category)

        folder_regex = r'<li class="vrt-labelnav--item "[^>]*>\s*(?:<h2[^<]*>\s*)?<a[^>]*href="(?<url>[^"]+)"[^>]*>(?:\W*<nui[^>]*>\W*)?(?<title>[^<]+)</'
        folder_regex = Regexer.from_expresso(folder_regex)
        self._add_data_parser("*", name="Folder/Season parser",
                              parser=folder_regex, creator=self.create_folder_item)

        video_regex = r'<a[^>]+href="(?<url>/vrtnu/(?:[^/]+/){2}[^/]*?(?<year2>\d*)/[^"]+)"[^>]*>' \
                      r'\W*(?<title>[^<]+)(?:<br\s*/>\s*)?</a>\s*</h3>\s*<p[^>]*>\W*(?<channel>[^<]+)' \
                      r'</p>\s*(?:<p[^<]+</p>\s*)?<div[^>]*class="meta[^>]*>\s*(?:<time[^>]+datetime=' \
                      r'"(?<year>\d+)-(?<month>\d+)-(?<day>\d+))?[\w\W]{0,1000}?ata-responsive-image=' \
                      r'"(?<thumburl>[^"]+)'

        # No need for a subtitle for now as it only includes the textual date
        video_regex = Regexer.from_expresso(video_regex)
        self._add_data_parser("*", name="Video item parser",
                              parser=video_regex, creator=self.create_video_item)

        # needs to be after the standard video item regex
        single_video_regex = r'<script type="application/ld\+json">\W+({[\w\W]+?})\s*</script'
        single_video_regex = Regexer.from_expresso(single_video_regex)
        self._add_data_parser("*", name="Single video item parser",
                              parser=single_video_regex, creator=self.create_single_video_item)

        self._add_data_parser("*", updater=self.update_video_item, requires_logon=True)

        # ===============================================================================================================
        # non standard items
        self.__hasAlreadyVideoItems = False
        self.__currentChannel = None

        # The key is the channel live stream key
        self.__channelData = {
            "vualto_mnm": {
                "title": "MNM",
                "metaCode": "mnm",
                "fanart": TextureHandler.instance().get_texture_uri(self, "mnmfanart.jpg"),
                "thumb": TextureHandler.instance().get_texture_uri(self, "mnmimage.jpg"),
                "icon": TextureHandler.instance().get_texture_uri(self, "mnmicon.png")
            },
            "vualto_stubru": {
                "title": "Studio Brussel",
                "metaCode": "stubru",
                "fanart": TextureHandler.instance().get_texture_uri(self, "stubrufanart.jpg"),
                "thumb": TextureHandler.instance().get_texture_uri(self, "stubruimage.jpg"),
                "icon": TextureHandler.instance().get_texture_uri(self, "stubruicon.png")
            },
            "vualto_een_geo": {
                "title": "E&eacute;n",
                "metaCode": "een",
                "fanart": TextureHandler.instance().get_texture_uri(self, "eenfanart.jpg"),
                "thumb": TextureHandler.instance().get_texture_uri(self, "eenimage.png"),
                "icon": TextureHandler.instance().get_texture_uri(self, "eenlarge.png"),
                # "url": "https://live-vrt.akamaized.net/groupc/live/8edf3bdf-7db3-41c3-a318-72cb7f82de66/live_aes.isml/.m3u8"
            },
            "vualto_canvas_geo": {
                "title": "Canvas",
                "metaCode": "canvas",
                "fanart": TextureHandler.instance().get_texture_uri(self, "canvasfanart.png"),
                "thumb": TextureHandler.instance().get_texture_uri(self, "canvasimage.png"),
                "icon": TextureHandler.instance().get_texture_uri(self, "canvaslarge.png"),
                # "url": "https://live-vrt.akamaized.net/groupc/live/14a2c0f6-3043-4850-88a5-7fb062fe7f05/live_aes.isml/.m3u8"
            },
            "vualto_ketnet_geo": {
                "title": "KetNet",
                "metaCode": "ketnet",
                "fanart": TextureHandler.instance().get_texture_uri(self, "ketnetfanart.jpg"),
                "thumb": TextureHandler.instance().get_texture_uri(self, "ketnetimage.jpg"),
                "icon": TextureHandler.instance().get_texture_uri(self, "ketnetlarge.png"),
                # "url": "https://live-vrt.akamaized.net/groupc/live/f132f1b8-d04d-404e-90e0-6da1abb4f4fc/live_aes.isml/.m3u8"
            },
            "vualto_sporza_geo": {  # not in the channel filter maps, so no metaCode
                "title": "Sporza",
                "fanart": TextureHandler.instance().get_texture_uri(self, "sporzafanart.jpg"),
                "thumb": TextureHandler.instance().get_texture_uri(self, "sporzaimage.jpg"),
                "icon": TextureHandler.instance().get_texture_uri(self, "sporzalarge.png"),
                # "url": "https://live-vrt.akamaized.net/groupa/live/7d5f0e4a-3429-4861-91d4-aa3229d7ad7b/live_aes.isml/.m3u8"
            },
            "ketnet-jr": {  # Not in the live channels
                "title": "KetNet Junior",
                "metaCode": "ketnet-jr",
                "fanart": TextureHandler.instance().get_texture_uri(self, "ketnetfanart.jpg"),
                "thumb": TextureHandler.instance().get_texture_uri(self, "ketnetimage.jpg"),
                "icon": TextureHandler.instance().get_texture_uri(self, "ketnetlarge.png")
            }
        }

        # To get the tokens:
        # POST
        # Content-Type:application/json
        # https://media-services-public.vrt.be/vualto-video-aggregator-web/rest/external/v1/tokens

        # ===============================================================================================================
        # Test cases:

        # ====================================== Actual channel setup STOPS here =======================================
        return
    def __init__(self, channel_info):
        """ Initialisation of the class.

        All class variables should be instantiated here and this method should not
        be overridden by any derived classes.

        :param ChannelInfo channel_info: The channel info object to base this channel on.

        """

        chn_class.Channel.__init__(self, channel_info)

        # ============== Actual channel setup STARTS here and should be overwritten from derived classes ===============
        # setup the main parsing data
        if self.channelCode == 'nickelodeon':
            self.noImage = "nickelodeonimage.png"
            self.mainListUri = "http://www.nickelodeon.nl/shows"
            self.baseUrl = "http://www.nickelodeon.nl"

        elif self.channelCode == "nickno":
            self.noImage = "nickelodeonimage.png"
            self.mainListUri = "http://www.nickelodeon.no/program/"
            self.baseUrl = "http://www.nickelodeon.no"

        else:
            raise NotImplementedError("Unknown channel code")

        episode_item_regex = r"""<a[^>]+href="(?<url>/[^"]+)"[^>]*>\W*<img[^>]+src='(?<thumburl>[^']+)'[^>]*>\W*<div class='info'>\W+<h2 class='title'>(?<title>[^<]+)</h2>\W+<p class='sub_title'>(?<description>[^<]+)</p>"""
        episode_item_regex = Regexer.from_expresso(episode_item_regex)
        self._add_data_parser(self.mainListUri,
                              match_type=ParserData.MatchExact,
                              preprocessor=self.no_nick_jr,
                              parser=episode_item_regex,
                              creator=self.create_episode_item)
        # <h2 class='row-title'>Nick Jr

        video_item_regex = r"""<li[^>]+data-item-id='\d+'>\W+<a href='(?<url>[^']+)'>\W+<img[^>]+src="(?<thumburl>[^"]+)"[^>]*>\W+<p class='title'>(?<title>[^<]+)</p>\W+<p[^>]+class='subtitle'[^>]*>(?<subtitle>[^>]+)</p>"""
        video_item_regex = Regexer.from_expresso(video_item_regex)
        self._add_data_parser("*",
                              preprocessor=self.pre_process_folder_list,
                              parser=video_item_regex,
                              creator=self.create_video_item,
                              updater=self.update_video_item)

        self.pageNavigationRegex = r'href="(/video[^?"]+\?page_\d*=)(\d+)"'
        self.pageNavigationRegexIndex = 1
        self._add_data_parser("*",
                              parser=self.pageNavigationRegex,
                              creator=self.create_page_item)

        self.mediaUrlRegex = '<param name="src" value="([^"]+)" />'  # used for the update_video_item
        self.swfUrl = "http://origin-player.mtvnn.com/g2/g2player_2.1.7.swf"

        #===============================================================================================================
        # Test cases:
        #  NO: Avator -> Other items
        #  SE: Hotel 13 -> Other items
        #  NL: Sam & Cat -> Other items

        # ====================================== Actual channel setup STOPS here =======================================
        return
    def __init__(self, channel_info):
        """ Initialisation of the class.

        All class variables should be instantiated here and this method should not
        be overridden by any derived classes.

        :param ChannelInfo channel_info: The channel info object to base this channel on.

        """

        chn_class.Channel.__init__(self, channel_info)

        # ============== Actual channel setup STARTS here and should be overwritten from derived classes ===============
        if self.channelCode == "sporza":
            self.noImage = "sporzaimage.jpg"
            self.mainListUri = "http://sporza.be/cm/sporza/videozone"
            self.baseUrl = "http://sporza.be"
        else:
            raise IndexError("Invalid Channel Code")

        # elif self.channelCode == "ketnet":
        #     self.noImage = "ketnetimage.png"
        #     self.mainListUri = "http://video.ketnet.be/cm/ketnet/ketnet-mediaplayer"
        #     self.baseUrl = "http://video.ketnet.be"
        #
        # elif self.channelCode == "cobra":
        #     self.noImage = "cobraimage.png"
        #     self.mainListUri = "http://www.cobra.be/cm/cobra/cobra-mediaplayer"
        #     self.baseUrl = "http://www.cobra.be"

        # setup the urls
        self.swfUrl = "%s/html/flash/common/player.5.10.swf" % (self.baseUrl,)

        # setup the main parsing data
        episode_regex = r'<li[^>]*>\W*<a href="(/cm/[^"]+/videozone/programmas/[^"]+)" ' \
                        r'title="([^"]+)"\W*>'
        self._add_data_parser(self.mainListUri, match_type=ParserData.MatchExact,
                              preprocessor=self.add_live_channel,
                              parser=episode_regex,
                              creator=self.create_episode_item)

        # extract the right section, although it is hard to determine the actual one
        self._add_data_parser("*", preprocessor=self.extract_video_section)

        # the main video of the page
        regex = Regexer.from_expresso(
            r'<img[^>]+src="(?<thumburl>[^"]+)"[^>]*>[\w\W]{0,700}<p>(?<description>[^<]+)</p>'
            r'[\w\W]{0,500}?<a href="(?<url>/cm/[^/]+/videozone/[^?"]+)" >(?<title>[^<]+)</a>')
        self._add_data_parser("*", name="Main video of the page",
                              parser=regex, creator=self.create_video_item)

        # other videos in the side bar
        regex = Regexer.from_expresso(
            r'<a[^>]*href="(?<url>[^"]+)"[^>]*class="videolink"[^>]*>\W*<span[^>]*>(?<title>[^"]+)'
            r'</span>\W*(?:<span[^>]*>(?<desciption>[^"]+)</span>\W*)?<span[^>]*>\W*<img[^>]*'
            r'src="(?<thumburl>[^"]+)"')
        self._add_data_parser("*", name="Other videos in the sidebar",
                              parser=regex, creator=self.create_video_item,
                              updater=self.update_video_item)

        # live streams
        live_regex = r'data-video-title="([^"]+)"\W+data-video-iphone-server="([^"]+)"\W+' \
                     r'[\w\W]{0,1000}data-video-sitestat-pubdate="(\d+)"[\w\W]{0,2000}' \
                     r'data-video-geoblocking="(\w+)"[^>]+>\W*<img[^>]*src="([^"]+)"'
        self._add_data_parser("http://sporza.be/cm/sporza/matchcenter/mc_livestream",
                              creator=self.create_live_channel,
                              parser=live_regex)
        self._add_data_parser("http://live.stream.vrt.be", updater=self.update_live_item)

        self.mediaUrlRegex = r'data-video-((?:src|rtmp|iphone|mobile)[^=]*)="([^"]+)"\W+' \
                             r'(?:data-video-[^"]+path="([^"]+)){0,1}'

        # ====================================== Actual channel setup STOPS here =======================================
        return
    def __init__(self, channel_info):
        """ Initialisation of the class.

        All class variables should be instantiated here and this method should not
        be overridden by any derived classes.

        :param ChannelInfo channel_info: The channel info object to base this channel on.

        """

        chn_class.Channel.__init__(self, channel_info)

        # ==== Actual channel setup STARTS here and should be overwritten from derived classes ====
        self.noImage = "urplayimage.png"

        # setup the urls
        self.mainListUri = "https://urplay.se/api/bff/v1/search?product_type=series&rows=10000&start=0"
        self.baseUrl = "https://urplay.se"
        self.swfUrl = "https://urplay.se/assets/jwplayer-6.12-17973009ab259c1dea1258b04bde6e53.swf"

        # Match the "series" API -> shows TV Shows
        self._add_data_parser(self.mainListUri,
                              json=True,
                              name="Show parser with categories",
                              match_type=ParserData.MatchExact,
                              preprocessor=self.add_categories_and_search,
                              parser=["results"],
                              creator=self.create_episode_json_item)

        # Match Videos (programs)
        self._add_data_parser(
            "https://urplay.se/api/bff/v1/search?product_type=program",
            name="Most viewed",
            json=True,
            parser=["results"],
            creator=self.create_video_item_json)

        self._add_data_parser("*",
                              json=True,
                              name="Json based video parser",
                              preprocessor=self.extract_json_data,
                              parser=["currentProduct", "series", "programs"],
                              creator=self.create_video_item_json)

        self._add_data_parser("*", updater=self.update_video_item)

        # Categories
        cat_reg = r'<a[^>]+href="(?<url>/blad[^"]+/(?<slug>[^"]+))"[^>]*>(?<title>[^<]+)<'
        cat_reg = Regexer.from_expresso(cat_reg)
        self._add_data_parser("https://urplay.se/",
                              name="Category parser",
                              match_type=ParserData.MatchExact,
                              parser=cat_reg,
                              creator=self.create_category_item)

        self._add_data_parsers([
            "https://urplay.se/api/bff/v1/search?play_category",
            "https://urplay.se/api/bff/v1/search?response_type=category"
        ],
                               name="Category content",
                               json=True,
                               parser=["results"],
                               creator=self.create_json_item)

        # Searching
        self._add_data_parser("https://urplay.se/search/json",
                              json=True,
                              parser=["programs"],
                              creator=self.create_search_result_program)
        self._add_data_parser("https://urplay.se/search/json",
                              json=True,
                              parser=["series"],
                              creator=self.create_search_result_serie)

        self.mediaUrlRegex = r"urPlayer.init\(([^<]+)\);"

        #===========================================================================================
        # non standard items
        self.__videoItemFound = False
        self.__cateogory_slugs = {
            "dokumentarfilmer": "dokument%C3%A4rfilmer",
            "forelasningar": "f%C3%B6rel%C3%A4sningar",
            "kultur-och-historia": "kultur%20och%20historia",
            "reality-och-livsstil": "reality%20och%20livsstil",
            "samhalle": "samh%C3%A4lle"
        }
        self.__cateogory_urls = {
            "radio":
            "https://urplay.se/api/bff/v1/search?response_type=category"
            "&singles_and_series=true"
            "&rows=1000&start=0"
            "&type=programradio&view=title",
            "syntolkat":
            "https://urplay.se/api/bff/v1/search?response_type=category"
            "&singles_and_series=true"
            "&rows=1000&start=0"
            "&view=title"
            "&with_audio_description=true",
            "teckensprak":
            "https://urplay.se/api/bff/v1/search?response_type=category"
            "&language=sgn-SWE"
            "&rows=1000&start=0"
            "&view=title"
            "&singles_and_series=true&view=title"
        }

        self.__timezone = pytz.timezone("Europe/Amsterdam")
        self.__episode_text = LanguageHelper.get_localized_string(
            LanguageHelper.EpisodeId)
        #===========================================================================================
        # Test cases:
        #   Anaconda Auf Deutch : RTMP, Subtitles

        # ====================================== Actual channel setup STOPS here ===================
        return
示例#16
0
    def __init__(self, channel_info):
        """ Initialisation of the class.

        All class variables should be instantiated here and this method should not
        be overridden by any derived classes.

        :param ChannelInfo channel_info: The channel info object to base this channel on.

        """

        chn_class.Channel.__init__(self, channel_info)

        self.liveUrl = None  # : the live url if present
        self.jsonParsing = False

        if self.channelCode == "omroepzeeland":
            self.noImage = "omroepzeelandimage.png"
            self.mainListUri = "https://www.omroepzeeland.nl/tvgemist"
            self.baseUrl = "https://www.omroepzeeland.nl"
            self.liveUrl = "https://zeeland.rpoapp.nl/v01/livestreams/AndroidTablet.json"

        elif self.channelCode == "rtvutrecht":
            self.noImage = "rtvutrechtimage.png"
            self.mainListUri = "https://www.rtvutrecht.nl/gemist/rtvutrecht/"
            self.baseUrl = "https://www.rtvutrecht.nl"
            # Uses NPO stream with smshield cookie
            self.liveUrl = "https://utrecht.rpoapp.nl/v02/livestreams/AndroidTablet.json"

        else:
            raise NotImplementedError("Channelcode '%s' not implemented" %
                                      (self.channelCode, ))

        # JSON Based Main lists
        self._add_data_parser(
            "https://www.omroepzeeland.nl/tvgemist",
            preprocessor=self.add_live_channel_and_extract_data,
            match_type=ParserData.MatchExact,
            parser=[],
            creator=self.create_json_episode_item,
            json=True)

        # HTML Based Main lists
        html_episode_regex = r'<option\s+value="(?<url>/gemist/uitzending/[^"]+)">(?<title>[^<]*)'
        html_episode_regex = Regexer.from_expresso(html_episode_regex)
        self._add_data_parser(
            "https://www.rtvutrecht.nl/gemist/rtvutrecht/",
            preprocessor=self.add_live_channel_and_extract_data,
            match_type=ParserData.MatchExact,
            parser=html_episode_regex,
            creator=self.create_episode_item,
            json=False)

        video_item_regex = r'<img src="(?<thumburl>[^"]+)"[^>]+alt="(?<title>[^"]+)"[^>]*/>\W*' \
                           r'</a>\W*<figcaption(?:[^>]+>\W*){2}<time[^>]+datetime="' \
                           r'(?<date>[^"]+)[^>]*>(?:[^>]+>\W*){3}<a[^>]+href="(?<url>[^"]+)"' \
                           r'[^>]*>\W*(?:[^>]+>\W*){3}<a[^>]+>(?<description>.+?)</a>'
        video_item_regex = Regexer.from_expresso(video_item_regex)
        self._add_data_parser(
            "https://www.rtvutrecht.nl/",
            name="HTML Video parsers and updater for JWPlayer embedded JSON",
            parser=video_item_regex,
            creator=self.create_video_item,
            updater=self.update_video_item_json_player)

        # Json based stuff
        self._add_data_parser("https://www.omroepzeeland.nl/RadioTv/Results?",
                              name="Video item parser",
                              json=True,
                              parser=[
                                  "searchResults",
                              ],
                              creator=self.create_json_video_item)

        self._add_data_parser(
            "https://www.omroepzeeland.nl/",
            name="Updater for Javascript file based stream data",
            updater=self.update_video_item_javascript)

        # Live Stuff
        self._add_data_parser(self.liveUrl,
                              name="Live Stream Creator",
                              creator=self.create_live_item,
                              parser=[],
                              json=True)

        self._add_data_parser(".+/live/.+",
                              match_type=ParserData.MatchRegex,
                              updater=self.update_live_item)
        #===============================================================================================================
        # non standard items

        #===============================================================================================================
        # Test cases:
        #   Omroep Zeeland: M3u8 playist

        # ====================================== Actual channel setup STOPS here =======================================
        return
示例#17
0
    def __init__(self, channel_info):
        """ Initialisation of the class.

        All class variables should be instantiated here and this method should not
        be overridden by any derived classes.

        :param ChannelInfo channel_info: The channel info object to base this channel on.

        """

        chn_class.Channel.__init__(self, channel_info)

        # ==== Actual channel setup STARTS here and should be overwritten from derived classes =====
        self.noImage = "rtbfimage.png"

        # setup the urls
        self.mainListUri = "https://www.rtbf.be/auvio/emissions"
        self.baseUrl = "https://www.rtbf.be"

        # setup the main parsing data
        episode_regex = r'<article[^>]+data-id="(?<id>(?<url>\d+))"[^>]*>\W+<figure[^>]+>\W+' \
                        r'<figcaption[^>]+>(?<title>[^{][^<]+)</figcaption>\W*<div[^>]*>\W*' \
                        r'<img[^>]*(?<thumburl>http[^"]+) \d+w"'
        episode_regex = Regexer.from_expresso(episode_regex)
        self._add_data_parser(self.mainListUri,
                              match_type=ParserData.MatchExact,
                              preprocessor=self.add_category_and_live_items,
                              parser=episode_regex,
                              creator=self.create_episode_item)

        self._add_data_parser("http://www.rtbf.be/news/api/menu?site=media",
                              json=True,
                              match_type=ParserData.MatchExact,
                              parser=["item", 3, "item"],
                              creator=self.create_category)

        live_regex = r'<img[^>]*(?<thumburl>http[^"]+) \d+w"[^>]*>[\w\W]{0,1000}Maintenant' \
                     r'</span> (?:sur )?(?<channel>[^>]+)</div>\W*<h3[^>]*>\W*<a[^>]+href="' \
                     r'(?<url>[^"]+=(?<liveId>\d+))"[^>]+title="(?<title>[^"]+)'
        live_regex = Regexer.from_expresso(live_regex)
        self._add_data_parser("https://www.rtbf.be/auvio/direct/",
                              parser=live_regex,
                              creator=self.create_video_item)

        self._add_data_parser("https://www.rtbf.be/auvio/embed/direct",
                              updater=self.update_live_item)

        video_regex = r'<img[^>]*alt="(?<title>[^"]+)"[^>]*(?<thumburl>http[^"]+) \d+w"[^>]*>' \
                      r'[\w\W]{0,1000}?<h4[^>]+>\W+<a[^>]+href="(?<url>[^<"]+=(?<videoId>\d+))"' \
                      r'[^>]*>[^<]*</a>\W*</h4>\W*(?:<h5[^>]+>(?<description>[^<]*)</h5>|<div)' \
                      r'[\w\W]{0,1000}?<time[^>]+datetime="(?<date>[^"]+)"'
        video_regex = Regexer.from_expresso(video_regex)
        self._add_data_parser("*",
                              parser=video_regex,
                              creator=self.create_video_item,
                              updater=self.update_video_item)

        self.pageNavigationRegexIndex = 1
        page_regex = r'<li class="(?:|[^a][^"]+)">\W+<a class="rtbf-pagination__link" ' \
                     r'href="([^"]+&p=)(\d+)"'
        self._add_data_parser("*",
                              parser=page_regex,
                              creator=self.create_page_item)

        self.swfUrl = "http://www.static.rtbf.be/rtbf/embed/js/vendor/jwplayer/jwplayer.flash.swf"
        # ==========================================================================================
        # Test cases:
        # 5@7

        # ====================================== Actual channel setup STOPS here ===================
        return
示例#18
0
    def __init__(self, channel_info):
        """ Initialisation of the class.

        All class variables should be instantiated here and this method should not
        be overridden by any derived classes.

        :param ChannelInfo channel_info: The channel info object to base this channel on.

        """

        chn_class.Channel.__init__(self, channel_info)

        # ==== Actual channel setup STARTS here and should be overwritten from derived classes ====
        self.noImage = "urplayimage.png"

        # setup the urls
        self.mainListUri = "#mainlist_merge"
        self.baseUrl = "https://urplay.se"
        self.swfUrl = "https://urplay.se/assets/jwplayer-6.12-17973009ab259c1dea1258b04bde6e53.swf"

        # Match the "series" API -> shows TV Shows
        self._add_data_parser(
            self.mainListUri,
            json=True,
            name="Show parser with categories",
            match_type=ParserData.MatchExact,
            preprocessor=self.merge_add_categories_and_search,
            parser=["results"],
            creator=self.create_episode_json_item)

        # Match Videos (programs)
        self._add_data_parser(
            "https://urplay.se/api/bff/v1/search?product_type=program",
            name="Most viewed",
            json=True,
            parser=["results"],
            creator=self.create_video_item_json_with_show_title)

        self._add_data_parser("*",
                              json=True,
                              name="Json based video parser",
                              parser=["accessibleEpisodes"],
                              creator=self.create_video_item_json)

        self._add_data_parser("*", updater=self.update_video_item)

        # Categories
        cat_reg = r'<a[^>]+href="(?<url>/blad[^"]+/(?<slug>[^"]+))"[^>]*>' \
                  r'(?:<svg[\w\W]{0,2000}?</svg>)?(?<title>[^<]+)<'
        cat_reg = Regexer.from_expresso(cat_reg)
        self._add_data_parser("https://urplay.se/",
                              name="Category parser",
                              match_type=ParserData.MatchExact,
                              parser=cat_reg,
                              creator=self.create_category_item)

        self._add_data_parsers([
            "https://urplay.se/api/bff/v1/search?play_category",
            "https://urplay.se/api/bff/v1/search?main_genre",
            "https://urplay.se/api/bff/v1/search?response_type=category",
            "https://urplay.se/api/bff/v1/search?type=programradio",
            "https://urplay.se/api/bff/v1/search?age=",
            "https://urplay.se/api/bff/v1/search?response_type=limited"
        ],
                               name="Category content",
                               json=True,
                               preprocessor=self.merge_category_items,
                               parser=["results"],
                               creator=self.create_json_item)

        # Searching
        self._add_data_parser("https://urplay.se/search/json",
                              json=True,
                              parser=["programs"],
                              creator=self.create_search_result_program)
        self._add_data_parser("https://urplay.se/search/json",
                              json=True,
                              parser=["series"],
                              creator=self.create_search_result_serie)

        self.mediaUrlRegex = r"urPlayer.init\(([^<]+)\);"

        #===========================================================================================
        # non standard items
        self.__videoItemFound = False

        # There is either a slug lookup or an url lookup
        self.__cateogory_slugs = {}

        self.__cateogory_urls = {
            "alla-program":
            "https://urplay.se/api/bff/v1/search?"
            "response_type=limited&"
            "product_type=series&"
            "rows={}&start={}&view=title",
            "barn":
            "https://urplay.se/api/bff/v1/search?"
            "age=children&"
            "platform=urplay&"
            "rows={}&"
            "singles_and_series=true&"
            "start={}"
            "&view=title",
            "dokumentarfilmer":
            "https://urplay.se/api/bff/v1/search?"
            "main_genre[]=dokument%C3%A4rfilm&main_genre[]=dokument%C3%A4rserie&"
            # "platform=urplay&"
            "singles_and_series=true&view=title&"
            "rows={}&"
            "singles_and_series=true&"
            "start={}"
            "&view=title",
            "drama":
            "https://urplay.se/api/bff/v1/search?"
            "main_genre[]=drama&main_genre[]=kortfilm&main_genre[]=fiktiva%20ber%C3%A4ttelser&"
            "platform=urplay&"
            "rows={}&"
            "singles_and_series=true&"
            "start={}&"
            "view=title",
            "forelasningar":
            "https://urplay.se/api/bff/v1/search?"
            "main_genre[]=f%C3%B6rel%C3%A4sning&main_genre[]=panelsamtal&"
            "platform=urplay&"
            "rows={}&"
            "singles_and_series=true&"
            "start={}&"
            "view=title",
            "halsa-och-relationer":
            "https://urplay.se/api/bff/v1/search?"
            "main_genre_must_not[]=forelasning&"
            "main_genre_must_not[]=panelsamtal&"
            "platform=urplay&"
            "rows={}&"
            "sab_category=kropp%20%26%20sinne&"
            "singles_and_series=true&"
            "start={}&"
            "view=title",
            "kultur-och-historia":
            "https://urplay.se/api/bff/v1/search?"
            "main_genre_must_not[]=forelasning&main_genre_must_not[]=panelsamtal&"
            "platform=urplay&"
            "rows={}&"
            "sab_category=kultur%20%26%20historia&"
            "singles_and_series=true&"
            "start={}&"
            "view=title",
            "natur-och-resor":
            "https://urplay.se/api/bff/v1/search?"
            "main_genre_must_not[]=forelasning&main_genre_must_not[]=panelsamtal&"
            "platform=urplay&"
            "rows={}&"
            "sab_category=natur%20%26%20resor&"
            "singles_and_series=true&"
            "start={}&"
            "view=title",
            "radio":
            "https://urplay.se/api/bff/v1/search?"
            "type=programradio&"
            "platform=urplay&"
            "rows={}&"
            "singles_and_series=true&"
            "start={}&"
            "view=title",
            "samhalle":
            "https://urplay.se/api/bff/v1/search?"
            "main_genre_must_not[]=forelasning&main_genre_must_not[]=panelsamtal&"
            "platform=urplay&"
            "rows={}&"
            "sab_category=samh%C3%A4lle&"
            "singles_and_series=true&"
            "start={}&"
            "view=title",
            "sprak":
            "https://urplay.se/api/bff/v1/search?"
            "main_genre_must_not[]=forelasning&main_genre_must_not[]=panelsamtal&"
            "platform=urplay&"
            "rows={}&"
            "sab_category=spr%C3%A5k&"
            "singles_and_series=true&"
            "start={}&"
            "view=title",
            "syntolkat":
            "https://urplay.se/api/bff/v1/search?"
            "response_type=category&"
            "is_audio_described=true&"
            "platform=urplay&"
            "rows={}&"
            "singles_and_series=true&"
            "start={}&"
            "view=title",
            "teckensprak":
            "https://urplay.se/api/bff/v1/search?"
            "response_type=category&"
            "language=sgn-SWE&"
            "platform=urplay&"
            "rows={}&"
            "singles_and_series=true&"
            "start={}&"
            "view=title",
            "utbildning-och-media":
            "https://urplay.se/api/bff/v1/search?"
            "main_genre_must_not[]=forelasning&"
            "main_genre_must_not[]=panelsamtal&"
            "platform=urplay&"
            "rows={}&"
            "sab_category=utbildning%20%26%20media&"
            "singles_and_series=true&"
            "start={}&"
            "view=title",
            "vetenskap":
            "https://urplay.se/api/bff/v1/search?"
            "main_genre_must_not[]=forelasning&main_genre_must_not[]=panelsamtal&"
            "platform=urplay&"
            "rows={}&"
            "sab_category=vetenskap%20%26%20teknik&"
            "singles_and_series=true&"
            "start={}&"
            "view=title"
        }

        self.__timezone = pytz.timezone("Europe/Amsterdam")
        self.__episode_text = LanguageHelper.get_localized_string(
            LanguageHelper.EpisodeId)
        #===========================================================================================
        # Test cases:
        #   Anaconda Auf Deutch : RTMP, Subtitles

        # ====================================== Actual channel setup STOPS here ===================
        return
示例#19
0
    def __init__(self, channel_info):
        """ Initialisation of the class.

        All class variables should be instantiated here and this method should not
        be overridden by any derived classes.

        :param ChannelInfo channel_info: The channel info object to base this channel on.

        """

        chn_class.Channel.__init__(self, channel_info)

        # ============== Actual channel setup STARTS here and should be overwritten from derived classes ===============
        # The following data was taken from http://playapi.mtgx.tv/v3/channels
        self.channelIds = None
        self.mainListUri = None

        # The LV channels
        if self.channelCode == "tv3lv":
            self.noImage = "tv3lvimage.png"
            self.mainListUri = "https://tvplay.skaties.lv/seriali/"
            self.channelIds = (
                1482,  # TV3
                6400,  # LNT
                6401,  # TV6
                6402,  # TV5
                6403,  # Kanals2
                6404,  # TVPlay
                6405  # 3+
            )

        # EE channels
        elif self.channelCode == "tv3ee":
            self.mainListUri = "https://tvplay.tv3.ee/saated/tv3/"
            self.noImage = "tv3noimage.png"
            self.channelId = (1375, 6301, 6302)

        elif self.channelCode == "tv6ee":
            self.mainListUri = "https://tvplay.tv3.ee/saated/tv6/"
            self.noImage = "tv6seimage.png"
            self.channelId = (6300, )

        # Lithuanian channels
        elif self.channelCode == "tv3lt":
            self.mainListUri = "https://tvplay.tv3.lt/pramogines-laidos/tv3/"
            self.noImage = "tv3ltimage.png"
            self.channelId = (3000, 6503)

        elif self.channelCode == "tv6lt":
            self.mainListUri = "https://tvplay.tv3.lt/pramogines-laidos/tv6/"
            self.noImage = "tv6ltimage.png"
            self.channelId = (6501, )

        elif self.channelCode == "tv8lt":
            self.mainListUri = "https://tvplay.tv3.lt/pramogines-laidos/tv8/"
            self.noImage = "tv8seimage.png"
            self.channelId = (6502, )

        else:
            raise ValueError("Unknown channelcode {0}".format(
                self.channelCode))

        self.episodeItemRegex = r'<a[^>*]+href="(?<url>[^"]+)"[^>]*>\W+<img[^>]+data-srcset="[^"]*' \
                                r'(?<thumburl>http[^" ]+)[^"]+"[^>]+alt="(?<title>[^"]+)"'
        self.videoItemRegex = r'{0}[\w\W]{{0,1000}}?site-thumb-info[^>]+>(?<description>[^<]+)'. \
            format(self.episodeItemRegex)

        self.folderItemRegex = r'<option value="(?<url>[^"]+)"\W*>(?<title>[^<]+)</option>'

        self.episodeItemRegex = Regexer.from_expresso(self.episodeItemRegex)
        self._add_data_parser(self.mainListUri,
                              match_type=ParserData.MatchExact,
                              preprocessor=self.add_search,
                              parser=self.episodeItemRegex,
                              creator=self.create_episode_item)

        self.videoItemRegex = Regexer.from_expresso(self.videoItemRegex)
        self._add_data_parser("*",
                              preprocessor=self.remove_clips,
                              parser=self.videoItemRegex,
                              creator=self.create_video_item)

        self.folderItemRegex = Regexer.from_expresso(self.folderItemRegex)
        self._add_data_parser("*",
                              parser=self.folderItemRegex,
                              creator=self.create_folder_item)

        # Add an updater
        self._add_data_parser("*", updater=self.update_video_item)

        self.baseUrl = "{0}//{2}".format(*self.mainListUri.split("/", 3))
        self.searchInfo = {
            "se": ["sok", "S&ouml;k"],
            "ee": ["otsi", "Otsi"],
            "dk": ["sog", "S&oslash;g"],
            "no": ["sok", "S&oslash;k"],
            "lt": ["paieska", "Paie&scaron;ka"],
            "lv": ["meklet", "Mekl&#275;t"]
        }
示例#20
0
    def __init__(self, channel_info):
        """ Initialisation of the class.

        All class variables should be instantiated here and this method should not
        be overridden by any derived classes.

        :param ChannelInfo channel_info: The channel info object to base this channel on.

        """

        chn_class.Channel.__init__(self, channel_info)

        # ==== Actual channel setup STARTS here and should be overwritten from derived classes ====
        self.noImage = "urplayimage.png"

        # setup the urls
        self.mainListUri = "https://urplay.se/api/bff/v1/search?product_type=series&rows=10000&start=0"
        self.baseUrl = "https://urplay.se"
        self.swfUrl = "https://urplay.se/assets/jwplayer-6.12-17973009ab259c1dea1258b04bde6e53.swf"

        # Match the "series" API -> shows TV Shows
        self._add_data_parser(self.mainListUri, json=True,
                              name="Show parser with categories",
                              match_type=ParserData.MatchExact,
                              preprocessor=self.add_categories_and_search,
                              parser=["results"], creator=self.create_json_episode_item)

        # Match Videos (programs)
        self._add_data_parser("https://urplay.se/api/bff/v1/search?product_type=program",
                              name="Most viewed", json=True,
                              parser=["results"], creator=self.create_json_video_item)

        item_regex = r'href="/(?<url>[^/]+/(?<id>\d+)[^"]+)"[^>]*>[^<]+</a>\W+<figure[^>]*>[\W\w]' \
                     r'{0,3000}?<h2[^>]*>(?<title>[^<]+)</h2>\W+<p[^>]+>[^>]*<span[^>]+>' \
                     r'(?<description>[^<]*).{2}<[^>]+>\s*<span[^>]+>(?<duration>\d{1,3})\smin[^>]+' \
                     r'>\s*<span[^>]*>(?<description2>[^<]+)'
        item_regex = Regexer.from_expresso(item_regex)

        single_video_regex = r'<meta \w+="name" content="(?:[^:]+: )?(?<title>[^"]+)' \
                             r'"[^>]*>\W*<meta \w+="description" content="(?<description>[^"]+)"' \
                             r'[^>]*>\W*<meta \w+="url" content="(?:[^"]+/(?<url>\w+/' \
                             r'(?<id>\d+)[^"]+))"[^>]*>\W*<meta \w+="thumbnailURL[^"]*" ' \
                             r'content="(?<thumbnail>[^"]+)"[^>]*>\W+<meta \w+="uploadDate" ' \
                             r'content="(?<date>[^"]+)"'
        single_video_regex = Regexer.from_expresso(single_video_regex)

        self._add_data_parser("*", parser=item_regex, preprocessor=self.get_video_section,
                              creator=self.create_video_item)
        self._add_data_parser("*", parser=single_video_regex, preprocessor=self.get_video_section,
                              creator=self.create_single_video_item, updater=self.update_video_item)

        # Folders (Seasons)
        season_regex = '<li[^>]+>[^>]+data-description="(?<description>[^"]+)"[^>]+' \
                       'data-asset-id="(?<id>[^"]+)"[^>]+>[\n\r ]*(?<title>[^<]+?)[\n\r ]*<'
        season_regex = Regexer.from_expresso(season_regex)
        self._add_data_parser("*", name="Season Folders",
                              parser=season_regex, creator=self.create_folder_item)

        # Categories
        cat_reg = r'<a[^>]+href="(?<url>/blad[^"]+/(?<slug>[^"]+))"[^>]*>(?<title>[^<]+)<'
        cat_reg = Regexer.from_expresso(cat_reg)
        self._add_data_parser("https://urplay.se/", name="Category parser",
                              match_type=ParserData.MatchExact,
                              parser=cat_reg,
                              creator=self.create_category_item)

        self._add_data_parsers(["https://urplay.se/api/bff/v1/search?play_category",
                                "https://urplay.se/api/bff/v1/search?response_type=category"],
                               name="Category content", json=True,
                               parser=["results"], creator=self.create_json_item)

        # Searching
        self._add_data_parser("https://urplay.se/search/json", json=True,
                              parser=["programs"], creator=self.create_search_result_program)
        self._add_data_parser("https://urplay.se/search/json", json=True,
                              parser=["series"], creator=self.create_search_result_serie)

        self.mediaUrlRegex = r"urPlayer.init\(([^<]+)\);"

        #===========================================================================================
        # non standard items
        self.__videoItemFound = False
        self.__cateogory_slugs = {
            "dokumentarfilmer": "dokument%C3%A4rfilmer",
            "forelasningar": "f%C3%B6rel%C3%A4sningar",
            "kultur-och-historia": "kultur%20och%20historia",
            "reality-och-livsstil": "reality%20och%20livsstil",
            "samhalle": "samh%C3%A4lle"
        }
        self.__cateogory_urls = {
            "radio": "https://urplay.se/api/bff/v1/search?response_type=category"
                     "&singles_and_series=true"
                     "&rows=1000&start=0"
                     "&type=programradio&view=title",
            "syntolkat": "https://urplay.se/api/bff/v1/search?response_type=category"
                         "&singles_and_series=true"
                         "&rows=1000&start=0"
                         "&view=title"
                         "&with_audio_description=true",
            "teckensprak": "https://urplay.se/api/bff/v1/search?response_type=category"
                           "&language=sgn-SWE"
                           "&rows=1000&start=0"
                           "&view=title"                         
                           "&singles_and_series=true&view=title"
        }

        #===========================================================================================
        # Test cases:
        #   Anaconda Auf Deutch : RTMP, Subtitles

        # ====================================== Actual channel setup STOPS here ===================
        return