Unsubscribe button on channels if already subscribed

This commit is contained in:
James Taylor 2019-06-10 17:04:06 -07:00
parent e7989db931
commit 103b37030f
4 changed files with 61 additions and 9 deletions

View File

@ -1,5 +1,5 @@
import base64 import base64
from youtube import util, yt_data_extract, html_common from youtube import util, yt_data_extract, html_common, subscriptions
import http_errors import http_errors
import urllib import urllib
@ -241,6 +241,12 @@ def channel_videos_html(polymer_json, current_page=1, current_sort=3, number_of_
microformat = get_microformat(response) microformat = get_microformat(response)
channel_url = microformat['urlCanonical'].rstrip('/') channel_url = microformat['urlCanonical'].rstrip('/')
channel_id = channel_url[channel_url.rfind('/')+1:] channel_id = channel_url[channel_url.rfind('/')+1:]
if subscriptions.is_subscribed(channel_id):
action_name = 'Unsubscribe'
action = 'unsubscribe'
else:
action_name = 'Subscribe'
action = 'subscribe'
items = get_grid_items(response) items = get_grid_items(response)
items_html = grid_items_html(items, {'author': microformat['title']}) items_html = grid_items_html(items, {'author': microformat['title']})
@ -256,6 +262,8 @@ def channel_videos_html(polymer_json, current_page=1, current_sort=3, number_of_
items = items_html, items = items_html,
page_buttons = html_common.page_buttons_html(current_page, math.ceil(number_of_videos/30), util.URL_ORIGIN + "/channel/" + channel_id + "/videos", current_query_string), page_buttons = html_common.page_buttons_html(current_page, math.ceil(number_of_videos/30), util.URL_ORIGIN + "/channel/" + channel_id + "/videos", current_query_string),
number_of_results = '{:,}'.format(number_of_videos) + " videos", number_of_results = '{:,}'.format(number_of_videos) + " videos",
action_name = action_name,
action = action,
) )
def channel_playlists_html(polymer_json, current_sort=3): def channel_playlists_html(polymer_json, current_sort=3):
@ -264,6 +272,13 @@ def channel_playlists_html(polymer_json, current_sort=3):
channel_url = microformat['urlCanonical'].rstrip('/') channel_url = microformat['urlCanonical'].rstrip('/')
channel_id = channel_url[channel_url.rfind('/')+1:] channel_id = channel_url[channel_url.rfind('/')+1:]
if subscriptions.is_subscribed(channel_id):
action_name = 'Unsubscribe'
action = 'unsubscribe'
else:
action_name = 'Subscribe'
action = 'subscribe'
items = get_grid_items(response) items = get_grid_items(response)
items_html = grid_items_html(items, {'author': microformat['title']}) items_html = grid_items_html(items, {'author': microformat['title']})
@ -278,6 +293,8 @@ def channel_playlists_html(polymer_json, current_sort=3):
items = items_html, items = items_html,
page_buttons = '', page_buttons = '',
number_of_results = '', number_of_results = '',
action_name = action_name,
action = action,
) )
# Example channel where tabs do not have definite index: https://www.youtube.com/channel/UC4gQ8i3FD7YbhOgqUkeQEJg # Example channel where tabs do not have definite index: https://www.youtube.com/channel/UC4gQ8i3FD7YbhOgqUkeQEJg
@ -323,6 +340,16 @@ def channel_about_page(polymer_json):
continue continue
else: else:
stats += stat_template.substitute(stat_value=stat_value) stats += stat_template.substitute(stat_value=stat_value)
channel_id = channel_metadata['channelId']
if subscriptions.is_subscribed(channel_id):
action_name = 'Unsubscribe'
action = 'unsubscribe'
else:
action_name = 'Subscribe'
action = 'subscribe'
try: try:
description = yt_data_extract.format_text_runs(yt_data_extract.get_formatted_text(channel_metadata['description'])) description = yt_data_extract.format_text_runs(yt_data_extract.get_formatted_text(channel_metadata['description']))
except KeyError: except KeyError:
@ -335,8 +362,10 @@ def channel_about_page(polymer_json):
description = description, description = description,
links = channel_links, links = channel_links,
stats = stats, stats = stats,
channel_id = channel_metadata['channelId'], channel_id = channel_id,
channel_tabs = channel_tabs_html(channel_metadata['channelId'], 'About'), channel_tabs = channel_tabs_html(channel_metadata['channelId'], 'About'),
action_name = action_name,
action = action,
) )
def channel_search_page(polymer_json, query, current_page=1, number_of_videos = 1000, current_query_string=''): def channel_search_page(polymer_json, query, current_page=1, number_of_videos = 1000, current_query_string=''):
@ -345,7 +374,14 @@ def channel_search_page(polymer_json, query, current_page=1, number_of_videos =
channel_url = microformat['urlCanonical'].rstrip('/') channel_url = microformat['urlCanonical'].rstrip('/')
channel_id = channel_url[channel_url.rfind('/')+1:] channel_id = channel_url[channel_url.rfind('/')+1:]
if subscriptions.is_subscribed(channel_id):
action_name = 'Unsubscribe'
action = 'unsubscribe'
else:
action_name = 'Subscribe'
action = 'subscribe'
try: try:
items = tab_with_content(response['contents']['twoColumnBrowseResultsRenderer']['tabs'])['sectionListRenderer']['contents'] items = tab_with_content(response['contents']['twoColumnBrowseResultsRenderer']['tabs'])['sectionListRenderer']['contents']
except KeyError: except KeyError:
@ -364,6 +400,8 @@ def channel_search_page(polymer_json, query, current_page=1, number_of_videos =
page_buttons = html_common.page_buttons_html(current_page, math.ceil(number_of_videos/29), util.URL_ORIGIN + "/channel/" + channel_id + "/search", current_query_string), page_buttons = html_common.page_buttons_html(current_page, math.ceil(number_of_videos/29), util.URL_ORIGIN + "/channel/" + channel_id + "/search", current_query_string),
number_of_results = '', number_of_results = '',
sort_buttons = '', sort_buttons = '',
action_name = action_name,
action = action,
) )
def get_channel_search_json(channel_id, query, page): def get_channel_search_json(channel_id, query, page):
params = proto.string(2, 'search') + proto.string(15, str(page)) params = proto.string(2, 'search') + proto.string(15, str(page))

