def _history_playlist_id_change(provider, context, re_match, method): playlist_id = context.get_param('playlist_id', '') if not playlist_id: raise kodion.KodionException('history_list/%s: missing playlist_id' % method) playlist_name = context.get_param('playlist_name', '') if not playlist_name: raise kodion.KodionException('history_list/%s: missing playlist_name' % method) if method == 'set': current_pl_id = context.get_settings().get_string('youtube.folder.history.playlist', '').strip() if current_pl_id: if context.get_ui().on_yes_no_input(context.get_name(), context.localize(30574) % playlist_name): context.get_settings().set_string('youtube.folder.history.playlist', playlist_id) else: return else: context.get_settings().set_string('youtube.folder.history.playlist', playlist_id) elif method == 'remove': if context.get_ui().on_yes_no_input(context.get_name(), context.localize(30573) % playlist_name): context.get_settings().set_string('youtube.folder.history.playlist', '') else: return else: return context.get_ui().refresh_container()
def _on_play(self, context, re_match): params = context.get_params() url = params.get('url', '') audio_id = params.get('audio_id', '') client = self.get_client(context) result = None update_playlist = False if url and not audio_id: json_data = client.resolve_url(url) path = context.get_path() result = self._do_item(context, json_data, path, process_playlist=True) if isinstance(result, AudioItem): audio_id = json_data['id'] update_playlist = True pass elif isinstance(result, list): playlist = context.get_audio_playlist() playlist.clear() for track in result: playlist.add(track) pass return result[0] pass elif audio_id: json_data = client.get_track(audio_id) path = context.get_path() result = self._do_item(context, json_data, path, process_playlist=True) pass else: raise kodion.KodionException("Audio ID or URL missing") json_data = client.get_track_url(audio_id) location = json_data.get('location') if not location: raise kodion.KodionException("Could not get url for track '%s'" % audio_id) result.set_uri(location.encode('utf-8')) if update_playlist: playlist = context.get_audio_playlist() playlist.clear() playlist.add(result) pass return result
def _process_add_video(provider, context, re_match): playlist_id = context.get_param('playlist_id', '') if not playlist_id: raise kodion.KodionException('Playlist/Remove: missing playlist_id') video_id = context.get_param('video_id', '') if not video_id: raise kodion.KodionException('Playlist/Remove: missing video_id') json_data = provider.get_client(context).add_video_to_playlist(playlist_id=playlist_id, video_id=video_id) if not v3.handle_error(provider, context, json_data): return False return True
def _process_play_all(provider, context, re_match): """ plugin://plugin.video.youtube/?path=/root/video&action=play_all&playlist=PL8_6CHho8Tq4Iie-oNxb-g0ECxIhq3CxW plugin://plugin.video.youtube/?action=play_all&playlist=PLZRRxQcaEjA5fgfW3a3Q0rzm6NgbmICtg&videoid=qmlYe2KS0-Y """ playlist_id = context.get_param('playlist', '') if not playlist_id: raise kodion.KodionException( 'old_actions/play_all: missing playlist_id') # optional starting video id of the playlist video_id = context.get_param('videoid', '') if video_id: context.log_warning( 'USE INSTEAD "plugin://%s/play/?playlist_id=%s&video_id=%s"' % (context.get_id(), playlist_id, video_id)) pass else: context.log_warning('USE INSTEAD "plugin://%s/play/?playlist_id=%s"' % (context.get_id(), playlist_id)) pass new_params = {'playlist_id': playlist_id} new_path = '/play/' new_context = context.clone(new_path=new_path, new_params=new_params) return provider.on_play(new_context, re_match)
def _process_rate_video(provider, context, re_match): video_id = context.get_param('video_id', '') if not video_id: raise kodion.KodionException('video/rate/: missing video_id') client = provider.get_client(context) json_data = client.get_video_rating(video_id) if not v3.handle_error(provider, context, json_data): return False items = json_data.get('items', []) if items: current_rating = items[0].get('rating', '') ratings = ['like', 'dislike', 'none'] rating_items = [] for rating in ratings: if rating != current_rating: rating_items.append((context.localize( provider.LOCAL_MAP['youtube.video.rate.%s' % rating]), rating)) pass pass result = context.get_ui().on_select( context.localize(provider.LOCAL_MAP['youtube.video.rate']), rating_items) if result != -1: client = provider.get_client(context).rate_video(video_id, result) # this will be set if we are in the 'Liked Video' playlist if context.get_param('refresh_container', '0') == '1': context.get_ui().refresh_container() pass pass pass pass
def process(category, provider, context, re_match): result = [] # we need a login client = provider.get_client(context) if not provider.is_logged_in() and category in [ 'new_uploaded_videos_tv', 'disliked_videos' ]: return UriItem(context.create_uri(['sign', 'in'])) if category == 'related_videos': return _process_related_videos(provider, context, re_match) elif category == 'popular_right_now': return _process_popular_right_now(provider, context, re_match) elif category == 'recommendations': return _process_recommendations(provider, context, re_match) elif category == 'browse_channels': return _process_browse_channels(provider, context, re_match) elif category == 'new_uploaded_videos_tv': return _process_new_uploaded_videos_tv(provider, context, re_match) elif category == 'disliked_videos': return _process_disliked_videos(provider, context, re_match) elif category == 'live': return _process_live_events(provider, context, re_match) elif category == 'description_links': return _process_description_links(provider, context, re_match) else: raise kodion.KodionException( "YouTube special category '%s' not found" % category)
def process(category, provider, context, re_match): result = [] if category == 'related_videos': result.extend(_process_related_videos(provider, context, re_match)) pass elif category == 'popular_right_now': result.extend(_process_popular_right_now(provider, context, re_match)) pass elif category == 'browse_channels': result.extend(_process_browse_channels(provider, context, re_match)) pass elif category == 'new_uploaded_videos': result.extend(_process_new_uploaded_videos(provider, context, re_match)) pass elif category == 'disliked_videos': result.extend(_process_disliked_videos(provider, context, re_match)) pass elif category == 'live': result.extend(_process_live_events(provider, context, re_match)) pass else: raise kodion.KodionException("YouTube special category '%s' not found" % category) return result
def process(method, provider, context, re_match): if method == 'rate': return _process_rate_video(provider, context, re_match) else: raise kodion.KodionException("Unknown method '%s'" % method) return True
def _process_remove_playlist(provider, context, re_match): playlist_id = context.get_param('playlist_id', '') if not playlist_id: raise kodion.KodionException('Playlist/Remove: missing playlist_id') playlist_name = context.get_param('playlist_name', '') if not playlist_name: raise kodion.KodionException('Playlist/Remove: missing playlist_name') if context.get_ui().on_delete_content(playlist_name): json_data = provider.get_client(context).remove_playlist(playlist_id=playlist_id) if not v3.handle_error(provider, context, json_data): return False context.get_ui().refresh_container() pass return True
def response_to_items(provider, context, json_data, sort=None, reverse_sort=False, process_next_page=True): result = [] kind = json_data.get('kind', '') if kind == u'youtube#searchListResponse' or kind == u'youtube#playlistItemListResponse' or \ kind == u'youtube#playlistListResponse' or kind == u'youtube#subscriptionListResponse' or \ kind == u'youtube#guideCategoryListResponse' or kind == u'youtube#channelListResponse' or \ kind == u'youtube#videoListResponse' or kind == u'youtube#activityListResponse': result.extend(_process_list_response(provider, context, json_data)) pass else: raise kodion.KodionException("Unknown kind '%s'" % kind) if sort is not None: result = sorted(result, key=sort, reverse=reverse_sort) pass # no processing of next page item if not process_next_page: return result # next page """ This will try to prevent the issue 7163 (https://code.google.com/p/gdata-issues/issues/detail?id=7163). Somehow the APIv3 is missing the token for the next page. We implemented our own calculation for the token into the YouTube client...this should work for up to ~2000 entries. """ yt_total_results = int( json_data.get('pageInfo', {}).get('totalResults', 0)) yt_results_per_page = int( json_data.get('pageInfo', {}).get('resultsPerPage', 0)) page = int(context.get_param('page', 1)) yt_next_page_token = json_data.get('nextPageToken', '') if yt_next_page_token or (page * yt_results_per_page < yt_total_results): if not yt_next_page_token: client = provider.get_client(context) yt_next_page_token = client.calculate_next_page_token( page + 1, yt_results_per_page) pass new_params = {} new_params.update(context.get_params()) new_params['page_token'] = yt_next_page_token new_context = context.clone(new_params=new_params) current_page = int(new_context.get_param('page', 1)) next_page_item = items.NextPageItem( new_context, current_page, fanart=provider.get_fanart(new_context)) result.append(next_page_item) pass return result
def response_to_items(provider, context, json_data): video_id_dict = {} channel_item_dict = {} result = [] feed = json_data.get('feed', None) if feed: entry = feed.get('entry', []) for item in entry: video_id = '' video_id_match = re.match( 'tag:youtube.com,(\d+):video:(?P<video_id>.*)', item['id']['$t']) if video_id_match: video_id = video_id_match.group('video_id') pass title = item['title']['$t'] video_item = items.VideoItem( title, context.create_uri(['play'], {'video_id': video_id})) video_item.set_fanart(provider.get_fanart(context)) result.append(video_item) video_id_dict[video_id] = video_item channel_id = item['media$group']['yt$uploaderId']['$t'] if not channel_id in channel_item_dict: channel_item_dict[channel_id] = [] channel_item_dict[channel_id].append(video_item) pass utils.update_video_infos(provider, context, video_id_dict) utils.update_channel_infos(provider, context, channel_item_dict) page = int(context.get_param('page', 1)) items_per_page = int( feed.get('openSearch$itemsPerPage', {}).get('$t', 0)) total = int(feed.get('openSearch$totalResults', {}).get('$t', 0)) if page * items_per_page < total: new_params = {} new_params.update(context.get_params()) new_params['start-index'] = (page * items_per_page) + 1 new_context = context.clone(new_params=new_params) current_page = int(new_context.get_param('page', 1)) next_page_item = items.NextPageItem( new_context, current_page, fanart=provider.get_fanart(new_context)) result.append(next_page_item) pass pass else: raise kodion.KodionException("Couldn't find feed") return result
def process_old_action(provider, context, re_match): action = context.get_param('action', '') if action == 'play_video': return _process_play_video(provider, context, re_match) elif action == 'play_all': return _process_play_all(provider, context, re_match) else: raise kodion.KodionException('old_actions: unknown action "%s"' % action) pass
def process(method, provider, context, re_match): result = [] if method == 'list': result.extend(_process_list(provider, context, re_match)) pass elif method == 'add': return _process_add(provider, context, re_match) elif method == 'remove': return _process_remove(provider, context, re_match) else: raise kodion.KodionException("Unknown subscriptions method '%s'" % method) return result
def process(method, category, provider, context, re_match): if method == 'add' and category == 'video': return _process_add_video(provider, context, re_match) elif method == 'remove' and category == 'video': return _process_remove_video(provider, context, re_match) elif method == 'remove' and category == 'playlist': return _process_remove_playlist(provider, context, re_match) elif method == 'select' and category == 'playlist': return _process_select_playlist(provider, context, re_match) elif method == 'rename' and category == 'playlist': return _process_rename_playlist(provider, context, re_match) else: raise kodion.KodionException("Unknown category '%s' or method '%s'" % (category, method)) return True
def _process_play_video(provider, context, re_match): """ plugin://plugin.video.youtube/?action=play_video&videoid=[ID] """ video_id = context.get_param('videoid', '') if not video_id: raise kodion.KodionException( 'old_actions/play_video: missing video_id') context.log_warning('DEPRECATED "%s"' % context.get_uri()) context.log_warning('USE INSTEAD "plugin://%s/play/?video_id=%s"' % (context.get_id(), video_id)) new_params = {'video_id': video_id} new_path = '/play/' new_context = context.clone(new_path=new_path, new_params=new_params) return provider.on_play(new_context, re_match)
def _process_rename_playlist(provider, context, re_match): playlist_id = context.get_param('playlist_id', '') if not playlist_id: raise kodion.KodionException('playlist/rename: missing playlist_id') current_playlist_name = context.get_param('playlist_name', '') result, text = context.get_ui().on_keyboard_input(context.localize(provider.LOCAL_MAP['youtube.rename']), default=current_playlist_name) if result and text: json_data = provider.get_client(context).rename_playlist(playlist_id=playlist_id, new_title=text) if not v3.handle_error(provider, context, json_data): return context.get_ui().refresh_container() pass pass
def process_old_action(provider, context, re_match): """ if context.get_system_version().get_version() >= (15, 0): message = u"You're using old YouTube-Plugin calls - please review the log for updated end points starting with Isengard" context.get_ui().show_notification(message, time_milliseconds=15000) pass """ action = context.get_param('action', '') if action == 'play_video': return _process_play_video(provider, context, re_match) elif action == 'play_all': return _process_play_all(provider, context, re_match) else: raise kodion.KodionException('old_actions: unknown action "%s"' % action) pass
def _process_more_for_video(provider, context, re_match): video_id = context.get_param('video_id', '') if not video_id: raise kodion.KodionException('video/more/: missing video_id') items = [] is_logged_in = context.get_param('logged_in', '0') if is_logged_in == '1': # add video to a playlist items.append( (context.localize( provider.LOCAL_MAP['youtube.video.add_to_playlist']), 'RunPlugin(%s)' % context.create_uri( ['playlist', 'select', 'playlist'], {'video_id': video_id}))) # default items items.extend([ (context.localize(provider.LOCAL_MAP['youtube.related_videos']), 'Container.Update(%s)' % context.create_uri( ['special', 'related_videos'], {'video_id': video_id})), (context.localize( provider.LOCAL_MAP['youtube.video.description.links']), 'Container.Update(%s)' % context.create_uri( ['special', 'description_links'], {'video_id': video_id})) ]) if is_logged_in == '1': # rate a video refresh_container = context.get_param('refresh_container', '0') items.append( (context.localize(provider.LOCAL_MAP['youtube.video.rate']), 'RunPlugin(%s)' % context.create_uri(['video', 'rate'], { 'video_id': video_id, 'refresh_container': refresh_container }))) pass result = context.get_ui().on_select( context.localize(provider.LOCAL_MAP['youtube.video.more']), items) if result != -1: context.execute(result) pass pass
def _on_like(self, context, re_match): content_id = re_match.group('content_id') category = re_match.group('category') params = context.get_params() like = params.get('like', '') == '1' if category == 'track': json_data = self.get_client(context).like_track(content_id, like) elif category == 'playlist': json_data = self.get_client(context).like_playlist( content_id, like) else: raise kodion.KodionException("Unknown category '%s' in 'on_like'" % category) if not like: context.get_ui().refresh_container() pass return True
def process(method, provider, context, re_match): result = [] # we need a login client = provider.get_client(context) if not provider.is_logged_in(): return UriItem(context.create_uri(['sign', 'in'])) if method == 'list': result.extend(_process_list(provider, context, re_match)) pass elif method == 'add': return _process_add(provider, context, re_match) elif method == 'remove': return _process_remove(provider, context, re_match) else: raise kodion.KodionException("Unknown subscriptions method '%s'" % method) return result
def do_xml_featured_response(context, provider, xml): root = ET.fromstring(xml) if not do_xml_error(context, provider, root): return [] result = [] for item in root: item_type = item.find('type').text if item_type == 'channel': channel_id = item.find('id').text channel_name = item.find('title').text channel_image = item.find('header_url').text channel_item = DirectoryItem(channel_name, context.create_uri(['channel', channel_id]), image=channel_image) channel_item.set_fanart(provider.get_fanart(context)) result.append(channel_item) pass else: raise kodion.KodionException('Unknown type "%s" for featured' % item_type) pass return result
def response_to_items(provider, context, json_data, sort=None, reverse_sort=False, process_next_page=True): result = [] kind = json_data.get('kind', '') if kind == u'youtube#searchListResponse' or kind == u'youtube#playlistItemListResponse' or \ kind == u'youtube#playlistListResponse' or kind == u'youtube#subscriptionListResponse' or \ kind == u'youtube#guideCategoryListResponse' or kind == u'youtube#channelListResponse' or \ kind == u'youtube#videoListResponse': result.extend(_process_list_response(provider, context, json_data)) pass else: raise kodion.KodionException("Unknown kind '%s'" % kind) if sort is not None: result = sorted(result, key=sort, reverse=reverse_sort) pass # next page yt_next_page_token = json_data.get('nextPageToken', '') if process_next_page and yt_next_page_token: new_params = {} new_params.update(context.get_params()) new_params['page_token'] = yt_next_page_token new_context = context.clone(new_params=new_params) current_page = int(new_context.get_param('page', 1)) next_page_item = items.NextPageItem( new_context, current_page, fanart=provider.get_fanart(new_context)) result.append(next_page_item) pass return result
def _process_list_response(provider, context, json_data): video_id_dict = {} channel_id_dict = {} playlist_id_dict = {} playlist_item_id_dict = {} subscription_id_dict = {} result = [] yt_items = json_data.get('items', []) if len(yt_items) == 0: context.log_warning('List of search result is empty') return result for yt_item in yt_items: yt_kind = yt_item.get('kind', '') if yt_kind == u'youtube#video': video_id = yt_item['id'] snippet = yt_item['snippet'] title = snippet['title'] image = snippet.get('thumbnails', {}).get('medium', {}).get('url', '') video_item = items.VideoItem(title, context.create_uri( ['play'], {'video_id': video_id}), image=image) video_item.set_fanart(provider.get_fanart(context)) result.append(video_item) video_id_dict[video_id] = video_item pass elif yt_kind == u'youtube#channel': channel_id = yt_item['id'] snippet = yt_item['snippet'] title = snippet['title'] image = snippet.get('thumbnails', {}).get('medium', {}).get('url', '') channel_item = items.DirectoryItem(title, context.create_uri( ['channel', channel_id]), image=image) channel_item.set_fanart(provider.get_fanart(context)) # if logged in => provide subscribing to the channel if provider.is_logged_in(): context_menu = [] yt_context_menu.append_subscribe_to_channel( context_menu, provider, context, channel_id) channel_item.set_context_menu(context_menu) pass result.append(channel_item) channel_id_dict[channel_id] = channel_item pass elif yt_kind == u'youtube#guideCategory': guide_id = yt_item['id'] snippet = yt_item['snippet'] title = snippet['title'] guide_item = items.DirectoryItem( title, context.create_uri(['special', 'browse_channels'], {'guide_id': guide_id})) guide_item.set_fanart(provider.get_fanart(context)) result.append(guide_item) pass elif yt_kind == u'youtube#subscription': snippet = yt_item['snippet'] image = snippet.get('thumbnails', {}).get('high', {}).get('url', '') channel_id = snippet['resourceId']['channelId'] channel_item = items.DirectoryItem(snippet['title'], context.create_uri( ['channel', channel_id]), image=image) channel_item.set_fanart(provider.get_fanart(context)) # map channel id with subscription id - we need it for the unsubscription subscription_id_dict[channel_id] = yt_item['id'] result.append(channel_item) channel_id_dict[channel_id] = channel_item pass elif yt_kind == u'youtube#playlist': playlist_id = yt_item['id'] snippet = yt_item['snippet'] title = snippet['title'] image = snippet.get('thumbnails', {}).get('medium', {}).get('url', '') channel_id = snippet['channelId'] # if the path directs to a playlist of our own, we correct the channel id to 'mine' if context.get_path() == '/channel/mine/playlists/': channel_id = 'mine' pass playlist_item = items.DirectoryItem(title, context.create_uri([ 'channel', channel_id, 'playlist', playlist_id ]), image=image) playlist_item.set_fanart(provider.get_fanart(context)) result.append(playlist_item) playlist_id_dict[playlist_id] = playlist_item pass elif yt_kind == u'youtube#playlistItem': snippet = yt_item['snippet'] video_id = snippet['resourceId']['videoId'] # store the id of the playlistItem - for deleting this item we need this item playlist_item_id_dict[video_id] = yt_item['id'] title = snippet['title'] image = snippet.get('thumbnails', {}).get('medium', {}).get('url', '') video_item = items.VideoItem(title, context.create_uri( ['play'], {'video_id': video_id}), image=image) video_item.set_fanart(provider.get_fanart(context)) #Get Track-ID from Playlist video_item.set_track_number(snippet['position'] + 1) result.append(video_item) video_id_dict[video_id] = video_item pass elif yt_kind == 'youtube#activity': snippet = yt_item['snippet'] details = yt_item['contentDetails'] actType = snippet['type'] # recommendations if actType == 'recommendation': video_id = details['recommendation']['resourceId']['videoId'] elif actType == 'upload': video_id = details['upload']['videoId'] else: continue title = snippet['title'] image = snippet.get('thumbnails', {}).get('medium', {}).get('url', '') video_item = items.VideoItem(title, context.create_uri( ['play'], {'video_id': video_id}), image=image) video_item.set_fanart(provider.get_fanart(context)) result.append(video_item) video_id_dict[video_id] = video_item pass elif yt_kind == 'youtube#searchResult': yt_kind = yt_item.get('id', {}).get('kind', '') # video if yt_kind == 'youtube#video': video_id = yt_item['id']['videoId'] snippet = yt_item['snippet'] title = snippet['title'] image = snippet.get('thumbnails', {}).get('medium', {}).get('url', '') video_item = items.VideoItem( title, context.create_uri(['play'], {'video_id': video_id}), image=image) video_item.set_fanart(provider.get_fanart(context)) result.append(video_item) video_id_dict[video_id] = video_item pass # playlist elif yt_kind == 'youtube#playlist': playlist_id = yt_item['id']['playlistId'] snippet = yt_item['snippet'] title = snippet['title'] image = snippet.get('thumbnails', {}).get('medium', {}).get('url', '') channel_id = snippet['channelId'] # if the path directs to a playlist of our own, we correct the channel id to 'mine' if context.get_path() == '/channel/mine/playlists/': channel_id = 'mine' pass channel_name = snippet.get('channelTitle', '') playlist_item = items.DirectoryItem(title, context.create_uri([ 'channel', channel_id, 'playlist', playlist_id ]), image=image) playlist_item.set_fanart(provider.get_fanart(context)) result.append(playlist_item) playlist_id_dict[playlist_id] = playlist_item pass elif yt_kind == 'youtube#channel': channel_id = yt_item['id']['channelId'] snippet = yt_item['snippet'] title = snippet['title'] image = snippet.get('thumbnails', {}).get('medium', {}).get('url', '') channel_item = items.DirectoryItem( title, context.create_uri(['channel', channel_id]), image=image) channel_item.set_fanart(provider.get_fanart(context)) result.append(channel_item) channel_id_dict[channel_id] = channel_item pass else: raise kodion.KodionException("Unknown kind '%s'" % yt_kind) pass else: raise kodion.KodionException("Unknown kind '%s'" % yt_kind) pass # this will also update the channel_id_dict with the correct channel id for each video. channel_items_dict = {} utils.update_video_infos(provider, context, video_id_dict, playlist_item_id_dict, channel_items_dict) utils.update_playlist_infos(provider, context, playlist_id_dict, channel_items_dict) utils.update_channel_infos(provider, context, channel_id_dict, subscription_id_dict, channel_items_dict) utils.update_fanarts(provider, context, channel_items_dict) return result
def _do_item(self, context, json_item, path, process_playlist=False): def _get_track_year(collection_item_json): # this would be the default info, but is mostly not set :( year = collection_item_json.get('release_year', '') if year: return year # we use a fallback. # created_at=2013/03/24 00:32:01 +0000 re_match = re.match('(?P<year>\d{4})(.*)', collection_item_json.get('created_at', '')) if re_match: year = re_match.group('year') if year: return year pass return '' def _get_image(json_data): image_url = json_data.get('artwork_url', '') # test avatar image if not image_url: image_url = json_data.get('avatar_url', '') # test tracks (used for playlists) if not image_url: tracks = json_data.get('tracks', []) if len(tracks) > 0: return _get_image(tracks[0]) # fall back is the user avatar (at least) image_url = json_data.get('user', {}).get('avatar_url', '') pass return self._get_hires_image(image_url) kind = json_item.get('kind', '') if kind == 'playlist': if process_playlist: result = [] tracks = json_item['tracks'] track_number = 1 for track in tracks: path = context.get_path() track_item = self._do_item(context, track, path) # set the name of the playlist for the albumname track_item.set_album_name(json_item['title']) # based on the position in the playlist we add a track number track_item.set_track_number(track_number) result.append(track_item) track_number += 1 pass return result else: playlist_item = DirectoryItem( json_item['title'], context.create_uri(['playlist', unicode(json_item['id'])]), image=_get_image(json_item)) playlist_item.set_fanart(self.get_fanart(context)) if path == '/user/favorites/me/': context_menu = [ (context.localize( self._local_map['soundcloud.unlike']), 'RunPlugin(%s)' % context.create_uri( ['like/playlist', unicode(json_item['id'])], {'like': '0'})) ] else: context_menu = [ (context.localize(self._local_map['soundcloud.like']), 'RunPlugin(%s)' % context.create_uri( ['like/playlist', unicode(json_item['id'])], {'like': '1'})) ] playlist_item.set_context_menu(context_menu) return playlist_item pass elif kind == 'user': username = json_item['username'] user_id = unicode(json_item['id']) if path == '/': user_id = 'me' username = '******' + username + '[/B]' pass user_item = DirectoryItem(username, context.create_uri( ['user/tracks', user_id]), image=_get_image(json_item)) user_item.set_fanart(self.get_fanart(context)) if path == '/user/following/me/': context_menu = [( context.localize(self._local_map['soundcloud.unfollow']), 'RunPlugin(%s)' % context.create_uri( ['follow', unicode(json_item['id'])], {'follow': '0'})) ] pass else: context_menu = [( context.localize(self._local_map['soundcloud.follow']), 'RunPlugin(%s)' % context.create_uri( ['follow', unicode(json_item['id'])], {'follow': '1'})) ] pass user_item.set_context_menu(context_menu) return user_item elif kind == 'track': title = json_item['title'] track_item = AudioItem( title, context.create_uri('play', {'audio_id': unicode(json_item['id'])}), image=_get_image(json_item)) track_item.set_fanart(self.get_fanart(context)) # title track_item.set_title(title) # genre track_item.set_genre(json_item.get('genre', '')) # duration track_item.set_duration_from_milli_seconds( json_item.get('duration', 0)) # artist track_item.set_artist_name( json_item.get('user', {}).get('username', '')) # year track_item.set_year(_get_track_year(json_item)) context_menu = [] # recommended tracks context_menu.append( (context.localize(self._local_map['soundcloud.recommended']), 'Container.Update(%s)' % context.create_uri([ 'explore', 'recommended', 'tracks', unicode(json_item['id']) ]))) # like/unlike a track if path == '/user/favorites/me/': context_menu.append( (context.localize(self._local_map['soundcloud.unlike']), 'RunPlugin(%s)' % context.create_uri( ['like/track', unicode(json_item['id'])], {'like': '0'}))) pass else: context_menu.append( (context.localize(self._local_map['soundcloud.like']), 'RunPlugin(%s)' % context.create_uri( ['like/track', unicode(json_item['id'])], {'like': '1'}))) pass # go to user username = json_item['user']['username'] user_id = str(json_item['user']['id']) if path != '/user/tracks/%s/' % user_id: context_menu.append( (context.localize(self._local_map['soundcloud.user.go_to']) % ('[B]%s[/B]' % username), 'Container.Update(%s)' % context.create_uri(['user', 'tracks', user_id]))) pass track_item.set_context_menu(context_menu) return track_item elif kind == 'like': # A like has 'playlist' or 'track' so we find one of them and call this routine again, because the # data is same. test_playlist = json_item.get('playlist', None) if test_playlist is not None: return self._do_item(context, test_playlist, path) test_track = json_item.get('track', None) if test_track is not None: return self._do_item(context, test_track, path) pass elif kind == 'group': # at the moment we don't support groups """ group_item = DirectoryItem('Group-Dummy', '') return group_item """ return None raise kodion.KodionException("Unknown kind of item '%s'" % kind)
def _process_list_response(provider, context, json_data): video_id_dict = {} channel_id_dict = {} playlist_item_id_dict = {} result = [] yt_items = json_data.get('items', []) if len(yt_items) == 0: context.log_warning('List of search result is empty') return result for yt_item in yt_items: yt_kind = yt_item.get('kind', '') if yt_kind == u'youtube#video': video_id = yt_item['id'] snippet = yt_item['snippet'] title = snippet['title'] image = snippet.get('thumbnails', {}).get('medium', {}).get('url', '') video_item = items.VideoItem(title, context.create_uri( ['play'], {'video_id': video_id}), image=image) video_item.set_fanart(provider.get_fanart(context)) result.append(video_item) video_id_dict[video_id] = video_item pass elif yt_kind == u'youtube#channel': channel_id = yt_item['id'] snippet = yt_item['snippet'] title = snippet['title'] image = snippet.get('thumbnails', {}).get('medium', {}).get('url', '') channel_item = items.DirectoryItem(title, context.create_uri( ['channel', channel_id]), image=image) channel_item.set_fanart(provider.get_fanart(context)) # if logged in => provide subscribing to the channel if provider.is_logged_in(): context_menu = [] yt_context_menu.append_subscribe_to_channel( context_menu, provider, context, channel_id) channel_item.set_context_menu(context_menu) pass result.append(channel_item) # map channel if not channel_id in channel_id_dict: channel_id_dict[channel_id] = [] channel_id_dict[channel_id].append(channel_item) pass elif yt_kind == u'youtube#guideCategory': guide_id = yt_item['id'] snippet = yt_item['snippet'] title = snippet['title'] guide_item = items.DirectoryItem( title, context.create_uri(['special', 'browse_channels'], {'guide_id': guide_id})) guide_item.set_fanart(provider.get_fanart(context)) result.append(guide_item) pass elif yt_kind == u'youtube#subscription': snippet = yt_item['snippet'] image = snippet.get('thumbnails', {}).get('high', {}).get('url', '') channel_id = snippet['resourceId']['channelId'] playlist_item = items.DirectoryItem(snippet['title'], context.create_uri( ['channel', channel_id]), image=image) playlist_item.set_fanart(provider.get_fanart(context)) # unsubscribe from a channel subscription_id = yt_item['id'] context_menu = [] yt_context_menu.append_unsubscribe_from_channel( context_menu, provider, context, subscription_id) playlist_item.set_context_menu(context_menu) result.append(playlist_item) # map playlist to channel if not channel_id in channel_id_dict: channel_id_dict[channel_id] = [] channel_id_dict[channel_id].append(playlist_item) pass elif yt_kind == u'youtube#playlist': playlist_id = yt_item['id'] snippet = yt_item['snippet'] title = snippet['title'] image = snippet.get('thumbnails', {}).get('medium', {}).get('url', '') channel_id = snippet['channelId'] # if the path directs to a playlist of our own, we correct the channel id to 'mine' if context.get_path() == '/channel/mine/playlists/': channel_id = 'mine' pass playlist_item = items.DirectoryItem(title, context.create_uri([ 'channel', channel_id, 'playlist', playlist_id ]), image=image) playlist_item.set_fanart(provider.get_fanart(context)) channel_name = snippet.get('channelTitle', '') if provider.is_logged_in(): context_menu = [] # play all videos of the playlist yt_context_menu.append_play_all_from_playlist( context_menu, provider, context, playlist_id) if channel_id != 'mine': # subscribe to the channel via the playlist item yt_context_menu.append_subscribe_to_channel( context_menu, provider, context, channel_id, channel_name) pass else: # remove my playlist yt_context_menu.append_delete_playlist( context_menu, provider, context, playlist_id, title) # rename playlist yt_context_menu.append_rename_playlist( context_menu, provider, context, playlist_id, title) pass playlist_item.set_context_menu(context_menu) pass result.append(playlist_item) # map playlist to channel if not channel_id in channel_id_dict: channel_id_dict[channel_id] = [] channel_id_dict[channel_id].append(playlist_item) pass elif yt_kind == u'youtube#playlistItem': snippet = yt_item['snippet'] video_id = snippet['resourceId']['videoId'] # store the id of the playlistItem - for deleting this item we need this item playlist_item_id_dict[video_id] = yt_item['id'] title = snippet['title'] image = snippet.get('thumbnails', {}).get('medium', {}).get('url', '') video_item = items.VideoItem(title, context.create_uri( ['play'], {'video_id': video_id}), image=image) video_item.set_fanart(provider.get_fanart(context)) result.append(video_item) video_id_dict[video_id] = video_item pass elif yt_kind == 'youtube#searchResult': yt_kind = yt_item.get('id', {}).get('kind', '') # video if yt_kind == 'youtube#video': video_id = yt_item['id']['videoId'] snippet = yt_item['snippet'] title = snippet['title'] image = snippet.get('thumbnails', {}).get('medium', {}).get('url', '') video_item = items.VideoItem( title, context.create_uri(['play'], {'video_id': video_id}), image=image) video_item.set_fanart(provider.get_fanart(context)) result.append(video_item) video_id_dict[video_id] = video_item pass # playlist elif yt_kind == 'youtube#playlist': playlist_id = yt_item['id']['playlistId'] snippet = yt_item['snippet'] title = snippet['title'] image = snippet.get('thumbnails', {}).get('medium', {}).get('url', '') channel_id = snippet['channelId'] # if the path directs to a playlist of our own, we correct the channel id to 'mine' if context.get_path() == '/channel/mine/playlists/': channel_id = 'mine' pass channel_name = snippet.get('channelTitle', '') playlist_item = items.DirectoryItem(title, context.create_uri([ 'channel', channel_id, 'playlist', playlist_id ]), image=image) playlist_item.set_fanart(provider.get_fanart(context)) context_menu = [] # play all videos of the playlist yt_context_menu.append_play_all_from_playlist( context_menu, provider, context, playlist_id) if provider.is_logged_in(): # subscribe to the channel of the playlist yt_context_menu.append_subscribe_to_channel( context_menu, provider, context, channel_id, channel_name) pass if len(context_menu) > 0: playlist_item.set_context_menu(context_menu) pass result.append(playlist_item) # map playlist to channel if not channel_id in channel_id_dict: channel_id_dict[channel_id] = [] channel_id_dict[channel_id].append(playlist_item) pass elif yt_kind == 'youtube#channel': channel_id = yt_item['id']['channelId'] snippet = yt_item['snippet'] title = snippet['title'] image = snippet.get('thumbnails', {}).get('medium', {}).get('url', '') channel_item = items.DirectoryItem( title, context.create_uri(['channel', channel_id]), image=image) channel_item.set_fanart(provider.get_fanart(context)) # subscribe to the channel if provider.is_logged_in(): context_menu = [] yt_context_menu.append_subscribe_to_channel( context_menu, provider, context, channel_id) channel_item.set_context_menu(context_menu) pass result.append(channel_item) # map channel if not channel_id in channel_id_dict: channel_id_dict[channel_id] = [] channel_id_dict[channel_id].append(channel_item) pass else: raise kodion.KodionException("Unknown kind '%s'" % yt_kind) pass else: raise kodion.KodionException("Unknown kind '%s'" % yt_kind) pass # this will also update the channel_id_dict with the correct channel id for each video. utils.update_video_infos(provider, context, video_id_dict, playlist_item_id_dict, channel_id_dict) utils.update_channel_infos(provider, context, channel_id_dict) return result