Esempio n. 1
0
    def __show_first_time_message(self, channel_info):
        """ Checks if it is the first time a channel is executed and if a first time message is
        available it will be shown.

        Shows a message dialog if the message should be shown.  Make sure that each line fits
        in a single line of a Kodi Dialog box (50 chars).

        :param ChannelInfo channel_info:    The ChannelInfo to show a message for.

        """

        hide_first_time = AddonSettings.hide_first_time_messages()
        if channel_info.firstTimeMessage:
            if not hide_first_time:
                Logger.info(
                    "Showing first time message '%s' for channel chn_%s.",
                    channel_info.firstTimeMessage, channel_info.moduleName)

                title = LanguageHelper.get_localized_string(
                    LanguageHelper.ChannelMessageId)
                XbmcWrapper.show_dialog(
                    title, channel_info.firstTimeMessage.split("|"))
            else:
                Logger.debug(
                    "Not showing first time message due to add-on setting set to '%s'.",
                    hide_first_time)
        return
Esempio n. 2
0
    def set_bitrate(self):
        """ Sets the bitrate for the selected channel via a specific dialog. """

        if self.channelObject is None:
            raise ValueError("Missing channel")

        # taken from the settings.xml
        bitrate_options = "Retrospect|100|250|500|750|1000|1500|2000|2500|4000|8000|20000"\
            .split("|")

        current_bitrate = AddonSettings.get_max_channel_bitrate(
            self.channelObject)
        Logger.debug("Found bitrate for %s: %s", self.channelObject,
                     current_bitrate)
        current_bitrate_index = 0 if current_bitrate not in bitrate_options \
            else bitrate_options.index(current_bitrate)

        dialog = xbmcgui.Dialog()
        heading = LanguageHelper.get_localized_string(
            LanguageHelper.BitrateSelection)
        selected_bitrate = dialog.select(heading,
                                         bitrate_options,
                                         preselect=current_bitrate_index)
        if selected_bitrate < 0:
            return

        Logger.info("Changing bitrate for %s from %s to %s",
                    self.channelObject, bitrate_options[current_bitrate_index],
                    bitrate_options[selected_bitrate])

        AddonSettings.set_max_channel_bitrate(
            self.channelObject, bitrate_options[selected_bitrate])
        return
