pep8
This commit is contained in:
parent
cf8e8ea5b1
commit
f4b36a220d
@ -13,16 +13,21 @@ import hashlib
|
|||||||
|
|
||||||
latest_version = sys.argv[1]
|
latest_version = sys.argv[1]
|
||||||
|
|
||||||
|
|
||||||
def check(code):
|
def check(code):
|
||||||
if code != 0:
|
if code != 0:
|
||||||
raise Exception('Got nonzero exit code from command')
|
raise Exception('Got nonzero exit code from command')
|
||||||
|
|
||||||
|
|
||||||
def check_subp(x):
|
def check_subp(x):
|
||||||
if x.returncode != 0:
|
if x.returncode != 0:
|
||||||
raise Exception('Got nonzero exit code from command')
|
raise Exception('Got nonzero exit code from command')
|
||||||
|
|
||||||
|
|
||||||
def log(line):
|
def log(line):
|
||||||
print('[generate_release.py] ' + line)
|
print('[generate_release.py] ' + line)
|
||||||
|
|
||||||
|
|
||||||
# https://stackoverflow.com/questions/7833715/python-deleting-certain-file-extensions
|
# https://stackoverflow.com/questions/7833715/python-deleting-certain-file-extensions
|
||||||
def remove_files_with_extensions(path, extensions):
|
def remove_files_with_extensions(path, extensions):
|
||||||
for root, dirs, files in os.walk(path):
|
for root, dirs, files in os.walk(path):
|
||||||
@ -30,6 +35,7 @@ def remove_files_with_extensions(path, extensions):
|
|||||||
if os.path.splitext(file)[1] in extensions:
|
if os.path.splitext(file)[1] in extensions:
|
||||||
os.remove(os.path.join(root, file))
|
os.remove(os.path.join(root, file))
|
||||||
|
|
||||||
|
|
||||||
def download_if_not_exists(file_name, url, sha256=None):
|
def download_if_not_exists(file_name, url, sha256=None):
|
||||||
if not os.path.exists('./' + file_name):
|
if not os.path.exists('./' + file_name):
|
||||||
log('Downloading ' + file_name + '..')
|
log('Downloading ' + file_name + '..')
|
||||||
@ -45,6 +51,7 @@ def download_if_not_exists(file_name, url, sha256=None):
|
|||||||
else:
|
else:
|
||||||
log('Using existing ' + file_name)
|
log('Using existing ' + file_name)
|
||||||
|
|
||||||
|
|
||||||
def wine_run_shell(command):
|
def wine_run_shell(command):
|
||||||
if os.name == 'posix':
|
if os.name == 'posix':
|
||||||
check(os.system('wine ' + command.replace('\\', '/')))
|
check(os.system('wine ' + command.replace('\\', '/')))
|
||||||
@ -53,12 +60,14 @@ def wine_run_shell(command):
|
|||||||
else:
|
else:
|
||||||
raise Exception('Unsupported OS')
|
raise Exception('Unsupported OS')
|
||||||
|
|
||||||
|
|
||||||
def wine_run(command_parts):
|
def wine_run(command_parts):
|
||||||
if os.name == 'posix':
|
if os.name == 'posix':
|
||||||
command_parts = ['wine',] + command_parts
|
command_parts = ['wine',] + command_parts
|
||||||
if subprocess.run(command_parts).returncode != 0:
|
if subprocess.run(command_parts).returncode != 0:
|
||||||
raise Exception('Got nonzero exit code from command')
|
raise Exception('Got nonzero exit code from command')
|
||||||
|
|
||||||
|
|
||||||
# ---------- Get current release version, for later ----------
|
# ---------- Get current release version, for later ----------
|
||||||
log('Getting current release version')
|
log('Getting current release version')
|
||||||
describe_result = subprocess.run(['git', 'describe', '--tags'], stdout=subprocess.PIPE)
|
describe_result = subprocess.run(['git', 'describe', '--tags'], stdout=subprocess.PIPE)
|
||||||
@ -100,7 +109,8 @@ visual_c_runtime_sha256 = '2549eb4d2ce4cf3a87425ea01940f74368bf1cda378ef8a8a1f1a
|
|||||||
download_if_not_exists('get-pip.py', get_pip_url)
|
download_if_not_exists('get-pip.py', get_pip_url)
|
||||||
download_if_not_exists('python-dist-' + latest_version + '.zip', latest_dist_url)
|
download_if_not_exists('python-dist-' + latest_version + '.zip', latest_dist_url)
|
||||||
download_if_not_exists('vc15_(14.10.25017.0)_2017_x86.7z',
|
download_if_not_exists('vc15_(14.10.25017.0)_2017_x86.7z',
|
||||||
visual_c_runtime_url, sha256=visual_c_runtime_sha256)
|
visual_c_runtime_url,
|
||||||
|
sha256=visual_c_runtime_sha256)
|
||||||
|
|
||||||
if os.path.exists('./python'):
|
if os.path.exists('./python'):
|
||||||
log('Removing old python distribution')
|
log('Removing old python distribution')
|
||||||
|
17
server.py
17
server.py
@ -21,8 +21,6 @@ import re
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def youtu_be(env, start_response):
|
def youtu_be(env, start_response):
|
||||||
id = env['PATH_INFO'][1:]
|
id = env['PATH_INFO'][1:]
|
||||||
env['PATH_INFO'] = '/watch'
|
env['PATH_INFO'] = '/watch'
|
||||||
@ -32,6 +30,7 @@ def youtu_be(env, start_response):
|
|||||||
env['QUERY_STRING'] += '&v=' + id
|
env['QUERY_STRING'] += '&v=' + id
|
||||||
yield from yt_app(env, start_response)
|
yield from yt_app(env, start_response)
|
||||||
|
|
||||||
|
|
||||||
def proxy_site(env, start_response, video=False):
|
def proxy_site(env, start_response, video=False):
|
||||||
headers = {
|
headers = {
|
||||||
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)',
|
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)',
|
||||||
@ -79,12 +78,14 @@ def proxy_site(env, start_response, video=False):
|
|||||||
|
|
||||||
cleanup_func(response)
|
cleanup_func(response)
|
||||||
|
|
||||||
|
|
||||||
def proxy_video(env, start_response):
|
def proxy_video(env, start_response):
|
||||||
yield from proxy_site(env, start_response, video=True)
|
yield from proxy_site(env, start_response, video=True)
|
||||||
|
|
||||||
|
|
||||||
site_handlers = {
|
site_handlers = {
|
||||||
'youtube.com':yt_app,
|
'youtube.com': yt_app,
|
||||||
'youtu.be':youtu_be,
|
'youtu.be': youtu_be,
|
||||||
'ytimg.com': proxy_site,
|
'ytimg.com': proxy_site,
|
||||||
'yt3.ggpht.com': proxy_site,
|
'yt3.ggpht.com': proxy_site,
|
||||||
'lh3.googleusercontent.com': proxy_site,
|
'lh3.googleusercontent.com': proxy_site,
|
||||||
@ -92,6 +93,7 @@ site_handlers = {
|
|||||||
'googlevideo.com': proxy_video,
|
'googlevideo.com': proxy_video,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def split_url(url):
|
def split_url(url):
|
||||||
''' Split https://sub.example.com/foo/bar.html into ('sub.example.com', '/foo/bar.html')'''
|
''' Split https://sub.example.com/foo/bar.html into ('sub.example.com', '/foo/bar.html')'''
|
||||||
# XXX: Is this regex safe from REDOS?
|
# XXX: Is this regex safe from REDOS?
|
||||||
@ -103,11 +105,11 @@ def split_url(url):
|
|||||||
return match.group(1), match.group(2)
|
return match.group(1), match.group(2)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def error_code(code, start_response):
|
def error_code(code, start_response):
|
||||||
start_response(code, ())
|
start_response(code, ())
|
||||||
return code.encode()
|
return code.encode()
|
||||||
|
|
||||||
|
|
||||||
def site_dispatch(env, start_response):
|
def site_dispatch(env, start_response):
|
||||||
client_address = env['REMOTE_ADDR']
|
client_address = env['REMOTE_ADDR']
|
||||||
try:
|
try:
|
||||||
@ -117,7 +119,7 @@ def site_dispatch(env, start_response):
|
|||||||
method = env['REQUEST_METHOD']
|
method = env['REQUEST_METHOD']
|
||||||
path = env['PATH_INFO']
|
path = env['PATH_INFO']
|
||||||
|
|
||||||
if method=="POST" and client_address not in ('127.0.0.1', '::1'):
|
if method == "POST" and client_address not in ('127.0.0.1', '::1'):
|
||||||
yield error_code('403 Forbidden', start_response)
|
yield error_code('403 Forbidden', start_response)
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -159,12 +161,15 @@ def site_dispatch(env, start_response):
|
|||||||
class FilteredRequestLog:
|
class FilteredRequestLog:
|
||||||
'''Don't log noisy thumbnail and avatar requests'''
|
'''Don't log noisy thumbnail and avatar requests'''
|
||||||
filter_re = re.compile(r'"GET /https://(i\.ytimg\.com/|www\.youtube\.com/data/subscription_thumbnails/|yt3\.ggpht\.com/|www\.youtube\.com/api/timedtext).*" 200')
|
filter_re = re.compile(r'"GET /https://(i\.ytimg\.com/|www\.youtube\.com/data/subscription_thumbnails/|yt3\.ggpht\.com/|www\.youtube\.com/api/timedtext).*" 200')
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def write(self, s):
|
def write(self, s):
|
||||||
if not self.filter_re.search(s):
|
if not self.filter_re.search(s):
|
||||||
sys.stderr.write(s)
|
sys.stderr.write(s)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
if settings.allow_foreign_addresses:
|
if settings.allow_foreign_addresses:
|
||||||
server = WSGIServer(('0.0.0.0', settings.port_number), site_dispatch,
|
server = WSGIServer(('0.0.0.0', settings.port_number), site_dispatch,
|
||||||
|
26
settings.py
26
settings.py
@ -235,19 +235,23 @@ def comment_string(comment):
|
|||||||
result += '# ' + line + '\n'
|
result += '# ' + line + '\n'
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def save_settings(settings_dict):
|
def save_settings(settings_dict):
|
||||||
with open(settings_file_path, 'w', encoding='utf-8') as file:
|
with open(settings_file_path, 'w', encoding='utf-8') as file:
|
||||||
for setting_name, setting_info in SETTINGS_INFO.items():
|
for setting_name, setting_info in SETTINGS_INFO.items():
|
||||||
file.write(comment_string(setting_info['comment']) + setting_name + ' = ' + repr(settings_dict[setting_name]) + '\n\n')
|
file.write(comment_string(setting_info['comment']) + setting_name + ' = ' + repr(settings_dict[setting_name]) + '\n\n')
|
||||||
|
|
||||||
|
|
||||||
def add_missing_settings(settings_dict):
|
def add_missing_settings(settings_dict):
|
||||||
result = default_settings()
|
result = default_settings()
|
||||||
result.update(settings_dict)
|
result.update(settings_dict)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def default_settings():
|
def default_settings():
|
||||||
return {key: setting_info['default'] for key, setting_info in SETTINGS_INFO.items()}
|
return {key: setting_info['default'] for key, setting_info in SETTINGS_INFO.items()}
|
||||||
|
|
||||||
|
|
||||||
def upgrade_to_2(settings_dict):
|
def upgrade_to_2(settings_dict):
|
||||||
'''Upgrade to settings version 2'''
|
'''Upgrade to settings version 2'''
|
||||||
new_settings = settings_dict.copy()
|
new_settings = settings_dict.copy()
|
||||||
@ -260,6 +264,7 @@ def upgrade_to_2(settings_dict):
|
|||||||
new_settings['settings_version'] = 2
|
new_settings['settings_version'] = 2
|
||||||
return new_settings
|
return new_settings
|
||||||
|
|
||||||
|
|
||||||
def upgrade_to_3(settings_dict):
|
def upgrade_to_3(settings_dict):
|
||||||
new_settings = settings_dict.copy()
|
new_settings = settings_dict.copy()
|
||||||
if 'route_tor' in settings_dict:
|
if 'route_tor' in settings_dict:
|
||||||
@ -267,17 +272,17 @@ def upgrade_to_3(settings_dict):
|
|||||||
new_settings['settings_version'] = 3
|
new_settings['settings_version'] = 3
|
||||||
return new_settings
|
return new_settings
|
||||||
|
|
||||||
|
|
||||||
upgrade_functions = {
|
upgrade_functions = {
|
||||||
1: upgrade_to_2,
|
1: upgrade_to_2,
|
||||||
2: upgrade_to_3,
|
2: upgrade_to_3,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def log_ignored_line(line_number, message):
|
def log_ignored_line(line_number, message):
|
||||||
print("WARNING: Ignoring settings.txt line " + str(node.lineno) + " (" + message + ")")
|
print("WARNING: Ignoring settings.txt line " + str(node.lineno) + " (" + message + ")")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if os.path.isfile("settings.txt"):
|
if os.path.isfile("settings.txt"):
|
||||||
print("Running in portable mode")
|
print("Running in portable mode")
|
||||||
settings_dir = os.path.normpath('./')
|
settings_dir = os.path.normpath('./')
|
||||||
@ -356,16 +361,15 @@ else:
|
|||||||
globals().update(current_settings_dict)
|
globals().update(current_settings_dict)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if route_tor:
|
if route_tor:
|
||||||
print("Tor routing is ON")
|
print("Tor routing is ON")
|
||||||
else:
|
else:
|
||||||
print("Tor routing is OFF - your Youtube activity is NOT anonymous")
|
print("Tor routing is OFF - your Youtube activity is NOT anonymous")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
hooks = {}
|
hooks = {}
|
||||||
|
|
||||||
|
|
||||||
def add_setting_changed_hook(setting, func):
|
def add_setting_changed_hook(setting, func):
|
||||||
'''Called right before new settings take effect'''
|
'''Called right before new settings take effect'''
|
||||||
if setting in hooks:
|
if setting in hooks:
|
||||||
@ -382,11 +386,16 @@ def set_img_prefix(old_value=None, value=None):
|
|||||||
img_prefix = '/'
|
img_prefix = '/'
|
||||||
else:
|
else:
|
||||||
img_prefix = ''
|
img_prefix = ''
|
||||||
|
|
||||||
|
|
||||||
set_img_prefix()
|
set_img_prefix()
|
||||||
|
|
||||||
add_setting_changed_hook('proxy_images', set_img_prefix)
|
add_setting_changed_hook('proxy_images', set_img_prefix)
|
||||||
|
|
||||||
|
|
||||||
categories = ['network', 'interface', 'playback', 'other']
|
categories = ['network', 'interface', 'playback', 'other']
|
||||||
|
|
||||||
|
|
||||||
def settings_page():
|
def settings_page():
|
||||||
if request.method == 'GET':
|
if request.method == 'GET':
|
||||||
settings_by_category = {categ: [] for categ in categories}
|
settings_by_category = {categ: [] for categ in categories}
|
||||||
@ -395,9 +404,10 @@ def settings_page():
|
|||||||
settings_by_category[categ].append(
|
settings_by_category[categ].append(
|
||||||
(setting_name, setting_info, current_settings_dict[setting_name])
|
(setting_name, setting_info, current_settings_dict[setting_name])
|
||||||
)
|
)
|
||||||
return flask.render_template('settings.html',
|
return flask.render_template(
|
||||||
categories = categories,
|
'settings.html',
|
||||||
settings_by_category = settings_by_category,
|
categories=categories,
|
||||||
|
settings_by_category=settings_by_category,
|
||||||
)
|
)
|
||||||
elif request.method == 'POST':
|
elif request.method == 'POST':
|
||||||
for key, value in request.values.items():
|
for key, value in request.values.items():
|
||||||
|
@ -46,6 +46,7 @@ def get_video_sources(info, tor_bypass=False):
|
|||||||
|
|
||||||
return video_sources
|
return video_sources
|
||||||
|
|
||||||
|
|
||||||
def make_caption_src(info, lang, auto=False, trans_lang=None):
|
def make_caption_src(info, lang, auto=False, trans_lang=None):
|
||||||
label = lang
|
label = lang
|
||||||
if auto:
|
if auto:
|
||||||
@ -59,6 +60,7 @@ def make_caption_src(info, lang, auto=False, trans_lang=None):
|
|||||||
'on': False,
|
'on': False,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def lang_in(lang, sequence):
|
def lang_in(lang, sequence):
|
||||||
'''Tests if the language is in sequence, with e.g. en and en-US considered the same'''
|
'''Tests if the language is in sequence, with e.g. en and en-US considered the same'''
|
||||||
if lang is None:
|
if lang is None:
|
||||||
@ -66,6 +68,7 @@ def lang_in(lang, sequence):
|
|||||||
lang = lang[0:2]
|
lang = lang[0:2]
|
||||||
return lang in (l[0:2] for l in sequence)
|
return lang in (l[0:2] for l in sequence)
|
||||||
|
|
||||||
|
|
||||||
def lang_eq(lang1, lang2):
|
def lang_eq(lang1, lang2):
|
||||||
'''Tests if two iso 639-1 codes are equal, with en and en-US considered the same.
|
'''Tests if two iso 639-1 codes are equal, with en and en-US considered the same.
|
||||||
Just because the codes are equal does not mean the dialects are mutually intelligible, but this will have to do for now without a complex language model'''
|
Just because the codes are equal does not mean the dialects are mutually intelligible, but this will have to do for now without a complex language model'''
|
||||||
@ -73,6 +76,7 @@ def lang_eq(lang1, lang2):
|
|||||||
return False
|
return False
|
||||||
return lang1[0:2] == lang2[0:2]
|
return lang1[0:2] == lang2[0:2]
|
||||||
|
|
||||||
|
|
||||||
def equiv_lang_in(lang, sequence):
|
def equiv_lang_in(lang, sequence):
|
||||||
'''Extracts a language in sequence which is equivalent to lang.
|
'''Extracts a language in sequence which is equivalent to lang.
|
||||||
e.g. if lang is en, extracts en-GB from sequence.
|
e.g. if lang is en, extracts en-GB from sequence.
|
||||||
@ -83,6 +87,7 @@ def equiv_lang_in(lang, sequence):
|
|||||||
return l
|
return l
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def get_subtitle_sources(info):
|
def get_subtitle_sources(info):
|
||||||
'''Returns these sources, ordered from least to most intelligible:
|
'''Returns these sources, ordered from least to most intelligible:
|
||||||
native_video_lang (Automatic)
|
native_video_lang (Automatic)
|
||||||
@ -167,6 +172,7 @@ def get_ordered_music_list_attributes(music_list):
|
|||||||
|
|
||||||
return ordered_attributes
|
return ordered_attributes
|
||||||
|
|
||||||
|
|
||||||
def save_decrypt_cache():
|
def save_decrypt_cache():
|
||||||
try:
|
try:
|
||||||
f = open(os.path.join(settings.data_dir, 'decrypt_function_cache.json'), 'w')
|
f = open(os.path.join(settings.data_dir, 'decrypt_function_cache.json'), 'w')
|
||||||
@ -177,6 +183,7 @@ def save_decrypt_cache():
|
|||||||
f.write(json.dumps({'version': 1, 'decrypt_cache':decrypt_cache}, indent=4, sort_keys=True))
|
f.write(json.dumps({'version': 1, 'decrypt_cache':decrypt_cache}, indent=4, sort_keys=True))
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
|
||||||
watch_headers = (
|
watch_headers = (
|
||||||
('Accept', '*/*'),
|
('Accept', '*/*'),
|
||||||
('Accept-Language', 'en-US,en;q=0.5'),
|
('Accept-Language', 'en-US,en;q=0.5'),
|
||||||
@ -184,6 +191,7 @@ watch_headers = (
|
|||||||
('X-YouTube-Client-Version', '2.20180830'),
|
('X-YouTube-Client-Version', '2.20180830'),
|
||||||
) + util.mobile_ua
|
) + util.mobile_ua
|
||||||
|
|
||||||
|
|
||||||
def decrypt_signatures(info, video_id):
|
def decrypt_signatures(info, video_id):
|
||||||
'''return error string, or False if no errors'''
|
'''return error string, or False if no errors'''
|
||||||
if not yt_data_extract.requires_decryption(info):
|
if not yt_data_extract.requires_decryption(info):
|
||||||
@ -206,6 +214,7 @@ def decrypt_signatures(info, video_id):
|
|||||||
err = yt_data_extract.decrypt_signatures(info)
|
err = yt_data_extract.decrypt_signatures(info)
|
||||||
return err
|
return err
|
||||||
|
|
||||||
|
|
||||||
def extract_info(video_id, use_invidious, playlist_id=None, index=None):
|
def extract_info(video_id, use_invidious, playlist_id=None, index=None):
|
||||||
# bpctr=9999999999 will bypass are-you-sure dialogs for controversial
|
# bpctr=9999999999 will bypass are-you-sure dialogs for controversial
|
||||||
# videos
|
# videos
|
||||||
@ -255,7 +264,8 @@ def extract_info(video_id, use_invidious, playlist_id=None, index=None):
|
|||||||
if (info['hls_manifest_url']
|
if (info['hls_manifest_url']
|
||||||
and (info['live'] or not info['formats'] or not info['urls_ready'])
|
and (info['live'] or not info['formats'] or not info['urls_ready'])
|
||||||
):
|
):
|
||||||
manifest = util.fetch_url(info['hls_manifest_url'],
|
manifest = util.fetch_url(
|
||||||
|
info['hls_manifest_url'],
|
||||||
debug_name='hls_manifest.m3u8',
|
debug_name='hls_manifest.m3u8',
|
||||||
report_text='Fetched hls manifest'
|
report_text='Fetched hls manifest'
|
||||||
).decode('utf-8')
|
).decode('utf-8')
|
||||||
@ -292,6 +302,7 @@ def extract_info(video_id, use_invidious, playlist_id=None, index=None):
|
|||||||
print('Error: exceeded max redirects while checking video URL')
|
print('Error: exceeded max redirects while checking video URL')
|
||||||
return info
|
return info
|
||||||
|
|
||||||
|
|
||||||
def video_quality_string(format):
|
def video_quality_string(format):
|
||||||
if format['vcodec']:
|
if format['vcodec']:
|
||||||
result =str(format['width'] or '?') + 'x' + str(format['height'] or '?')
|
result =str(format['width'] or '?') + 'x' + str(format['height'] or '?')
|
||||||
@ -303,6 +314,7 @@ def video_quality_string(format):
|
|||||||
|
|
||||||
return '?'
|
return '?'
|
||||||
|
|
||||||
|
|
||||||
def audio_quality_string(format):
|
def audio_quality_string(format):
|
||||||
if format['acodec']:
|
if format['acodec']:
|
||||||
result = str(format['audio_bitrate'] or '?') + 'k'
|
result = str(format['audio_bitrate'] or '?') + 'k'
|
||||||
@ -314,6 +326,7 @@ def audio_quality_string(format):
|
|||||||
|
|
||||||
return '?'
|
return '?'
|
||||||
|
|
||||||
|
|
||||||
# from https://github.com/ytdl-org/youtube-dl/blob/master/youtube_dl/utils.py
|
# from https://github.com/ytdl-org/youtube-dl/blob/master/youtube_dl/utils.py
|
||||||
def format_bytes(bytes):
|
def format_bytes(bytes):
|
||||||
if bytes is None:
|
if bytes is None:
|
||||||
@ -330,6 +343,8 @@ def format_bytes(bytes):
|
|||||||
|
|
||||||
|
|
||||||
time_table = {'h': 3600, 'm': 60, 's': 1}
|
time_table = {'h': 3600, 'm': 60, 's': 1}
|
||||||
|
|
||||||
|
|
||||||
@yt_app.route('/watch')
|
@yt_app.route('/watch')
|
||||||
@yt_app.route('/embed')
|
@yt_app.route('/embed')
|
||||||
@yt_app.route('/embed/<video_id>')
|
@yt_app.route('/embed/<video_id>')
|
||||||
@ -354,15 +369,15 @@ def get_watch_page(video_id=None):
|
|||||||
use_invidious = bool(int(request.args.get('use_invidious', '1')))
|
use_invidious = bool(int(request.args.get('use_invidious', '1')))
|
||||||
tasks = (
|
tasks = (
|
||||||
gevent.spawn(comments.video_comments, video_id, int(settings.default_comment_sorting), lc=lc ),
|
gevent.spawn(comments.video_comments, video_id, int(settings.default_comment_sorting), lc=lc ),
|
||||||
gevent.spawn(extract_info, video_id, use_invidious, playlist_id=playlist_id,
|
gevent.spawn(extract_info, video_id, use_invidious,
|
||||||
index=index)
|
playlist_id=playlist_id, index=index)
|
||||||
)
|
)
|
||||||
gevent.joinall(tasks)
|
gevent.joinall(tasks)
|
||||||
util.check_gevent_exceptions(tasks[1])
|
util.check_gevent_exceptions(tasks[1])
|
||||||
comments_info, info = tasks[0].value, tasks[1].value
|
comments_info, info = tasks[0].value, tasks[1].value
|
||||||
|
|
||||||
if info['error']:
|
if info['error']:
|
||||||
return flask.render_template('error.html', error_message = info['error'])
|
return flask.render_template('error.html', error_message=info['error'])
|
||||||
|
|
||||||
video_info = {
|
video_info = {
|
||||||
"duration": util.seconds_to_timestamp(info["duration"] or 0),
|
"duration": util.seconds_to_timestamp(info["duration"] or 0),
|
||||||
@ -409,7 +424,6 @@ def get_watch_page(video_id=None):
|
|||||||
subdomain = url[0:url.find(".googlevideo.com")]
|
subdomain = url[0:url.find(".googlevideo.com")]
|
||||||
f.write(subdomain + "\n")
|
f.write(subdomain + "\n")
|
||||||
|
|
||||||
|
|
||||||
download_formats = []
|
download_formats = []
|
||||||
|
|
||||||
for format in (info['formats'] + info['hls_formats']):
|
for format in (info['formats'] + info['hls_formats']):
|
||||||
@ -523,8 +537,9 @@ def get_transcript(caption_path):
|
|||||||
msg = ('Error retrieving captions: ' + str(e) + '\n\n'
|
msg = ('Error retrieving captions: ' + str(e) + '\n\n'
|
||||||
+ 'The caption url may have expired.')
|
+ 'The caption url may have expired.')
|
||||||
print(msg)
|
print(msg)
|
||||||
return flask.Response(msg,
|
return flask.Response(
|
||||||
status = e.code,
|
msg,
|
||||||
|
status=e.code,
|
||||||
mimetype='text/plain;charset=UTF-8')
|
mimetype='text/plain;charset=UTF-8')
|
||||||
|
|
||||||
lines = captions.splitlines()
|
lines = captions.splitlines()
|
||||||
@ -572,6 +587,3 @@ def get_transcript(caption_path):
|
|||||||
|
|
||||||
return flask.Response(result.encode('utf-8'),
|
return flask.Response(result.encode('utf-8'),
|
||||||
mimetype='text/plain;charset=UTF-8')
|
mimetype='text/plain;charset=UTF-8')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user