]>
git.gir.st - subscriptionfeed.git/blob - app/dangerous/__init__.py
1 # this is an alternative to proxying through invidious. the search endpoint has only been (loosely) tested by
2 #17:50 < perflyst[m]> appears to be working
3 #, so i hope™ this works. if not, that's why it's in the 'dangerous' blueprint
5 from flask
import Blueprint
, render_template
, request
, flash
, g
, url_for
, redirect
7 from ..common
.common
import *
8 from ..common
.innertube
import *
10 from .protobuf
import make_sp
, make_channel_params
, make_playlist_params
12 frontend
= Blueprint('dangerous', __name__
,
13 template_folder
='templates',
14 static_folder
='static',
15 static_url_path
='/static/ys')
17 @frontend.route('/search')
19 #token = getattr(current_user, 'token', 'guest')
20 q
= request
.args
.get('q')
21 page
= int(request
.args
.get('page', 1))
24 k
:v
for k
,v
in request
.args
.items()
25 if k
in ['sort','date','type','len']
26 }, extras
=['dont_fix_spelling']*0) # extras disabled
29 yt_results
= fetch_searchresults(q
, page
, sp
)
31 results
, extras
= prepare_searchresults(yt_results
)
38 return render_template('search.html.j2', rows
=results
, query
=q
, page
=page
)
40 # TODO: channels, playlists:
41 # https://github.com/iv-org/invidious/blob/452d1e8307d6344dd51c5437ccd032a566291c34/src/invidious/channels.cr#L399
43 @frontend.route('/channel/<channel_id>/')
44 @frontend.route('/channel/<channel_id>/<subpage>')
45 def channel(channel_id
, subpage
="videos"):
46 if subpage
== "videos":
47 page
= int(request
.args
.get('page', 1))
48 sort_by
= request
.args
.get('sort', "newest")
50 elif subpage
== "playlists":
51 page
= None # TODO: cursor
52 sort_by
= request
.args
.get('sort', "modified")
54 elif subpage
== "search":
55 query
= request
.args
.get('q')
56 page
= int(request
.args
.get('page', 1))
58 else: # we don't support /home, /about, ..., so redirect to /videos.
59 return redirect(url_for('.channel', channel_id
=channel_id
))
62 result
= fetch_ajax(make_channel_params(channel_id
, subpage
, page
, sort_by
, query
))
65 result
= fetch_ajax(make_channel_params(channel_id
, subpage
, page
, sort_by
, query
, v2
=True))
66 except RuntimeError: # XXX: this should never happen™ -- log to somewhere
67 flash("unable to fetch results from 'classic' ajax; displaying fallback results (15 newest)", "error")
68 return fallback_route(channel_id
, subpage
)
70 title
, descr
, thumb
, rows
, more
= prepare_channel(result
, channel_id
)
71 # TODO: add is_pinned/is_hidden
73 return render_template('channel.html.j2',
77 channel_id
=channel_id
,
83 @frontend.route('/user/<user>')
84 @frontend.route('/user/<user>/<subpage>')
85 @frontend.route('/c/<user>')
86 @frontend.route('/c/<user>/<subpage>')
87 def channel_redirect(user
, subpage
=None):
89 The browse_ajax 'API' needs the UCID. We can get that from the RSS feeds.
91 xmlfeed
= fetch_xml("user", user
)
92 _
, _
, _
, channel_id
, _
= parse_xml(xmlfeed
)
94 url_for('.channel', channel_id
=channel_id
, subpage
=subpage
), 308
97 @frontend.route('/playlist')
99 #TODO: if anything goes wrong, fall back to xmlfeed
100 playlist_id
= request
.args
.get('list')
102 return "bad list id", 400 # todo
103 page
= int(request
.args
.get('page', 1))
105 xmlfeed
= fetch_xml("playlist_id", playlist_id
)
107 return "not found or something", 404 # XXX
108 title
, author
, _
, channel_id
, _
= parse_xml(xmlfeed
)
110 offset
= (page
-1)*100 # each call returns 100 items
111 result
= fetch_ajax(make_playlist_params(playlist_id
, offset
))
113 rows
, more
= prepare_playlist(result
)
115 return render_template('playlist.html.j2',
118 channel_id
=channel_id
,
123 @frontend.before_app_request
125 if not 'header_items' in g
:
127 g
.header_items
.append({
129 'url': url_for('dangerous.search'),
130 'parent': frontend
.name
,