Esempio n. 3
0
    def add_categories_and_search(self, data):
        """ Adds some generic items such as search and categories to the main listing.

        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 = []
        max_items = 200
        categories = {
            LanguageHelper.Popular: "https://urplay.se/api/bff/v1/search?product_type=program&query=&rows={}&start=0&view=most_viewed".format(max_items),
            LanguageHelper.MostRecentEpisodes: "https://urplay.se/api/bff/v1/search?product_type=program&rows={}&start=0&view=published".format(max_items),
            LanguageHelper.LastChance: "https://urplay.se/api/bff/v1/search?product_type=program&rows={}&start=0&view=last_chance".format(max_items),
            LanguageHelper.Categories: "https://urplay.se/",
            LanguageHelper.Search: "searchSite"
        }

        for cat in categories:
            title = "\a.: {} :.".format(LanguageHelper.get_localized_string(cat))
            item = MediaItem(title, categories[cat])
            item.thumb = self.noImage
            item.complete = True
            item.icon = self.icon
            item.dontGroup = True
            items.append(item)

        Logger.debug("Pre-Processing finished")
        return data, items
    def create_api_tvseason_type(self, result_set):
        """ Creates a new MediaItem for an TV Season.

        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

        """

        season_number = result_set["seasonNumber"]
        title = LanguageHelper.get_localized_string(LanguageHelper.SeasonId)
        title = "{} {:02d}".format(title, season_number)

        season_id = result_set["id"].rsplit("/", 1)[-1]
        url = self.__get_api_query_url(
            query=
            'programs(tvSeasonId:"{}",programTypes:EPISODE,skip:0,limit:{})'.
            format(season_id, self.__list_limit),
            fields=self.__video_fields)

        item = MediaItem(title, url)
        return item
Esempio n. 5
0
    def execute(self):
        title = LanguageHelper.get_localized_string(
            LanguageHelper.CleanupCache)[:-1]
        clean = \
            XbmcWrapper.show_yes_no(title, LanguageHelper.CleanupConfirmation)
        if not clean:
            Logger.warning("Clean-up cancelled")
            return

        files_to_remove = {
            "channelindex.json": "Cleaning: Channel Index",
            "xot.session.lock": "Cleaning: Session lock"
        }
        for file_name, log_line in files_to_remove.items():
            Logger.info(log_line)
            files_to_remove = os.path.join(Config.profileDir, file_name)
            if os.path.isfile(files_to_remove):
                os.remove(files_to_remove)

        Logger.info("Clearing cookies")
        UriHandler.clear_cookies()

        Logger.info("Cleaning: PickeStore objects")
        self.parameter_parser.pickler.purge_store(Config.addonId, age=0)

        Logger.info("Cleaning: Cache objects in cache folder")
        env_ctrl = EnvController(Logger.instance())
        env_ctrl.cache_clean_up(Config.cacheDir, 0)
Esempio n. 6
0
    def create_page_item(self, result_set):
        """ Creates a MediaItem of type 'page' using the result_set from the regex.

        This method creates a new MediaItem from the Regular Expression or Json
        results <result_set>. The method should be implemented by derived classes
        and are specific to the channel.

        :param list[str]|dict[str,str] result_set: The result_set of the self.episodeItemRegex

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

        """

        items = []
        if 'next' in result_set:
            title = LanguageHelper.get_localized_string(
                LanguageHelper.MorePages)
            url = result_set['next']
            item = MediaItem(title, url)
            item.fanart = self.parentItem.fanart
            item.thumb = self.parentItem.thumb
            items.append(item)

        return items
Esempio n. 7
0
    def create_page_item(self, result_set):
        """ Creates a MediaItem of type 'page' using the result_set from the regex.

        This method creates a new MediaItem from the Regular Expression or Json
        results <result_set>. The method should be implemented by derived classes
        and are specific to the channel.

        :param list[str]|dict[str,str] result_set: The result_set of the self.episodeItemRegex

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

        """

        Logger.trace(result_set)
        next_page = result_set["next"]
        if not next_page:
            Logger.debug("No more items available")
            return None

        more = LanguageHelper.get_localized_string(LanguageHelper.MorePages)
        url = "%s=%s" % (self.parentItem.url.rsplit("=", 1)[0], next_page)
        item = MediaItem(more, url)
        item.complete = True
        return item
    def create_alpha_item(self, result_set):
        """ Creates a MediaItem of type 'folder' using the Alpha chars available. It uses
        the result_set from the regex.

        This method creates a new MediaItem from the Regular Expression or Json
        results <result_set>. The method should be implemented by derived classes
        and are specific to the channel.

        :param list[str]|dict result_set: The result_set of the self.episodeItemRegex

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

        """

        program_count = result_set.get("availableInternationally", 0)
        if program_count <= 0:
            return None

        title = result_set["title"]
        url_part = title.lower()
        if url_part == "0-9":
            url_part = "$"
        url = "https://psapi.nrk.no/medium/tv/letters/{}/indexelements?onlyOnDemandRights=false&" \
              "apiKey={}".format(url_part, self.__api_key)

        title = LanguageHelper.get_localized_string(
            LanguageHelper.StartWith) % (title, )
        item = MediaItem(title, url)
        item.type = 'folder'
        return item
    def show_folder_selection(title,
                              default_path=None,
                              dialog_type=3,
                              mask=''):
        """ Shows a file/folder selection dialog for a given `dialog_type`:

        * 0 : ShowAndGetDirectory
        * 1 : ShowAndGetFile
        * 2 : ShowAndGetImage
        * 3 : ShowAndGetWriteableDirectory

        :param str|int title:        The title of the box or its language ID.
        :param str default_path:     Default path or file.
        :param int dialog_type:      Type of file/folder selection type.
        :param str mask:            '|' separated file mask. (i.e. '.jpg|.png').

        :return: the selected file/folder.
        :rtype: str

        """

        if isinstance(title, int):
            title = LanguageHelper.get_localized_string(title)

        if default_path is None:
            default_path = translatePath("special://home")

        browse_dialog = xbmcgui.Dialog()
        dest_folder = browse_dialog.browse(dialog_type, title, 'files', mask,
                                           False, False, default_path)
        return dest_folder
    def add_live_channel_and_extract_data(self, data):
        """ Add the live channel and extract the correct data to process further.

        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 = []

        title = LanguageHelper.get_localized_string(
            LanguageHelper.LiveStreamTitleId)
        item = MediaItem("\a.: {} :.".format(title), self.liveUrl)
        item.type = "folder"
        items.append(item)

        if not data:
            return "[]", items

        json_data = Regexer.do_regex(
            r"setupBroadcastArchive\('Tv',\s*([^;]+)\);", data)
        if isinstance(json_data, (tuple, list)) and len(json_data) > 0:
            Logger.debug("Pre-Processing finished")
            return json_data[0], items

        Logger.info("Cannot extract JSON data from HTML.")
        return data, items
