diff options
author | Biswakalyan Bhuyan <biswa@surgot.in> | 2024-09-19 15:33:11 +0530 |
---|---|---|
committer | Biswakalyan Bhuyan <biswa@surgot.in> | 2024-09-19 15:33:11 +0530 |
commit | a4e01da27c08e43a67b2618ad1e71c1f8f86d5cd (patch) | |
tree | 5b8f407dbb7e9d1ab2106ac0cc8564897e7a2098 /youtube/__init__.py | |
download | yt-local-a4e01da27c08e43a67b2618ad1e71c1f8f86d5cd.tar.gz yt-local-a4e01da27c08e43a67b2618ad1e71c1f8f86d5cd.tar.bz2 yt-local-a4e01da27c08e43a67b2618ad1e71c1f8f86d5cd.zip |
Diffstat (limited to 'youtube/__init__.py')
-rw-r--r-- | youtube/__init__.py | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/youtube/__init__.py b/youtube/__init__.py new file mode 100644 index 0000000..64aed56 --- /dev/null +++ b/youtube/__init__.py @@ -0,0 +1,166 @@ +from youtube import util +from .get_app_version import app_version +import flask +from flask import request +import jinja2 +import settings +import traceback +import re +from sys import exc_info +yt_app = flask.Flask(__name__) +yt_app.config['TEMPLATES_AUTO_RELOAD'] = True +yt_app.url_map.strict_slashes = False +# yt_app.jinja_env.trim_blocks = True +# yt_app.jinja_env.lstrip_blocks = True + + +yt_app.add_url_rule('/settings', 'settings_page', settings.settings_page, methods=['POST', 'GET']) + + +@yt_app.route('/') +def homepage(): + return flask.render_template('home.html', title="YT Local") + + +@yt_app.route('/licenses') +def licensepage(): + return flask.render_template( + 'licenses.html', + title="Licenses - YT Local" + ) + + +theme_names = { + 0: 'light_theme', + 1: 'gray_theme', + 2: 'dark_theme', +} + + +@yt_app.context_processor +def inject_theme_preference(): + return { + 'theme_path': '/youtube.com/static/' + theme_names[settings.theme] + '.css', + 'settings': settings, + # Detect version + 'current_version': app_version()['version'], + 'current_branch': app_version()['branch'], + 'current_commit': app_version()['commit'], + } + + +@yt_app.template_filter('commatize') +def commatize(num): + if num is None: + return '' + if isinstance(num, str): + try: + num = int(num) + except ValueError: + return num + return '{:,}'.format(num) + + +def timestamp_replacement(match): + time_seconds = 0 + for part in match.group(0).split(':'): + time_seconds = 60*time_seconds + int(part) + return ( + """ + <a href="#" id="timestamp%s">%s</a> + <script> + // @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later + (function main() { + 'use strict'; + const player = document.getElementById('js-video-player'); + const a = document.getElementById('timestamp%s'); + a.addEventListener('click', function(event) { + player.currentTime = %s + }); + }()); + // @license-end + </script> + """ % ( + str(time_seconds), + match.group(0), + str(time_seconds), + str(time_seconds) + ) + ) + + +TIMESTAMP_RE = re.compile(r'\b(\d?\d:)?\d?\d:\d\d\b') + + +@yt_app.template_filter('timestamps') +def timestamps(text): + return TIMESTAMP_RE.sub(timestamp_replacement, text) + + +@yt_app.errorhandler(500) +def error_page(e): + slim = request.args.get('slim', False) # whether it was an ajax request + if (exc_info()[0] == util.FetchError + and exc_info()[1].code == '429' + and settings.route_tor + ): + error_message = ('Error: YouTube blocked the request because the Tor' + ' exit node is overutilized. Try getting a new exit node by' + ' using the New Identity button in the Tor Browser.') + if exc_info()[1].error_message: + error_message += '\n\n' + exc_info()[1].error_message + if exc_info()[1].ip: + error_message += '\n\nExit node IP address: ' + exc_info()[1].ip + return flask.render_template('error.html', error_message=error_message, slim=slim), 502 + elif exc_info()[0] == util.FetchError and exc_info()[1].error_message: + return (flask.render_template( + 'error.html', + error_message=exc_info()[1].error_message, + slim=slim + ), 502) + elif (exc_info()[0] == util.FetchError + and exc_info()[1].code == '404' + ): + error_message = ('Error: The page you are looking for isn\'t here. ¯\_(ツ)_/¯') + return flask.render_template('error.html', + error_code=exc_info()[1].code, + error_message=error_message, + slim=slim), 404 + return flask.render_template('error.html', traceback=traceback.format_exc(), + error_code=exc_info()[1].code, + slim=slim), 500 + # return flask.render_template('error.html', traceback=traceback.format_exc(), slim=slim), 500 + + +font_choices = { + 0: 'initial', + 1: '"liberation serif", "times new roman", calibri, carlito, serif', + 2: 'arial, "liberation sans", sans-serif', + 3: 'verdana, sans-serif', + 4: 'tahoma, sans-serif', +} + + +@yt_app.route('/shared.css') +def get_css(): + return flask.Response( + flask.render_template( + 'shared.css', + font_family=font_choices[settings.font] + ), + mimetype='text/css', + ) + + +# This is okay because the flask urlize function puts the href as the first +# property +YOUTUBE_LINK_RE = re.compile(r'<a href="(' + util.YOUTUBE_URL_RE_STR + ')"') +old_urlize = jinja2.filters.urlize + + +def prefix_urlize(*args, **kwargs): + result = old_urlize(*args, **kwargs) + return YOUTUBE_LINK_RE.sub(r'<a href="/\1"', result) + + +jinja2.filters.urlize = prefix_urlize |