From ea61da126231aa75b6619e30dd354bea5d90998a Mon Sep 17 00:00:00 2001 From: girst Date: Thu, 24 Sep 2020 18:49:51 +0200 Subject: [PATCH 01/16] remove v1 usage from /channels/ doesn't appear to be used any more after a small and informal survey on --- app/browse/__init__.py | 10 ++-------- app/browse/protobuf.py | 31 +++++++++++++------------------ 2 files changed, 15 insertions(+), 26 deletions(-) diff --git a/app/browse/__init__.py b/app/browse/__init__.py index 44083cb..debc741 100644 --- a/app/browse/__init__.py +++ b/app/browse/__init__.py @@ -63,17 +63,11 @@ def channel(channel_id, subpage="videos"): if not re.match(r"(UC[A-Za-z0-9_-]{22})", channel_id): return redirect(url_for('.channel_redirect', user=channel_id)) - result = fetch_ajax(make_channel_params(channel_id, subpage, page, sort_by, query)) - - # Note: as of 2020-08-15, using the v1 format sometimes returns an error. if that's the case, try v3. - alert = listget(listget(result,1,{}).get('response',{}).get('alerts',[]),0,{}).get('alertRenderer',{}) - if alert.get('type','') == "ERROR": # alert['text']['simpleText'] == "Unknown error." - result = fetch_ajax(make_channel_params(channel_id, subpage, page, sort_by, query, v3=True)) + result = fetch_ajax(make_channel_params(channel_id, subpage, page, sort_by, query, v3=(subpage == "videos"))) title, descr, thumb, rows, more = prepare_channel(result, channel_id) - # TODO: add is_pinned/is_hidden - if title is None: # if both v1 and v3 failed, fall back to xmlfeed: + if title is None or not rows: # if fetching from innertube failed, fall back to xmlfeed: flash("unable to fetch results from ajax; displaying fallback results (15 newest)", "error") return fallback_route(channel_id, subpage) diff --git a/app/browse/protobuf.py b/app/browse/protobuf.py index c7623e4..ae85ec8 100644 --- a/app/browse/protobuf.py +++ b/app/browse/protobuf.py @@ -55,7 +55,15 @@ def make_sp(sort=None, date=None, type=None, len=None, features=[], extras=[]): ).dumps()) # }}} SEARCH -# CHANNEL v1 {{{ +# CHANNEL v1/v3 {{{ +@message +@dataclass +class ChannelDataInner: + offset: int64 = field(1) +@message +@dataclass +class ChannelDataContainer: + data: str = field(1) # base64 of ChannelDataInner @message @dataclass class Subparams: @@ -85,7 +93,7 @@ class Continuation: def make_channel_params(subject, typ="videos", page=1, sort=None, query=None, v3=False): typestr = dict(videos="videos", playlists="playlists", search="search") typeint = dict(videos=0, playlists=1, search=None) # not supporting autogen'd - sortorder = dict(newest=None, popular=1, oldest=2) # v1: newest=None, v3: newest=3 + sortorder = dict(popular=1, oldest=2, newest=3) if typ == "playlists": sortorder = dict(oldest=2, newest=3, modified=4) elif typ == "search": @@ -97,9 +105,8 @@ def make_channel_params(subject, typ="videos", page=1, sort=None, query=None, v3 params=b64e(Subparams( type_s=typestr.get(typ), type_i=typeint.get(typ), - sort=sortorder.get(sort) or 3, - #page=str(page) if page else None # Note: ucid/playlists doesn't support pagination - page=None if v3 or not page else str(page), + sort=sortorder.get(sort), + page=str(page) if not v3 and page else None, field61=b64e( ChannelDataContainer( data=b64e( @@ -113,19 +120,7 @@ def make_channel_params(subject, typ="videos", page=1, sort=None, query=None, v3 query=query, ), ).dumps()) -# }}} CHANNEL v1 - -# CHANNEL v3 {{{ -# NOTE: on hosts that are supposed to use v3, accessing v1 results in an "Unknown error.". on v1-hosts, accessing v3 always returns the first page. -@message -@dataclass -class ChannelDataInner: - offset: int64 = field(1) -@message -@dataclass -class ChannelDataContainer: - data: str = field(1) # base64 of ChannelDataInner -# }}} CHANNEL v3 +# }}} CHANNEL v1/v3 # PLAYLIST {{{ @message -- 2.39.3 From 60621e8c9487583b2e558adf0f7b7c278c70aeed Mon Sep 17 00:00:00 2001 From: girst Date: Thu, 24 Sep 2020 20:11:09 +0200 Subject: [PATCH 02/16] remove more button from xmlfeeds makes it necessary to remove the fallback from invidious (untested) --- app/invidious/__init__.py | 8 -------- app/youtube/templates/xmlfeed.html.j2 | 4 ---- 2 files changed, 12 deletions(-) diff --git a/app/invidious/__init__.py b/app/invidious/__init__.py index 1099f07..aa97677 100644 --- a/app/invidious/__init__.py +++ b/app/invidious/__init__.py @@ -50,10 +50,6 @@ def search(): @frontend.route('/channel/') @frontend.route('/user/') def channel(channel_id): - # proxying invidious is way slower, so we don't do it for page 0 (i.e the 15 newest videos we can get from youtube ourselves) - if 'page' not in request.args: - return fallback_route(channel_id) - page = int(request.args.get('page', 1)) sort_by = request.args.get('sort_by', 'newest') provider = request.args.get('provider', 'invidio.us:443') @@ -70,10 +66,6 @@ def channel(channel_id): @frontend.route('/playlist') def playlist(): - # proxying invidious is way slower, so we don't do it for page 0 (i.e the 15 newest videos we can get from youtube ourselves) - if 'page' not in request.args: - return fallback_route() - playlist_id = request.args.get('list') if not playlist_id: return "bad list id", 400 # todo diff --git a/app/youtube/templates/xmlfeed.html.j2 b/app/youtube/templates/xmlfeed.html.j2 index 646382a..e4a76cb 100644 --- a/app/youtube/templates/xmlfeed.html.j2 +++ b/app/youtube/templates/xmlfeed.html.j2 @@ -15,8 +15,4 @@ {% if not rows|length %}no more results{% endif %} - -
-{{ macros.pagination("more", {'page':(+1,0)}, +1) }} -
{% endblock %} -- 2.39.3 From 7c9c129ee8f3024033cd41521064376d359fa41e Mon Sep 17 00:00:00 2001 From: girst Date: Fri, 25 Sep 2020 16:41:08 +0200 Subject: [PATCH 03/16] support "?t=1h2m3s" and "?t=123s" style start-offsets documentation on media fragments: https://www.w3.org/TR/2012/REC-media-frags-20120925/ --- app/youtube/__init__.py | 12 ++++++++++++ app/youtube/templates/watch.html.j2 | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/app/youtube/__init__.py b/app/youtube/__init__.py index 37cdc19..1229206 100644 --- a/app/youtube/__init__.py +++ b/app/youtube/__init__.py @@ -354,3 +354,15 @@ def format_time(i): m = i // 60 % 60 s = i % 60 return '%d:%02d:%02d' % (h,m,s) if h else '%02d:%02d' % (m,s) + +@frontend.app_template_filter('timeoffset') +def timeoffset(s): + if s is None: + return None + match = re.match(r"^(\d+)s?$", s) # e.g. 2040s + if match: + return match.group(1) + match = re.match(r"^(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?$", s) # e.g. 34m, 1h23s + if match: + return ":".join([n.zfill(2) for n in match.groups('0')]) + return None diff --git a/app/youtube/templates/watch.html.j2 b/app/youtube/templates/watch.html.j2 index 1cf7db1..a89e78f 100644 --- a/app/youtube/templates/watch.html.j2 +++ b/app/youtube/templates/watch.html.j2 @@ -7,7 +7,7 @@ {% if video_url %}