Esempio n. 11
0
    def alpha_listing(self, data):
        """ Creates a alpha listing with items pointing to the alpha listing on line.

        :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 an Alpha list for BBC")

        items = []
        # https://www.bbc.co.uk/iplayer/a-z/a

        title_format = LanguageHelper.get_localized_string(
            LanguageHelper.StartWith)
        url_format = "https://www.bbc.co.uk/iplayer/a-z/%s"
        for char in "abcdefghijklmnopqrstuvwxyz0":
            if char == "0":
                char = "0-9"
            sub_item = MediaItem(title_format % (char.upper(), ),
                                 url_format % (char, ))
            sub_item.complete = True
            sub_item.dontGroup = True
            sub_item.HttpHeaders = {"X-Requested-With": "XMLHttpRequest"}
            items.append(sub_item)
        return data, items
Esempio n. 12
0
    def add_live_channel(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("Performing Pre-Processing")
        items = []

        title = LanguageHelper.get_localized_string(
            LanguageHelper.LiveStreamTitleId)
        item = MediaItem("\a.: {} :.".format(title), "")
        item.type = "folder"
        items.append(item)

        live_item = MediaItem(title, "#livestream")
        live_item.type = "video"
        live_item.isLive = True
        item.items.append(live_item)

        Logger.debug("Pre-Processing finished")
        return data, items
    def create_api_tvseason_type(self, result_set):
        """ Creates a new MediaItem for an TV Season.

        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

        """

        season_number = result_set["seasonNumber"]
        title = LanguageHelper.get_localized_string(LanguageHelper.SeasonId)
        title = "{} {:02d}".format(title, season_number)

        season_id = result_set["id"].rsplit("/", 1)[-1]
        url = self.__get_api_query_url(
            query='programs(tvSeasonId:"{}",programTypes:EPISODE,skip:0,limit:100)'.format(season_id),
            fields="{items{__typename,title,description,guid,updated,seriesTvSeasons{id},"
                   "imageMedia{url,label},type,sources{type,drm,file},series{title},seasonNumber,"
                   "tvSeasonEpisodeNumber,lastPubDate}}")

        item = MediaItem(title, url)
        return item
Esempio n. 14
0
    def __get_title(self, name):
        """ Create the title based on the MediaItems name and type.

        :param str name: the name to update.

        :return: an updated name
        :rtype: str

        """

        if not name:
            name = self.name

        if self.type == 'page':
            # We need to add the Page prefix to the item
            name = "%s %s" % (LanguageHelper.get_localized_string(
                LanguageHelper.Page), name)
            Logger.debug("MediaItem.__get_title :: Adding Page Prefix")

        elif self.__date != '' and not self.is_playable() \
                and not AddonSettings.is_min_version(AddonSettings.KodiLeia):
            # not playable items should always show date
            name = "%s [COLOR=dimgray](%s)[/COLOR]" % (name, self.__date)

        folder_prefix = AddonSettings.get_folder_prefix()
        if self.type == "folder" and not folder_prefix == "":
            name = "%s %s" % (folder_prefix, name)

        return name
Esempio n. 15
0
    def add_live_streams(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 = []
        if self.parentItem is None:
            live_item = MediaItem(
                "\a.: Live TV :.",
                "https://d5ms27yy6exnf.cloudfront.net/live/omroepflevoland/tv/index.m3u8"
            )
            live_item.icon = self.icon
            live_item.thumb = self.noImage
            live_item.type = 'video'
            live_item.dontGroup = True
            now = datetime.datetime.now()
            live_item.set_date(now.year, now.month, now.day, now.hour,
                               now.minute, now.second)
            items.append(live_item)

            live_item = MediaItem(
                "\a.: Live Radio :.",
                "https://d5ms27yy6exnf.cloudfront.net/live/omroepflevoland/radio/index.m3u8"
            )
            live_item.icon = self.icon
            live_item.thumb = self.noImage
            live_item.type = 'video'
            live_item.dontGroup = True
            now = datetime.datetime.now()
            live_item.set_date(now.year, now.month, now.day, now.hour,
                               now.minute, now.second)
            items.append(live_item)

        # add "More"
        more = LanguageHelper.get_localized_string(LanguageHelper.MorePages)
        current_url = self.parentItem.url if self.parentItem is not None else self.mainListUri
        url, page = current_url.rsplit("=", 1)
        url = "{}={}".format(url, int(page) + 1)

        item = MediaItem(more, url)
        item.thumb = self.noImage
        item.icon = self.icon
        item.fanart = self.fanart
        item.complete = True
        items.append(item)

        return data, items
Esempio n. 16
0
    def __get_context_menu_items(self, channel, item=None):
        """ Retrieves the custom context menu items to display.

        favouritesList : Boolean   - Indication that the menu is for the favorites

        :param Channel|None channel:    The channel from which to get the context menu items.
                                        The channel might be None in case of some actions that
                                        do not require a channel.
        :param MediaItem|None item:     The item to which the context menu belongs.

        :return: A list of context menu names and their commands.
        :rtype: list[tuple[str,str]]

        """

        context_menu_items = []

        # Genenric, none-Python menu items that would normally cause an unwanted reload of the
        # Python interpreter instance within Kodi.
        refresh = LanguageHelper.get_localized_string(LanguageHelper.RefreshListId)
        context_menu_items.append((refresh, 'XBMC.Container.Refresh()'))

        if item is None:
            return context_menu_items

        # if it was a favourites list, don't add the channel methods as they might be from a different channel
        if channel is None:
            return context_menu_items

        # now we process the other items
        possible_methods = self.__get_members(channel)
        # Logger.Debug(possible_methods)

        for menu_item in channel.contextMenuItems:
            # Logger.Debug(menu_item)
            if menu_item.itemTypes is None or item.type in menu_item.itemTypes:
                # We don't care for complete here!
                # if menu_item.completeStatus == None or menu_item.completeStatus == item.complete:

                # see if the method is available
                method_available = False

                for method in possible_methods:
                    if method == menu_item.functionName:
                        method_available = True
                        # break from the method loop
                        break

                if not method_available:
                    Logger.warning("No method for: %s", menu_item)
                    continue

                cmd_url = self._create_action_url(channel, action=menu_item.functionName, item=item)
                cmd = "XBMC.RunPlugin(%s)" % (cmd_url,)
                title = "Retro: %s" % (menu_item.label,)
                Logger.trace("Adding command: %s | %s", title, cmd)
                context_menu_items.append((title, cmd))

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

        others = MediaItem(
            "\b.: Populair :.",
            "https://api.kijk.nl/v2/default/sections/popular_PopularVODs?offset=0"
        )
        items.append(others)

        days = MediaItem("\b.: Deze week :.", "#lastweek")
        items.append(days)

        search = MediaItem("\b.: Zoeken :.", "searchSite")
        search.complete = True
        search.dontGroup = True
        search.HttpHeaders = {"X-Requested-With": "XMLHttpRequest"}
        items.append(search)

        if self.channelCode == "veronica":
            live = LanguageHelper.get_localized_string(
                LanguageHelper.LiveStreamTitleId)
            live_radio = MediaItem("Radio Veronica {}".format(live), "")
            live_radio.type = "video"
            live_radio.dontGroup = True

            part = live_radio.create_new_empty_media_part()
            live_stream = "https://talparadiohls-i.akamaihd.net/hls/live/585615/VR-Veronica-1/playlist.m3u8"
            if AddonSettings.use_adaptive_stream_add_on(with_encryption=False,
                                                        channel=self):
                stream = part.append_media_stream(live_stream, 0)
                M3u8.set_input_stream_addon_input(stream, self.proxy)
                live_radio.complete = True
            else:
                for s, b in M3u8.get_streams_from_m3u8(live_stream,
                                                       self.proxy):
                    live_radio.complete = True
                    part.append_media_stream(s, b)

            items.append(live_radio)

        Logger.debug("Pre-Processing finished")
        return data, items
    def __update_video_from_mpd(self, item, mpd_info,
                                use_adaptive_with_encryption):
        """ Updates an existing MediaItem with more data based on an MPD stream.

        :param dict[str,str] mpd_info:              Stream info retrieved from the stream json.
        :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

        """

        Logger.debug("Updating streams using BrightCove data.")

        part = item.create_new_empty_media_part()
        mpd_manifest_url = "https:{0}".format(mpd_info["mediaLocator"])
        mpd_data = UriHandler.open(mpd_manifest_url)
        subtitles = Regexer.do_regex(r'<BaseURL>([^<]+\.vtt)</BaseURL>',
                                     mpd_data)

        if subtitles:
            Logger.debug("Found subtitle: %s", subtitles[0])
            subtitle = SubtitleHelper.download_subtitle(subtitles[0],
                                                        format="webvtt")
            part.Subtitle = subtitle

        if use_adaptive_with_encryption:
            # We can use the adaptive add-on with encryption
            Logger.info("Using MPD InputStreamAddon")
            license_url = Regexer.do_regex('licenseUrl="([^"]+)"', mpd_data)[0]
            token = "Bearer {0}".format(mpd_info["playToken"])
            key_headers = {"Authorization": token}
            license_key = Mpd.get_license_key(license_url,
                                              key_headers=key_headers)

            stream = part.append_media_stream(mpd_manifest_url, 0)
            Mpd.set_input_stream_addon_input(stream, license_key=license_key)
            item.complete = True
        else:
            XbmcWrapper.show_dialog(
                LanguageHelper.get_localized_string(LanguageHelper.DrmTitle),
                LanguageHelper.get_localized_string(
                    LanguageHelper.WidevineLeiaRequired))

        return item
Esempio n. 19
0
    def create_main_list(self, data):
        """ Performs pre-process actions for data processing and creates the main menu list

        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 = []

        live = LanguageHelper.get_localized_string(
            LanguageHelper.LiveStreamTitleId)
        live_tv = "{} - TV".format(live)
        live_radio = "{} - Radio".format(live)

        links = {
            live_tv:
            "https://psapi.nrk.no/tv/live?apiKey={}".format(self.__api_key),
            live_radio:
            "https://psapi.nrk.no/radio/live?apiKey={}".format(self.__api_key),
            "Recommended":
            "https://psapi.nrk.no/medium/tv/recommendedprograms?maxnumber=100&startRow=0&apiKey={}"
            .format(self.__api_key),
            "Popular":
            "https://psapi.nrk.no/medium/tv/popularprogramssuper?maxnumber=100&startRow=0&apiKey={}"
            .format(self.__api_key),
            "Recent":
            "https://psapi.nrk.no/medium/tv/recentlysentprograms?maxnumber=100&startRow=0&apiKey={}"
            .format(self.__api_key),
            "Categories":
            "https://psapi.nrk.no/medium/tv/categories?apiKey={}".format(
                self.__api_key),
            "A - Å":
            "https://psapi.nrk.no/medium/tv/letters?apiKey={}".format(
                self.__api_key),
            "S&oslash;k":
            "#searchSite"
        }
        for name, url in links.items():
            item = MediaItem(name, url)
            item.icon = self.icon
            item.thumb = self.noImage
            item.complete = True
            item.HttpHeaders = self.httpHeaders
            items.append(item)

        Logger.debug("Pre-Processing finished")
        return data, items
