astrXbian/.install/.kodi/addons/plugin.video.youtube/resources/lib/youtube_plugin/youtube/helper/yt_specials.py

369 lines
14 KiB
Python
Raw Normal View History

2020-12-17 21:52:17 +01:00
# -*- coding: utf-8 -*-
"""
Copyright (C) 2014-2016 bromix (plugin.video.youtube)
Copyright (C) 2016-2018 plugin.video.youtube
SPDX-License-Identifier: GPL-2.0-only
See LICENSES/GPL-2.0-only for more information.
"""
from ... import kodion
from ...kodion.items import DirectoryItem, UriItem
from ...youtube.helper import v3, tv, extract_urls, UrlResolver, UrlToItemConverter
from . import utils
def _process_related_videos(provider, context):
provider.set_content_type(context, kodion.constants.content_type.VIDEOS)
result = []
page_token = context.get_param('page_token', '')
video_id = context.get_param('video_id', '')
if video_id:
json_data = provider.get_client(context).get_related_videos(video_id=video_id, page_token=page_token)
if not v3.handle_error(provider, context, json_data):
return False
result.extend(v3.response_to_items(provider, context, json_data, process_next_page=False))
return result
def _process_parent_comments(provider, context):
provider.set_content_type(context, kodion.constants.content_type.FILES)
result = []
page_token = context.get_param('page_token', '')
video_id = context.get_param('video_id', '')
if video_id:
json_data = provider.get_client(context).get_parent_comments(video_id=video_id, page_token=page_token)
if not v3.handle_error(provider, context, json_data):
return False
result.extend(v3.response_to_items(provider, context, json_data))
return result
def _process_child_comments(provider, context):
provider.set_content_type(context, kodion.constants.content_type.FILES)
result = []
page_token = context.get_param('page_token', '')
parent_id = context.get_param('parent_id', '')
if parent_id:
json_data = provider.get_client(context).get_child_comments(parent_id=parent_id, page_token=page_token)
if not v3.handle_error(provider, context, json_data):
return False
result.extend(v3.response_to_items(provider, context, json_data))
return result
def _process_recommendations(provider, context):
provider.set_content_type(context, kodion.constants.content_type.VIDEOS)
result = []
page_token = context.get_param('page_token', '')
json_data = provider.get_client(context).get_activities('home', page_token=page_token)
if not v3.handle_error(provider, context, json_data):
return False
result.extend(v3.response_to_items(provider, context, json_data))
return result
def _process_popular_right_now(provider, context):
provider.set_content_type(context, kodion.constants.content_type.VIDEOS)
result = []
page_token = context.get_param('page_token', '')
json_data = provider.get_client(context).get_popular_videos(page_token=page_token)
if not v3.handle_error(provider, context, json_data):
return False
result.extend(v3.response_to_items(provider, context, json_data))
return result
def _process_browse_channels(provider, context):
provider.set_content_type(context, kodion.constants.content_type.FILES)
result = []
# page_token = context.get_param('page_token', '')
guide_id = context.get_param('guide_id', '')
client = provider.get_client(context)
if guide_id:
json_data = client.get_guide_category(guide_id)
if not v3.handle_error(provider, context, json_data):
return False
result.extend(v3.response_to_items(provider, context, json_data))
else:
json_data = context.get_function_cache().get(kodion.utils.FunctionCache.ONE_MONTH, client.get_guide_categories)
if not v3.handle_error(provider, context, json_data):
return False
result.extend(v3.response_to_items(provider, context, json_data))
return result
def _process_disliked_videos(provider, context):
provider.set_content_type(context, kodion.constants.content_type.VIDEOS)
result = []
page_token = context.get_param('page_token', '')
json_data = provider.get_client(context).get_disliked_videos(page_token=page_token)
if not v3.handle_error(provider, context, json_data):
return False
result.extend(v3.response_to_items(provider, context, json_data))
return result
def _process_live_events(provider, context, event_type='live'):
def _sort(x):
return x.get_aired()
provider.set_content_type(context, kodion.constants.content_type.VIDEOS)
result = []
# TODO: cache result
page_token = context.get_param('page_token', '')
location = str(context.get_param('location', False)).lower() == 'true'
json_data = provider.get_client(context).get_live_events(event_type=event_type, page_token=page_token, location=location)
if not v3.handle_error(provider, context, json_data):
return False
result.extend(v3.response_to_items(provider, context, json_data, sort=_sort, reverse_sort=True))
return result
def _process_description_links(provider, context):
incognito = str(context.get_param('incognito', False)).lower() == 'true'
addon_id = context.get_param('addon_id', '')
def _extract_urls(_video_id):
provider.set_content_type(context, kodion.constants.content_type.VIDEOS)
url_resolver = UrlResolver(context)
result = []
progress_dialog = \
context.get_ui().create_progress_dialog(heading=context.localize(kodion.constants.localize.COMMON_PLEASE_WAIT),
background=False)
resource_manager = provider.get_resource_manager(context)
video_data = resource_manager.get_videos([_video_id])
yt_item = video_data[_video_id]
snippet = yt_item['snippet'] # crash if not conform
description = kodion.utils.strip_html_from_text(snippet['description'])
urls = context.get_function_cache().get(kodion.utils.FunctionCache.ONE_WEEK, extract_urls, description)
progress_dialog.set_total(len(urls))
res_urls = []
for url in urls:
context.log_debug('Resolving url "%s"' % url)
progress_dialog.update(steps=1, text=url)
resolved_url = url_resolver.resolve(url)
context.log_debug('Resolved url "%s"' % resolved_url)
res_urls.append(resolved_url)
if progress_dialog.is_aborted():
context.log_debug('Resolving urls aborted')
break
context.sleep(50)
url_to_item_converter = UrlToItemConverter()
url_to_item_converter.add_urls(res_urls, provider, context)
result.extend(url_to_item_converter.get_items(provider, context))
progress_dialog.close()
if len(result) == 0:
progress_dialog.close()
context.get_ui().on_ok(title=context.localize(provider.LOCAL_MAP['youtube.video.description.links']),
text=context.localize(
provider.LOCAL_MAP['youtube.video.description.links.not_found']))
return False
return result
def _display_channels(_channel_ids):
_channel_id_dict = {}
item_params = {}
if incognito:
item_params.update({'incognito': incognito})
if addon_id:
item_params.update({'addon_id': addon_id})
for channel_id in _channel_ids:
item_uri = context.create_uri(['channel', channel_id], item_params)
channel_item = DirectoryItem('', item_uri)
channel_item.set_fanart(provider.get_fanart(context))
_channel_id_dict[channel_id] = channel_item
_channel_item_dict = {}
utils.update_channel_infos(provider, context, _channel_id_dict, channel_items_dict=_channel_item_dict)
# clean up - remove empty entries
_result = []
for key in _channel_id_dict:
_channel_item = _channel_id_dict[key]
if _channel_item.get_name():
_result.append(_channel_item)
return _result
def _display_playlists(_playlist_ids):
_playlist_id_dict = {}
item_params = {}
if incognito:
item_params.update({'incognito': incognito})
if addon_id:
item_params.update({'addon_id': addon_id})
for playlist_id in _playlist_ids:
item_uri = context.create_uri(['playlist', playlist_id], item_params)
playlist_item = DirectoryItem('', item_uri)
playlist_item.set_fanart(provider.get_fanart(context))
_playlist_id_dict[playlist_id] = playlist_item
_channel_item_dict = {}
utils.update_playlist_infos(provider, context, _playlist_id_dict, _channel_item_dict)
utils.update_fanarts(provider, context, _channel_item_dict)
# clean up - remove empty entries
_result = []
for key in _playlist_id_dict:
_playlist_item = _playlist_id_dict[key]
if _playlist_item.get_name():
_result.append(_playlist_item)
return _result
video_id = context.get_param('video_id', '')
if video_id:
return _extract_urls(video_id)
channel_ids = context.get_param('channel_ids', '')
if channel_ids:
channel_ids = channel_ids.split(',')
if len(channel_ids) > 0:
return _display_channels(channel_ids)
playlist_ids = context.get_param('playlist_ids', '')
if playlist_ids:
playlist_ids = playlist_ids.split(',')
if len(playlist_ids) > 0:
return _display_playlists(playlist_ids)
context.log_error('Missing video_id or playlist_ids for description links')
return False
def _process_saved_playlists_tv(provider, context):
provider.set_content_type(context, kodion.constants.content_type.FILES)
result = []
next_page_token = context.get_param('next_page_token', '')
offset = int(context.get_param('offset', 0))
json_data = provider.get_client(context).get_saved_playlists(page_token=next_page_token, offset=offset)
result.extend(tv.saved_playlists_to_items(provider, context, json_data))
return result
def _process_watch_history_tv(provider, context):
provider.set_content_type(context, kodion.constants.content_type.VIDEOS)
result = []
next_page_token = context.get_param('next_page_token', '')
offset = int(context.get_param('offset', 0))
json_data = provider.get_client(context).get_watch_history(page_token=next_page_token, offset=offset)
result.extend(tv.tv_videos_to_items(provider, context, json_data))
return result
def _process_purchases_tv(provider, context):
provider.set_content_type(context, kodion.constants.content_type.VIDEOS)
result = []
next_page_token = context.get_param('next_page_token', '')
offset = int(context.get_param('offset', 0))
json_data = provider.get_client(context).get_purchases(page_token=next_page_token, offset=offset)
result.extend(tv.tv_videos_to_items(provider, context, json_data))
return result
def _process_new_uploaded_videos_tv(provider, context):
provider.set_content_type(context, kodion.constants.content_type.VIDEOS)
result = []
next_page_token = context.get_param('next_page_token', '')
offset = int(context.get_param('offset', 0))
json_data = provider.get_client(context).get_my_subscriptions(page_token=next_page_token, offset=offset)
result.extend(tv.my_subscriptions_to_items(provider, context, json_data))
return result
def _process_new_uploaded_videos_tv_filtered(provider, context):
provider.set_content_type(context, kodion.constants.content_type.VIDEOS)
result = []
next_page_token = context.get_param('next_page_token', '')
offset = int(context.get_param('offset', 0))
json_data = provider.get_client(context).get_my_subscriptions(page_token=next_page_token, offset=offset)
result.extend(tv.my_subscriptions_to_items(provider, context, json_data, do_filter=True))
return result
def process(category, provider, context):
_ = provider.get_client(context) # required for provider.is_logged_in()
if not provider.is_logged_in() and category in ['new_uploaded_videos_tv', 'new_uploaded_videos_tv_filtered', 'disliked_videos']:
return UriItem(context.create_uri(['sign', 'in']))
if category == 'related_videos':
return _process_related_videos(provider, context)
elif category == 'popular_right_now':
return _process_popular_right_now(provider, context)
elif category == 'recommendations':
return _process_recommendations(provider, context)
elif category == 'browse_channels':
return _process_browse_channels(provider, context)
elif category == 'watch_history_tv':
return _process_watch_history_tv(provider, context)
elif category == 'new_uploaded_videos_tv':
return _process_new_uploaded_videos_tv(provider, context)
elif category == 'new_uploaded_videos_tv_filtered':
return _process_new_uploaded_videos_tv_filtered(provider, context)
elif category == 'saved_playlists':
return _process_saved_playlists_tv(provider, context)
elif category == 'purchases':
return _process_purchases_tv(provider, context)
elif category == 'disliked_videos':
return _process_disliked_videos(provider, context)
elif category == 'live':
return _process_live_events(provider, context)
elif category == 'upcoming_live':
return _process_live_events(provider, context, event_type='upcoming')
elif category == 'completed_live':
return _process_live_events(provider, context, event_type='completed')
elif category == 'description_links':
return _process_description_links(provider, context)
elif category == 'parent_comments':
return _process_parent_comments(provider, context)
elif category == 'child_comments':
return _process_child_comments(provider, context)
else:
raise kodion.KodionException("YouTube special category '%s' not found" % category)