]>
git.gir.st - subscriptionfeed.git/blob - app/invidious/__init__.py
2 from flask
import Blueprint
, render_template
, request
, flash
, g
, url_for
4 from ..common
.common
import fallback_route
6 frontend
= Blueprint('invidious', __name__
,
7 template_folder
='templates',
8 static_folder
='static',
9 static_url_path
='/static/iv')
11 # TODO: minimal implementation (invidio.us hardcoded, videos only, no optional_params)
12 @frontend.route('/search')
14 #token = getattr(current_user, 'token', 'guest')
15 q
= request
.args
.get('q')
16 page
= int(request
.args
.get('page', 1))
17 provider
= request
.args
.get('provider', 'invidio.us:443')
20 sort_by: "relevance", "rating", "upload_date", "view_count"
21 date: "hour", "today", "week", "month", "year"
22 duration: "short", "long"
23 type: "video", "playlist", "channel", "all", (default: video)
24 features: "hd", "subtitles", "creative_commons", "3d", "live",
25 "purchased", "4k", "360", "location", "hdr" (comma separated)
26 region: ISO 3166 country code (default: "US")
29 p
: request
.args
.get(p
)
30 for p
in ['sort_by', 'date', 'duration', 'type', 'features', 'region']
34 r
= requests
.get(f
"https://invidio.us/api/v1/search", {
40 return "error fetching search results", 502 # TODO: better
41 # XXX: should check r.json if it really are search results (if other provider)
42 # XXX: should transform invidious-json to our naming scheme
47 return render_template('search.html.j2', rows
=results
, query
=q
, page
=page
,
48 optional_params
=optional_params
)
50 @frontend.route('/channel/<channel_id>')
51 @frontend.route('/user/<channel_id>')
52 def channel(channel_id
):
53 # 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)
54 if 'page' not in request
.args
:
55 return fallback_route(channel_id
)
57 page
= int(request
.args
.get('page', 1))
58 sort_by
= request
.args
.get('sort_by', 'newest')
59 provider
= request
.args
.get('provider', 'invidio.us:443')
61 r
= requests
.get(f
"https://invidio.us/api/v1/channels/{channel_id}/videos", {
64 }, allow_redirects
=False)
65 if not r
.ok
or r
.status_code
!= 200:
66 flash("invidious did not find the channel or is blocked. showing minimal response", "error")
67 return fallback_route(channel_id
)
69 return render_template('channel.html.j2', rows
=r
.json(), sort_by
=sort_by
, page
=page
)
71 @frontend.route('/playlist')
73 # 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)
74 if 'page' not in request
.args
:
75 return fallback_route()
77 playlist_id
= request
.args
.get('list')
79 return "bad list id", 400 # todo
81 page
= int(request
.args
.get('page', 1))
82 provider
= request
.args
.get('provider', 'invidio.us:443')
84 r
= requests
.get(f
"https://invidio.us/api/v1/playlists/{playlist_id}", {
86 }, allow_redirects
=False)
87 if not r
.ok
or r
.status_code
!= 200:
88 flash("invidious did not find the channel or is blocked. showing minimal response", "error")
89 return fallback_route()
91 return render_template('channel.html.j2', rows
=r
.json().get('videos',[]), page
=page
)
93 @frontend.before_app_request
94 def inject_search_button():
95 if not 'header_items' in g
:
97 g
.header_items
.append({
99 'url': url_for('invidious.search'),
100 'parent': frontend
.name
,