Esempio n. 20
0
    def __show_empty_information(self, items, favs=False):
        """ Adds an empty item to a list or just shows a message.
        @type favs: boolean
        @param items:

        :param list[MediaItem] items:   The list of items.
        :param bool favs:               Indicating that we are dealing with favourites.

        :return: boolean indicating to report the listing as succes or not.
        :rtype: ok

        """

        if favs:
            title = LanguageHelper.get_localized_string(
                LanguageHelper.NoFavsId)
        else:
            title = LanguageHelper.get_localized_string(
                LanguageHelper.ErrorNoEpisodes)

        behaviour = AddonSettings.get_empty_list_behaviour()

        Logger.debug("Showing empty info for mode (favs=%s): [%s]", favs,
                     behaviour)
        if behaviour == "error":
            # show error
            ok = False
        elif behaviour == "dummy" and not favs:
            # We should add a dummy items, but not for favs
            empty_list_item = MediaItem("- %s -" % (title.strip("."), ),
                                        "",
                                        type='video')
            empty_list_item.dontGroup = True
            empty_list_item.complete = True

            # if we add one, set OK to True
            ok = True
            items.append(empty_list_item)
        else:
            ok = True

        XbmcWrapper.show_notification(
            LanguageHelper.get_localized_string(LanguageHelper.ErrorId), title,
            XbmcWrapper.Error, 2500)
        return ok
    def __show_warnings(self, media_item):
        """ Show playback warnings for this MediaItem

        :param MediaItem media_item: The current MediaItem that will be played.

        """

        if (media_item.isDrmProtected or media_item.isPaid) and AddonSettings.show_drm_paid_warning():
            if media_item.isDrmProtected:
                Logger.debug("Showing DRM Warning message")
                title = LanguageHelper.get_localized_string(LanguageHelper.DrmTitle)
                message = LanguageHelper.get_localized_string(LanguageHelper.DrmText)
                XbmcWrapper.show_dialog(title, message)
            elif media_item.isPaid:
                Logger.debug("Showing Paid Warning message")
                title = LanguageHelper.get_localized_string(LanguageHelper.PaidTitle)
                message = LanguageHelper.get_localized_string(LanguageHelper.PaidText)
                XbmcWrapper.show_dialog(title, message)
