diff --git a/addon.xml b/addon.xml index e3456e35..788ca87d 100644 --- a/addon.xml +++ b/addon.xml @@ -1,5 +1,5 @@ - + @@ -13,20 +13,13 @@ -[add] 'Play (Ask for quality)' context menu -[add] search by channel or playlist id -[add] hide_folders, hide_playlists, hide_search, and hide_live to /channel/<channel_id>/ end-point - - ie. plugin://plugin.video.youtube/channel/UC4PooiX37Pld1T8J5SYT-SQ/?hide_folders=true will hide all folders(Playlists, Search, and Live) in the channel listing -[fix] playback for some videos (ie. music videos) -[fix] playback of some videos with no adaptive video streams -[fix] don't update watch history when incognito/screensaver/live |contrib: regseb| -[fix] search prompting for input after video playback or refresh -[lang] el_gr strings |contrib: twilight0| -[lang] es_es strings |contrib: roliverosc| -[lang] pt_br strings |contrib: MediaBrasil| -[lang] cs_cz strings |contrib: llzn.cz| -[lang] it_it strings |contrib: SebastianoPistore| -[lang] de_de strings |contrib: tweimer| +[add] send PlaybackStarted notification containing video_id of the playing video +[fix] allow playback regardless of API status + - fixes playback for strm, playlists, other add-ons, and sharing videos from devices +[fix] fix possible loop due to invalid keys and login information +[fix] fix playback of mpeg-dash streams if HTTP Server - Listen on IP is blank +[upd] use a dialog to notify users of API key requirements with link to wiki + - https://ytaddon.page.link/keys icon.png diff --git a/changelog.txt b/changelog.txt index f2a04528..85796c3e 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,12 @@ +6.7.0 +[add] send PlaybackStarted notification containing video_id of the playing video +[fix] allow playback regardless of API status + - fixes playback for strm, playlists, other add-ons, and sharing videos from devices +[fix] fix possible loop due to invalid keys and login information +[fix] fix playback of mpeg-dash streams if HTTP Server - Listen on IP is blank +[upd] use a dialog to notify users of API key requirements with link to wiki + - https://ytaddon.page.link/keys + 6.6.0 [add] 'Play (Ask for quality)' context menu [add] search by channel or playlist id diff --git a/resources/language/resource.language.bg_bg/strings.po b/resources/language/resource.language.bg_bg/strings.po index c2e597a7..007f49ad 100644 --- a/resources/language/resource.language.bg_bg/strings.po +++ b/resources/language/resource.language.bg_bg/strings.po @@ -1189,3 +1189,7 @@ msgstr "" msgctxt "#30730" msgid "Play (Ask for quality)" msgstr "" + +msgctxt "#30731" +msgid "The YouTube add-on now requires that you use your own API keys.[CR]For more information see the wiki: [B]https://ytaddon.page.link/keys[/B][CR][CR]Sorry for the inconvenience." +msgstr "" diff --git a/resources/language/resource.language.cs_cz/strings.po b/resources/language/resource.language.cs_cz/strings.po index ec7cc34e..e68bbb0b 100644 --- a/resources/language/resource.language.cs_cz/strings.po +++ b/resources/language/resource.language.cs_cz/strings.po @@ -1206,3 +1206,7 @@ msgstr "" msgctxt "#30730" msgid "Play (Ask for quality)" msgstr "" + +msgctxt "#30731" +msgid "The YouTube add-on now requires that you use your own API keys.[CR]For more information see the wiki: [B]https://ytaddon.page.link/keys[/B][CR][CR]Sorry for the inconvenience." +msgstr "" diff --git a/resources/language/resource.language.de_de/strings.po b/resources/language/resource.language.de_de/strings.po index 342cf6d1..04f1618b 100644 --- a/resources/language/resource.language.de_de/strings.po +++ b/resources/language/resource.language.de_de/strings.po @@ -1206,3 +1206,7 @@ msgstr "Fernbedienungsfreundliche Suche" msgctxt "#30730" msgid "Play (Ask for quality)" msgstr "Abspielen (nach Qualität fragen)" + +msgctxt "#30731" +msgid "The YouTube add-on now requires that you use your own API keys.[CR]For more information see the wiki: [B]https://ytaddon.page.link/keys[/B][CR][CR]Sorry for the inconvenience." +msgstr "" diff --git a/resources/language/resource.language.el_gr/strings.po b/resources/language/resource.language.el_gr/strings.po index 77315ad0..e5e06a9e 100644 --- a/resources/language/resource.language.el_gr/strings.po +++ b/resources/language/resource.language.el_gr/strings.po @@ -1205,3 +1205,7 @@ msgstr "Αναζήτηση φιλική για χειριστήριο" msgctxt "#30730" msgid "Play (Ask for quality)" msgstr "Αναπαραγωγή (Ερώτηση για ποιότητα)" + +msgctxt "#30731" +msgid "The YouTube add-on now requires that you use your own API keys.[CR]For more information see the wiki: [B]https://ytaddon.page.link/keys[/B][CR][CR]Sorry for the inconvenience." +msgstr "" diff --git a/resources/language/resource.language.en_gb/strings.po b/resources/language/resource.language.en_gb/strings.po index 76a4a7d0..3ca3bfb6 100644 --- a/resources/language/resource.language.en_gb/strings.po +++ b/resources/language/resource.language.en_gb/strings.po @@ -1206,3 +1206,7 @@ msgstr "" msgctxt "#30730" msgid "Play (Ask for quality)" msgstr "" + +msgctxt "#30731" +msgid "The YouTube add-on now requires that you use your own API keys.[CR]For more information see the wiki: [B]https://ytaddon.page.link/keys[/B][CR][CR]Sorry for the inconvenience." +msgstr "" diff --git a/resources/language/resource.language.en_us/strings.po b/resources/language/resource.language.en_us/strings.po index 8d79cb58..0a2bcd08 100644 --- a/resources/language/resource.language.en_us/strings.po +++ b/resources/language/resource.language.en_us/strings.po @@ -1207,3 +1207,7 @@ msgstr "" msgctxt "#30730" msgid "Play (Ask for quality)" msgstr "" + +msgctxt "#30731" +msgid "The YouTube add-on now requires that you use your own API keys.[CR]For more information see the wiki: [B]https://ytaddon.page.link/keys[/B][CR][CR]Sorry for the inconvenience." +msgstr "" diff --git a/resources/language/resource.language.es_es/strings.po b/resources/language/resource.language.es_es/strings.po index eec6a6dc..7e9a04fa 100644 --- a/resources/language/resource.language.es_es/strings.po +++ b/resources/language/resource.language.es_es/strings.po @@ -1206,3 +1206,7 @@ msgstr "" msgctxt "#30730" msgid "Play (Ask for quality)" msgstr "" + +msgctxt "#30731" +msgid "The YouTube add-on now requires that you use your own API keys.[CR]For more information see the wiki: [B]https://ytaddon.page.link/keys[/B][CR][CR]Sorry for the inconvenience." +msgstr "" diff --git a/resources/language/resource.language.es_mx/strings.po b/resources/language/resource.language.es_mx/strings.po index f30fbb59..0cddcc55 100644 --- a/resources/language/resource.language.es_mx/strings.po +++ b/resources/language/resource.language.es_mx/strings.po @@ -1206,3 +1206,7 @@ msgstr "" msgctxt "#30730" msgid "Play (Ask for quality)" msgstr "" + +msgctxt "#30731" +msgid "The YouTube add-on now requires that you use your own API keys.[CR]For more information see the wiki: [B]https://ytaddon.page.link/keys[/B][CR][CR]Sorry for the inconvenience." +msgstr "" diff --git a/resources/language/resource.language.fi_fi/strings.po b/resources/language/resource.language.fi_fi/strings.po index a16ac708..eec2ee28 100644 --- a/resources/language/resource.language.fi_fi/strings.po +++ b/resources/language/resource.language.fi_fi/strings.po @@ -1191,3 +1191,7 @@ msgstr "" msgctxt "#30730" msgid "Play (Ask for quality)" msgstr "" + +msgctxt "#30731" +msgid "The YouTube add-on now requires that you use your own API keys.[CR]For more information see the wiki: [B]https://ytaddon.page.link/keys[/B][CR][CR]Sorry for the inconvenience." +msgstr "" diff --git a/resources/language/resource.language.fr_fr/strings.po b/resources/language/resource.language.fr_fr/strings.po index 729365de..9f6dfb7c 100644 --- a/resources/language/resource.language.fr_fr/strings.po +++ b/resources/language/resource.language.fr_fr/strings.po @@ -1192,3 +1192,7 @@ msgstr "" msgctxt "#30730" msgid "Play (Ask for quality)" msgstr "" + +msgctxt "#30731" +msgid "The YouTube add-on now requires that you use your own API keys.[CR]For more information see the wiki: [B]https://ytaddon.page.link/keys[/B][CR][CR]Sorry for the inconvenience." +msgstr "" diff --git a/resources/language/resource.language.he_il/strings.po b/resources/language/resource.language.he_il/strings.po index 776d3277..68d1d99a 100644 --- a/resources/language/resource.language.he_il/strings.po +++ b/resources/language/resource.language.he_il/strings.po @@ -1200,3 +1200,7 @@ msgstr "" msgctxt "#30730" msgid "Play (Ask for quality)" msgstr "" + +msgctxt "#30731" +msgid "The YouTube add-on now requires that you use your own API keys.[CR]For more information see the wiki: [B]https://ytaddon.page.link/keys[/B][CR][CR]Sorry for the inconvenience." +msgstr "" diff --git a/resources/language/resource.language.hu_hu/strings.po b/resources/language/resource.language.hu_hu/strings.po index 6b35eb35..00dab8dd 100644 --- a/resources/language/resource.language.hu_hu/strings.po +++ b/resources/language/resource.language.hu_hu/strings.po @@ -1188,3 +1188,7 @@ msgstr "" msgctxt "#30730" msgid "Play (Ask for quality)" msgstr "" + +msgctxt "#30731" +msgid "The YouTube add-on now requires that you use your own API keys.[CR]For more information see the wiki: [B]https://ytaddon.page.link/keys[/B][CR][CR]Sorry for the inconvenience." +msgstr "" diff --git a/resources/language/resource.language.it_it/strings.po b/resources/language/resource.language.it_it/strings.po index 33de32dd..b55917f2 100644 --- a/resources/language/resource.language.it_it/strings.po +++ b/resources/language/resource.language.it_it/strings.po @@ -1201,3 +1201,7 @@ msgstr "" msgctxt "#30730" msgid "Play (Ask for quality)" msgstr "" + +msgctxt "#30731" +msgid "The YouTube add-on now requires that you use your own API keys.[CR]For more information see the wiki: [B]https://ytaddon.page.link/keys[/B][CR][CR]Sorry for the inconvenience." +msgstr "" diff --git a/resources/language/resource.language.ko_kr/strings.po b/resources/language/resource.language.ko_kr/strings.po index 885e5399..ff3610c5 100644 --- a/resources/language/resource.language.ko_kr/strings.po +++ b/resources/language/resource.language.ko_kr/strings.po @@ -1189,3 +1189,7 @@ msgstr "" msgctxt "#30730" msgid "Play (Ask for quality)" msgstr "" + +msgctxt "#30731" +msgid "The YouTube add-on now requires that you use your own API keys.[CR]For more information see the wiki: [B]https://ytaddon.page.link/keys[/B][CR][CR]Sorry for the inconvenience." +msgstr "" diff --git a/resources/language/resource.language.nb_no/strings.po b/resources/language/resource.language.nb_no/strings.po index 9381d43e..9e2d29f4 100644 --- a/resources/language/resource.language.nb_no/strings.po +++ b/resources/language/resource.language.nb_no/strings.po @@ -1206,3 +1206,7 @@ msgstr "" msgctxt "#30730" msgid "Play (Ask for quality)" msgstr "" + +msgctxt "#30731" +msgid "The YouTube add-on now requires that you use your own API keys.[CR]For more information see the wiki: [B]https://ytaddon.page.link/keys[/B][CR][CR]Sorry for the inconvenience." +msgstr "" diff --git a/resources/language/resource.language.nl_nl/strings.po b/resources/language/resource.language.nl_nl/strings.po index 2f43bd2a..9140372c 100644 --- a/resources/language/resource.language.nl_nl/strings.po +++ b/resources/language/resource.language.nl_nl/strings.po @@ -1198,3 +1198,7 @@ msgstr "" msgctxt "#30730" msgid "Play (Ask for quality)" msgstr "" + +msgctxt "#30731" +msgid "The YouTube add-on now requires that you use your own API keys.[CR]For more information see the wiki: [B]https://ytaddon.page.link/keys[/B][CR][CR]Sorry for the inconvenience." +msgstr "" diff --git a/resources/language/resource.language.pl_pl/strings.po b/resources/language/resource.language.pl_pl/strings.po index 692ead6d..89b4f128 100644 --- a/resources/language/resource.language.pl_pl/strings.po +++ b/resources/language/resource.language.pl_pl/strings.po @@ -1188,3 +1188,7 @@ msgstr "" msgctxt "#30730" msgid "Play (Ask for quality)" msgstr "" + +msgctxt "#30731" +msgid "The YouTube add-on now requires that you use your own API keys.[CR]For more information see the wiki: [B]https://ytaddon.page.link/keys[/B][CR][CR]Sorry for the inconvenience." +msgstr "" diff --git a/resources/language/resource.language.pt_br/strings.po b/resources/language/resource.language.pt_br/strings.po index c3254e54..79692f5f 100644 --- a/resources/language/resource.language.pt_br/strings.po +++ b/resources/language/resource.language.pt_br/strings.po @@ -1187,3 +1187,7 @@ msgstr "" msgctxt "#30730" msgid "Play (Ask for quality)" msgstr "" + +msgctxt "#30731" +msgid "The YouTube add-on now requires that you use your own API keys.[CR]For more information see the wiki: [B]https://ytaddon.page.link/keys[/B][CR][CR]Sorry for the inconvenience." +msgstr "" diff --git a/resources/language/resource.language.pt_pt/strings.po b/resources/language/resource.language.pt_pt/strings.po index 9b09ccf3..5504d2af 100644 --- a/resources/language/resource.language.pt_pt/strings.po +++ b/resources/language/resource.language.pt_pt/strings.po @@ -1189,3 +1189,7 @@ msgstr "" msgctxt "#30730" msgid "Play (Ask for quality)" msgstr "" + +msgctxt "#30731" +msgid "The YouTube add-on now requires that you use your own API keys.[CR]For more information see the wiki: [B]https://ytaddon.page.link/keys[/B][CR][CR]Sorry for the inconvenience." +msgstr "" diff --git a/resources/language/resource.language.ro_ro/strings.po b/resources/language/resource.language.ro_ro/strings.po index 16406105..0ffe1344 100644 --- a/resources/language/resource.language.ro_ro/strings.po +++ b/resources/language/resource.language.ro_ro/strings.po @@ -1189,3 +1189,7 @@ msgstr "" msgctxt "#30730" msgid "Play (Ask for quality)" msgstr "" + +msgctxt "#30731" +msgid "The YouTube add-on now requires that you use your own API keys.[CR]For more information see the wiki: [B]https://ytaddon.page.link/keys[/B][CR][CR]Sorry for the inconvenience." +msgstr "" diff --git a/resources/language/resource.language.ru_ru/strings.po b/resources/language/resource.language.ru_ru/strings.po index c47f854e..67536dd1 100644 --- a/resources/language/resource.language.ru_ru/strings.po +++ b/resources/language/resource.language.ru_ru/strings.po @@ -1206,3 +1206,7 @@ msgstr "" msgctxt "#30730" msgid "Play (Ask for quality)" msgstr "" + +msgctxt "#30731" +msgid "The YouTube add-on now requires that you use your own API keys.[CR]For more information see the wiki: [B]https://ytaddon.page.link/keys[/B][CR][CR]Sorry for the inconvenience." +msgstr "" diff --git a/resources/language/resource.language.sk_sk/strings.po b/resources/language/resource.language.sk_sk/strings.po index 7a92415d..964b897b 100644 --- a/resources/language/resource.language.sk_sk/strings.po +++ b/resources/language/resource.language.sk_sk/strings.po @@ -1189,3 +1189,7 @@ msgstr "" msgctxt "#30730" msgid "Play (Ask for quality)" msgstr "" + +msgctxt "#30731" +msgid "The YouTube add-on now requires that you use your own API keys.[CR]For more information see the wiki: [B]https://ytaddon.page.link/keys[/B][CR][CR]Sorry for the inconvenience." +msgstr "" diff --git a/resources/language/resource.language.tr_tr/strings.po b/resources/language/resource.language.tr_tr/strings.po index feb6dcac..66091e43 100644 --- a/resources/language/resource.language.tr_tr/strings.po +++ b/resources/language/resource.language.tr_tr/strings.po @@ -1207,3 +1207,7 @@ msgstr "" msgctxt "#30730" msgid "Play (Ask for quality)" msgstr "" + +msgctxt "#30731" +msgid "The YouTube add-on now requires that you use your own API keys.[CR]For more information see the wiki: [B]https://ytaddon.page.link/keys[/B][CR][CR]Sorry for the inconvenience." +msgstr "" diff --git a/resources/language/resource.language.uk_ua/strings.po b/resources/language/resource.language.uk_ua/strings.po index 9db93efb..692d0947 100644 --- a/resources/language/resource.language.uk_ua/strings.po +++ b/resources/language/resource.language.uk_ua/strings.po @@ -1189,3 +1189,7 @@ msgstr "" msgctxt "#30730" msgid "Play (Ask for quality)" msgstr "" + +msgctxt "#30731" +msgid "The YouTube add-on now requires that you use your own API keys.[CR]For more information see the wiki: [B]https://ytaddon.page.link/keys[/B][CR][CR]Sorry for the inconvenience." +msgstr "" diff --git a/resources/language/resource.language.zh_cn/strings.po b/resources/language/resource.language.zh_cn/strings.po index a398bc46..69b2a7c3 100644 --- a/resources/language/resource.language.zh_cn/strings.po +++ b/resources/language/resource.language.zh_cn/strings.po @@ -1189,3 +1189,7 @@ msgstr "" msgctxt "#30730" msgid "Play (Ask for quality)" msgstr "" + +msgctxt "#30731" +msgid "The YouTube add-on now requires that you use your own API keys.[CR]For more information see the wiki: [B]https://ytaddon.page.link/keys[/B][CR][CR]Sorry for the inconvenience." +msgstr "" diff --git a/resources/language/resource.language.zh_tw/strings.po b/resources/language/resource.language.zh_tw/strings.po index c6f233c3..631aa91a 100644 --- a/resources/language/resource.language.zh_tw/strings.po +++ b/resources/language/resource.language.zh_tw/strings.po @@ -1204,3 +1204,7 @@ msgstr "" msgctxt "#30730" msgid "Play (Ask for quality)" msgstr "" + +msgctxt "#30731" +msgid "The YouTube add-on now requires that you use your own API keys.[CR]For more information see the wiki: [B]https://ytaddon.page.link/keys[/B][CR][CR]Sorry for the inconvenience." +msgstr "" diff --git a/resources/lib/youtube_plugin/kodion/impl/abstract_settings.py b/resources/lib/youtube_plugin/kodion/impl/abstract_settings.py index 87bda185..a73b064b 100644 --- a/resources/lib/youtube_plugin/kodion/impl/abstract_settings.py +++ b/resources/lib/youtube_plugin/kodion/impl/abstract_settings.py @@ -155,7 +155,14 @@ def httpd_port(self): return self.get_int(constants.setting.HTTPD_PORT, 50152) def httpd_listen(self): - return self.get_string(constants.setting.HTTPD_LISTEN, '0.0.0.0') + ip_address = self.get_string(constants.setting.HTTPD_LISTEN, '0.0.0.0') + try: + ip_address = ip_address.strip() + except AttributeError: + pass + if not ip_address: + ip_address = '0.0.0.0' + return ip_address def set_httpd_listen(self, value): return self.set_string(constants.setting.HTTPD_LISTEN, value) diff --git a/resources/lib/youtube_plugin/kodion/utils/player.py b/resources/lib/youtube_plugin/kodion/utils/player.py index d107f5a3..a50d8f72 100644 --- a/resources/lib/youtube_plugin/kodion/utils/player.py +++ b/resources/lib/youtube_plugin/kodion/utils/player.py @@ -108,7 +108,13 @@ def run(self): plugin_play_path = 'plugin://plugin.video.youtube/play/' video_id_param = 'video_id=%s' % self.video_id + notification_sent = False + while player.isPlaying() and not self.context.abort_requested() and not self.stopped(): + if not notification_sent: + notification_sent = True + self.context.send_notification('PlaybackStarted', {'video_id': self.video_id}) + last_total_time = self.total_time last_current_time = self.current_time last_segment_start = self.segment_start diff --git a/resources/lib/youtube_plugin/youtube/helper/resource_manager.py b/resources/lib/youtube_plugin/youtube/helper/resource_manager.py index 67deeb0e..974122f2 100644 --- a/resources/lib/youtube_plugin/youtube/helper/resource_manager.py +++ b/resources/lib/youtube_plugin/youtube/helper/resource_manager.py @@ -8,6 +8,7 @@ See LICENSES/GPL-2.0-only for more information. """ +from ..youtube_exceptions import YouTubeException from ...kodion.utils import FunctionCache, DataCache, strip_html_from_text @@ -80,7 +81,7 @@ def _update_channels(self, channel_ids): return result - def _update_videos(self, video_ids, live_details=False): + def _update_videos(self, video_ids, live_details=False, suppress_errors=False): result = dict() json_data = dict() video_ids_to_update = list() @@ -118,7 +119,7 @@ def _update_videos(self, video_ids, live_details=False): for k in list(result.keys()): result[k]['play_data'] = played_items.get(k, dict()) - if self.handle_error(json_data): + if self.handle_error(json_data, suppress_errors) or suppress_errors: return result @staticmethod @@ -130,12 +131,12 @@ def _make_list_of_50(list_of_ids): pos += 50 return list_of_50 - def get_videos(self, video_ids, live_details=False): + def get_videos(self, video_ids, live_details=False, suppress_errors=False): list_of_50s = self._make_list_of_50(video_ids) result = {} for list_of_50 in list_of_50s: - result.update(self._update_videos(list_of_50, live_details)) + result.update(self._update_videos(list_of_50, live_details, suppress_errors)) return result def _update_playlists(self, playlists_ids): @@ -225,18 +226,35 @@ def get_fanarts(self, channel_ids): return result - def handle_error(self, json_data): + def handle_error(self, json_data, suppress_errors=False): context = self._context if json_data and 'error' in json_data: + ok_dialog = False + message_timeout = 5000 message = json_data['error'].get('message', '') message = strip_html_from_text(message) reason = json_data['error']['errors'][0].get('reason', '') title = '%s: %s' % (context.get_name(), reason) - message_timeout = 5000 + error_message = 'Error reason: |%s| with message: |%s|' % (reason, message) + + context.log_error(error_message) + + if reason == 'accessNotConfigured': + message = context.localize(30731) + ok_dialog = True + if reason == 'quotaExceeded' or reason == 'dailyLimitExceeded': message_timeout = 7000 - context.get_ui().show_notification(message, title, time_milliseconds=message_timeout) - error_message = 'Error reason: |%s| with message: |%s|' % (reason, message) - raise Exception(error_message) + + if not suppress_errors: + if ok_dialog: + context.get_ui().on_ok(title, message) + else: + context.get_ui().show_notification(message, title, + time_milliseconds=message_timeout) + + raise YouTubeException(error_message) + + return False return True diff --git a/resources/lib/youtube_plugin/youtube/helper/utils.py b/resources/lib/youtube_plugin/youtube/helper/utils.py index d9b2bb8b..c9d93405 100644 --- a/resources/lib/youtube_plugin/youtube/helper/utils.py +++ b/resources/lib/youtube_plugin/youtube/helper/utils.py @@ -408,12 +408,15 @@ def update_play_info(provider, context, video_id, video_item, video_stream, use_ settings = context.get_settings() ui = context.get_ui() resource_manager = provider.get_resource_manager(context) - video_data = resource_manager.get_videos([video_id]) + + video_data = resource_manager.get_videos([video_id], suppress_errors=True) meta_data = video_stream.get('meta', None) thumb_size = settings.use_thumbnail_size() image = None + video_item.video_id = video_id + if meta_data: video_item.set_subtitles(meta_data.get('subtitles', None)) image = get_thumbnail(thumb_size, meta_data.get('images', {})) @@ -421,18 +424,6 @@ def update_play_info(provider, context, video_id, video_item, video_stream, use_ if 'headers' in video_stream: video_item.set_headers(video_stream['headers']) - yt_item = video_data[video_id] - - snippet = yt_item['snippet'] # crash if not conform - play_data = yt_item['play_data'] - video_item.live = snippet.get('liveBroadcastContent') == 'live' - - video_item.video_id = video_id - - # set the title - if not video_item.get_title(): - video_item.set_title(snippet['title']) - # set uses_dash video_item.set_use_dash(settings.use_dash()) @@ -449,6 +440,48 @@ def update_play_info(provider, context, video_id, video_item, video_stream, use_ ui.set_home_window_property('license_url', license_info.get('url')) ui.set_home_window_property('license_token', license_info.get('token')) + """ + This is experimental. We try to get the most information out of the title of a video. + This is not based on any language. In some cases this won't work at all. + TODO: via language and settings provide the regex for matching episode and season. + """ + + for regex in __RE_SEASON_EPISODE_MATCHES__: + re_match = regex.search(video_item.get_name()) + if re_match: + if 'season' in re_match.groupdict(): + video_item.set_season(int(re_match.group('season'))) + + if 'episode' in re_match.groupdict(): + video_item.set_episode(int(re_match.group('episode'))) + break + + if video_item.live: + video_item.set_play_count(0) + + if image: + if video_item.live: + image = ''.join([image, '?ct=', get_thumb_timestamp()]) + video_item.set_image(image) + + # set fanart + video_item.set_fanart(provider.get_fanart(context)) + + if not video_data: + return video_item + + # requires API + # =============== + yt_item = video_data[video_id] + + snippet = yt_item['snippet'] # crash if not conform + play_data = yt_item['play_data'] + video_item.live = snippet.get('liveBroadcastContent') == 'live' + + # set the title + if not video_item.get_title(): + video_item.set_title(snippet['title']) + # duration if not video_item.live and use_play_data and play_data.get('total_time'): video_item.set_duration_from_seconds(float(play_data.get('total_time'))) @@ -472,25 +505,6 @@ def update_play_info(provider, context, video_id, video_item, video_stream, use_ if play_data.get('last_played'): video_item.set_last_played(play_data.get('last_played')) - elif video_item.live: - video_item.set_play_count(0) - - """ - This is experimental. We try to get the most information out of the title of a video. - This is not based on any language. In some cases this won't work at all. - TODO: via language and settings provide the regex for matching episode and season. - """ - # video_item.set_season(1) - # video_item.set_episode(1) - for regex in __RE_SEASON_EPISODE_MATCHES__: - re_match = regex.search(video_item.get_name()) - if re_match: - if 'season' in re_match.groupdict(): - video_item.set_season(int(re_match.group('season'))) - - if 'episode' in re_match.groupdict(): - video_item.set_episode(int(re_match.group('episode'))) - break # plot channel_name = snippet.get('channelTitle', '') @@ -513,12 +527,9 @@ def update_play_info(provider, context, video_id, video_item, video_stream, use_ if not image: image = get_thumbnail(thumb_size, snippet.get('thumbnails', {})) - if video_item.live and image: - image = ''.join([image, '?ct=', get_thumb_timestamp()]) - video_item.set_image(image) - - # set fanart - video_item.set_fanart(provider.get_fanart(context)) + if video_item.live and image: + image = ''.join([image, '?ct=', get_thumb_timestamp()]) + video_item.set_image(image) return video_item diff --git a/resources/lib/youtube_plugin/youtube/helper/v3.py b/resources/lib/youtube_plugin/youtube/helper/v3.py index 71d6a32c..c12a169a 100644 --- a/resources/lib/youtube_plugin/youtube/helper/v3.py +++ b/resources/lib/youtube_plugin/youtube/helper/v3.py @@ -307,22 +307,32 @@ def response_to_items(provider, context, json_data, sort=None, reverse_sort=Fals def handle_error(provider, context, json_data): if json_data and 'error' in json_data: - open_settings = False + ok_dialog = False message_timeout = 5000 + message = kodion.utils.strip_html_from_text(json_data['error'].get('message', '')) log_message = kodion.utils.strip_html_from_text(json_data['error'].get('message', '')) reason = json_data['error']['errors'][0].get('reason', '') + title = '%s: %s' % (context.get_name(), reason) + + context.log_error('Error reason: |%s| with message: |%s|' % (reason, log_message)) + + if reason == 'accessNotConfigured': + message = context.localize(provider.LOCAL_MAP['youtube.key.requirement.notification']) + ok_dialog = True + if reason == 'keyInvalid' and message == 'Bad Request': message = context.localize(provider.LOCAL_MAP['youtube.api.key.incorrect']) message_timeout = 7000 - open_settings = True - title = '%s: %s' % (context.get_name(), reason) + if reason == 'quotaExceeded' or reason == 'dailyLimitExceeded': message_timeout = 7000 - context.get_ui().show_notification(message, title, time_milliseconds=message_timeout) - context.log_error('Error reason: |%s| with message: |%s|' % (reason, log_message)) - if open_settings: - context.get_ui().open_settings() + + if ok_dialog: + context.get_ui().on_ok(title, message) + else: + context.get_ui().show_notification(message, title, time_milliseconds=message_timeout) + return False return True diff --git a/resources/lib/youtube_plugin/youtube/provider.py b/resources/lib/youtube_plugin/youtube/provider.py index 68eb6485..39a1bf82 100644 --- a/resources/lib/youtube_plugin/youtube/provider.py +++ b/resources/lib/youtube_plugin/youtube/provider.py @@ -169,6 +169,7 @@ class Provider(kodion.AbstractProvider): 'youtube.unsubscribed.from.channel': 30720, 'youtube.uploads': 30726, 'youtube.video.play_ask_for_quality': 30730, + 'youtube.key.requirement.notification': 30731, } def __init__(self): @@ -1620,8 +1621,8 @@ def set_content_type(context, content_type): def handle_exception(self, context, exception_to_handle): if (isinstance(exception_to_handle, InvalidGrant) or isinstance(exception_to_handle, LoginException)): + ok_dialog = False message_timeout = 5000 - failed_refresh = False message = exception_to_handle.get_message() msg = exception_to_handle.get_message() @@ -1646,8 +1647,19 @@ def handle_exception(self, context, exception_to_handle): if 'code' in msg: code = msg['code'] - if message == u'Unauthorized' and error == u'unauthorized_client': - failed_refresh = True + if error and code: + title = '%s: [%s] %s' % ('LoginException', code, error) + elif error: + title = '%s: %s' % ('LoginException', error) + else: + title = 'LoginException' + + context.log_error('%s: %s' % (title, log_message)) + + if error == 'deleted_client': + message = context.localize(self.LOCAL_MAP['youtube.key.requirement.notification']) + context.get_access_manager().update_access_token(access_token='', refresh_token='') + ok_dialog = True if error == 'invalid_client': if message == 'The OAuth client was not found.': @@ -1657,17 +1669,11 @@ def handle_exception(self, context, exception_to_handle): message = context.localize(self.LOCAL_MAP['youtube.client.secret.incorrect']) message_timeout = 7000 - if error and code: - title = '%s: [%s] %s' % ('LoginException', code, error) - elif error: - title = '%s: %s' % ('LoginException', error) + if ok_dialog: + context.get_ui().on_ok(title, message) else: - title = 'LoginException' + context.get_ui().show_notification(message, title, time_milliseconds=message_timeout) - context.get_ui().show_notification(message, title, time_milliseconds=message_timeout) - context.log_error('%s: %s' % (title, log_message)) - if not failed_refresh: - context.get_ui().open_settings() return False return True