diff --git a/plugin.video.retrospect/addon.xml b/plugin.video.retrospect/addon.xml index 0d7bac6be5..1cb597bf3d 100644 --- a/plugin.video.retrospect/addon.xml +++ b/plugin.video.retrospect/addon.xml @@ -1,6 +1,6 @@ @@ -14,6 +14,7 @@ + all GPL-3.0-or-later en nl de sv no lt lv fi - [B]Retrospect v5.7.4 - Changelog - 2023-12-20[/B] + [B]Retrospect v5.7.5 - Changelog - 2024-01-18[/B] -Minor fix for the NPO `Recent` items. +This release fixes issues with MTV and NPO. It also restores the IPTV functionality for NPO and introduces Videoland as a replacement for RTL XL. [B]Framework related[/B] -* None +* Fixed: For search results, keep the sort order as "unsorted". +* Changed: Various fixes for log-in and log-out. [B]GUI/Settings/Language related[/B] -* None +* Added: Option to have a channel dedicated filter of premium items. [B]Channel related[/B] -* Fixed: Recent times broke (Fixes #1750). +* Fixed: NPO Recent items did not display videos unrelated to shows. +* Fixed: MTV channels. +* Fixed: NPO IPTV Support. +* Fixed: SVT `new`-items diff --git a/plugin.video.retrospect/channels/channel.nick/nickelodeon/chn_nickelodeon.py b/plugin.video.retrospect/channels/channel.nick/nickelodeon/chn_nickelodeon.py index 20afe04244..03be97e407 100644 --- a/plugin.video.retrospect/channels/channel.nick/nickelodeon/chn_nickelodeon.py +++ b/plugin.video.retrospect/channels/channel.nick/nickelodeon/chn_nickelodeon.py @@ -36,21 +36,25 @@ def __init__(self, channel_info): self.noImage = "nickelodeonimage.png" self.mainListUri = "https://www.nickelodeon.nl/shows" self.baseUrl = "https://www.nickelodeon.nl" + self.__mgid = "" elif self.channelCode == "nickno": self.noImage = "nickelodeonimage.png" self.mainListUri = "https://www.nickelodeon.no/shows" self.baseUrl = "https://www.nickelodeon.no" + self.__mgid = "" elif self.channelCode == "mtvnl": self.mainListUri = "https://www.mtv.nl/shows" self.baseUrl = "https://www.mtv.nl" self.noImage = "mtvnlimage.png" + self.__mgid = "mtv.nl" elif self.channelCode == "mtvde": self.mainListUri = "https://www.mtv.de/shows" self.baseUrl = "https://www.mtv.de" self.noImage = "mtvnlimage.png" + self.__mgid = "mtv.de" else: raise NotImplementedError("Unknown channel code") @@ -287,7 +291,8 @@ def create_json_video_item(self, result_set): if sub_heading: name = "{} - {}".format(name, sub_heading) - url = "{}{}".format(self.baseUrl, result_set["url"]) + url = f"https://topaz.viacomcbs.digital/topaz/api/mgid:arc:episode:{self.__mgid}:{result_set['id']}/mica.json?clientPlatform=desktop" + url = f"https://topaz.viacomcbs.digital/topaz/api/mgid:arc:episode:mtv.nl:84c9904e-6fed-11e9-9fb2-70df2f866ace/mica.json?clientPlatform=desktop&ssus=44545c3d-6208-45e5-953e-801abf27ae7b&browser=Chrome&device=Desktop&os=Windows+10" item = MediaItem(name, url, media_type=EPISODE) item.description = meta.get("description") item.thumb = result_set.get("media", {}).get("image", {}).get("url") @@ -333,26 +338,9 @@ def update_video_item(self, item): Logger.debug('Starting update_video_item for %s (%s)', item.name, self.channelName) from resources.lib.streams.m3u8 import M3u8 - data = UriHandler.open(item.url) - video_id = Regexer.do_regex(r'{"video":{"config":{"uri":"([^"]+)', data)[0] - url = "http://media.mtvnservices.com/pmt/e1/access/index.html?uri={}&configtype=edge".format(video_id) - meta_data = UriHandler.open(url, referer=self.baseUrl) - meta = JsonHelper(meta_data) - stream_parts = meta.get_value("feed", "items") - for stream_part in stream_parts: - stream_url = stream_part["group"]["content"] - stream_url = stream_url.replace("&device={device}", "") - stream_url = "%s&format=json&acceptMethods=hls" % (stream_url,) - stream_data = UriHandler.open(stream_url) - stream = JsonHelper(stream_data) - - # subUrls = stream.get_value("package", "video", "item", 0, "transcript", 0, "typographic") # NOSONAR - - hls_streams = stream.get_value("package", "video", "item", 0, "rendition") - for hls_stream in hls_streams: - hls_url = hls_stream["src"] - item.complete |= M3u8.update_part_with_m3u8_streams(item, hls_url) - - item.complete = True + data = JsonHelper(UriHandler.open(item.url)) + stream_url = data.get_value("stitchedstream", "source") + item.complete |= M3u8.update_part_with_m3u8_streams(item, stream_url) + Logger.trace("Media url: %s", item) return item diff --git a/plugin.video.retrospect/channels/channel.nos/nos2010/chn_nos2010.py b/plugin.video.retrospect/channels/channel.nos/nos2010/chn_nos2010.py index ba3c770a5a..6943779857 100644 --- a/plugin.video.retrospect/channels/channel.nos/nos2010/chn_nos2010.py +++ b/plugin.video.retrospect/channels/channel.nos/nos2010/chn_nos2010.py @@ -24,6 +24,7 @@ from resources.lib.mediaitem import MediaItem, FolderItem from resources.lib.xbmcwrapper import XbmcWrapper from resources.lib.actions import action +from resources.lib.textures import TextureHandler class Channel(chn_class.Channel): @@ -117,6 +118,10 @@ def __init__(self, channel_info: ChannelInfo): name="Season content API parser", json=True, parser=[], creator=self.create_api_episode_item) + self._add_data_parser("https://npo.nl/start/video/", + name="Single video items from recent guid", + updater=self.update_single_video) + # Standard updater self._add_data_parser("*", requires_logon=True, updater=self.update_video_item) @@ -711,27 +716,35 @@ def load_all_epg_channels(self, data: Union[str, JsonHelper]) -> Tuple[Union[str def create_api_epg_item(self, result_set: dict) -> Optional[MediaItem]: series_slug = (result_set["series"] or {}).get("slug") - if not series_slug: - return None program_guid = (result_set["program"] or {}).get("guid") - if not program_guid: + season_slug = None + + if not series_slug and program_guid: + # It is a single video not belonging to a series. + program_slug = result_set["program"]["slug"] + url = f"https://npo.nl/start/video/{program_slug}" + elif series_slug and program_guid: + url = f"https://npo.nl/start/api/domain/series-seasons?slug={series_slug}" + season_slug = result_set["season"]["slug"] + else: return None - url = f"https://npo.nl/start/api/domain/series-seasons?slug={series_slug}" name = result_set["title"] - season_slug = result_set["season"]["slug"] start = result_set["programStart"] channel = result_set["channel"] date_stamp = DateHelper.get_date_from_posix(start, tz=self.__timezone) - if date_stamp > datetime.datetime.now(tz=pytz.UTC): - return None + # Check not needed. Programs in the future that are unavailable don't have a result_set.program property, which is already checked above. + # https://github.com/retrospect-addon/plugin.video.retrospect/pull/1754#issuecomment-1884550951 + # if date_stamp > datetime.datetime.now(tz=pytz.UTC): + # return None item = MediaItem(f"{date_stamp.hour:02d}:{date_stamp.minute:02d} - {channel} - {name}", url, media_type=mediatype.EPISODE) - item.metaData = { - "season_slug": season_slug, - "program_guid": program_guid - } + if season_slug and program_guid: + item.metaData = { + "season_slug": season_slug, + "program_guid": program_guid + } item.set_date(date_stamp.year, date_stamp.month, date_stamp.day, date_stamp.hour, date_stamp.minute, date_stamp.second) duration = result_set.get("durationInSeconds") @@ -744,6 +757,17 @@ def create_api_epg_item(self, result_set: dict) -> Optional[MediaItem]: item.description = image_data.get("description") return item + def update_single_video(self, item: MediaItem) -> MediaItem: + data = UriHandler.open(item.url) + whatson_info = Regexer.do_regex(r'"productId"\W+"([^"]+)"', data) + if not whatson_info: + # Retry as with a login it might fail + data = UriHandler.open(item.url) + whatson_info = Regexer.do_regex(r'"productId"\W+"([^"]+)"', data) + + whatson_id = whatson_info[0] + return self.__update_video_item(item, whatson_id) + def update_epg_series_item(self, item: MediaItem) -> MediaItem: # Go from season slug, show slug & program guid -> # ?? https://npo.nl/start/api/domain/series-detail?slug=boer-zoekt-vrouw @@ -1144,7 +1168,7 @@ def update_video_item_live(self, item: MediaItem) -> MediaItem: return item def create_iptv_streams(self, parameter_parser): - """ Fetch the available live channels using EPG endpoint and format them into JSON-STREAMS + """ Fetch the available live channels using guide-channels endpoint and format them into JSON-STREAMS :param ActionParser parameter_parser: a ActionParser object to is used to parse and create urls @@ -1152,37 +1176,34 @@ def create_iptv_streams(self, parameter_parser): :return: Formatted stations :rtype: list """ - epg_url = datetime.datetime.now().strftime("https://start-api.npo.nl/epg/%Y-%m-%d?type=tv") - epg_data = UriHandler.open(epg_url, - no_cache=True, - additional_headers=self.__jsonApiKeyHeader) - epg = JsonHelper(epg_data) - + channel_data = JsonHelper(UriHandler.open(f"https://npo.nl/start/api/domain/guide-channels")) parent_item = MediaItem("Live", "https://www.npostart.nl/live", media_type=mediatype.FOLDER) items = [] iptv_streams = [] - for stations in epg.get_value("epg"): - livestream = JsonHelper.get_from(stations, "channel", "liveStream") - item = MediaItem(JsonHelper.get_from(livestream, "title"), - JsonHelper.get_from(livestream, "shareUrl"), - media_type=mediatype.VIDEO) - item.isLive = True - item.isGeoLocked = True + logo_sources = { + "NPO1": TextureHandler.instance().get_texture_uri(self, "npo1.png"), + "NPO2": TextureHandler.instance().get_texture_uri(self, "npo2.png"), + "NPO3": TextureHandler.instance().get_texture_uri(self, "npo3.png"), + "NPO1 Extra": TextureHandler.instance().get_texture_uri(self, "npo1extra.png"), + "NPO2 Extra": TextureHandler.instance().get_texture_uri(self, "npo2extra.png"), + "NPO Politiek en Nieuws": TextureHandler.instance().get_texture_uri(self, "npopolitiekennieuws.png") + } + + for livestream in channel_data.json: + item = self.create_api_live_tv(livestream) items.append(item) iptv_streams.append(dict( - id=JsonHelper.get_from(livestream, "id"), + id=JsonHelper.get_from(livestream, "guid"), name=JsonHelper.get_from(livestream, "title"), - logo=JsonHelper.get_from(livestream, "images", "original", "formats", "tv", - "source"), + logo=logo_sources[JsonHelper.get_from(livestream, "title")], group=self.channelName, stream=parameter_parser.create_action_url(self, action=action.PLAY_VIDEO, item=item, store_id=parent_item.guid), )) - + parameter_parser.pickler.store_media_items(parent_item.guid, parent_item, items) - return iptv_streams def create_iptv_epg(self, parameter_parser): @@ -1195,46 +1216,41 @@ def create_iptv_epg(self, parameter_parser): :rtype: dict """ + channel_data = JsonHelper(UriHandler.open(f"https://npo.nl/start/api/domain/guide-channels")) parent = MediaItem("EPG", "https://start-api.npo.nl/epg/", media_type=mediatype.FOLDER) iptv_epg = dict() media_items = [] + + for livestream in channel_data.json: + iptv_epg[livestream["guid"]] = [] + + # Fetch 3 days in the past and in the future + start = datetime.datetime.now() - datetime.timedelta(days=3) + for i in range(0, 6, 1): + air_date = start + datetime.timedelta(i) + date = air_date.strftime("%d-%m-%Y") + guid = livestream["guid"] + guide_data = JsonHelper(UriHandler.open(f"https://npo.nl/start/api/domain/guide-channel?guid={guid}&date={date}")) + + for item in guide_data.json: + item["channel"] = livestream["title"] + media_item = self.create_api_epg_item(item) + iptv_epg_item = dict( + start=datetime.datetime.fromtimestamp(JsonHelper.get_from(item, "programStart"), datetime.timezone.utc).isoformat(), + stop=datetime.datetime.fromtimestamp(JsonHelper.get_from(item, "programEnd"), datetime.timezone.utc).isoformat(), + title=JsonHelper.get_from(item, "title")) + + if len(JsonHelper.get_from(item, "images")) > 0: + iptv_epg_item["image"] = JsonHelper.get_from(item, "images")[0].get("url") + + if media_item is not None: + iptv_epg_item["stream"] = parameter_parser.create_action_url(self, action=action.PLAY_VIDEO, + item=media_item, + store_id=parent.guid) + media_items.append(media_item) + + iptv_epg[livestream["guid"]].append(iptv_epg_item) - start = datetime.datetime.now() - datetime.timedelta(days=3) - for i in range(0, 7, 1): - air_date = start + datetime.timedelta(i) - data = UriHandler.open( - air_date.strftime("https://start-api.npo.nl/epg/%Y-%m-%d?type=tv"), - no_cache=True, - additional_headers=self.__jsonApiKeyHeader) - - json_data = JsonHelper.loads(data) - for epg_item in JsonHelper.get_from(json_data, "epg"): - epg_id = JsonHelper.get_from(epg_item, "channel", 'liveStream', 'id') - iptv_epg[epg_id] = iptv_epg.get(epg_id, []) - for program in JsonHelper.get_from(epg_item, "schedule"): - media_item = MediaItem(JsonHelper.get_from(program, "program", "title"), - JsonHelper.get_from(program, "program", "id"), - media_type=mediatype.EPISODE) - region_restrictions = JsonHelper.get_from(program, "program", - "regionRestrictions") - media_item.isGeoBlocked = any( - [r for r in region_restrictions if r != "PLUSVOD:EU"]) - media_items.append(media_item) - iptv_epg[epg_id].append(dict( - start=JsonHelper.get_from(program, "startsAt"), - stop=JsonHelper.get_from(program, "endsAt"), - title=JsonHelper.get_from(program, "program", "title"), - description=JsonHelper.get_from(program, "program", "descriptionLong"), - image=JsonHelper.get_from(program, "program", "images", "header", "formats", - "tv", "source"), - genre=JsonHelper.get_from(program, "program", "genres", 0, - "terms") if JsonHelper.get_from(program, - "program", - "genres") else [], - stream=parameter_parser.create_action_url(self, action=action.PLAY_VIDEO, - item=media_item, - store_id=parent.guid), - )) parameter_parser.pickler.store_media_items(parent.guid, parent, media_items) return iptv_epg diff --git a/plugin.video.retrospect/channels/channel.rtlnl/rtl/chn_rtl.json b/plugin.video.retrospect/channels/channel.rtlnl/rtl/chn_rtl.json index 1a27af0165..29c07fac44 100644 --- a/plugin.video.retrospect/channels/channel.rtlnl/rtl/chn_rtl.json +++ b/plugin.video.retrospect/channels/channel.rtlnl/rtl/chn_rtl.json @@ -13,7 +13,8 @@ "language": "nl", "fanart": "rtlfanart.png", "poster": "rtlposter_white.png", - "adaptiveAddonSelectable": false + "adaptiveAddonSelectable": false, + "ignore": true } ], "settings": [ diff --git a/plugin.video.retrospect/channels/channel.se/svt/chn_svt.py b/plugin.video.retrospect/channels/channel.se/svt/chn_svt.py index 9a54b28645..1f7acabcad 100644 --- a/plugin.video.retrospect/channels/channel.se/svt/chn_svt.py +++ b/plugin.video.retrospect/channels/channel.se/svt/chn_svt.py @@ -2,6 +2,8 @@ # SPDX-License-Identifier: GPL-3.0-or-later import datetime +from typing import Optional, List, Tuple + import pytz from resources.lib import chn_class, mediatype, contenttype @@ -88,10 +90,13 @@ def __init__(self, channel_info): parser=["data", "selectionById", "items"], creator=self.create_api_typed_item) - self._add_data_parser("https://api.svt.se/contento/graphql?operationName=FionaPage", - name="GraphQL FionaPage parsers for Nytt pa Play", json=True, - parser=["data", "selectionById", "items"], - creator=self.create_api_typed_item) + self._add_data_parsers([ + "https://api.svt.se/contento/graphql?operationName=FionaPage", + "https://contento.svt.se/graphql?operationName=FionaPage" + ], + name="GraphQL FionaPage parsers for Nytt pa Play", json=True, + parser=["data", "selectionById", "items"], + creator=self.create_api_typed_item) self._add_data_parser("https://api.svt.se/contento/graphql?operationName=MainGenres", name="GraphQL for main genre listding", json=True, @@ -110,6 +115,10 @@ def __init__(self, channel_info): parser=["videos"], creator=self.create_api_typed_item) + self._add_data_parser("https://www.svtplay.se", match_type=ParserData.MatchExact, + name="SVTPlay data retriever for New on SVT", + preprocessor=self.extract_new_on_svt_id) + # Setup channel listing based on JSON data in the HTML self._add_data_parser( "https://api.svt.se/contento/graphql?operationName=BroadcastSchedule", @@ -217,11 +226,13 @@ def add_live_items_and_genres(self, data): ), # The selection ID might change over time. + # We need to determine the `selectionId` LanguageHelper.get_localized_string(LanguageHelper.NewOnChannel) % self.channelName: ( - self.__get_api_url( - "FionaPage", - "dc8f85e195903fe6227a76ec1e1d300d470ee8ea123bea6bee26215cc6e4959d", - variables={"includeFullOppetArkiv": True, "selectionId": "svtId_egWQ3y7"}), + # self.__get_api_url( + # "FionaPage", + # "b4e65a8f4cedc6bd9981e3539690908443f625c6854ea65f18c4b3b3be66b5dc", + # variables={"includeFullOppetArkiv": True, "selectionId": "svtId_jGVZ7AL"}), + "https://www.svtplay.se", False) } # https://api.svt.se/contento/graphql?operationName=FionaPage&variables={"includeFullOppetArkiv":true,"selectionId":"svtId_egWQ3y7","userIsAbroad":true}&extensions={"persistedQuery":{"sha256Hash":"dc8f85e195903fe6227a76ec1e1d300d470ee8ea123bea6bee26215cc6e4959d","version":1}}&ua=svtplaywebb-render-low-prio-client @@ -645,7 +656,7 @@ def create_api_episode_type(self, result_set, add_parent_title=False): item.thumb = self.__get_thumb(result_set["image"], width=720) self.__extract_artwork(result_set.get("images"), item) - valid_from = result_set.get("validFrom", None) + valid_from: Optional[str] = result_set.get("validFrom", None) if bool(valid_from) and valid_from.endswith("Z"): # We need to change the timezone valid_from_date = DateHelper.get_datetime_from_string(valid_from[:-1], time_zone="UTC") @@ -658,7 +669,7 @@ def create_api_episode_type(self, result_set, add_parent_title=False): valid_from_date = DateHelper.get_date_from_string(valid_from, "%Y-%m-%dT%H:%M:%S") item.set_date(*valid_from_date[0:6]) - valid_to = result_set.get("validTo", None) + valid_to: Optional[str] = result_set.get("validTo", None) if valid_to: self.__set_expire_time(valid_to, item) @@ -870,6 +881,17 @@ def create_api_search_hit(self, result_set): else: return self.create_api_genre_type(result_set) + def extract_new_on_svt_id(self, data: str) -> Tuple[str, List[MediaItem]]: + new_id = Regexer.do_regex(r'href="/lista/([^/]+)/nytt-pa-play"', data)[0] + url = self.__get_api_url( + "FionaPage", + "b4e65a8f4cedc6bd9981e3539690908443f625c6854ea65f18c4b3b3be66b5dc", + variables={"includeFullOppetArkiv": True, "selectionId": new_id}) + + self.parentItem.url = url + items = self.process_folder_list(self.parentItem) + return data, items + # noinspection PyUnusedLocal def fetch_program_api_data(self, data): """ Loaded the data that contains the main episodes for a show. diff --git a/plugin.video.retrospect/channels/channel.videoland/videolandnl/chn_videolandnl.json b/plugin.video.retrospect/channels/channel.videoland/videolandnl/chn_videolandnl.json new file mode 100644 index 0000000000..bdbe7f96a6 --- /dev/null +++ b/plugin.video.retrospect/channels/channel.videoland/videolandnl/chn_videolandnl.json @@ -0,0 +1,40 @@ +{ + "channels": [ + { + "guid": "C5182B93-6B71-44BE-948F-0B74E6C2BAA6", + "name": "Videoland", + "description": { + "en": "Broadcasts of Videoland.", + "nl": "Uitzendingen van Videoland." + }, + "icon": "videolandnl-icon.png", + "category": "National", + "sortorder": 4, + "language": "nl", + "fanart": "videolandnl-fanart-red.jpg", + "poster": "videolandnl-poster.jpg" + } + ], + "settings": [ + { + "order": 1, + "value": "type=\"text\" label=\"30094\" default=\"\"", + "id": "videolandnl_username" + }, + { + "order": 2, + "value": "default=\"\"", + "id": "videolandnl_password" + }, + { + "order": 3, + "value": "label=\"30093\" type=\"action\" action=\"RunScript(plugin.video.retrospect, 0, ?action=encryptsetting&settingid=channel_C5182B93-6B71-44BE-948F-0B74E6C2BAA6_videolandnl_password&settingname=Videoland&tabfocus=102)\" option=\"close\"", + "id": "videolandnl_password_set" + }, + { + "order": 4, + "value": "type=\"select\" lvalues=\"30126|30127|30128\" default=\"0\" label=\"30081\"", + "id": "filter_premium" + } + ] +} \ No newline at end of file diff --git a/plugin.video.retrospect/channels/channel.videoland/videolandnl/chn_videolandnl.py b/plugin.video.retrospect/channels/channel.videoland/videolandnl/chn_videolandnl.py new file mode 100644 index 0000000000..da4e3a4805 --- /dev/null +++ b/plugin.video.retrospect/channels/channel.videoland/videolandnl/chn_videolandnl.py @@ -0,0 +1,403 @@ +# SPDX-License-Identifier: GPL-3.0-or-later +import datetime +from typing import Union, List, Optional, Tuple, Dict + +import pytz + +from resources.lib import chn_class, contenttype, mediatype +from resources.lib.addonsettings import AddonSettings +from resources.lib.authentication.authenticator import Authenticator +from resources.lib.authentication.gigyahandler import GigyaHandler +from resources.lib.helpers.datehelper import DateHelper +from resources.lib.helpers.jsonhelper import JsonHelper +from resources.lib.helpers.languagehelper import LanguageHelper +from resources.lib.mediaitem import MediaItem, FolderItem +from resources.lib.parserdata import ParserData +from resources.lib.streams.mpd import Mpd +from resources.lib.textures import TextureHandler +from resources.lib.urihandler import UriHandler +from resources.lib.xbmcwrapper import XbmcWrapper + + +class Channel(chn_class.Channel): + 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 = "videolandnl-thumb.jpg" + self.httpHeaders = { + "X-Client-Release": "5.81.1", + "X-Customer-Name": "rtlnl" + } + + # setup the urls + self.mainListUri = "https://layout.videoland.bedrock.tech/front/v1/rtlnl/m6group_web/main/token-web-4/alias/home/layout?nbPages=1" + # https://pc.middleware.videoland.bedrock.tech/6play/v2/platforms/m6group_web/services/videoland/programs?limit=999&offset=0&csa=tot_18_jaar&with=rights + # https://pc.middleware.videoland.bedrock.tech/6play/v2/platforms/m6group_web/services/videoland/programs/first-letters?csa=tot_18_jaar + + self._add_data_parser(self.mainListUri, requires_logon=True, json=True, + name="Mainlist for Videoland", + preprocessor=self.add_others_and_check_correct_url, + parser=["blocks"], creator=self.create_mainlist_item) + + self._add_data_parsers([ + r"^https://layout.videoland.bedrock.tech/front/v1/rtlnl/m6group_web/main/token-web-4/service/videoland_root/block/", + r"^https://layout.videoland.bedrock.tech/front/v1/rtlnl/m6group_web/main/token-web-4/program/\d+/block/"], + match_type=ParserData.MatchRegex, + name="Main processor that create content items (folders/videos) from blocks", + json=True, requires_logon=True, + parser=["content", "items"], creator=self.create_content_item) + + self._add_data_parser( + r"https://layout.videoland.bedrock.tech/front/v1/rtlnl/m6group_web/main/token-web-4/program/\d+/layout", + match_type=ParserData.MatchRegex, json=True, requires_logon=True, + name="Parser for the main folder of a show show/program.", + preprocessor=self.extract_program_id, + parser=["blocks"], creator=self.create_program_item) + + self._add_data_parser( + "https://layout.videoland.bedrock.tech/front/v1/rtlnl/m6group_web/main/token-web-4/video/", + requires_logon=True, + name="Video updater", json=True, updater=self.update_video_item) + + self._add_data_parser("algolia.net", match_type=ParserData.MatchContains, json=True, + name="Search results", + parser=["results", 0, "hits"], creator=self.create_search_result) + + # Authentication + handler = GigyaHandler( + "videoland.com", "3_t2Z1dFrbWR-IjcC-Bod1kei6W91UKmeiu3dETVG5iKaY4ILBRzVsmgRHWWo0fqqd", + "4_hRanGnYDFjdiZQfh-ghhhg", AddonSettings.get_client_id()) + self.__authenticator = Authenticator(handler) + self.__jwt = None + self.__uid = None + self.__has_premium = False + + # =============================================================================================================== + # non standard items + self.__program_id = None + self.__pages = 10 + self.__timezone = pytz.timezone("Europe/Amsterdam") + + def add_others_and_check_correct_url(self, data: str) -> Tuple[JsonHelper, List[MediaItem]]: + items = [] + search = FolderItem(LanguageHelper.get_localized_string(LanguageHelper.Search), + "#searchSite", content_type=contenttype.TVSHOWS) + items.append(search) + + extras: Dict[int, Tuple[str, str]] = { + LanguageHelper.Recent: ( + "page_6599c70de291a2.86703456--6918fda7-49db-49d5-b7f3-1e4a5b6bfab3", + contenttype.TVSHOWS), + # Already a standard item + # LanguageHelper.Popular: ("page_6599c70de291a2.86703456--47a90b2c-669e-453f-8e3d-07eebbe4d4d0_167", contenttype.TVSHOWS) + } + + for lang_id, extra in extras.items(): + page_id, content_type = extra + title = LanguageHelper.get_localized_string(lang_id) + url = f"https://layout.videoland.bedrock.tech/front/v1/rtlnl/m6group_web/main/token-web-4/service/videoland_root/block/{page_id}?nbPages={self.__pages}" + item = FolderItem(title, url, content_type=content_type) + items.append(item) + + # Now apparently the root of Videoland returns a different response every now and then. We + # need to check that and retry otherwise. + json_data = JsonHelper(data) + blockes = json_data.get_value("blocks") + if len(blockes) > 10: + fallback = [ + { + "title": {"long": LanguageHelper.get_localized_string(LanguageHelper.Popular)}, + "id": "page_65a44d889f7982.33185461--6d1869d5-ef61-461c-b634-226a1bb29c7d", + "featureId": "programs_by_segment" + }, + { + "title": {"long": "Verder kijken"}, + "id": "page_65a44d889f7982.33185461--2d2d40f6-8648-449a-9af4-a68162e6404a", + "featureId": "recommended_videos_by_user" + }, + { + "title": {"long": "Dagelijkse programma's"}, + "id": "page_65a453843fcbe7.99183628--35d0c383-60fb-49b0-9852-f05bfa1bfeaa_494", + "featureId": "programs_by_folder_by_service" + }, + { + "title": {"long": "RTL 4"}, + "id": "page_65a45411767f89.39008634--582cb0eb-3bd2-4d20-9732-8963d05d05ef", + "featureId": "videos_by_tags" + }, + { + "title": {"long": "RTL 5"}, + "id": "page_65a45411767f89.39008634--810d0bf5-2bd9-4e79-8ad1-af5700fa614c", + "featureId": "videos_by_tags" + }, + { + "title": {"long": "RTL 7"}, + "id": "page_65a45411767f89.39008634--2cf10b26-4064-49d3-9729-69011dba752e", + "featureId": "videos_by_tags" + }, + { + "title": {"long": "RTL 8"}, + "id": "page_65a45411767f89.39008634--7099088c-902b-4d43-817e-c6b0661f0ba5", + "featureId": "videos_by_tags" + }, + { + "title": {"long": "RTL Z"}, + "id": "page_65a45411767f89.39008634--a97c9122-7731-45be-a884-fd7cc1399250", + "featureId": "videos_by_tags" + } + ] + for result_set in fallback: + items.append(self.create_mainlist_item(result_set)) + + return json_data, items + + def create_mainlist_item(self, result_set: Union[str, dict]) -> Union[ + MediaItem, List[MediaItem], None]: + if not result_set["title"]: + return None + title = result_set["title"].get("long", result_set["title"].get("short")) + page_id = result_set["id"] + url = f"https://layout.videoland.bedrock.tech/front/v1/rtlnl/m6group_web/main/token-web-4/service/videoland_root/block/{page_id}?nbPages={self.__pages}" + + feature_id = result_set["featureId"] + item = FolderItem(title, url, content_type=contenttype.EPISODES if "videos" in feature_id else contenttype.TVSHOWS) + + if title.lower().startswith("rtl"): + poster_slug = title.lower().replace(" ", "") + poster = f"{poster_slug}-poster.png" + poster_url = TextureHandler.instance().get_texture_uri(self, poster) + item.poster = poster_url + return item + + def create_content_item(self, result_set: Union[str, dict]) -> Union[ + MediaItem, List[MediaItem], None]: + result_set: dict = result_set["itemContent"] + + title = result_set["title"] + extra_title = result_set.get("extraTitle") + if extra_title and title: + title = f"{title} - {extra_title}" + elif not title and extra_title: + title = extra_title + + # What type is it + action_info = result_set.get("action", {}) + action = action_info.get("label", "").lower() + item_id = action_info["target"]["value_layout"]["id"] + if "content" in action: + url = f"https://layout.videoland.bedrock.tech/front/v1/rtlnl/m6group_web/main/token-web-4/program/{item_id}/layout?nbPages={self.__pages}" + item = FolderItem(title, url, content_type=contenttype.TVSHOWS) + elif "collectie" in action: + return None + else: + url = f"https://layout.videoland.bedrock.tech/front/v1/rtlnl/m6group_web/main/token-web-4/video/{item_id}/layout?nbPages=2" + item = MediaItem(title, url, media_type=mediatype.EPISODE) + item.isPaid = action == "abonneren" + + def set_images(item: MediaItem, image_info: dict, set_fanart: bool, set_poster: bool): + for ratio, image_id in image_info["idsByRatio"].items(): + image_url = f"https://images-fio.videoland.bedrock.tech/v2/images/{image_id}/raw" + if ratio == "16:9": + item.thumb = image_url + if set_fanart: + item.fanart = image_url + elif ratio == "2:3" and set_poster: + item.poster = image_url + + if "image" in result_set and item.is_playable: + set_images(item, result_set["image"], set_fanart=False, set_poster=False) + elif "secondaryImage" in result_set and not item.is_playable: + set_images(item, result_set["secondaryImage"], set_fanart=True, set_poster=True) + + time_value = result_set["highlight"] + if time_value and "min" in time_value: + # 20min or 1uur20min + hours = 0 + mins = 0 + if "uur" in time_value: + hours, others = time_value.split("uur") + mins, _ = others.split("min") + elif "min" in time_value: + mins, _ = time_value.split("min") + item.set_info_label(MediaItem.LabelDuration, 60 * int(hours) + int(mins)) + + date_value = (result_set["details"] or "").lower() + if date_value: + if date_value == "vandaag": + # Vandaag + time_stamp = datetime.datetime.now() + item.set_date(time_stamp.year, time_stamp.month, time_stamp.day) + elif date_value == "gisteren": + # Gisteren + time_stamp = datetime.datetime.now() - datetime.timedelta(days=1) + item.set_date(time_stamp.year, time_stamp.month, time_stamp.day) + elif date_value[-2].isnumeric(): + # 'Di 09 jan 24' + weekday, day, month, year = date_value.split(" ") + month = DateHelper.get_month_from_name(month, language="nl", short=True) + year = 2000 + int(year) + item.set_date(year, month, day) + + return item + + def extract_program_id(self, data: str) -> Tuple[Union[str, JsonHelper], List[MediaItem]]: + json_data = JsonHelper(data) + self.__program_id = json_data.get_value("entity", "id", fallback=None) + return json_data, [] + + def create_program_item(self, result_set: dict) -> Union[MediaItem, List[MediaItem], None]: + if not result_set["title"]: + return None + + title = result_set["title"].get("long", result_set["title"].get("short")) + page_id = result_set["id"] + url = f"https://layout.videoland.bedrock.tech/front/v1/rtlnl/m6group_web/main/token-web-4/program/{self.__program_id}/block/{page_id}?nbPages=10&page=1" + item = FolderItem(title, url, content_type=contenttype.EPISODES) + + # Preload them, but this makes paging difficult. + # for sub_result in result_set["content"].get("items", []) or []: + # sub_item = self.create_content_item(sub_result) + # if sub_item: + # item.items.append(sub_item) + + return item + + def search_site(self, url=None): + """ Creates an list of items by searching the site. + + This method is called when the URL of an item is "searchSite". The channel + calling this should implement the search functionality. This could also include + showing of an input keyboard and following actions. + + The %s the url will be replaced with an URL encoded representation of the + text to search for. + + :param str url: Url to use to search with a %s for the search parameters. + + :return: A list with search results as MediaItems. + :rtype: list[MediaItem] + + """ + + needle = XbmcWrapper.show_key_board() + if not needle: + return [] + + url = "https://nhacvivxxk-dsn.algolia.net/1/indexes/*/queries?x-algolia-agent=Algolia%20for%20JavaScript%20(4.14.2)%3B%20Browser" + data = {"requests": [{ + "indexName": "videoland_prod_bedrock_layout_items_v2_rtlnl_main", + "query": needle, + "params": "hitsPerPage=50&facetFilters=%5B%5B%22metadata.item_type%3Aprogram%22%5D%2C%5B%22metadata.platforms_assets%3Am6group_web%22%5D%5D" + }]} + + headers = { + "X-Algolia-Api-Key": "6ef59fc6d78ac129339ab9c35edd41fa", + "X-Algolia-Application-Id": "NHACVIVXXK" + } + search_item = FolderItem("search", url, content_type=contenttype.TVSHOWS) + search_item.HttpHeaders = headers + search_item.postJson = data + return self.process_folder_list(search_item) + + def create_search_result( + self, result_set: Union[str, dict]) -> Union[MediaItem, List[MediaItem], None]: + last_activity_date = result_set["metadata"].get("last_activity_date") + + result_set = result_set["item"] + item = self.create_content_item(result_set) + if not item: + return None + + if not item.has_date(): + # 2021-11-30 00:00:00 + time_stamp = DateHelper.get_date_from_string(last_activity_date, "%Y-%m-%d %H:%M:%S") + item.set_date(*time_stamp[0:6]) + return item + + def filter_premium(self) -> Optional[bool]: + filter_paid = int(self._get_setting("filter_premium", '0')) + if not filter_paid: + return None + + # 0: Default, 1: Show all, 2: Filter + return filter_paid > 1 + + def update_video_item(self, item: MediaItem) -> MediaItem: + data = JsonHelper(UriHandler.open(item.url, additional_headers=self.httpHeaders)) + video_info = data.get_value("blocks", 0, "content", "items", 0, "itemContent", "video") + video_id = video_info["id"] + + # Construct license info + license_token_url = f"https://drm.videoland.bedrock.tech/v1/customers/rtlnl/platforms/m6group_web/services/videoland_catchup/users/{self.__uid}/videos/{video_id}/upfront-token" + license_token = JsonHelper( + UriHandler.open(license_token_url, additional_headers=self.httpHeaders)).get_value( + "token") + license_key = Mpd.get_license_key("https://lic.drmtoday.com/license-proxy-widevine/cenc/", + key_headers={ + "x-dt-auth-token": license_token, + "content-type": "application/octstream" + }, json_filter="JBlicense") + + for asset in video_info["assets"]: + quality = asset["video_quality"] + url = asset["path"] + video_type = asset["video_container"] + # video_container = asset["container"] + video_format = asset["format"] + + if quality == "hd": + continue + + if video_type == "mpd" or video_format == "dashcenc" or video_format == "dash": + stream = item.add_stream(url, 2000 if quality == "hd" else 1200) + Mpd.set_input_stream_addon_input(stream, license_key=license_key) + item.complete = True + # elif video_type == "m3u8": + # # Not working in Kodi + # stream = item.add_stream(url, 2000 if quality == "hd" else 1200) + # item.complete = True + # M3u8.set_input_stream_addon_input(stream) + return item + + def log_on(self): + """ Logs on to a website, using an url. + + First checks if the channel requires log on. If so and it's not already + logged on, it should handle the log on. That part should be implemented + by the specific channel. + + More arguments can be passed on, but must be handled by custom code. + + After a successful log on the self.loggedOn property is set to True and + True is returned. + + :return: indication if the login was successful. + :rtype: bool + + """ + + # Always try to log on. If the username was changed to empty, we should clear the current + # log in. + username: Optional[str] = self._get_setting("videolandnl_username", value_for_none=None) + if not username: + XbmcWrapper.show_dialog(None, LanguageHelper.MissingCredentials) + + result = self.__authenticator.log_on(username=username, channel_guid=self.guid, + setting_id="videolandnl_password") + + # Set some defaults + self.__uid = result.uid + self.__has_premium = result.has_premium + self.__jwt = result.jwt if result.jwt else self.__authenticator.get_authentication_token() + self.httpHeaders["Authorization"] = f"Bearer {self.__jwt}" + return result.logged_on diff --git a/plugin.video.retrospect/resources/language/resource.language.af_za/strings.po b/plugin.video.retrospect/resources/language/resource.language.af_za/strings.po index 6fb737dec7..eee7e8bc1a 100644 --- a/plugin.video.retrospect/resources/language/resource.language.af_za/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.af_za/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.am_et/strings.po b/plugin.video.retrospect/resources/language/resource.language.am_et/strings.po index 7181fdca50..0c5981edd4 100644 --- a/plugin.video.retrospect/resources/language/resource.language.am_et/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.am_et/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.ar_sa/strings.po b/plugin.video.retrospect/resources/language/resource.language.ar_sa/strings.po index 3bfd73e7fd..3a1598b847 100644 --- a/plugin.video.retrospect/resources/language/resource.language.ar_sa/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.ar_sa/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.ast_es/strings.po b/plugin.video.retrospect/resources/language/resource.language.ast_es/strings.po index 2e060527f3..865052289d 100644 --- a/plugin.video.retrospect/resources/language/resource.language.ast_es/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.ast_es/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.az_az/strings.po b/plugin.video.retrospect/resources/language/resource.language.az_az/strings.po index 7f97af0ef2..45198bd4eb 100644 --- a/plugin.video.retrospect/resources/language/resource.language.az_az/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.az_az/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.be_by/strings.po b/plugin.video.retrospect/resources/language/resource.language.be_by/strings.po index e7107d1d33..ed62559db1 100644 --- a/plugin.video.retrospect/resources/language/resource.language.be_by/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.be_by/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.bg_bg/strings.po b/plugin.video.retrospect/resources/language/resource.language.bg_bg/strings.po index 8ba79b1cbe..ab835f550e 100644 --- a/plugin.video.retrospect/resources/language/resource.language.bg_bg/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.bg_bg/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.bs_ba/strings.po b/plugin.video.retrospect/resources/language/resource.language.bs_ba/strings.po index 27a5e99e97..6973dc9bca 100644 --- a/plugin.video.retrospect/resources/language/resource.language.bs_ba/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.bs_ba/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.ca_es/strings.po b/plugin.video.retrospect/resources/language/resource.language.ca_es/strings.po index f5b816907d..5b59ad5d91 100644 --- a/plugin.video.retrospect/resources/language/resource.language.ca_es/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.ca_es/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.cs_cz/strings.po b/plugin.video.retrospect/resources/language/resource.language.cs_cz/strings.po index 63befacb8a..7ea2d0f46a 100644 --- a/plugin.video.retrospect/resources/language/resource.language.cs_cz/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.cs_cz/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.cy_gb/strings.po b/plugin.video.retrospect/resources/language/resource.language.cy_gb/strings.po index dea1ce16ac..b14f01a557 100644 --- a/plugin.video.retrospect/resources/language/resource.language.cy_gb/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.cy_gb/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.da_dk/strings.po b/plugin.video.retrospect/resources/language/resource.language.da_dk/strings.po index 88e2c66af6..adbf0d7ea0 100644 --- a/plugin.video.retrospect/resources/language/resource.language.da_dk/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.da_dk/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.de_de/strings.po b/plugin.video.retrospect/resources/language/resource.language.de_de/strings.po index 63f1d6f514..b8b916d657 100644 --- a/plugin.video.retrospect/resources/language/resource.language.de_de/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.de_de/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.el_gr/strings.po b/plugin.video.retrospect/resources/language/resource.language.el_gr/strings.po index d6bad602a7..ee4a7bbbc1 100644 --- a/plugin.video.retrospect/resources/language/resource.language.el_gr/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.el_gr/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.en_au/strings.po b/plugin.video.retrospect/resources/language/resource.language.en_au/strings.po index 3159758570..19934f109f 100644 --- a/plugin.video.retrospect/resources/language/resource.language.en_au/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.en_au/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.en_gb/strings.po b/plugin.video.retrospect/resources/language/resource.language.en_gb/strings.po index 9977ca8fa9..51f59c417e 100644 --- a/plugin.video.retrospect/resources/language/resource.language.en_gb/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.en_gb/strings.po @@ -542,8 +542,19 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" -# used for list limits -# empty strings from id 30126 to 30189 +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + +# empty strings from id 30129 to 30189 msgctxt "#30190" msgid "Monday" diff --git a/plugin.video.retrospect/resources/language/resource.language.en_nz/strings.po b/plugin.video.retrospect/resources/language/resource.language.en_nz/strings.po index 0e8617fbeb..5a58d21e57 100644 --- a/plugin.video.retrospect/resources/language/resource.language.en_nz/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.en_nz/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.en_us/strings.po b/plugin.video.retrospect/resources/language/resource.language.en_us/strings.po index a6f3b23ef6..4c83414e9a 100644 --- a/plugin.video.retrospect/resources/language/resource.language.en_us/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.en_us/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.eo/strings.po b/plugin.video.retrospect/resources/language/resource.language.eo/strings.po index ebcb1afb95..5b8c8d1360 100644 --- a/plugin.video.retrospect/resources/language/resource.language.eo/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.eo/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.es_ar/strings.po b/plugin.video.retrospect/resources/language/resource.language.es_ar/strings.po index 2a221948a6..9c11dc2481 100644 --- a/plugin.video.retrospect/resources/language/resource.language.es_ar/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.es_ar/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.es_es/strings.po b/plugin.video.retrospect/resources/language/resource.language.es_es/strings.po index 87b2ab18c3..536cc6dcb8 100644 --- a/plugin.video.retrospect/resources/language/resource.language.es_es/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.es_es/strings.po @@ -4,7 +4,7 @@ msgstr "" "Project-Id-Version: Retrospect Add-on\n" "Report-Msgid-Bugs-To: https://github.com/retrospect-addon/plugin.video.retrospect/issues\n" "POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n" -"PO-Revision-Date: 2023-11-21 18:11+0000\n" +"PO-Revision-Date: 2023-12-11 11:11+0000\n" "Last-Translator: José Antonio Alvarado \n" "Language-Team: Spanish (Spain) \n" "Language: es_es\n" @@ -12,7 +12,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.1\n" +"X-Generator: Weblate 5.2.1\n" msgctxt "Addon Summary" msgid "Retrospect allows you to watch re-runs/catch-ups of TV shows made available via their official broadcasters." @@ -522,6 +522,18 @@ msgstr "Encuentre el token de actualización para su cuenta examinando la msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" +msgstr "Mostrar futuros episodios en 'Reciente > Hoy'" + +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" msgstr "" # used for list limits diff --git a/plugin.video.retrospect/resources/language/resource.language.es_mx/strings.po b/plugin.video.retrospect/resources/language/resource.language.es_mx/strings.po index 3143006471..578651a44f 100644 --- a/plugin.video.retrospect/resources/language/resource.language.es_mx/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.es_mx/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.et_ee/strings.po b/plugin.video.retrospect/resources/language/resource.language.et_ee/strings.po index 910d86b782..0d59d2b293 100644 --- a/plugin.video.retrospect/resources/language/resource.language.et_ee/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.et_ee/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.eu_es/strings.po b/plugin.video.retrospect/resources/language/resource.language.eu_es/strings.po index ca3a903467..40d7b0714f 100644 --- a/plugin.video.retrospect/resources/language/resource.language.eu_es/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.eu_es/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.fa_af/strings.po b/plugin.video.retrospect/resources/language/resource.language.fa_af/strings.po index a55b24c47a..7d9b741592 100644 --- a/plugin.video.retrospect/resources/language/resource.language.fa_af/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.fa_af/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.fa_ir/strings.po b/plugin.video.retrospect/resources/language/resource.language.fa_ir/strings.po index 0eeae76030..d9d8aae7e0 100644 --- a/plugin.video.retrospect/resources/language/resource.language.fa_ir/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.fa_ir/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.fi_fi/strings.po b/plugin.video.retrospect/resources/language/resource.language.fi_fi/strings.po index 2cf4dd5d1c..40f407767e 100644 --- a/plugin.video.retrospect/resources/language/resource.language.fi_fi/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.fi_fi/strings.po @@ -522,6 +522,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.fo_fo/strings.po b/plugin.video.retrospect/resources/language/resource.language.fo_fo/strings.po index 676b579ae2..89dcbbda41 100644 --- a/plugin.video.retrospect/resources/language/resource.language.fo_fo/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.fo_fo/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.fr_ca/strings.po b/plugin.video.retrospect/resources/language/resource.language.fr_ca/strings.po index 749b157f6d..be13cf52c6 100644 --- a/plugin.video.retrospect/resources/language/resource.language.fr_ca/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.fr_ca/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.fr_fr/strings.po b/plugin.video.retrospect/resources/language/resource.language.fr_fr/strings.po index a6fd506968..64b5f4814d 100644 --- a/plugin.video.retrospect/resources/language/resource.language.fr_fr/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.fr_fr/strings.po @@ -4,7 +4,7 @@ msgstr "" "Project-Id-Version: Retrospect Add-on\n" "Report-Msgid-Bugs-To: https://github.com/retrospect-addon/plugin.video.retrospect/issues\n" "POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n" -"PO-Revision-Date: 2023-10-24 00:11+0000\n" +"PO-Revision-Date: 2024-01-16 02:44+0000\n" "Last-Translator: Christian Gade \n" "Language-Team: French (France) \n" "Language: fr_fr\n" @@ -12,7 +12,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 5.0.2\n" +"X-Generator: Weblate 5.3\n" msgctxt "Addon Summary" msgid "Retrospect allows you to watch re-runs/catch-ups of TV shows made available via their official broadcasters." @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" @@ -657,7 +669,7 @@ msgstr "Rechercher" msgctxt "#30351" msgid "Categories" -msgstr "" +msgstr "Catégories" msgctxt "#30352" msgid "TV shows" diff --git a/plugin.video.retrospect/resources/language/resource.language.gl_es/strings.po b/plugin.video.retrospect/resources/language/resource.language.gl_es/strings.po index b35980e17d..321af4f3bc 100644 --- a/plugin.video.retrospect/resources/language/resource.language.gl_es/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.gl_es/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.he_il/strings.po b/plugin.video.retrospect/resources/language/resource.language.he_il/strings.po index 7cea7e0b5f..3e9ce3648e 100644 --- a/plugin.video.retrospect/resources/language/resource.language.he_il/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.he_il/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.hi_in/strings.po b/plugin.video.retrospect/resources/language/resource.language.hi_in/strings.po index 9a98fe6af5..646c3b002c 100644 --- a/plugin.video.retrospect/resources/language/resource.language.hi_in/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.hi_in/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.hr_hr/strings.po b/plugin.video.retrospect/resources/language/resource.language.hr_hr/strings.po index 3675573839..f6b00e5c42 100644 --- a/plugin.video.retrospect/resources/language/resource.language.hr_hr/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.hr_hr/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.hu_hu/strings.po b/plugin.video.retrospect/resources/language/resource.language.hu_hu/strings.po index 160c0c0749..76f15fa719 100644 --- a/plugin.video.retrospect/resources/language/resource.language.hu_hu/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.hu_hu/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.hy_am/strings.po b/plugin.video.retrospect/resources/language/resource.language.hy_am/strings.po index d812066665..f05db3ddf0 100644 --- a/plugin.video.retrospect/resources/language/resource.language.hy_am/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.hy_am/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.id_id/strings.po b/plugin.video.retrospect/resources/language/resource.language.id_id/strings.po index f170a5d9f1..8c3afefb09 100644 --- a/plugin.video.retrospect/resources/language/resource.language.id_id/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.id_id/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.is_is/strings.po b/plugin.video.retrospect/resources/language/resource.language.is_is/strings.po index 4bc07999b6..fdbe9558fd 100644 --- a/plugin.video.retrospect/resources/language/resource.language.is_is/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.is_is/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.it_it/strings.po b/plugin.video.retrospect/resources/language/resource.language.it_it/strings.po index c02d9866ed..75f5b8f4c4 100644 --- a/plugin.video.retrospect/resources/language/resource.language.it_it/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.it_it/strings.po @@ -4,7 +4,7 @@ msgstr "" "Project-Id-Version: Retrospect Add-on\n" "Report-Msgid-Bugs-To: https://github.com/retrospect-addon/plugin.video.retrospect/issues\n" "POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n" -"PO-Revision-Date: 2023-11-13 00:11+0000\n" +"PO-Revision-Date: 2023-12-11 11:11+0000\n" "Last-Translator: Massimo Pissarello \n" "Language-Team: Italian \n" "Language: it_it\n" @@ -12,7 +12,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.1\n" +"X-Generator: Weblate 5.2.1\n" msgctxt "Addon Summary" msgid "Retrospect allows you to watch re-runs/catch-ups of TV shows made available via their official broadcasters." @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" @@ -685,7 +697,7 @@ msgstr "" msgctxt "#30358" msgid "Episodes" -msgstr "" +msgstr "Episodi" msgctxt "#30359" msgid "Genres" diff --git a/plugin.video.retrospect/resources/language/resource.language.ja_jp/strings.po b/plugin.video.retrospect/resources/language/resource.language.ja_jp/strings.po index 1b4c10ac80..76c20da00d 100644 --- a/plugin.video.retrospect/resources/language/resource.language.ja_jp/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.ja_jp/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.kn_in/strings.po b/plugin.video.retrospect/resources/language/resource.language.kn_in/strings.po index 11d0d0d91d..e9e7dc996c 100644 --- a/plugin.video.retrospect/resources/language/resource.language.kn_in/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.kn_in/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.ko_kr/strings.po b/plugin.video.retrospect/resources/language/resource.language.ko_kr/strings.po index 21254abe7a..47db7f812e 100644 --- a/plugin.video.retrospect/resources/language/resource.language.ko_kr/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.ko_kr/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.lt_lt/strings.po b/plugin.video.retrospect/resources/language/resource.language.lt_lt/strings.po index 7fb6ddd5be..c866a3c42c 100644 --- a/plugin.video.retrospect/resources/language/resource.language.lt_lt/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.lt_lt/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.lv_lv/strings.po b/plugin.video.retrospect/resources/language/resource.language.lv_lv/strings.po index 94cfad7245..239d32f9b2 100644 --- a/plugin.video.retrospect/resources/language/resource.language.lv_lv/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.lv_lv/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.mi/strings.po b/plugin.video.retrospect/resources/language/resource.language.mi/strings.po index fab317d4b8..e450cb7cdf 100644 --- a/plugin.video.retrospect/resources/language/resource.language.mi/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.mi/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.mk_mk/strings.po b/plugin.video.retrospect/resources/language/resource.language.mk_mk/strings.po index 9fbc8ef7fd..a779af6601 100644 --- a/plugin.video.retrospect/resources/language/resource.language.mk_mk/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.mk_mk/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.ml_in/strings.po b/plugin.video.retrospect/resources/language/resource.language.ml_in/strings.po index d8c517c681..ab0e5b1301 100644 --- a/plugin.video.retrospect/resources/language/resource.language.ml_in/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.ml_in/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.mn_mn/strings.po b/plugin.video.retrospect/resources/language/resource.language.mn_mn/strings.po index 146a5350da..30ee0c0efb 100644 --- a/plugin.video.retrospect/resources/language/resource.language.mn_mn/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.mn_mn/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.ms_my/strings.po b/plugin.video.retrospect/resources/language/resource.language.ms_my/strings.po index e36fb7224d..a82b294438 100644 --- a/plugin.video.retrospect/resources/language/resource.language.ms_my/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.ms_my/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.mt_mt/strings.po b/plugin.video.retrospect/resources/language/resource.language.mt_mt/strings.po index 562284e2b3..7f9f171b5a 100644 --- a/plugin.video.retrospect/resources/language/resource.language.mt_mt/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.mt_mt/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.my_mm/strings.po b/plugin.video.retrospect/resources/language/resource.language.my_mm/strings.po index 57c8871037..46b5f0d8cd 100644 --- a/plugin.video.retrospect/resources/language/resource.language.my_mm/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.my_mm/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.nb_no/strings.po b/plugin.video.retrospect/resources/language/resource.language.nb_no/strings.po index 49fb641f84..b6af962e56 100644 --- a/plugin.video.retrospect/resources/language/resource.language.nb_no/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.nb_no/strings.po @@ -522,6 +522,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.nl_nl/strings.po b/plugin.video.retrospect/resources/language/resource.language.nl_nl/strings.po index 2845238010..cad30d4866 100644 --- a/plugin.video.retrospect/resources/language/resource.language.nl_nl/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.nl_nl/strings.po @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: Retrospect Add-on\n" "Report-Msgid-Bugs-To: https://github.com/retrospect-addon/plugin.video.retrospect/issues\n" "POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n" -"PO-Revision-Date: 2023-11-21 18:11+0000\n" +"PO-Revision-Date: 2023-12-11 11:11+0000\n" "Last-Translator: bas \n" "Language-Team: Dutch \n" "Language: nl_nl\n" @@ -15,7 +15,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.1\n" +"X-Generator: Weblate 5.2.1\n" msgctxt "Addon Summary" msgid "Retrospect allows you to watch re-runs/catch-ups of TV shows made available via their official broadcasters." @@ -525,6 +525,18 @@ msgstr "Zoek de refresh-token voor het account door de cookies van de web msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" +msgstr "Toon toekomstige afleveringen in 'Recent > Vandaag'" + +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" msgstr "" # used for list limits diff --git a/plugin.video.retrospect/resources/language/resource.language.os_os/strings.po b/plugin.video.retrospect/resources/language/resource.language.os_os/strings.po index 1f83329698..1ed2d4949f 100644 --- a/plugin.video.retrospect/resources/language/resource.language.os_os/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.os_os/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.pl_pl/strings.po b/plugin.video.retrospect/resources/language/resource.language.pl_pl/strings.po index 08eabe6514..37c124ce26 100644 --- a/plugin.video.retrospect/resources/language/resource.language.pl_pl/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.pl_pl/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.pt_br/strings.po b/plugin.video.retrospect/resources/language/resource.language.pt_br/strings.po index 0ec981d06e..785019240f 100644 --- a/plugin.video.retrospect/resources/language/resource.language.pt_br/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.pt_br/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.pt_pt/strings.po b/plugin.video.retrospect/resources/language/resource.language.pt_pt/strings.po index f389df9b9f..fe0a360bee 100644 --- a/plugin.video.retrospect/resources/language/resource.language.pt_pt/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.pt_pt/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.ro_ro/strings.po b/plugin.video.retrospect/resources/language/resource.language.ro_ro/strings.po index acde62cc39..a0663e8d5f 100644 --- a/plugin.video.retrospect/resources/language/resource.language.ro_ro/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.ro_ro/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.ru_ru/strings.po b/plugin.video.retrospect/resources/language/resource.language.ru_ru/strings.po index 1ebc5f6b53..462bec5be8 100644 --- a/plugin.video.retrospect/resources/language/resource.language.ru_ru/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.ru_ru/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.si_lk/strings.po b/plugin.video.retrospect/resources/language/resource.language.si_lk/strings.po index 8cdcc488b0..b7b4ad7371 100644 --- a/plugin.video.retrospect/resources/language/resource.language.si_lk/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.si_lk/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.sk_sk/strings.po b/plugin.video.retrospect/resources/language/resource.language.sk_sk/strings.po index a5910b4ebd..4dfb9395ef 100644 --- a/plugin.video.retrospect/resources/language/resource.language.sk_sk/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.sk_sk/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.sl_si/strings.po b/plugin.video.retrospect/resources/language/resource.language.sl_si/strings.po index 5c893fa6dd..857df744bf 100644 --- a/plugin.video.retrospect/resources/language/resource.language.sl_si/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.sl_si/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.sq_al/strings.po b/plugin.video.retrospect/resources/language/resource.language.sq_al/strings.po index 3a21350937..7fc8fb5eda 100644 --- a/plugin.video.retrospect/resources/language/resource.language.sq_al/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.sq_al/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.sr_rs/strings.po b/plugin.video.retrospect/resources/language/resource.language.sr_rs/strings.po index 94367644a0..50d612e786 100644 --- a/plugin.video.retrospect/resources/language/resource.language.sr_rs/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.sr_rs/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.sr_rs@latin/strings.po b/plugin.video.retrospect/resources/language/resource.language.sr_rs@latin/strings.po index fdf9cd015a..0516f59d7a 100644 --- a/plugin.video.retrospect/resources/language/resource.language.sr_rs@latin/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.sr_rs@latin/strings.po @@ -525,6 +525,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.sv_se/strings.po b/plugin.video.retrospect/resources/language/resource.language.sv_se/strings.po index c52253b236..409525b1f5 100644 --- a/plugin.video.retrospect/resources/language/resource.language.sv_se/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.sv_se/strings.po @@ -528,6 +528,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.szl/strings.po b/plugin.video.retrospect/resources/language/resource.language.szl/strings.po index b2f917db42..d1333fc069 100644 --- a/plugin.video.retrospect/resources/language/resource.language.szl/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.szl/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.ta_in/strings.po b/plugin.video.retrospect/resources/language/resource.language.ta_in/strings.po index 098e3de3ff..b52817e377 100644 --- a/plugin.video.retrospect/resources/language/resource.language.ta_in/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.ta_in/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.te_in/strings.po b/plugin.video.retrospect/resources/language/resource.language.te_in/strings.po index d0a70e788b..c9f4f03dd9 100644 --- a/plugin.video.retrospect/resources/language/resource.language.te_in/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.te_in/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.tg_tj/strings.po b/plugin.video.retrospect/resources/language/resource.language.tg_tj/strings.po index de8194db54..cd27b8ce8e 100644 --- a/plugin.video.retrospect/resources/language/resource.language.tg_tj/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.tg_tj/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.th_th/strings.po b/plugin.video.retrospect/resources/language/resource.language.th_th/strings.po index 9be93617f7..d2594ee5d4 100644 --- a/plugin.video.retrospect/resources/language/resource.language.th_th/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.th_th/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.tr_tr/strings.po b/plugin.video.retrospect/resources/language/resource.language.tr_tr/strings.po index cf6c6bf760..eb866e6435 100644 --- a/plugin.video.retrospect/resources/language/resource.language.tr_tr/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.tr_tr/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.uk_ua/strings.po b/plugin.video.retrospect/resources/language/resource.language.uk_ua/strings.po index c4c78f3e64..9a171fe5f9 100644 --- a/plugin.video.retrospect/resources/language/resource.language.uk_ua/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.uk_ua/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.uz_uz/strings.po b/plugin.video.retrospect/resources/language/resource.language.uz_uz/strings.po index 73afa5ed85..f582bcd933 100644 --- a/plugin.video.retrospect/resources/language/resource.language.uz_uz/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.uz_uz/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.vi_vn/strings.po b/plugin.video.retrospect/resources/language/resource.language.vi_vn/strings.po index 6c52734eb6..68c5910b7b 100644 --- a/plugin.video.retrospect/resources/language/resource.language.vi_vn/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.vi_vn/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.zh_cn/strings.po b/plugin.video.retrospect/resources/language/resource.language.zh_cn/strings.po index fac5ee5c1c..d8b6370f01 100644 --- a/plugin.video.retrospect/resources/language/resource.language.zh_cn/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.zh_cn/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/language/resource.language.zh_tw/strings.po b/plugin.video.retrospect/resources/language/resource.language.zh_tw/strings.po index 9f0ff2ce1f..2d339fa95c 100644 --- a/plugin.video.retrospect/resources/language/resource.language.zh_tw/strings.po +++ b/plugin.video.retrospect/resources/language/resource.language.zh_tw/strings.po @@ -524,6 +524,18 @@ msgctxt "#30125" msgid "Show future episodes under 'Recent > Today'" msgstr "" +msgctxt "#30126" +msgid "Default" +msgstr "" + +msgctxt "#30127" +msgid "Show All" +msgstr "" + +msgctxt "#30128" +msgid "Filter Premium" +msgstr "" + # used for list limits # empty strings from id 30109 to 30189 msgctxt "#30190" diff --git a/plugin.video.retrospect/resources/lib/actions/actionparser.py b/plugin.video.retrospect/resources/lib/actions/actionparser.py index b7e22de612..64dfac85b0 100644 --- a/plugin.video.retrospect/resources/lib/actions/actionparser.py +++ b/plugin.video.retrospect/resources/lib/actions/actionparser.py @@ -156,8 +156,9 @@ def create_action_url(self, channel, action, item=None, store_id=None, category= if channel: params[keyword.CHANNEL] = channel.url_id - if item is None and channel is not None: - params[keyword.RANDOM_LIVE] = random.randint(10000, 99999) + # Introduced to fix a 'mark all as watched' issue, but resets the sorting every reload. + # if item is None and channel is not None: + # params[keyword.RANDOM_LIVE] = random.randint(10000, 99999) params[keyword.ACTION] = action diff --git a/plugin.video.retrospect/resources/lib/actions/folderaction.py b/plugin.video.retrospect/resources/lib/actions/folderaction.py index f958baa7e9..b9a53d12f9 100644 --- a/plugin.video.retrospect/resources/lib/actions/folderaction.py +++ b/plugin.video.retrospect/resources/lib/actions/folderaction.py @@ -295,6 +295,11 @@ def __add_sort_method_to_handle(self, handle, items=None): # Some items have episodes, only add the sorting options. sort_methods.append(xbmcplugin.SORT_METHOD_EPISODE) # 24 + is_search = self.__media_item.is_search(self.__media_item.url) if self.__media_item else False + if is_search: + sort_methods.remove(xbmcplugin.SORT_METHOD_UNSORTED) + sort_methods.insert(0, xbmcplugin.SORT_METHOD_UNSORTED) + # Actually add them Logger.debug("Sorting methods: %s", sort_methods) for sort_method in sort_methods: diff --git a/plugin.video.retrospect/resources/lib/authentication/authenticationhandler.py b/plugin.video.retrospect/resources/lib/authentication/authenticationhandler.py index 185bac5d76..f87b61fd3b 100644 --- a/plugin.video.retrospect/resources/lib/authentication/authenticationhandler.py +++ b/plugin.video.retrospect/resources/lib/authentication/authenticationhandler.py @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-3.0-or-later +from typing import Optional from resources.lib.addonsettings import AddonSettings from resources.lib.addonsettings import LOCAL @@ -6,11 +7,11 @@ class AuthenticationHandler(object): - def __init__(self, realm, device_id): + def __init__(self, realm: str, device_id: Optional[str]): """ Initializes a handler for the authentication provider - :param str realm: - :param str|None device_id: + :param realm: + :param device_id: """ @@ -25,55 +26,53 @@ def __init__(self, realm, device_id): def realm(self): return self._realm - def log_on(self, username, password): + def log_on(self, username: str, password: str) -> AuthenticationResult: """ Peforms the logon of a user. - :param str username: The username - :param str password: The password to use + :param username: The username + :param password: The password to use :returns: a AuthenticationResult with the result of the log on - :rtype: AuthenticationResult """ + raise NotImplementedError - def active_authentication(self): + def active_authentication(self) -> AuthenticationResult: """ Check if the user with the given name is currently authenticated. :returns: a AuthenticationResult with the account data. - :rtype: AuthenticationResult """ raise NotImplementedError - def log_off(self, username): + def log_off(self, username) -> bool: """ Check if the user with the given name is currently authenticated. :param str username: The username to log off :returns: Indication of success - :rtype: bool """ raise NotImplementedError - def get_authentication_token(self): + def get_authentication_token(self) -> Optional[str]: """ Returns a token that can be used for authentication of the current session. The user needs to be logged in for this. :return: An authentication token. - :rtype: str """ + raise NotImplementedError - def _store_current_user_in_settings(self, username): + def _store_current_user_in_settings(self, username: str): """ Store the current user in the local settings. - :param str|None username: The currently authenticated user + :param username: The currently authenticated user Can be used if there is no other means of retrieving the currently authenticated user. @@ -82,7 +81,7 @@ def _store_current_user_in_settings(self, username): store = AddonSettings.store(LOCAL) store.set_setting("{}:authenticated_user".format(self._realm), username) - def _get_current_user_in_settings(self): + def _get_current_user_in_settings(self) -> str: """ Retrieves the current user in the local settings. Can be used if there is no other means of retrieving the currently authenticated user. diff --git a/plugin.video.retrospect/resources/lib/authentication/authenticationresult.py b/plugin.video.retrospect/resources/lib/authentication/authenticationresult.py index 3fe03c6070..49d0c7b56c 100644 --- a/plugin.video.retrospect/resources/lib/authentication/authenticationresult.py +++ b/plugin.video.retrospect/resources/lib/authentication/authenticationresult.py @@ -1,14 +1,27 @@ # SPDX-License-Identifier: GPL-3.0-or-later +from typing import Optional class AuthenticationResult: - def __init__(self, username, has_premium=False, existing_login=False): + username: str + logged_on: bool + existing_login: bool + has_premium: bool + uid: Optional[str] + error: Optional[str] + jwt: Optional[str] + + def __init__(self, username: str, has_premium: bool = False, existing_login: bool = False, + uid: Optional[str] = None, error: Optional[str] = None, jwt: Optional[str] = None): """ Log on result object - :param str|None username: The user name that is used for logging in. - :param bool existing_login: Indication whether the user was already logged in and this - was just a the renew of the authentication session. - :param bool has_premium: Indication whether the user has a premium/paid account. + :param username: The user name that is used for logging in. + :param existing_login: Indication whether the user was already logged in and this + was just a the renew of the authentication session. + :param has_premium: Indication whether the user has a premium/paid account. + :param uid: The internal user id for the username + :param error: Error value + :param jwt A possible JWT value. """ @@ -16,8 +29,11 @@ def __init__(self, username, has_premium=False, existing_login=False): self.logged_on = bool(username) self.existing_login = existing_login self.has_premium = has_premium + self.uid = uid + self.error = error + self.jwt = jwt - def __str__(self): + def __str__(self) -> str: if not self.logged_on: return "Not logged on" diff --git a/plugin.video.retrospect/resources/lib/authentication/authenticator.py b/plugin.video.retrospect/resources/lib/authentication/authenticator.py index 0b27338ab8..8784206253 100644 --- a/plugin.video.retrospect/resources/lib/authentication/authenticator.py +++ b/plugin.video.retrospect/resources/lib/authentication/authenticator.py @@ -1,13 +1,15 @@ # SPDX-License-Identifier: GPL-3.0-or-later +from typing import Optional from .authenticationhandler import AuthenticationHandler from .authenticationresult import AuthenticationResult from ..logger import Logger from ..vault import Vault +from ..xbmcwrapper import XbmcWrapper class Authenticator(object): - def __init__(self, handler): + def __init__(self, handler: AuthenticationHandler): """ Main logic handler for authentication. :param AuthenticationHandler handler: The authentication handler to use. @@ -22,31 +24,31 @@ def __init__(self, handler): self.__hander = handler - def log_on(self, username, password=None, setting_id=None, channel_guid=None): - """ Peforms the logon of a user. Either with the specified password or via a lookup + def log_on(self, username: str, password: Optional[str] = None, setting_id: Optional[str] = None, channel_guid: Optional[str] = None): + """ Peforms the logon of a user. Either with the specified password or via a lookup. Also + logs off a previous user if the username has changed from previous logins. - :param str username: The username - :param str|None password: The password to use - :param str|None setting_id: The ID of the setting where the password is stored - :param str|None channel_guid: The GUID of the channel, if the password is stored in a - channel setting. + :param username: The username + :param password: The password to use + :param setting_id: The ID of the setting where the password is stored + :param channel_guid: The GUID of the channel, if the password is stored in a + channel setting. :returns: An indication of a successful login. - :rtype: AuthenticationResult """ res = self.__hander.active_authentication() logged_on_user = res.username - # Check if the existing log in is the same as the requested one. + # Check if the existing login is the same as the requested one. if logged_on_user and logged_on_user != username: Logger.warning("Existing but different authenticated user (%s) found. Logging of first.", self.__safe_log(logged_on_user)) self.__hander.log_off(logged_on_user) elif logged_on_user and logged_on_user == username: - Logger.warning("Existing authenticated user (%s) found.", self.__safe_log(logged_on_user)) + Logger.info("Existing authenticated user (%s) found.", self.__safe_log(logged_on_user)) return res if not username: @@ -67,9 +69,11 @@ def log_on(self, username, password=None, setting_id=None, channel_guid=None): return AuthenticationResult(None) res = self.__hander.log_on(username, password) + if res.error: + XbmcWrapper.show_dialog(None, res.error) return res - def active_authentication(self): + def active_authentication(self) -> AuthenticationResult: """ Check if the user with the given name is currently authenticated. :returns: a AuthenticationResult with the account data @@ -79,11 +83,10 @@ def active_authentication(self): return self.__hander.active_authentication() - def get_authentication_token(self): + def get_authentication_token(self) -> Optional[str]: """ Fetches an authentication token for the given login :return: token value - :rtype: str """ diff --git a/plugin.video.retrospect/resources/lib/authentication/gigyahandler.py b/plugin.video.retrospect/resources/lib/authentication/gigyahandler.py new file mode 100644 index 0000000000..635ff9859e --- /dev/null +++ b/plugin.video.retrospect/resources/lib/authentication/gigyahandler.py @@ -0,0 +1,190 @@ +import time +from typing import Optional + +try: + import jwt +except ImportError: + # The package is named pyjwt in Kodi 18: https://github.com/lottaboost/script.module.pyjwt/pull/1 + # noinspection PyUnresolvedReferences + import pyjwt as jwt + +from resources.lib.addonsettings import AddonSettings, LOCAL +from resources.lib.authentication.authenticationhandler import AuthenticationHandler +from resources.lib.authentication.authenticationresult import AuthenticationResult +from resources.lib.helpers.jsonhelper import JsonHelper +from resources.lib.logger import Logger +from resources.lib.urihandler import UriHandler + + +class GigyaHandler(AuthenticationHandler): + def __init__(self, realm: str, api_key_3: str, api_key_4: str, device_id: str): + super().__init__(realm, device_id.replace("-", "") + device_id.replace("-", "")[::-1]) + + self.__api_key_3 = api_key_3 + self.__api_key_4 = api_key_4 + self.__build_id = "15627" + + self.__uid = None + self.__uid_signature = None + self.__uid_signature_timestamp = None + self.__has_premium = False + self.__jwt = None + + def log_on(self, username: str, password: str) -> AuthenticationResult: + bootstrap_url = f"https://accounts.eu1.gigya.com/accounts.webSdkBootstrap?apiKey={self.__api_key_3}&sdk=js_latest&sdkBuild={self.__build_id}&format=json" + bootstrap = UriHandler.open(bootstrap_url, no_cache=True) + bootstrap_json = JsonHelper(bootstrap) + if not bootstrap_json.get_value("statusReason") == "OK": + Logger.error("Error initiating login") + return AuthenticationResult(None) + + gmid = UriHandler.get_cookie("gmid", ".gigya.com").value + UriHandler.set_cookie(name="gmid", value=gmid, domain=f".{self._realm}") + + login_url = f"https://gigya-merge.{self._realm}/accounts.login" + login_data = { + "loginID": username, + "password": password, + "sessionExpiration": -2, + "targetEnv": "jssdk", + "include": "profile,data", + "includeUserInfo": True, + "lang": "en", + "APIKey": self.__api_key_4, + "sdk": "js_latest", + "authMode": "cookie", + "pageURL": f"https://www.{self._realm}/inloggen", + "sdkBuild": 15627, + "format": "json", + } + + headers = { + "content-type": "application/x-www-form-urlencoded" + } + login_result = UriHandler.open(login_url, data=login_data, no_cache=True, additional_headers=headers) + result = JsonHelper(login_result) + + error = result.get_value("errorDetails", fallback=None) + if error: + return AuthenticationResult(None, error=error) + account = result.get_value("profile", "email") + + self.__extract_uid_info(result) + + # Check for premium, which also happens to need the JWT + self.__check_for_premium() + + return AuthenticationResult( + username=account, uid=self.__uid, + has_premium=self.__has_premium, jwt=self.__jwt) + + def active_authentication(self) -> AuthenticationResult: + login_token_cookie = UriHandler.get_cookie(f"glt_{self.__api_key_4}", domain=f".{self.realm}") + if not login_token_cookie: + return AuthenticationResult(None) + + profile_data = { + "include": "profile,data", + "lang": "en", + "APIKey": self.__api_key_4, + "sdk": "js_latest", + "login_token": login_token_cookie.value, + "authMode": "cookie", + # "pageURL": "", + "sdkBuild": 15627, + "format": "json", + } + headers = { + "content-type": "application/x-www-form-urlencoded" + } + data = UriHandler.open(f"https://gigya-merge.{self._realm}/accounts.getAccountInfo", additional_headers=headers, data=profile_data) + json_data = JsonHelper(data) + if json_data.get_value("errorCode"): + error = json_data.get_value("statusReason") + error = json_data.get_value("errorMessage", fallback=error) + Logger.error(f"Gigya: getAccountInfo failed: {error}") + return AuthenticationResult(None) + + username = json_data.get_value("profile", "email") + self.__extract_uid_info(json_data) + + # Check for premium, which also happens to need the JWT + self.__check_for_premium() + + return AuthenticationResult( + username, existing_login=True, uid=self.__uid, + has_premium=self.__has_premium, jwt=self.__jwt) + + def log_off(self, username) -> bool: + UriHandler.delete_cookie(domain=".gigya.com") + UriHandler.delete_cookie(domain=f".{self.realm}") + AddonSettings.set_setting(f"{self.realm}-jwt", "", store=LOCAL) + + self.__uid = None + self.__uid_signature = None + self.__uid_signature_timestamp = None + self.__has_premium = False + self.__jwt = None + return True + + def get_authentication_token(self) -> Optional[str]: + if self.__jwt: + return self.__jwt + + token_value = AddonSettings.get_setting(f"{self.realm}-jwt", store=LOCAL) + if token_value: + token = jwt.decode(token_value, options={"verify_signature": False}) + expire = token.get("exp") + if expire < time.time(): + token = None + + if token: + self.__jwt = token_value + return token_value + + if not self.__uid: + return None + + # Get a generic token + url = "https://front-auth.videoland.bedrock.tech/v2/platforms/m6group_web/getJwt" + headers = { + "x-auth-device-id": self._device_id, + "x-auth-gigya-signature": self.__uid_signature, + "x-auth-gigya-signature-timestamp": str(self.__uid_signature_timestamp), + "x-auth-gigya-uid": self.__uid + } + + token = UriHandler.open(url, additional_headers=headers, no_cache=True) + if not token: + return None + + # Now load it for a profile + # TODO: Might be the wrong profile if there are more. + token_value = JsonHelper(token).get_value("token") + profile_url = f"https://users.videoland.bedrock.tech/v2/platforms/m6group_web/users/{self.__uid}/profiles" + profile_headers = { + "Authorization": f"Bearer {token_value}" + } + profile_info = JsonHelper(UriHandler.open(profile_url, additional_headers=profile_headers, no_cache=True)) + puid = profile_info.get_value(0, "uid") + + # Actually fetch a token for it. + headers["x-auth-profile-id"] = puid + token_value = JsonHelper(UriHandler.open(url, additional_headers=headers, no_cache=True)).get_value("token") + + AddonSettings.set_setting(f"{self.realm}-jwt", token_value, store=LOCAL) + self.__jwt = token_value + return token_value + + def __check_for_premium(self): + url = f"https://stores.videoland.bedrock.tech/premium/v4/customers/rtlnl/platforms/m6group_web/users/{self.__uid}/subscriptions" + jwt = self.get_authentication_token() + headers = {"Authorization": f"Bearer {jwt}"} + subscriptions = JsonHelper(UriHandler.open(url, additional_headers=headers)) + current_subscription = subscriptions.get_value("current", 0, "current_contract") + self.__has_premium = False if current_subscription.get("variant_id", "") == "Free" else True + + def __extract_uid_info(self, token: JsonHelper) -> None: + self.__uid = token.get_value("UID") + self.__uid_signature = token.get_value("UIDSignature") + self.__uid_signature_timestamp = token.get_value("signatureTimestamp") diff --git a/plugin.video.retrospect/resources/lib/chn_class.py b/plugin.video.retrospect/resources/lib/chn_class.py index 6e9f881eb0..1a805d9e35 100644 --- a/plugin.video.retrospect/resources/lib/chn_class.py +++ b/plugin.video.retrospect/resources/lib/chn_class.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later import urllib.parse as parse -from typing import Optional, List +from typing import Optional, List, Union from resources.lib.mediaitem import MediaItem, FolderItem, MediaStream from resources.lib import contenttype @@ -142,6 +142,12 @@ def init_channel(self): def sort_key(self): return "{0}-{1}".format(self.sortOrderPerCountry, self.channelName) + def filter_premium(self) -> Optional[bool]: + """ Does the channel have a specific 'filter premium' filter. If not None, it will + override the main Retrospect one """ + + return None + def process_folder_list(self, parent_item: Optional[MediaItem]=None) -> List[MediaItem]: # NOSONAR """ Process the selected item and gets it's child items using the available dataparsers. @@ -336,10 +342,13 @@ def process_folder_list(self, parent_item: Optional[MediaItem]=None) -> List[Med Logger.trace("Post-processing returned %d items", len(items)) self.currentParser = None + # Hide premium. First consider a channel setting, otherwise overall. + hide_premium = self.filter_premium() + hide_premium = AddonSettings.hide_premium_items() if hide_premium is None else hide_premium + # should we exclude DRM/GEO? hide_geo_locked = AddonSettings.hide_geo_locked_items_for_location(self.language) hide_drm_protected = AddonSettings.hide_drm_items() - hide_premium = AddonSettings.hide_premium_items() hide_folders = AddonSettings.hide_restricted_folders() type_to_exclude = [] if not hide_folders: @@ -522,7 +531,7 @@ def search_site(self, url=None): return items - def create_episode_item(self, result_set): + def create_episode_item(self, result_set: Union[str, dict]) -> Union[MediaItem, List[MediaItem], None]: """ Creates a new MediaItem for an episode. This method creates a new MediaItem from the Regular Expression or Json @@ -733,7 +742,7 @@ def create_video_item(self, result_set): item.complete = False return item - def update_video_item(self, item): + def update_video_item(self, item: MediaItem) -> MediaItem: """ Updates an existing MediaItem with more data. Used to update none complete MediaItems (self.complete = False). This @@ -931,7 +940,7 @@ def _add_data_parser(self, url, name=None, preprocessor=None, :param str|list[str|int|tuple] parser: The parser (regex or json). :param creator: The creator called with the results from the parser - :type creator: (list[str]|dict) -> MediaItem|None + :type creator: (list[str]|dict) -> MediaItem|None|list[MediaItem] :param updater: The updater called for updating a item :type updater: MediaItem -> MediaItem diff --git a/plugin.video.retrospect/resources/lib/settings/settingsstore.py b/plugin.video.retrospect/resources/lib/settings/settingsstore.py index c7bc6339d7..dfe74a422c 100644 --- a/plugin.video.retrospect/resources/lib/settings/settingsstore.py +++ b/plugin.video.retrospect/resources/lib/settings/settingsstore.py @@ -16,7 +16,7 @@ def __init__(self, logger): self._logger = logger # What settings should we not expose via the logger? - self._secure_setting_ids = ["application_key", "client_id"] + self._secure_setting_ids = ["application_key", "client_id", "jwt", "password"] def set_setting(self, setting_id, setting_value, channel=None): """ Returns a boolean value for the given setting_id. @@ -99,8 +99,10 @@ def _get_safe_print_value(self, setting_id, setting_value): """ - if setting_id in self._secure_setting_ids: + if (setting_id in self._secure_setting_ids or + any([v in setting_id.lower() for v in self._secure_setting_ids])): return "" + return setting_value def __del__(self): diff --git a/plugin.video.retrospect/resources/settings.xml b/plugin.video.retrospect/resources/settings.xml index dbfd0ca026..b5848bf30f 100644 --- a/plugin.video.retrospect/resources/settings.xml +++ b/plugin.video.retrospect/resources/settings.xml @@ -67,7 +67,7 @@ - + @@ -83,32 +83,33 @@ - - - - - - + + - + - + + + + + + - - - - + + + + - - - - + + + + - - - - + + + +