def _play(self, context, re_match): params = context.get_params() track_id = params.get('id', '') if not track_id: raise kodion.KodimonException('Missing if for audio file') json_data = self.get_client(context).get_track_url(track_id) location = json_data.get('location') if not location: raise kodion.KodimonException("Could not get url for trask '%s'" % track_id) item = AudioItem(track_id, location) return item
def _process_add_video(provider, context, re_match): playlist_id = context.get_param('playlist_id', '') if not playlist_id: raise kodion.KodimonException('Playlist/Remove: missing playlist_id') video_id = context.get_param('video_id', '') if not video_id: raise kodion.KodimonException('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_remove_video(provider, context, re_match): playlist_id = context.get_param('playlist_id', '') if not playlist_id: raise kodion.KodimonException('Playlist/Remove: missing playlist_id') video_id = context.get_param('video_id', '') if not video_id: raise kodion.KodimonException('Playlist/Remove: missing video_id') json_data = provider.get_client(context).remove_video_from_playlist( playlist_id=playlist_id, playlist_item_id=video_id) if not v3.handle_error(provider, context, json_data): return False context.get_ui().refresh_container() return True
def response_to_items(provider, context, json_data): 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.KodimonException("Unknown kind '%s'" % kind) # next page yt_next_page_token = json_data.get('nextPageToken', '') if 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 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.create_next_page_item( new_context, current_page) next_page_item.set_fanart(provider.get_fanart(new_context)) result.append(next_page_item) pass pass else: raise kodion.KodimonException("Couldn't find feed") return result
def _play(self, context, re_match): params = context.get_params() video_id = params.get('id', '') if video_id == '': raise kodion.KodimonException( "Missing parameter 'id' to play video") json_data = self._get_client(context).get_video_url(video_id) video_url = json_data.get('VideoURL', '') if not video_url: raise kodion.KodimonException( "Could not resolve url for video '%s'" % video_id) re_drm_match = re.search(r'no_flash_de|drm_update_app_de', video_url) if re_drm_match: context.get_ui().show_notification( context.localize( self._local_map['7tv.exception.drm_not_supported'])) return False return UriItem(video_url)
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) else: raise kodion.KodimonException("Unknown category '%s' or method '%s'" % (category, method)) return True
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.KodimonException("Unknown subscriptions method '%s'" % method) return result
def _process_rename_playlist(provider, context, re_match): playlist_id = context.get_param('playlist_id', '') if not playlist_id: raise kodion.KodimonException('Playlist/Remove: missing playlist_id') current_playlist_name = context.get_param('title', '') result, text = context.get_ui().on_keyboard_input( title='__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 _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.KodimonException("Unknown category '%s' in 'on_like'" % category) if not like: context.get_ui().refresh_container() pass return True
def process(category, provider, context, re_match): result = [] if category == 'related_videos': result.extend(_process_related_videos(provider, context, re_match)) pass elif category == 'what_to_watch': result.extend(_process_what_to_watch(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 else: raise kodion.KodimonException("YouTube category '%s' not found" % category) return result
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 = [] 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_remove_playlist( context_menu, provider, context, playlist_id) # 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)) if provider.is_logged_in(): context_menu = [] # subscribe to the channel of the playlist yt_context_menu.append_subscribe_to_channel( context_menu, provider, context, channel_id, channel_name) 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.KodimonException("Unknown kind '%s'" % yt_kind) pass else: raise kodion.KodimonException("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
def _screen_object_to_item(self, context, screen_object, show_format_title=False): screen_object_type = screen_object.get('type', '') if screen_object_type == '': raise kodion.KodimonException('Missing type for screenObject') fanart = self.get_fanart(context) format_id = screen_object.get('format_id', screen_object.get('id', '')).split(':') if len(format_id) == 2: channel_id = format_id[0] format_id = format_id[1] if channel_id == 'tvog': channel_id = 'pro7' pass data = self._load_format_content(context, channel_id, format_id, return_cached_only=True) fanart = data.get('fanart', self.get_fanart(context)) pass if screen_object_type == 'video_item_date_no_label' or screen_object_type == 'video_item_date' \ or screen_object_type == 'video_item_format_no_label' or screen_object_type == 'video_item_format': name = screen_object.get('title', screen_object['video_title']) if screen_object_type == 'video_item_format_no_label' or show_format_title: name = '%s - %s' % (screen_object['format_title'], name) pass video_item = VideoItem(name, context.create_uri( ['play'], {'id': screen_object['id']}), image=screen_object.get('image_url', '')) video_item.set_fanart(fanart) video_item.set_duration_from_seconds( int(screen_object.get('duration', '60'))) date_time = datetime_parser.parse( screen_object.get('start', '0000-00-00')) video_item.set_aired_from_datetime(date_time) video_item.set_premiered_from_datetime(date_time) video_item.set_year_from_datetime(date_time) try_set_season_and_episode(video_item) context_menu = [ (context.localize(kodion.constants.localize.WATCH_LATER), 'RunPlugin(%s)' % context.create_uri( [kodion.constants.paths.WATCH_LATER, 'add'], {'item': kodion.items.to_jsons(video_item)})) ] video_item.set_context_menu(context_menu) return video_item elif screen_object_type == 'format_item_home' or screen_object_type == 'format_item': format_item = DirectoryItem( screen_object['title'], context.create_uri([channel_id, 'library', format_id]), image=screen_object['image_url']) format_item.set_fanart(fanart) context_menu = [ (context.localize(kodion.constants.localize.FAVORITES_ADD), 'RunPlugin(%s)' % context.create_uri( [kodion.constants.paths.FAVORITES, 'add'], {'item': kodion.items.to_jsons(format_item)})) ] format_item.set_context_menu(context_menu) return format_item raise kodion.KodimonException("Unknown type '%s' for screen_object" % screen_object_type)
def _do_item(self, context, json_item, path): 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 # try to convert the image to 500x500 pixel return self._get_hires_image(image_url) kind = json_item.get('kind', '') if kind == 'playlist': 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 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', {'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)) if path == '/user/favorites/me/': context_menu = [(context.localize(self._local_map['soundcloud.unlike']), 'RunPlugin(%s)' % context.create_uri(['like/track', unicode(json_item['id'])], {'like': '0'}))] pass else: context_menu = [(context.localize(self._local_map['soundcloud.like']), 'RunPlugin(%s)' % context.create_uri(['like/track', unicode(json_item['id'])], {'like': '1'}))] 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.KodimonException("Unknown kind of item '%s'" % kind)