aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Taylor <user234683@users.noreply.github.com>2019-06-10 15:27:17 -0700
committerJames Taylor <user234683@users.noreply.github.com>2019-06-10 15:27:17 -0700
commit9da073000a54fba8f6d38dc37bfcfd9ca0a60d9a (patch)
treefb30cb7861ae3650bfd223d94b4c7972e9bbaf00
parentd637f5b29c2153b0e4fde2f7183230100b2f6309 (diff)
downloadyt-local-9da073000a54fba8f6d38dc37bfcfd9ca0a60d9a.tar.lz
yt-local-9da073000a54fba8f6d38dc37bfcfd9ca0a60d9a.tar.xz
yt-local-9da073000a54fba8f6d38dc37bfcfd9ca0a60d9a.zip
Use a single cursor for db operations when possible instead of reopening multiple times
-rw-r--r--youtube/subscriptions.py168
1 files changed, 80 insertions, 88 deletions
diff --git a/youtube/subscriptions.py b/youtube/subscriptions.py
index 7728c0c..5707286 100644
--- a/youtube/subscriptions.py
+++ b/youtube/subscriptions.py
@@ -63,66 +63,60 @@ def open_database():
# https://stackoverflow.com/questions/19522505/using-sqlite3-in-python-with-with-keyword
return contextlib.closing(connection)
-def _subscribe(channels):
+def with_open_db(function, *args, **kwargs):
+ with open_database() as connection:
+ with connection as cursor:
+ return function(cursor, *args, **kwargs)
+
+
+def _subscribe(cursor, channels):
''' channels is a list of (channel_id, channel_name) '''
# set time_last_checked to 0 on all channels being subscribed to
channels = ( (channel_id, channel_name, 0) for channel_id, channel_name in channels)
- with open_database() as connection:
- with connection as cursor:
- cursor.executemany('''INSERT OR IGNORE INTO subscribed_channels (yt_channel_id, channel_name, time_last_checked)
- VALUES (?, ?, ?)''', channels)
+ cursor.executemany('''INSERT OR IGNORE INTO subscribed_channels (yt_channel_id, channel_name, time_last_checked)
+ VALUES (?, ?, ?)''', channels)
# TODO: delete thumbnails
-def _unsubscribe(channel_ids):
+def _unsubscribe(cursor, channel_ids):
''' channel_ids is a list of channel_ids '''
- with open_database() as connection:
- with connection as cursor:
- cursor.executemany("DELETE FROM subscribed_channels WHERE yt_channel_id=?", ((channel_id, ) for channel_id in channel_ids))
+ cursor.executemany("DELETE FROM subscribed_channels WHERE yt_channel_id=?", ((channel_id, ) for channel_id in channel_ids))
-def _get_videos(number, offset):
- with open_database() as connection:
- with connection as cursor:
- db_videos = cursor.execute('''SELECT video_id, title, duration, channel_name
- FROM videos
- INNER JOIN subscribed_channels on videos.sql_channel_id = subscribed_channels.id
- ORDER BY time_published DESC
- LIMIT ? OFFSET ?''', (number, offset))
-
- for db_video in db_videos:
- yield {
- 'id': db_video[0],
- 'title': db_video[1],
- 'duration': db_video[2],
- 'author': db_video[3],
- }
-
-def _get_subscribed_channels():
- with open_database() as connection:
- with connection as cursor:
- for item in cursor.execute('''SELECT channel_name, yt_channel_id
- FROM subscribed_channels
- ORDER BY channel_name'''):
- yield item
+def _get_videos(cursor, number, offset):
+ db_videos = cursor.execute('''SELECT video_id, title, duration, channel_name
+ FROM videos
+ INNER JOIN subscribed_channels on videos.sql_channel_id = subscribed_channels.id
+ ORDER BY time_published DESC
+ LIMIT ? OFFSET ?''', (number, offset))
+ for db_video in db_videos:
+ yield {
+ 'id': db_video[0],
+ 'title': db_video[1],
+ 'duration': db_video[2],
+ 'author': db_video[3],
+ }
-def _add_tags(channel_ids, tags):
- with open_database() as connection:
- with connection as cursor:
- pairs = [(tag, yt_channel_id) for tag in tags for yt_channel_id in channel_ids]
- cursor.executemany('''INSERT OR IGNORE INTO tag_associations (tag, sql_channel_id)
- SELECT ?, id FROM subscribed_channels WHERE yt_channel_id = ? ''', pairs)
+def _get_subscribed_channels(cursor):
+ for item in cursor.execute('''SELECT channel_name, yt_channel_id
+ FROM subscribed_channels
+ ORDER BY channel_name'''):
+ yield item
-def _remove_tags(channel_ids, tags):
- with open_database() as connection:
- with connection as cursor:
- pairs = [(tag, yt_channel_id) for tag in tags for yt_channel_id in channel_ids]
- cursor.executemany('''DELETE FROM tag_associations
- WHERE tag = ? AND sql_channel_id = (
- SELECT id FROM subscribed_channels WHERE yt_channel_id = ?
- )''', pairs)
+def _add_tags(cursor, channel_ids, tags):
+ pairs = [(tag, yt_channel_id) for tag in tags for yt_channel_id in channel_ids]
+ cursor.executemany('''INSERT OR IGNORE INTO tag_associations (tag, sql_channel_id)
+ SELECT ?, id FROM subscribed_channels WHERE yt_channel_id = ? ''', pairs)
+
+
+def _remove_tags(cursor, channel_ids, tags):
+ pairs = [(tag, yt_channel_id) for tag in tags for yt_channel_id in channel_ids]
+ cursor.executemany('''DELETE FROM tag_associations
+ WHERE tag = ? AND sql_channel_id = (
+ SELECT id FROM subscribed_channels WHERE yt_channel_id = ?
+ )''', pairs)
@@ -133,22 +127,18 @@ def _get_tags(cursor, channel_id):
SELECT id FROM subscribed_channels WHERE yt_channel_id = ?
)''', (channel_id,))]
-def _get_all_tags():
- with open_database() as connection:
- with connection as cursor:
- return [row[0] for row in cursor.execute('''SELECT DISTINCT tag FROM tag_associations''')]
+def _get_all_tags(cursor):
+ return [row[0] for row in cursor.execute('''SELECT DISTINCT tag FROM tag_associations''')]
-def _get_channel_names(channel_ids):
+def _get_channel_names(cursor, channel_ids):
''' returns list of (channel_id, channel_name) '''
- with open_database() as connection:
- with connection as cursor:
- result = []
- for channel_id in channel_ids:
- row = cursor.execute('''SELECT channel_name
- FROM subscribed_channels
- WHERE yt_channel_id = ?''', (channel_id,)).fetchone()
- result.append( (channel_id, row[0]) )
- return result
+ result = []
+ for channel_id in channel_ids:
+ row = cursor.execute('''SELECT channel_name
+ FROM subscribed_channels
+ WHERE yt_channel_id = ?''', (channel_id,)).fetchone()
+ result.append( (channel_id, row[0]) )
+ return result
def _channels_with_tag(cursor, tag, order=False):
@@ -357,7 +347,7 @@ def import_subscriptions(env, start_response):
start_response('400 Bad Request', () )
return b'400 Bad Request: Unsupported file format: ' + html.escape(content_type).encode('utf-8') + b'. Only subscription.json files (from Google Takeouts) and XML OPML files exported from Youtube\'s subscription manager page are supported'
- _subscribe(channels)
+ with_open_db(_subscribe, channels)
start_response('303 See Other', [('Location', util.URL_ORIGIN + '/subscription_manager'),] )
return b''
@@ -388,7 +378,7 @@ def get_subscription_manager_page(env, start_response):
sort_link = util.URL_ORIGIN + '/subscription_manager'
main_list_html = '<ul class="tag-group-list">'
- for tag in _get_all_tags():
+ for tag in _get_all_tags(cursor):
sub_list_html = ''
for channel_id, channel_name in _channels_with_tag(cursor, tag, order=True):
sub_list_html += sub_list_item_template.substitute(
@@ -430,7 +420,7 @@ def get_subscription_manager_page(env, start_response):
sort_link = util.URL_ORIGIN + '/subscription_manager?group_by_tags=1'
main_list_html = '<ol class="sub-list">'
- for channel_name, channel_id in _get_subscribed_channels():
+ for channel_name, channel_id in _get_subscribed_channels(cursor):
main_list_html += sub_list_item_template.substitute(
channel_url = util.URL_ORIGIN + '/channel/' + channel_id,
channel_name = html.escape(channel_name),
@@ -461,11 +451,11 @@ def post_subscription_manager_page(env, start_response):
action = params['action'][0]
if action == 'add_tags':
- _add_tags(params['channel_ids'], [tag.lower() for tag in list_from_comma_separated_tags(params['tags'][0])])
+ with_open_db(_add_tags, params['channel_ids'], [tag.lower() for tag in list_from_comma_separated_tags(params['tags'][0])])
elif action == 'remove_tags':
- _remove_tags(params['channel_ids'], [tag.lower() for tag in list_from_comma_separated_tags(params['tags'][0])])
+ with_open_db(_remove_tags, params['channel_ids'], [tag.lower() for tag in list_from_comma_separated_tags(params['tags'][0])])
elif action == 'unsubscribe':
- _unsubscribe(params['channel_ids'])
+ with_open_db(_unsubscribe, params['channel_ids'])
elif action == 'unsubscribe_verify':
page = '''
<span>Are you sure you want to unsubscribe from these channels?</span>
@@ -479,7 +469,7 @@ def post_subscription_manager_page(env, start_response):
<input type="submit" value="Yes, unsubscribe">
</form>
<ul>'''
- for channel_id, channel_name in _get_channel_names(params['channel_ids']):
+ for channel_id, channel_name in with_open_db(_get_channel_names, params['channel_ids']):
page += unsubscribe_list_item_template.substitute(
channel_url = util.URL_ORIGIN + '/channel/' + channel_id,
channel_name = html.escape(channel_name),
@@ -526,29 +516,31 @@ sidebar_channel_item_template = Template('''
</li>''')
def get_subscriptions_page(env, start_response):
- items_html = '''<nav class="item-grid">\n'''
+ with open_database() as connection:
+ with connection as cursor:
+ items_html = '''<nav class="item-grid">\n'''
- for item in _get_videos(30, 0):
- if item['id'] in downloading_thumbnails:
- item['thumbnail'] = util.get_thumbnail_url(item['id'])
- else:
- item['thumbnail'] = util.URL_ORIGIN + '/data/subscription_thumbnails/' + item['id'] + '.jpg'
- items_html += html_common.video_item_html(item, html_common.small_video_item_template)
- items_html += '''\n</nav>'''
+ for item in _get_videos(cursor, 30, 0):
+ if item['id'] in downloading_thumbnails:
+ item['thumbnail'] = util.get_thumbnail_url(item['id'])
+ else:
+ item['thumbnail'] = util.URL_ORIGIN + '/data/subscription_thumbnails/' + item['id'] + '.jpg'
+ items_html += html_common.video_item_html(item, html_common.small_video_item_template)
+ items_html += '''\n</nav>'''
- tag_list_html = ''
- for tag_name in _get_all_tags():
- tag_list_html += sidebar_tag_item_template.substitute(tag_name = tag_name)
+ tag_list_html = ''
+ for tag_name in _get_all_tags(cursor):
+ tag_list_html += sidebar_tag_item_template.substitute(tag_name = tag_name)
- sub_list_html = ''
- for channel_name, channel_id in _get_subscribed_channels():
- sub_list_html += sidebar_channel_item_template.substitute(
- channel_url = util.URL_ORIGIN + '/channel/' + channel_id,
- channel_name = html.escape(channel_name),
- channel_id = channel_id,
- )
+ sub_list_html = ''
+ for channel_name, channel_id in _get_subscribed_channels(cursor):
+ sub_list_html += sidebar_channel_item_template.substitute(
+ channel_url = util.URL_ORIGIN + '/channel/' + channel_id,
+ channel_name = html.escape(channel_name),
+ channel_id = channel_id,
+ )
@@ -568,10 +560,10 @@ def post_subscriptions_page(env, start_response):
if len(params['channel_id']) != len(params['channel_name']):
start_response('400 Bad Request', ())
return b'400 Bad Request, length of channel_id != length of channel_name'
- _subscribe(zip(params['channel_id'], params['channel_name']))
+ with_open_db(_subscribe, zip(params['channel_id'], params['channel_name']))
elif action == 'unsubscribe':
- _unsubscribe(params['channel_id'])
+ with_open_db(_unsubscribe, params['channel_id'])
elif action == 'refresh':
type = params['type'][0]