aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesus E <heckyel@riseup.net>2023-05-28 21:19:55 -0400
committerJesus E <heckyel@riseup.net>2023-05-28 21:19:55 -0400
commit43e7f7ce936b34fedd01a70f606c5fe2997d70a5 (patch)
tree11a9d93318fb1aa237b54fdc43ad5b0692ccdb58
parent97032b31ee7c2d955c32be6bb7a69198f02411f6 (diff)
downloadyt-local-43e7f7ce936b34fedd01a70f606c5fe2997d70a5.tar.lz
yt-local-43e7f7ce936b34fedd01a70f606c5fe2997d70a5.tar.xz
yt-local-43e7f7ce936b34fedd01a70f606c5fe2997d70a5.zip
Cache channel metadata for pages that don't provide it
Ensures channel profile picture & description are displayed Also ensures that videos added to a local playlist from such pages will have the channel name included Fixes #151
-rw-r--r--youtube/channel.py53
1 files changed, 49 insertions, 4 deletions
diff --git a/youtube/channel.py b/youtube/channel.py
index 4ae6484..4cf6cdf 100644
--- a/youtube/channel.py
+++ b/youtube/channel.py
@@ -278,6 +278,31 @@ def get_channel_id(base_url):
return None
+metadata_cache = cachetools.LRUCache(128)
+@cachetools.cached(metadata_cache)
+def get_metadata(channel_id):
+ base_url = 'https://www.youtube.com/channel/' + channel_id
+ polymer_json = util.fetch_url(base_url + '/about?pbj=1',
+ headers_desktop,
+ debug_name='gen_channel_about',
+ report_text='Retrieved channel metadata')
+ info = yt_data_extract.extract_channel_info(json.loads(polymer_json),
+ 'about',
+ continuation=False)
+ return extract_metadata_for_caching(info)
+def set_cached_metadata(channel_id, metadata):
+ @cachetools.cached(metadata_cache)
+ def dummy_func_using_same_cache(channel_id):
+ return metadata
+ dummy_func_using_same_cache(channel_id)
+def extract_metadata_for_caching(channel_info):
+ metadata = {}
+ for key in ('approx_subscriber_count', 'short_description', 'channel_name',
+ 'avatar'):
+ metadata[key] = channel_info[key]
+ return metadata
+
+
def get_number_of_videos_general(base_url):
return get_number_of_videos_channel(get_channel_id(base_url))
@@ -390,6 +415,30 @@ def get_channel_page_general_url(base_url, tab, request, channel_id=None):
info = yt_data_extract.extract_channel_info(json.loads(polymer_json), tab,
continuation=continuation)
+ if channel_id:
+ info['channel_url'] = 'https://www.youtube.com/channel/' + channel_id
+ info['channel_id'] = channel_id
+ else:
+ channel_id = info['channel_id']
+
+ # Will have microformat present, cache metadata while we have it
+ if channel_id and default_params:
+ metadata = extract_metadata_for_caching(info)
+ set_cached_metadata(channel_id, metadata)
+ # Otherwise, populate with our (hopefully cached) metadata
+ elif channel_id and info['channel_name'] is None:
+ metadata = get_metadata(channel_id)
+ for key, value in metadata.items():
+ yt_data_extract.conservative_update(info, key, value)
+ # need to add this metadata to the videos/playlists
+ additional_info = {
+ 'author': info['channel_name'],
+ 'author_id': info['channel_id'],
+ 'author_url': info['channel_url'],
+ }
+ for item in info['items']:
+ item.update(additional_info)
+
if info['error'] is not None:
return flask.render_template('error.html', error_message=info['error'])
@@ -399,10 +448,6 @@ def get_channel_page_general_url(base_url, tab, request, channel_id=None):
info['header_playlist_names'] = local_playlist.get_playlist_names()
if tab in ('videos', 'playlists'):
info['current_sort'] = sort
- if channel_id:
- info['channel_url'] = ('https://www.youtube.com/channel/'
- + channel_id)
- info['channel_id'] = channel_id
elif tab == 'search':
info['search_box_value'] = query
info['header_playlist_names'] = local_playlist.get_playlist_names()