From 811d6d3c3104b3dfcb662e19082196766ad75995 Mon Sep 17 00:00:00 2001 From: girst Date: Sat, 18 Jul 2020 15:38:04 +0200 Subject: [PATCH] allow (un)pinning and (un)subscribing on /watch pinning also works now for videos yet not in the database --- app/common/common.py | 26 ++++++++++++++++++ app/static/style.css | 7 +++++ app/youtube/__init__.py | 42 ++++++++++++++++++++--------- app/youtube/templates/watch.html.j2 | 22 ++++++++++----- 4 files changed, 78 insertions(+), 19 deletions(-) diff --git a/app/common/common.py b/app/common/common.py index 3e500f0..4b73f79 100644 --- a/app/common/common.py +++ b/app/common/common.py @@ -3,6 +3,7 @@ import re import json import html import base64 +import sqlite3 import requests import hmac, hashlib import requests_cache @@ -431,6 +432,31 @@ def prepare_metadata(metadata): 'subtitles': subtitles, } +def store_video_metadata(video_id): + # check if we know about it, and if not, fetch and store video metadata + with sqlite3.connect(cf['global']['database']) as conn: + c = conn.cursor() + c.execute("SELECT 1 from videos where id = ?", (video_id,)) + new_video = len(c.fetchall()) < 1 + if new_video: + _, meta, _, _ = get_video_info(video_id) + if meta: + meta = prepare_metadata(meta) + c.execute(""" + INSERT OR IGNORE INTO videos (id, channel_id, title, published, crawled) + VALUES (?, ?, ?, datetime(?), datetime(?)) + """, ( + video_id, + meta['channel_id'], + meta['title'], + meta['published'], + meta['published'], + )) + c.execute(""" + INSERT OR REPLACE INTO channels (id, name) + VALUES (?, ?) + """, (meta['channel_id'], meta['author'])) + class RedditException(Exception): pass def fetch_reddit(subreddits, sorted_by="hot", time=None, *, limit=36, count=None, before=None, after=None): diff --git a/app/static/style.css b/app/static/style.css index 239393d..302774c 100644 --- a/app/static/style.css +++ b/app/static/style.css @@ -5,13 +5,16 @@ body { } .card-main .title, +.more-actions label, a:link, a:visited , summary { color: #ccc; text-decoration: none; + cursor: pointer; } .card-main:hover .title, .card-main:active .title, +.more-actions label:hover, .more-actions label:active, a:active, a:hover , summary:active, summary:hover { color: #fff; @@ -148,3 +151,7 @@ ul#submgr{list-style: none} width: 100%; height: 100%; } + +.more-actions input[type="checkbox"] { + margin: 0 .7em; /*like input.emoji's padding*/ +} diff --git a/app/youtube/__init__.py b/app/youtube/__init__.py index 12a23b2..7be9404 100644 --- a/app/youtube/__init__.py +++ b/app/youtube/__init__.py @@ -34,9 +34,9 @@ def feed(): FROM videos JOIN channels ON videos.channel_id = channels.id LEFT JOIN flags ON (videos.id = flags.video_id) AND (flags.user = ?) - WHERE channel_id IN - (SELECT channel_id FROM subscriptions WHERE user = ?) - AND flags.display IS NOT 'hidden' + WHERE (channel_id IN (SELECT channel_id FROM subscriptions WHERE user=?) + OR flags.display = 'pinned') + AND flags.display IS NOT 'hidden' ORDER BY (display = 'pinned') DESC, crawled DESC LIMIT 36 OFFSET 36*?""", (token, token, page)) @@ -52,6 +52,11 @@ def feed(): @frontend.route('/watch') def watch(): + if current_user.is_anonymous: + token = 'guest' + else: + token = current_user.token + if not 'v' in request.args: return "missing video id", 400 @@ -89,10 +94,21 @@ def watch(): else: if error and not metadata: # e.g. malformed, private/deleted video, ... return errdetails,400 # TODO: nicer - return render_template('watch.html.j2', - video_id=video_id, video_url=muxed, - video_error=error, errdetails=errdetails, invidious_url=invidious_url, - **prepare_metadata(metadata)) + meta = prepare_metadata(metadata) + with sqlite3.connect(cf['global']['database']) as conn: + c = conn.cursor() + c.execute(""" + SELECT COUNT(( + SELECT 1 FROM subscriptions WHERE channel_id = ? AND user = ? + )), COUNT(( + SELECT 1 FROM flags WHERE video_id = ? AND display = 'pinned' AND user = ? + ))""", (meta['channel_id'], token, video_id, token)) + (is_subscribed, is_pinned) = c.fetchone() + return render_template('watch.html.j2', + video_id=video_id, video_urls=muxed, + video_error=error, errdetails=errdetails, invidious_url=invidious_url, + is_pinned=is_pinned, is_subscribed=is_subscribed, + **meta) @frontend.route('/channel/') def channel(channel_id): @@ -175,12 +191,12 @@ def feed_post(): 'hide': 'hidden', }[action] with sqlite3.connect(cf['global']['database']) as conn: - #with conn.cursor() as c: - c = conn.cursor() - c.execute(""" - INSERT OR REPLACE INTO flags (user, video_id, display) - VALUES (?, ?, ?) - """, (token, video_id, display)) + c = conn.cursor() + store_video_metadata(video_id) # only needed for pinning + c.execute(""" + INSERT OR REPLACE INTO flags (user, video_id, display) + VALUES (?, ?, ?) + """, (token, video_id, display)) else: flash("unsupported action", "error") return redirect(request.url, code=303) diff --git a/app/youtube/templates/watch.html.j2 b/app/youtube/templates/watch.html.j2 index 9750682..1a04230 100644 --- a/app/youtube/templates/watch.html.j2 +++ b/app/youtube/templates/watch.html.j2 @@ -97,16 +97,26 @@
More Actions -
    +
    • {# TODO: make checked by default (need to inform the user about potential privacy concerns) #} -{% if current_user.name == "girst" %}{# TODO: doesn't work if video not already crawled!#} -
    • - - {#TODO: 'pinned' undefined!#} +{# TODO: don't redirect away (204 response?) #} +
    • + +
    • -{% endif %} +
    • + + +
      +
    • show raw video
    • view json metadata
    • watch on invidious -- 2.39.3