View File

@ -68,6 +68,20 @@ def with_open_db(function, *args, **kwargs):
with connection as cursor: with connection as cursor:
return function(cursor, *args, **kwargs) return function(cursor, *args, **kwargs)
def is_subscribed(channel_id):
if not os.path.exists(database_path):
return False
with open_database() as connection:
with connection as cursor:
result = cursor.execute('''SELECT EXISTS(
SELECT 1
FROM subscribed_channels
WHERE yt_channel_id=?
LIMIT 1
)''', [channel_id]).fetchone()
return bool(result[0])
def _subscribe(cursor, channels): def _subscribe(cursor, channels):
''' channels is a list of (channel_id, channel_name) ''' ''' channels is a list of (channel_id, channel_name) '''

View File

@ -56,11 +56,11 @@ $header
<img class="avatar" src="$avatar"> <img class="avatar" src="$avatar">
<div class="metadata"> <div class="metadata">
<h2 class="title">$channel_title</h2> <h2 class="title">$channel_title</h2>
<form method="POST" action="/youtube.com/subscriptions" class="subscribe"> <form method="POST" action="/youtube.com/subscriptions" class="subscribe-unsubscribe">
<input type="submit" value="Subscribe"> <input type="submit" value="$action_name">
<input type="hidden" name="channel_id" value="$channel_id"> <input type="hidden" name="channel_id" value="$channel_id">
<input type="hidden" name="channel_name" value="$channel_title"> <input type="hidden" name="channel_name" value="$channel_title">
<input type="hidden" name="action" value="subscribe"> <input type="hidden" name="action" value="$action">
</form> </form>
</div> </div>
<nav class="channel-tabs"> <nav class="channel-tabs">

View File

@ -72,11 +72,11 @@ $header
<img class="avatar" src="$avatar"> <img class="avatar" src="$avatar">
<div class="metadata"> <div class="metadata">
<h2 class="title">$channel_title</h2> <h2 class="title">$channel_title</h2>
<form method="POST" action="/youtube.com/subscriptions" class="subscribe"> <form method="POST" action="/youtube.com/subscriptions" class="subscribe-unsubscribe">
<input type="submit" value="Subscribe"> <input type="submit" value="$action_name">
<input type="hidden" name="channel_id" value="$channel_id"> <input type="hidden" name="channel_id" value="$channel_id">
<input type="hidden" name="channel_name" value="$channel_title"> <input type="hidden" name="channel_name" value="$channel_title">
<input type="hidden" name="action" value="subscribe"> <input type="hidden" name="action" value="$action">
</form> </form>
</div> </div>
<nav class="channel-tabs"> <nav class="channel-tabs">