import requests from flask import Blueprint, render_template, request, flash from ..common.common import fallback_route frontend = Blueprint('invidious', __name__, template_folder='templates', static_folder='static', static_url_path='/static/iv') # TODO: minimal implementation (invidio.us hardcoded, videos only, no optional_params) @frontend.route('/search') def search(): #token = getattr(current_user, 'token', 'guest') q = request.args.get('q') page = int(request.args.get('page', 1)) provider = request.args.get('provider', 'invidio.us:443') """ sort_by: "relevance", "rating", "upload_date", "view_count" date: "hour", "today", "week", "month", "year" duration: "short", "long" type: "video", "playlist", "channel", "all", (default: video) features: "hd", "subtitles", "creative_commons", "3d", "live", "purchased", "4k", "360", "location", "hdr" (comma separated) region: ISO 3166 country code (default: "US") """ optional_params = { p: request.args.get(p) for p in ['sort_by', 'date', 'duration', 'type', 'features', 'region'] } if not q: return "no search query", 400 r = requests.get(f"https://invidio.us/api/v1/search", { 'q': q, 'page': page, # **optional_params, }) if not r.ok: return "error fetching search results", 502 # TODO: better # XXX: should check r.json if it really are search results (if other provider) # XXX: should transform invidious-json to our naming scheme return render_template('search.html.j2', rows=r.json(), query=q, page=page, optional_params=optional_params) @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') r = requests.get(f"https://invidio.us/api/v1/channels/{channel_id}/videos", { 'sort_by': sort_by, 'page': page, }, allow_redirects=False) if not r.ok or r.status_code != 200: flash("invidious did not find the channel or is blocked. showing minimal response", "error") return fallback_route(channel_id) return render_template('channel.html.j2', rows=r.json(), sort_by=sort_by, page=page) @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 page = int(request.args.get('page', 1)) provider = request.args.get('provider', 'invidio.us:443') r = requests.get(f"https://invidio.us/api/v1/playlists/{playlist_id}", { 'page': page, }, allow_redirects=False) if not r.ok or r.status_code != 200: flash("invidious did not find the channel or is blocked. showing minimal response", "error") return fallback_route(playlist_id) return render_template('channel.html.j2', rows=r.json().get('videos',[]), page=page)