forked from axiom-team/astrXbian
369 lines
14 KiB
Python
369 lines
14 KiB
Python
|
# -*- 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)
|