Esempio n. 22
0
    def log_on(self):
        """ Logs on to a website, using an url.

        First checks if the channel requires log on. If so and it's not already
        logged on, it should handle the log on. That part should be implemented
        by the specific channel.

        More arguments can be passed on, but must be handled by custom code.

        After a successful log on the self.loggedOn property is set to True and
        True is returned.

        :return: indication if the login was successful.
        :rtype: bool

        """

        if self.__idToken:
            return True

        # check if there is a refresh token
        # refresh token: viervijfzes_refresh_token
        refresh_token = AddonSettings.get_setting("viervijfzes_refresh_token")
        client = AwsIdp("eu-west-1_dViSsKM5Y",
                        "6s1h851s8uplco5h6mqh1jac8m",
                        proxy=self.proxy,
                        logger=Logger.instance())
        if refresh_token:
            id_token = client.renew_token(refresh_token)
            if id_token:
                self.__idToken = id_token
                return True
            else:
                Logger.info("Extending token for VierVijfZes failed.")

        # username: viervijfzes_username
        username = AddonSettings.get_setting("viervijfzes_username")
        # password: viervijfzes_password
        v = Vault()
        password = v.get_setting("viervijfzes_password")
        if not username or not password:
            XbmcWrapper.show_dialog(
                title=None,
                lines=LanguageHelper.get_localized_string(
                    LanguageHelper.MissingCredentials),
            )
            return False

        id_token, refresh_token = client.authenticate(username, password)
        if not id_token or not refresh_token:
            Logger.error("Error getting a new token. Wrong password?")
            return False

        self.__idToken = id_token
        AddonSettings.set_setting("viervijfzes_refresh_token", refresh_token)
        return True
    def list_dates(self, data):
        """ Generates a list of the past week days.

        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 = []

        # https://api.kijk.nl/v2/templates/page/missed/all/20180201
        days = ["Maandag", "Dinsdag", "Woensdag", "Donderdag", "Vrijdag", "Zaterdag", "Zondag"]
        for i in range(0, 7):
            date = datetime.datetime.now() - datetime.timedelta(days=i)
            # https://api.kijk.nl/v2/templates/page/missed/all/20180626
            # url = "https://api.kijk.nl/v2/templates/page/missed/all/{0}{1:02d}{2:02d}".format(date.year, date.month, date.day)
            # https://api.kijk.nl/v1/default/sections/missed-all-20180619
            url = "https://api.kijk.nl/v1/default/sections/missed-all-{0}{1:02d}{2:02d}".format(date.year, date.month, date.day)
            if i == 0:
                title = LanguageHelper.get_localized_string(LanguageHelper.Today)
            elif i == 1:
                title = LanguageHelper.get_localized_string(LanguageHelper.Yesterday)
            elif i == 2:
                title = LanguageHelper.get_localized_string(LanguageHelper.DayBeforeYesterday)
            else:
                day_name = days[date.weekday()]
                title = day_name

            date_item = MediaItem(title, url)
            date_item.set_date(date.year, date.month, date.day)
            items.append(date_item)

        Logger.debug("Pre-Processing finished")
        return data, items
Esempio n. 24
0
    def toggle_cloak(self):
        """ Toggles the cloaking (showing/hiding) of the selected folder. """

        item = self.media_item
        Logger.info("Cloaking current item: %s", item)
        c = Cloaker(self.channelObject, AddonSettings.store(LOCAL), logger=Logger.instance())

        if c.is_cloaked(item.url):
            c.un_cloak(item.url)
            self.refresh()
            return

        first_time = c.cloak(item.url)
        if first_time:
            XbmcWrapper.show_dialog(LanguageHelper.get_localized_string(LanguageHelper.CloakFirstTime),
                                    LanguageHelper.get_localized_string(LanguageHelper.CloakMessage))

        del c
        self.refresh()
Esempio n. 25
0
    def __get_application_key(self):
        """ Gets the decrypted application key that is used for all the encryption.

        :return: The decrypted application key that is used for all the encryption.
        :rtype: bytes

        """

        application_key_encrypted = AddonSettings.get_setting(Vault.__APPLICATION_KEY_SETTING, store=LOCAL)
        # The key was never in the local store the value was None. It was "" if it was reset.
        if application_key_encrypted is None:
            application_key_encrypted = AddonSettings.get_setting(Vault.__APPLICATION_KEY_SETTING, store=KODI)
            if not application_key_encrypted:
                return None

            Logger.info("Moved ApplicationKey to local storage")
            AddonSettings.set_setting(Vault.__APPLICATION_KEY_SETTING, application_key_encrypted, store=LOCAL)

        # Still no application key? Then there was no key!
        if application_key_encrypted == "" or application_key_encrypted is None:
            return None

        vault_incorrect_pin = LanguageHelper.get_localized_string(LanguageHelper.VaultIncorrectPin)
        pin = XbmcWrapper.show_key_board(
            heading=LanguageHelper.get_localized_string(LanguageHelper.VaultInputPin),
            hidden=True)
        if not pin:
            XbmcWrapper.show_notification("", vault_incorrect_pin, XbmcWrapper.Error)
            raise RuntimeError("Incorrect Retrospect PIN specified")
        pin_key = self.__get_pbk(pin)
        application_key = self.__decrypt(application_key_encrypted, pin_key)
        if not application_key.startswith(Vault.__APPLICATION_KEY_SETTING):
            Logger.critical("Invalid Retrospect PIN")
            XbmcWrapper.show_notification("", vault_incorrect_pin, XbmcWrapper.Error)
            raise RuntimeError("Incorrect Retrospect PIN specified")

        application_key_value = application_key[len(Vault.__APPLICATION_KEY_SETTING) + 1:]
        Logger.info("Successfully decrypted the ApplicationKey.")
        if PY2:
            return application_key_value

        # We return bytes on Python 3
        return application_key_value.encode()
Esempio n. 26
0
    def process_video_item(self, item):
        """ Process a video item using the required dataparsers

        :param MediaItem item:    The Item to update

        :return: An updated item.
        :rtype: MediaItem

        """

        data_parsers = self.__get_data_parsers(item.url)
        if not data_parsers:
            Logger.error("No dataparsers found cannot update item.")
            return item

        data_parsers = [d for d in data_parsers if d.Updater is not None]
        if len(data_parsers) < 1:
            Logger.warning("No DataParsers with Updaters found.")
            return item

        if len(data_parsers) > 1:
            Logger.warning(
                "More than 2 DataParsers with Updaters found. Only using first one."
            )
        data_parser = data_parsers[0]

        if not data_parser.Updater:
            Logger.error("No videoupdater found cannot update item.")
            return item

        if data_parser.LogOnRequired:
            Logger.info("One or more dataparsers require logging in.")
            self.loggedOn = self.log_on()
            if not self.loggedOn:
                Logger.warning("Could not log on for: %s", self)
                title = LanguageHelper.get_localized_string(
                    LanguageHelper.LoginErrorTitle)
                text = LanguageHelper.get_localized_string(
                    LanguageHelper.LoginErrorText)
                XbmcWrapper.show_dialog(title, text)

        Logger.debug("Processing Updater from %s", data_parser)
        return data_parser.Updater(item)
Esempio n. 27
0
    def add_recent_items(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 = []
        today = datetime.datetime.now()
        days = LanguageHelper.get_days_list()
        for d in range(0, 7, 1):
            air_date = today - datetime.timedelta(d)
            Logger.trace("Adding item for: %s", air_date)

            # Determine a nice display date
            day = days[air_date.weekday()]
            if d == 0:
                day = LanguageHelper.get_localized_string(LanguageHelper.Today)
            elif d == 1:
                day = LanguageHelper.get_localized_string(LanguageHelper.Yesterday)

            title = "%04d-%02d-%02d - %s" % (air_date.year, air_date.month, air_date.day, day)
            url = "https://www.goplay.be/api/epg/{}/{:04d}-{:02d}-{:02d}".\
                format(self.__channel_brand, air_date.year, air_date.month, air_date.day)

            extra = MediaItem(title, url)
            extra.complete = True
            extra.dontGroup = True
            extra.set_date(air_date.year, air_date.month, air_date.day, text="")
            extra.content_type = contenttype.VIDEOS
            items.append(extra)

        return data, items
Esempio n. 28
0
    def __update_dash_video(self, item, stream_info):
        """

        :param MediaItem item:          The item that was updated
        :param JsonHelper stream_info:  The stream info
        """

        if not AddonSettings.use_adaptive_stream_add_on(with_encryption=True):
            XbmcWrapper.show_dialog(
                LanguageHelper.get_localized_string(LanguageHelper.DrmTitle),
                LanguageHelper.get_localized_string(
                    LanguageHelper.WidevineLeiaRequired))
            return item

        playback_item = stream_info.get_value("playbackItem")

        stream_url = playback_item["manifestUrl"]
        part = item.create_new_empty_media_part()
        stream = part.append_media_stream(stream_url, 0)

        license_info = playback_item.get("license", None)
        if license_info is not None:
            license_key_token = license_info["token"]
            auth_token = license_info["castlabsToken"]
            header = {
                "x-dt-auth-token": auth_token,
                "content-type": "application/octstream"
            }
            license_url = license_info["castlabsServer"]
            license_key = Mpd.get_license_key(license_url,
                                              key_value=license_key_token,
                                              key_headers=header)

            Mpd.set_input_stream_addon_input(stream,
                                             proxy=self.proxy,
                                             license_key=license_key)
            item.isDrmProtected = False
        else:
            Mpd.set_input_stream_addon_input(stream, proxy=self.proxy)

        item.complete = True
        return item
    def add_graphql_extras(self, data):
        """ Adds additional items to the main listings

        :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 = []
        if self.parentItem is not None:
            return data, items

        popular_url = self.__get_api_query_url(
            "trendingPrograms",
            "{__typename,title,description,guid,updated,seriesTvSeasons{id},imageMedia{url,label}}"
        )
        popular_title = LanguageHelper.get_localized_string(LanguageHelper.Popular)
        popular = MediaItem(
            "\a.: {} :.".format(popular_title),
            popular_url
        )
        popular.dontGroup = True
        items.append(popular)

        # https://graph.kijk.nl/graphql?operationName=programsByDate&variables={"date":"2020-04-19","numOfDays":7}&extensions={"persistedQuery":{"version":1,"sha256Hash":"1445cc0d283e10fa21fcdf95b127207d5f8c22834c1d0d17df1aacb8a9da7a8e"}}
        recent_url = "#recentgraphql"
        recent_title = LanguageHelper.get_localized_string(LanguageHelper.Recent)
        recent = MediaItem(
            "\a.: {} :.".format(recent_title),
            recent_url
        )
        recent.dontGroup = True
        items.append(recent)

        search_title = LanguageHelper.get_localized_string(LanguageHelper.Search)
        search = MediaItem("\a.: {} :.".format(search_title), "#searchSite")
        search.dontGroup = True
        items.append(search)

        return data, items
Esempio n. 30
0
    def execute(self):
        """ Send log files via Pastbin or Gist. """

        from resources.lib.helpers.logsender import LogSender
        sender_mode = 'hastebin'
        log_sender = LogSender(Config.logSenderApi, logger=Logger.instance(), mode=sender_mode)
        try:
            title = LanguageHelper.get_localized_string(LanguageHelper.LogPostSuccessTitle)
            url_text = LanguageHelper.get_localized_string(LanguageHelper.LogPostLogUrl)
            files_to_send = [Logger.instance().logFileName,
                             Logger.instance().logFileName.replace(".log", ".old.log")]
            paste_url = log_sender.send_file(Config.logFileNameAddon, files_to_send[0])
            XbmcWrapper.show_dialog(title, url_text % (paste_url,))
        except Exception as e:
            Logger.error("Error sending %s", Config.logFileNameAddon, exc_info=True)

            title = LanguageHelper.get_localized_string(LanguageHelper.LogPostErrorTitle)
            error_text = LanguageHelper.get_localized_string(LanguageHelper.LogPostError)
            error = error_text % (str(e),)
            XbmcWrapper.show_dialog(title, error.strip(": "))