1238 lines
42 KiB
Python
1238 lines
42 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
#
|
|
# Copyright (C) 2019-2022 A S Lewis
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify it under
|
|
# the terms of the GNU General Public License as published by the Free Software
|
|
# Foundation, either version 3 of the License, or (at your option) any later
|
|
# version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful, but WITHOUT
|
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
# details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License along with
|
|
# this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
"""Constant variables used in various parts of the code."""
|
|
|
|
|
|
# Import Gtk modules
|
|
# ...
|
|
|
|
|
|
# Import other modules
|
|
import datetime
|
|
import re
|
|
|
|
|
|
# Import our modules
|
|
# Use same gettext translations
|
|
from mainapp import _
|
|
|
|
|
|
# Supported locales: <ISO 639-1>_<ISO 3166-1 alpha-2>
|
|
locale_setup_list = [
|
|
'en_GB', 'English',
|
|
'en_US', 'English (American)',
|
|
'ko_KR', '한국어',
|
|
'nl_NL', 'Nederlands',
|
|
]
|
|
|
|
LOCALE_DEFAULT = locale_setup_list[0]
|
|
LOCALE_LIST = []
|
|
LOCALE_DICT = {}
|
|
|
|
while locale_setup_list:
|
|
key = locale_setup_list.pop(0)
|
|
value = locale_setup_list.pop(0)
|
|
|
|
LOCALE_LIST.append(key)
|
|
LOCALE_DICT[key] = value
|
|
|
|
# Some icons are different at Christmas/on national holidays
|
|
today = datetime.date.today()
|
|
day = today.strftime("%d")
|
|
month = today.strftime("%m")
|
|
|
|
xmas_flag = False
|
|
eesti_flag = False
|
|
anglo_flag = False
|
|
if (int(month) == 12 and int(day) >= 24) \
|
|
or (int(month) == 1 and int(day) <= 5):
|
|
xmas_flag = True
|
|
elif (int(month) == 2 and int(day) == 24) \
|
|
or (int(month) == 8 and int(day) == 20):
|
|
eesti_flag = True
|
|
elif (int(month) == 4 and int(day) == 23):
|
|
anglo_flag = True
|
|
|
|
language_setup_list = [
|
|
# ISO 639-1 Language Codes (with one extra key-value pair to handle live
|
|
# chat)
|
|
# English is top of the list, because it's the default setting in
|
|
# options.OptionsManager
|
|
# NB These values must not contain square brackets [...]
|
|
_('English'), 'en',
|
|
'YouTube live chat', 'live_chat',
|
|
'Abkhazian', 'ab',
|
|
'Afar', 'aa',
|
|
'Afrikaans', 'af',
|
|
'Akan', 'ak',
|
|
'Albanian', 'sq',
|
|
'Amharic', 'am',
|
|
'Arabic', 'ar',
|
|
'Aragonese', 'an',
|
|
'Armenian', 'hy',
|
|
'Assamese', 'as',
|
|
'Avaric', 'av',
|
|
'Avestan', 'ae',
|
|
'Aymara', 'ay',
|
|
'Azerbaijani', 'az',
|
|
'Bambara', 'bm',
|
|
'Bashkir', 'ba',
|
|
'Basque', 'eu',
|
|
'Belarusian', 'be',
|
|
'Bengali (Bangla)', 'bn',
|
|
'Bihari', 'bh',
|
|
'Bislama', 'bi',
|
|
'Bosnian', 'bs',
|
|
'Breton', 'br',
|
|
'Bulgarian', 'bg',
|
|
'Burmese', 'my',
|
|
'Catalan', 'ca',
|
|
'Chamorro', 'ch',
|
|
'Chechen', 'ce',
|
|
'Chichewa, Chewa, Nyanja', 'ny',
|
|
'Chinese', 'zh',
|
|
'Chinese (Simplified)', 'zh-Hans',
|
|
'Chinese (Traditional)', 'zh-Hant',
|
|
'Chuvash', 'cv',
|
|
'Cornish', 'kw',
|
|
'Corsican', 'co',
|
|
'Cree', 'cr',
|
|
'Croatian', 'hr',
|
|
'Czech', 'cs',
|
|
'Danish', 'da',
|
|
'Divehi, Dhivehi, Maldivian', 'dv',
|
|
_('Dutch'), 'nl',
|
|
'Dzongkha', 'dz',
|
|
'Esperanto', 'eo',
|
|
'Estonian', 'et',
|
|
'Ewe', 'ee',
|
|
'Faroese', 'fo',
|
|
'Fijian', 'fj',
|
|
'Finnish', 'fi',
|
|
'French', 'fr',
|
|
'Fula, Fulah, Pulaar, Pular', 'ff',
|
|
'Galician', 'gl',
|
|
'Gaelic (Scottish)', 'gd',
|
|
'Gaelic (Manx)', 'gv',
|
|
'Georgian', 'ka',
|
|
'German', 'de',
|
|
'Greek', 'el',
|
|
'Greenlandic, Kalaallisut', 'kl',
|
|
'Guarani', 'gn',
|
|
'Gujarati', 'gu',
|
|
'Haitian Creole', 'ht',
|
|
'Hausa', 'ha',
|
|
'Hebrew', 'he',
|
|
'Herero', 'hz',
|
|
'Hindi', 'hi',
|
|
'Hiri Motu', 'ho',
|
|
'Hungarian', 'hu',
|
|
'Icelandic', 'is',
|
|
'Ido', 'io',
|
|
'Igbo', 'ig',
|
|
'Indonesian', 'id',
|
|
'Interlingua', 'ia',
|
|
'Interlingue', 'ie',
|
|
'Inuktitut', 'iu',
|
|
'Inupiak', 'ik',
|
|
'Irish', 'ga',
|
|
'Italian', 'it',
|
|
'Japanese', 'ja',
|
|
'Javanese', 'jv',
|
|
'Kannada', 'kn',
|
|
'Kanuri', 'kr',
|
|
'Kashmiri', 'ks',
|
|
'Kazakh', 'kk',
|
|
'Khmer', 'km',
|
|
'Kikuyu', 'ki',
|
|
'Kinyarwanda (Rwanda)', 'rw',
|
|
'Kirundi', 'rn',
|
|
'Klingon', 'tlh', # Actually ISO 639-2
|
|
'Kyrgyz', 'ky',
|
|
'Komi', 'kv',
|
|
'Kongo', 'kg',
|
|
_('Korean'), 'ko',
|
|
'Kurdish', 'ku',
|
|
'Kwanyama', 'kj',
|
|
'Lao', 'lo',
|
|
'Latin', 'la',
|
|
'Latvian (Lettish)', 'lv',
|
|
'Limburgish ( Limburger)', 'li',
|
|
'Lingala', 'ln',
|
|
'Lithuanian', 'lt',
|
|
'Luga-Katanga', 'lu',
|
|
'Luganda, Ganda', 'lg',
|
|
'Luxembourgish', 'lb',
|
|
'Macedonian', 'mk',
|
|
'Malagasy', 'mg',
|
|
'Malay', 'ms',
|
|
'Malayalam', 'ml',
|
|
'Maltese', 'mt',
|
|
'Maori', 'mi',
|
|
'Marathi', 'mr',
|
|
'Marshallese', 'mh',
|
|
'Moldavian', 'mo',
|
|
'Mongolian', 'mn',
|
|
'Nauru', 'na',
|
|
'Navajo', 'nv',
|
|
'Ndonga', 'ng',
|
|
'Northern Ndebele', 'nd',
|
|
'Nepali', 'ne',
|
|
'Norwegian', 'no',
|
|
'Norwegian bokmål', 'nb',
|
|
'Norwegian nynorsk', 'nn',
|
|
'Occitan', 'oc',
|
|
'Ojibwe', 'oj',
|
|
'Old Church Slavonic, Old Bulgarian', 'cu',
|
|
'Oriya', 'or',
|
|
'Oromo (Afaan Oromo)', 'om',
|
|
'Ossetian', 'os',
|
|
'Pāli', 'pi',
|
|
'Pashto, Pushto', 'ps',
|
|
'Persian (Farsi)', 'fa',
|
|
'Polish', 'pl',
|
|
'Portuguese', 'pt',
|
|
'Punjabi (Eastern)', 'pa',
|
|
'Quechua', 'qu',
|
|
'Romansh', 'rm',
|
|
'Romanian', 'ro',
|
|
'Russian', 'ru',
|
|
'Sami', 'se',
|
|
'Samoan', 'sm',
|
|
'Sango', 'sg',
|
|
'Sanskrit', 'sa',
|
|
'Serbian', 'sr',
|
|
'Serbo-Croatian', 'sh',
|
|
'Sesotho', 'st',
|
|
'Setswana', 'tn',
|
|
'Shona', 'sn',
|
|
'Sichuan Yi, Nuoso', 'ii',
|
|
'Sindhi', 'sd',
|
|
'Sinhalese', 'si',
|
|
'Swati, Siswati', 'ss',
|
|
'Slovak', 'sk',
|
|
'Slovenian', 'sl',
|
|
'Somali', 'so',
|
|
'Southern Ndebele', 'nr',
|
|
'Spanish', 'es',
|
|
'Sundanese', 'su',
|
|
'Swahili (Kiswahili)', 'sw',
|
|
'Swedish', 'sv',
|
|
'Tagalog', 'tl',
|
|
'Tahitian', 'ty',
|
|
'Tajik', 'tg',
|
|
'Tamil', 'ta',
|
|
'Tatar', 'tt',
|
|
'Telugu', 'te',
|
|
'Thai', 'th',
|
|
'Tibetan', 'bo',
|
|
'Tigrinya', 'ti',
|
|
'Tonga', 'to',
|
|
'Tsonga', 'ts',
|
|
'Turkish', 'tr',
|
|
'Turkmen', 'tk',
|
|
'Twi', 'tw',
|
|
'Uyghur', 'ug',
|
|
'Ukrainian', 'uk',
|
|
'Urdu', 'ur',
|
|
'Uzbek', 'uz',
|
|
'Venda', 've',
|
|
'Vietnamese', 'vi',
|
|
'Volapük', 'vo',
|
|
'Wallon', 'wa',
|
|
'Welsh', 'cy',
|
|
'Wolof', 'wo',
|
|
'Western Frisian', 'fy',
|
|
'Xhosa', 'xh',
|
|
'Yiddish', 'yi',
|
|
'Yoruba', 'yo',
|
|
'Zhuang, Chuang', 'za',
|
|
'Zulu', 'zu',
|
|
]
|
|
|
|
LANGUAGE_CODE_LIST = []
|
|
LANGUAGE_CODE_DICT = {}
|
|
|
|
while language_setup_list:
|
|
key = language_setup_list.pop(0)
|
|
value = language_setup_list.pop(0)
|
|
|
|
LANGUAGE_CODE_LIST.append(key)
|
|
LANGUAGE_CODE_DICT[key] = value
|
|
|
|
# 'Enhanced' websites. As of v2.3.597, this data is only used to extract RSS
|
|
# feeds, but that functionality could be extended in the future
|
|
# The 'convert' templates work like this: any four-character sequence beginning
|
|
# and ending with a space character is replaced:
|
|
# ' vi ' - replaced with video ID
|
|
# ' vn ' - replaced with video name
|
|
# ' ci ' - replaced with channel ID
|
|
# ' cn ' - replaced with channel name
|
|
# ' pi ' - replaced with playlist ID
|
|
# ' pn ' - replaced with playlist name
|
|
# The IDs and/or names are those extracted from a full video/channel/playlist
|
|
# URL (or provided by a video's metadata file)
|
|
# In each mini-dictionary, the keys 'name', 'pretty_name' must be set. The
|
|
# 'detect_list' item must not be empty; all other values can be empty lists,
|
|
# if not applicable
|
|
enhanced_setup_list = [
|
|
{
|
|
# Key in the dictionary below
|
|
'name': 'youtube',
|
|
# Name displayed in the Video Catalogue
|
|
'pretty_name': 'YouTube',
|
|
# Regexes to recognise the website (no groups used)
|
|
'detect_list': [
|
|
'^https?:\/\/(www\.)?youtube\.com\/',
|
|
],
|
|
# Regexes to extract a video ID/name. The second group is used (so that
|
|
# the optional www can be the first group)
|
|
'extract_vid_list': [
|
|
'^https?:\/\/(www\.)?youtube\.com\/watch\?v=([^\/]+)',
|
|
],
|
|
'extract_vname_list': [],
|
|
# Regexes to extract a channel/playlist ID/name. The second group is
|
|
# used
|
|
'extract_cid_list': [
|
|
'^https?:\/\/(www\.)?youtube\.com\/channel\/([^\/]+)',
|
|
],
|
|
'extract_cname_list': [
|
|
'^https?:\/\/(www\.)?youtube\.com\/user\/([^\/]+)\/videos\/?',
|
|
'^https?:\/\/(www\.)?youtube\.com\/c\/([^\/]+)\/videos\/?',
|
|
],
|
|
# Regexes to extract a playlist ID/name. The second group is used
|
|
'extract_pid_list': [
|
|
'^https?:\/\/(www\.)?youtube\.com\/channel\?list=([^\/]+)',
|
|
'^https?:\/\/(www\.)?youtube\.com\/playlist\?list=([^\/]+)',
|
|
],
|
|
'extract_pname_list': [],
|
|
# Templates to convert video ID/name to URL
|
|
'convert_video_list': [
|
|
'https://www.youtube.com/watch?v= vi ',
|
|
],
|
|
# Templates to convert channel ID/name to URL
|
|
'convert_channel_list': [
|
|
'https://www.youtube.com/c/ cn /videos',
|
|
'https://www.youtube.com/user/ cn /videos',
|
|
'https://www.youtube.com/channel/ ci ',
|
|
],
|
|
# Templates to convert playlist ID/name to URL
|
|
'convert_playlist_list': [
|
|
# 'https://www.youtube.com/channel?list= pi ',
|
|
'https://www.youtube.com/playlist?list= pi ',
|
|
],
|
|
# Templates to convert channel ID/name to RSS feed
|
|
'rss_channel_list': [
|
|
'https://www.youtube.com/feeds/videos.xml?channel_id= ci ',
|
|
],
|
|
# Templates to convert playlist ID/name to RSS feed
|
|
'rss_playlist_list': [
|
|
'https://www.youtube.com/feeds/videos.xml?playlist_id= pi ',
|
|
],
|
|
},
|
|
{
|
|
'name': 'odysee',
|
|
'pretty_name': 'Odysee',
|
|
'detect_list': [
|
|
'^https?:\/\/(www\.)?odysee\.com\/',
|
|
],
|
|
'extract_vid_list': [],
|
|
'extract_vname_list': [
|
|
'^https?:\/\/(www\.)?odysee\.com\/\@[^\/]+\/([^\:]+)\:',
|
|
],
|
|
'extract_cid_list': [],
|
|
'extract_cname_list': [
|
|
'^https?:\/\/(www\.)?odysee\.com\/\@([^\:]+)\:',
|
|
],
|
|
'extract_pid_list': [],
|
|
'extract_pname_list': [],
|
|
'convert_video_list': [],
|
|
'convert_channel_list': [],
|
|
'convert_playlist_list': [],
|
|
'rss_channel_list': [
|
|
'https://lbryfeed.melroy.org/channel/odysee/ cn ',
|
|
],
|
|
'rss_playlist_list': [],
|
|
},
|
|
{
|
|
'name': 'bitchute',
|
|
'pretty_name': 'BitChute',
|
|
'detect_list': [
|
|
'^https?:\/\/(www\.)?bitchute\.com\/',
|
|
],
|
|
'extract_vid_list': [
|
|
'^https?:\/\/(www\.)?bitchute\.com\/video\/([^\/]+)',
|
|
],
|
|
'extract_vname_list': [],
|
|
'extract_cid_list': [
|
|
'^https?:\/\/(www\.)?bitchute\.com\/channel\/([^\/]+)',
|
|
],
|
|
'extract_cname_list': [],
|
|
'extract_pid_list': [],
|
|
'extract_pname_list': [],
|
|
'convert_video_list': [
|
|
'https://www.bitchute.com/video/ vi ',
|
|
],
|
|
'convert_channel_list': [
|
|
'https://www.bitchute.com/video/ ci ',
|
|
],
|
|
'convert_playlist_list': [],
|
|
'rss_channel_list': [
|
|
'https://www.bitchute.com/feeds/rss/channel/ cn ',
|
|
],
|
|
'rss_playlist_list': [],
|
|
},
|
|
{
|
|
'name': 'twitch',
|
|
'pretty_name': 'Twitch',
|
|
'detect_list': [
|
|
'^https?:\/\/(www\.)?twitch\.tv\/',
|
|
],
|
|
'extract_vid_list': [
|
|
'^https?:\/\/(www\.)?twitch\.tv\/videos\/([^\/]+)',
|
|
],
|
|
'extract_vname_list': [],
|
|
'extract_cid_list': [],
|
|
'extract_cname_list': [
|
|
'^https?:\/\/(www\.)?twitch\.tv\/([^\/]+)',
|
|
],
|
|
'extract_pid_list': [],
|
|
'extract_pname_list': [],
|
|
'convert_video_list': [
|
|
'https://www.twitch.tv/video/ vi ',
|
|
],
|
|
'convert_channel_list': [
|
|
'https://www.twitch.tv/ cn ',
|
|
],
|
|
'convert_playlist_list': [],
|
|
'rss_channel_list': [
|
|
'https://twitchrss.appspot.com/vod/ cn ',
|
|
],
|
|
'rss_playlist_list': [],
|
|
},
|
|
]
|
|
|
|
ENHANCED_SITE_LIST = []
|
|
ENHANCED_SITE_DICT = {}
|
|
|
|
for mini_dict in enhanced_setup_list:
|
|
ENHANCED_SITE_LIST.append(mini_dict['name'])
|
|
ENHANCED_SITE_DICT[mini_dict['name']] = mini_dict
|
|
|
|
# Standard list and dictionaries
|
|
time_metric_setup_list = [
|
|
'seconds', _('seconds'), 1,
|
|
'minutes', _('minutes'), 60,
|
|
'hours', _('hours'), int(60 * 60),
|
|
'days', _('days'), int(60 * 60 * 24),
|
|
'weeks', _('weeks'), int(60 * 60 * 24 * 7),
|
|
'years', _('years'), int(60 * 60 * 24 * 365),
|
|
]
|
|
|
|
TIME_METRIC_LIST = []
|
|
TIME_METRIC_DICT = {}
|
|
TIME_METRIC_TRANS_DICT = {}
|
|
|
|
while time_metric_setup_list:
|
|
key = time_metric_setup_list.pop(0)
|
|
trans_key = time_metric_setup_list.pop(0)
|
|
value = time_metric_setup_list.pop(0)
|
|
|
|
TIME_METRIC_LIST.append(key)
|
|
TIME_METRIC_DICT[key] = value
|
|
TIME_METRIC_TRANS_DICT[key] = trans_key
|
|
|
|
specified_days_setup_list = [
|
|
'every_day', _('Every day'),
|
|
'weekdays', _('Weekdays'),
|
|
'weekends', _('Weekends'),
|
|
'monday', _('Monday'),
|
|
'tuesday', _('Tuesday'),
|
|
'wednesday', _('Wednesday'),
|
|
'thursday', _('Thursday'),
|
|
'friday', _('Friday'),
|
|
'saturday', _('Saturday'),
|
|
'sunday', _('Sunday'),
|
|
]
|
|
|
|
SPECIFIED_DAYS_LIST = []
|
|
SPECIFIED_DAYS_DICT = {}
|
|
|
|
while specified_days_setup_list:
|
|
key = specified_days_setup_list.pop(0)
|
|
value = specified_days_setup_list.pop(0)
|
|
|
|
SPECIFIED_DAYS_LIST.append(key)
|
|
SPECIFIED_DAYS_DICT[key] = value
|
|
|
|
KILO_SIZE = 1024.0
|
|
filesize_metric_setup_list = [
|
|
'B', 1,
|
|
'KiB', int(KILO_SIZE ** 1),
|
|
'MiB', int(KILO_SIZE ** 2),
|
|
'GiB', int(KILO_SIZE ** 3),
|
|
'TiB', int(KILO_SIZE ** 4),
|
|
'PiB', int(KILO_SIZE ** 5),
|
|
'EiB', int(KILO_SIZE ** 6),
|
|
'ZiB', int(KILO_SIZE ** 7),
|
|
'YiB', int(KILO_SIZE ** 8),
|
|
]
|
|
|
|
FILESIZE_METRIC_LIST = []
|
|
FILESIZE_METRIC_DICT = {}
|
|
|
|
while filesize_metric_setup_list:
|
|
key = filesize_metric_setup_list.pop(0)
|
|
value = filesize_metric_setup_list.pop(0)
|
|
|
|
FILESIZE_METRIC_LIST.append(key)
|
|
FILESIZE_METRIC_DICT[key] = value
|
|
|
|
file_output_setup_list = [
|
|
0, 'Custom',
|
|
None, # (The same as option 2 by default)
|
|
1, 'ID',
|
|
'%(id)s.%(ext)s',
|
|
2, 'Title',
|
|
'%(title)s.%(ext)s',
|
|
3, 'Title + ID',
|
|
'%(title)s-%(id)s.%(ext)s',
|
|
4, 'Title + Quality',
|
|
'%(title)s-%(height)sp.%(ext)s',
|
|
5, 'Title + ID + Quality',
|
|
'%(title)s-%(id)s-%(height)sp.%(ext)s',
|
|
6, 'Autonumber + Title',
|
|
'%(playlist_index)s-%(title)s.%(ext)s',
|
|
7, 'Autonumber + Title + ID',
|
|
'%(playlist_index)s-%(title)s-%(id)s.%(ext)s',
|
|
8, 'Autonumber + Title + Quality',
|
|
'%(playlist_index)s-%(title)s-%(height)sp.%(ext)s',
|
|
9, 'Autonumber + Title + ID + Quality',
|
|
'%(playlist_index)s-%(title)s-%(id)s-%(height)sp.%(ext)s',
|
|
]
|
|
|
|
FILE_OUTPUT_NAME_DICT = {}
|
|
FILE_OUTPUT_CONVERT_DICT = {}
|
|
|
|
while file_output_setup_list:
|
|
key = file_output_setup_list.pop(0)
|
|
value = file_output_setup_list.pop(0)
|
|
value2 = file_output_setup_list.pop(0)
|
|
|
|
FILE_OUTPUT_NAME_DICT[key] = value
|
|
FILE_OUTPUT_CONVERT_DICT[key] = value2
|
|
|
|
YTDLP_OUTPUT_TYPE_LIST = [
|
|
'subtitle',
|
|
'thumbnail',
|
|
'description',
|
|
'annotation',
|
|
'infojson',
|
|
'pl_thumbnail',
|
|
'pl_description',
|
|
'pl_infojson',
|
|
'chapter',
|
|
]
|
|
|
|
SPONSORBLOCK_CATEGORY_LIST = [
|
|
'sponsor',
|
|
'selfpromo',
|
|
'interaction',
|
|
'intro',
|
|
'outro',
|
|
'preview',
|
|
'music_offtopic',
|
|
]
|
|
SPONSORBLOCK_ACTION_LIST = [
|
|
'skip',
|
|
]
|
|
|
|
video_option_setup_list = [
|
|
# List of YouTube extractor (format) codes, based on the original list in
|
|
# youtube-dl-gui, and supplemented by this list:
|
|
#
|
|
# https://gist.github.com/sidneys/7095afe4da4ae58694d128b1034e01e2
|
|
#
|
|
# Unfortunately, as of late September 2019, that list was already out of
|
|
# date
|
|
# Unfortunately, the list is YouTube-specific, and will not necessarily
|
|
# work on other websites
|
|
#
|
|
# I'm not sure about the meaning of some extractor codes; in those cases,
|
|
# I add the code itself to distinguish it from similar codes (e.g.
|
|
# compare codes 18 and 396)
|
|
#
|
|
# Dummy extractor codes - progressive scan resolutions
|
|
'144p', 'Any format [144p]', False,
|
|
'240p', 'Any format [240p]', False,
|
|
'360p', 'Any format [360p]', False,
|
|
'480p', 'Any format [480p]', False,
|
|
'720p', 'Any format [720p]', False,
|
|
'720p60', 'Any format [720p 60fps]', False,
|
|
'1080p', 'Any format [1080p]', False,
|
|
'1080p60', 'Any format [1080p 60fps]', False,
|
|
'1440p', 'Any format [1440p]', False,
|
|
'1440p60', 'Any format [1440p 60fps]', False,
|
|
'2160p', 'Any format [2160p]', False,
|
|
'2160p60', 'Any format [2160p 60fps]', False,
|
|
'4320p', 'Any format [4320p]', False,
|
|
'4320p60', 'Any format [4320p 60fps]', False,
|
|
# Dummy extractor codes - other
|
|
'3gp', '3gp', False,
|
|
'flv', 'flv', False,
|
|
'm4a', 'm4a', True,
|
|
'mp4', 'mp4', False,
|
|
'webm', 'webm', False,
|
|
# Real extractor codes
|
|
'17', '3gp [144p] <17>', False,
|
|
'36', '3gp [240p] <36>', False,
|
|
'5', 'flv [240p] <5>', False,
|
|
'6', 'flv [270p] <6>', False,
|
|
'34', 'flv [360p] <34>', False,
|
|
'35', 'flv [480p] <35>', False,
|
|
# v1.3.037 - not sure whether the HLS format codes should be added here, or
|
|
# not. 'hls' has not been added as a dummy extractor code because
|
|
# youtube-dl doesn't support that
|
|
'151', 'hls [72p] <151>', False,
|
|
'132', 'hls [240p] <132>', False,
|
|
'92', 'hls [240p] (3D) <92>', False,
|
|
'93', 'hls [360p] (3D) <93>', False,
|
|
'94', 'hls [480p] (3D) <94>', False,
|
|
'95', 'hls [720p] (3D) <95>', False,
|
|
'96', 'hls [1080p] <96>', False,
|
|
'139', 'm4a 48k (DASH Audio) <139>', True,
|
|
'140', 'm4a 128k (DASH Audio) <140>', True,
|
|
'256', 'm4a 192k (DASH Audio) <256>', True,
|
|
'141', 'm4a 256k (DASH Audio) <141>', True,
|
|
'258', 'm4a 384k (DASH Audio) <258>', True,
|
|
'18', 'mp4 [360p] <18>', False,
|
|
'22', 'mp4 [720p] <22>', False,
|
|
'37', 'mp4 [1080p] <37>', False,
|
|
'38', 'mp4 [4K] <38>', False,
|
|
'160', 'mp4 [144p] (DASH Video) <160>', False,
|
|
'133', 'mp4 [240p] (DASH Video) <133>', False,
|
|
'134', 'mp4 [360p] (DASH Video) <134>', False,
|
|
'135', 'mp4 [480p] (DASH Video) <135>', False,
|
|
'136', 'mp4 [720p] (DASH Video) <136>', False,
|
|
'298', 'mp4 [720p 60fps] (DASH Video) <298>', False,
|
|
'137', 'mp4 [1080p] (DASH Video) <137>', False,
|
|
'299', 'mp4 [1080p 60fps] (DASH Video) <299>', False,
|
|
'264', 'mp4 [1440p] (DASH Video) <264>', False,
|
|
'138', 'mp4 [2160p] (DASH Video) <138>', False,
|
|
'266', 'mp4 [2160p 60fps] (DASH Video) <266>', False,
|
|
'82', 'mp4 [360p] (3D) <82>', False,
|
|
'83', 'mp4 [480p] (3D) <83>', False,
|
|
'84', 'mp4 [720p] (3D) <84>', False,
|
|
'85', 'mp4 [1080p] (3D) <85>', False,
|
|
'394', 'mp4 [144p] <394>', False,
|
|
'395', 'mp4 [240p] <395>', False,
|
|
'396', 'mp4 [360p] <396>', False,
|
|
'397', 'mp4 [480p] <397>', False,
|
|
'398', 'mp4 [720p] <398>', False,
|
|
'399', 'mp4 [1080p] <399>', False,
|
|
'400', 'mp4 [1440p] <400>', False,
|
|
'401', 'mp4 [2160p] <401>', False,
|
|
'402', 'mp4 [2880p] <402>', False,
|
|
'571', 'mp4 [8k] <571>', False,
|
|
'43', 'webm [360p] <43>', False,
|
|
'44', 'webm [480p] <44>', False,
|
|
'45', 'webm [720p] <45>', False,
|
|
'46', 'webm [1080p] <46>', False,
|
|
'242', 'webm [240p] (DASH Video) <242>', False,
|
|
'243', 'webm [360p] (DASH Video) <243>', False,
|
|
'244', 'webm [480p] (DASH Video) <244>', False,
|
|
'247', 'webm [720p] (DASH Video) <247>', False,
|
|
'302', 'webm [720p 60fps] (DASH Video) <302>', False,
|
|
'248', 'webm [1080p] (DASH Video) <248>', False,
|
|
'303', 'webm [1080p 60fps] (DASH Video) <303>', False,
|
|
'271', 'webm [1440p] (DASH Video) <271>', False,
|
|
'308', 'webm [1440p 60fps] (DASH Video) <300>', False,
|
|
'313', 'webm [2160p] (DASH Video) <313>', False,
|
|
'315', 'webm [2160p 60fps] (DASH Video) <315>', False,
|
|
'272', 'webm [4320p] (DASH Video) <272>', False,
|
|
'100', 'webm [360p] (3D) <100>', False,
|
|
'101', 'webm [480p] (3D) <101>', False,
|
|
'102', 'webm [720p] (3D) <102>', False,
|
|
'330', 'webm [144p 60fps] (HDR) <330>', False,
|
|
'331', 'webm [240p 60fps] (HDR) <331>', False,
|
|
'332', 'webm [360p 60fps] (HDR) <332>', False,
|
|
'333', 'webm [480p 60fps] (HDR) <333>', False,
|
|
'334', 'webm [720p 60fps] (HDR) <334>', False,
|
|
'335', 'webm [1080p 60fps] (HDR) <335>', False,
|
|
'336', 'webm [1440p 60fps] (HDR) <336>', False,
|
|
'337', 'webm [2160p 60fps] (HDR) <337>', False,
|
|
'600', 'webm (36k Audio) <600>', True,
|
|
'249', 'webm (52k Audio) <249>', True,
|
|
'250', 'webm (64k Audio) <250>', True,
|
|
'251', 'webm (116k Audio) <251>', True,
|
|
'219', 'webm [144p] <219>', False,
|
|
'278', 'webm [144p] <278>', False,
|
|
'167', 'webm [360p] <167>', False,
|
|
'168', 'webm [480p] <168>', False,
|
|
'218', 'webm [480p] <218>', False,
|
|
'245', 'webm [480p] <245>', False,
|
|
'246', 'webm [480p] <246>', False,
|
|
'169', 'webm [1080p] <169>', False,
|
|
'171', 'webm 48k (DASH Audio) <171>', True,
|
|
'172', 'webm 256k (DASH Audio) <172>', True,
|
|
]
|
|
|
|
VIDEO_OPTION_LIST = []
|
|
VIDEO_OPTION_DICT = {}
|
|
VIDEO_OPTION_TYPE_DICT = {}
|
|
|
|
while video_option_setup_list:
|
|
value = video_option_setup_list.pop(0)
|
|
key = video_option_setup_list.pop(0)
|
|
audio_only_flag = video_option_setup_list.pop(0)
|
|
|
|
VIDEO_OPTION_LIST.append(key)
|
|
VIDEO_OPTION_DICT[key] = value
|
|
VIDEO_OPTION_TYPE_DICT[value] = audio_only_flag
|
|
|
|
video_resolution_setup_list = [
|
|
'144p', '144',
|
|
'240p', '240',
|
|
'360p', '360',
|
|
'480p', '480',
|
|
'720p', '720',
|
|
'720p60', '720',
|
|
'1080p', '1080',
|
|
'1080p60', '1080',
|
|
'1440p', '1440',
|
|
'1440p60', '1440',
|
|
'2160p', '2160',
|
|
'2160p60', '2160',
|
|
'4320p', '4320',
|
|
'4320p60', '4320',
|
|
]
|
|
|
|
VIDEO_RESOLUTION_LIST = []
|
|
VIDEO_RESOLUTION_DICT = {}
|
|
VIDEO_RESOLUTION_DEFAULT = '720p'
|
|
|
|
while video_resolution_setup_list:
|
|
key = video_resolution_setup_list.pop(0)
|
|
value = video_resolution_setup_list.pop(0)
|
|
|
|
VIDEO_RESOLUTION_LIST.append(key)
|
|
VIDEO_RESOLUTION_DICT[key] = value
|
|
|
|
VIDEO_FPS_DICT = {
|
|
# Contains a subset of VIDEO_RESOLUTION_DICT. Only required to distinguish
|
|
# 30fps from 60fps formats
|
|
'720p60': '60',
|
|
'1080p60': '60',
|
|
'1440p60': '60',
|
|
'2160p60': '60',
|
|
'4320p60': '60',
|
|
}
|
|
|
|
video_format_setup_list = ['mp4', 'flv', 'ogg', 'webm', 'mkv', 'avi']
|
|
|
|
VIDEO_FORMAT_LIST = []
|
|
VIDEO_FORMAT_DICT = {}
|
|
|
|
while video_format_setup_list:
|
|
key = value = video_format_setup_list.pop(0)
|
|
|
|
VIDEO_FORMAT_LIST.append(key)
|
|
VIDEO_FORMAT_DICT[key] = value
|
|
|
|
audio_setup_list = ['mp3', 'wav', 'aac', 'm4a', 'vorbis', 'opus', 'flac']
|
|
|
|
AUDIO_FORMAT_LIST = []
|
|
AUDIO_FORMAT_DICT = {}
|
|
|
|
while audio_setup_list:
|
|
key = value = audio_setup_list.pop(0)
|
|
|
|
AUDIO_FORMAT_LIST.append(key)
|
|
AUDIO_FORMAT_DICT[key] = value
|
|
|
|
# (Used for detecting video thumbnails. Unfortunately Gtk can't display .webp
|
|
# files yet)
|
|
IMAGE_FORMAT_LIST = ['.jpg', '.png', '.gif']
|
|
# (The same list including .webp, for any code that needs it)
|
|
IMAGE_FORMAT_EXT_LIST = ['.jpg', '.png', '.gif', '.webp']
|
|
|
|
FILE_SIZE_UNIT_LIST = [
|
|
['Bytes', ''],
|
|
['Kilobytes', 'k'],
|
|
['Megabytes', 'm'],
|
|
['Gigabytes', 'g'],
|
|
['Terabytes', 't'],
|
|
['Petabytes', 'p'],
|
|
['Exabytes', 'e'],
|
|
['Zetta', 'z'],
|
|
['Yotta', 'y'],
|
|
]
|
|
|
|
DIALOGUE_ICON_DICT = {
|
|
'newbie_classic_icon': 'newbie_classic_icon.png',
|
|
'newbie_icon': 'newbie_icon_64.png',
|
|
'ready_icon': 'ready_icon_64.png',
|
|
'setup_classic_icon': 'setup_classic_icon.png',
|
|
'system_icon': 'system_icon_64.png',
|
|
'yt_icon': 'yt_icon_32.png',
|
|
'yt_remind_icon_en': 'yt_remind_icon_en.png',
|
|
'yt_remind_icon_kr': 'yt_remind_icon_kr.png',
|
|
'yt_remind_icon_nl': 'yt_remind_icon_nl.png',
|
|
}
|
|
if xmas_flag:
|
|
DIALOGUE_ICON_DICT['system_icon'] = 'system_icon_xmas_64.png'
|
|
elif eesti_flag:
|
|
DIALOGUE_ICON_DICT['system_icon'] = 'system_icon_eesti_64.png'
|
|
elif anglo_flag:
|
|
DIALOGUE_ICON_DICT['system_icon'] = 'system_icon_anglo_64.png'
|
|
|
|
if xmas_flag:
|
|
STATUS_ICON_DICT = {
|
|
'default_icon': 'status_default_icon_xmas_64.png',
|
|
'check_icon': 'status_check_icon_xmas_64.png',
|
|
'check_live_icon': 'status_check_live_icon_xmas_64.png',
|
|
'download_icon': 'status_download_icon_xmas_64.png',
|
|
'download_live_icon': 'status_download_live_icon_xmas_64.png',
|
|
'update_icon': 'status_update_icon_xmas_64.png',
|
|
'refresh_icon': 'status_refresh_icon_xmas_64.png',
|
|
'info_icon': 'status_info_icon_xmas_64.png',
|
|
'tidy_icon': 'status_tidy_icon_xmas_64.png',
|
|
'livestream_icon': 'status_livestream_icon_xmas_64.png',
|
|
'process_icon': 'status_process_icon_xmas_64.png',
|
|
}
|
|
elif eesti_flag:
|
|
STATUS_ICON_DICT = {
|
|
'default_icon': 'status_default_icon_eesti_64.png',
|
|
'check_icon': 'status_check_icon_eesti_64.png',
|
|
'check_live_icon': 'status_check_live_icon_eesti_64.png',
|
|
'download_icon': 'status_download_icon_eesti_64.png',
|
|
'download_live_icon': 'status_download_live_icon_eesti_64.png',
|
|
'update_icon': 'status_update_icon_eesti_64.png',
|
|
'refresh_icon': 'status_refresh_icon_eesti_64.png',
|
|
'info_icon': 'status_info_icon_eesti_64.png',
|
|
'tidy_icon': 'status_tidy_icon_eesti_64.png',
|
|
'livestream_icon': 'status_livestream_icon_eesti_64.png',
|
|
'process_icon': 'status_process_icon_eesti_64.png',
|
|
}
|
|
elif anglo_flag:
|
|
STATUS_ICON_DICT = {
|
|
'default_icon': 'status_default_icon_anglo_64.png',
|
|
'check_icon': 'status_check_icon_anglo_64.png',
|
|
'check_live_icon': 'status_check_live_icon_anglo_64.png',
|
|
'download_icon': 'status_download_icon_anglo_64.png',
|
|
'download_live_icon': 'status_download_live_icon_anglo_64.png',
|
|
'update_icon': 'status_update_icon_anglo_64.png',
|
|
'refresh_icon': 'status_refresh_icon_anglo_64.png',
|
|
'info_icon': 'status_info_icon_anglo_64.png',
|
|
'tidy_icon': 'status_tidy_icon_anglo_64.png',
|
|
'livestream_icon': 'status_livestream_icon_anglo_64.png',
|
|
'process_icon': 'status_process_icon_anglo_64.png',
|
|
}
|
|
else:
|
|
STATUS_ICON_DICT = {
|
|
'default_icon': 'status_default_icon_64.png',
|
|
'check_icon': 'status_check_icon_64.png',
|
|
'check_live_icon': 'status_check_live_icon_64.png',
|
|
'download_icon': 'status_download_icon_64.png',
|
|
'download_live_icon': 'status_download_live_icon_64.png',
|
|
'update_icon': 'status_update_icon_64.png',
|
|
'refresh_icon': 'status_refresh_icon_64.png',
|
|
'info_icon': 'status_info_icon_64.png',
|
|
'tidy_icon': 'status_tidy_icon_64.png',
|
|
'livestream_icon': 'status_livestream_icon_64.png',
|
|
'process_icon': 'status_process_icon_64.png',
|
|
}
|
|
|
|
TOOLBAR_ICON_DICT = {
|
|
'tool_channel_large': 'channel_large.png',
|
|
'tool_channel_small': 'channel_small.png',
|
|
'tool_check_large': 'check_large.png',
|
|
'tool_check_small': 'check_small.png',
|
|
'tool_download_large': 'download_large.png',
|
|
'tool_download_small': 'download_small.png',
|
|
'tool_folder_large': 'folder_large.png',
|
|
'tool_folder_small': 'folder_small.png',
|
|
'tool_hide_large': 'hide_large.png',
|
|
'tool_hide_small': 'hide_small.png',
|
|
'tool_playlist_large': 'playlist_large.png',
|
|
'tool_playlist_small': 'playlist_small.png',
|
|
'tool_quit_large': 'quit_large.png',
|
|
'tool_quit_small': 'quit_small.png',
|
|
'tool_stop_large': 'stop_large.png',
|
|
'tool_stop_small': 'stop_small.png',
|
|
'tool_switch_large': 'switch_large.png',
|
|
'tool_switch_small': 'switch_small.png',
|
|
'tool_video_large': 'video_large.png',
|
|
'tool_video_small': 'video_small.png',
|
|
}
|
|
|
|
LARGE_ICON_DICT = {
|
|
'attention_large': 'attention.png',
|
|
'channel_large': 'channel.png',
|
|
'copy_large': 'copy.png',
|
|
'cursor_large': 'cursor.png',
|
|
'error_large': 'error.png',
|
|
'folder_large': 'folder_yellow.png',
|
|
'folder_fixed_large': 'folder_green.png',
|
|
'folder_no_parent_large': 'folder_black.png',
|
|
'folder_private_large': 'folder_red.png',
|
|
'folder_temp_large': 'folder_blue.png',
|
|
'hand_left_large': 'hand_left.png',
|
|
'hand_right_large': 'hand_right.png',
|
|
'limits_off_large': 'limits_off.png',
|
|
'limits_on_large': 'limits_on.png',
|
|
'playlist_large': 'playlist.png',
|
|
'question_large': 'question.png',
|
|
'video_large': 'video.png',
|
|
'warning_large': 'warning.png',
|
|
}
|
|
|
|
LARGE_ICON_COMPOSITE_LIST = [
|
|
'channel_large',
|
|
'folder_large',
|
|
'folder_fixed_large',
|
|
'folder_no_parent_large',
|
|
'folder_private_large',
|
|
'folder_temp_large',
|
|
'playlist_large',
|
|
'video_large',
|
|
]
|
|
|
|
SMALL_ICON_DICT = {
|
|
'video_small': 'video.png',
|
|
'channel_small': 'channel.png',
|
|
'playlist_small': 'playlist.png',
|
|
'folder_small': 'folder.png',
|
|
|
|
'archived_small': 'archived.png',
|
|
'arrow_up_small': 'arrow_up.png',
|
|
'arrow_down_small': 'arrow_down.png',
|
|
'attention_small': 'attention.png',
|
|
'check_small': 'check.png',
|
|
'comment_small': 'comment.png',
|
|
'debut_now_small': 'debut_now.png',
|
|
'debut_wait_small': 'debut_wait.png',
|
|
'delete_small': 'delete.png',
|
|
'dl_options_small': 'dl_options.png',
|
|
'download_small': 'download.png',
|
|
'error_small': 'error.png',
|
|
'external_small': 'external.png',
|
|
'favourite_small': 'favourite.png',
|
|
'folder_black_small': 'folder_black.png',
|
|
'folder_blue_small': 'folder_blue.png',
|
|
'folder_green_small': 'folder_green.png',
|
|
'folder_red_small': 'folder_red.png',
|
|
'keyboard_small': 'keyboard.png',
|
|
'likes_small': 'likes.png',
|
|
'have_file_small': 'have_file.png',
|
|
'live_now_small': 'live_now.png',
|
|
'live_old_small': 'live_old.png',
|
|
'live_old_no_file_small': 'live_old_no_file.png',
|
|
'live_wait_small': 'live_wait.png',
|
|
'no_file_small': 'no_file.png',
|
|
'slice_small': 'slice.png',
|
|
'split_file_small': 'split_file.png',
|
|
'stamp_small': 'stamp.png',
|
|
'subs_small': 'subs.png',
|
|
'system_error_small': 'system_error.png',
|
|
'system_warning_small': 'system_warning.png',
|
|
'unavailable_small': 'unavailable.png',
|
|
'uploader_small': 'uploader.png',
|
|
'warning_small': 'warning.png',
|
|
}
|
|
|
|
THUMB_ICON_DICT = {
|
|
'thumb_none_tiny': 'thumb_none_tiny.png',
|
|
'thumb_none_small': 'thumb_none_small.png',
|
|
'thumb_none_medium': 'thumb_none_medium.png',
|
|
'thumb_none_large': 'thumb_none_large.png',
|
|
'thumb_none_enormous': 'thumb_none_enormous.png',
|
|
|
|
'thumb_left_tiny': 'thumb_left_tiny.png',
|
|
'thumb_left_small': 'thumb_left_small.png',
|
|
'thumb_left_medium': 'thumb_left_medium.png',
|
|
'thumb_left_large': 'thumb_left_large.png',
|
|
'thumb_left_enormous': 'thumb_left_enormous.png',
|
|
|
|
'thumb_right_tiny': 'thumb_right_tiny.png',
|
|
'thumb_right_small': 'thumb_right_small.png',
|
|
'thumb_right_medium': 'thumb_right_medium.png',
|
|
'thumb_right_large': 'thumb_right_large.png',
|
|
'thumb_right_enormous': 'thumb_right_enormous.png',
|
|
|
|
'thumb_both_tiny': 'thumb_both_tiny.png',
|
|
'thumb_both_small': 'thumb_both_small.png',
|
|
'thumb_both_medium': 'thumb_both_medium.png',
|
|
'thumb_both_large': 'thumb_both_large.png',
|
|
'thumb_both_enormous': 'thumb_both_enormous.png',
|
|
|
|
'thumb_default_tiny': 'thumb_default_tiny.png',
|
|
'thumb_default_small': 'thumb_default_small.png',
|
|
'thumb_default_medium': 'thumb_default_medium.png',
|
|
'thumb_default_large': 'thumb_default_large.png',
|
|
'thumb_default_enormous': 'thumb_default_enormous.png',
|
|
|
|
'thumb_block_tiny': 'thumb_block_tiny.png',
|
|
'thumb_block_small': 'thumb_block_small.png',
|
|
'thumb_block_medium': 'thumb_block_medium.png',
|
|
'thumb_block_large': 'thumb_block_large.png',
|
|
'thumb_block_enormous': 'thumb_block_enormous.png',
|
|
}
|
|
|
|
EXTERNAL_ICON_DICT = {
|
|
'ytdl_gui': 'youtube-dl-gui.png',
|
|
}
|
|
|
|
# (Replaces system stock icons, if not available)
|
|
STOCK_ICON_DICT = {
|
|
'stock_add': 'add_small.png',
|
|
'stock_cancel': 'cancel_small.png',
|
|
'stock_delete': 'delete_small.png',
|
|
'stock_execute': 'ffmpeg_small.png',
|
|
'stock_file': 'file_small.png',
|
|
'stock_find': 'find_small.png',
|
|
'stock_go_back': 'go_back_small.png',
|
|
'stock_go_down': 'go_down_small.png',
|
|
'stock_go_forward': 'go_forward_small.png',
|
|
'stock_go_up': 'go_up_small.png',
|
|
'stock_goto_first': 'goto_first_small.png',
|
|
'stock_goto_last': 'goto_last_small.png',
|
|
'stock_hide_filter': 'hide_filter_small.png',
|
|
'stock_index': 'index_small.png',
|
|
'stock_media_play': 'media_play_small.png',
|
|
'stock_media_stop': 'media_stop_small.png',
|
|
'stock_open': 'open_small.png',
|
|
'stock_properties': 'properties.png',
|
|
'stock_properties_large': 'properties_large.png',
|
|
'stock_redo': 'resort_small.png', # Used for a sorting button
|
|
'stock_refresh': 'refresh_small.png',
|
|
'stock_show_filter': 'show_filter_small.png',
|
|
}
|
|
|
|
if xmas_flag:
|
|
WIN_ICON_LIST = [
|
|
'system_icon_xmas_16.png',
|
|
'system_icon_xmas_24.png',
|
|
'system_icon_xmas_32.png',
|
|
'system_icon_xmas_48.png',
|
|
'system_icon_xmas_64.png',
|
|
'system_icon_xmas_128.png',
|
|
'system_icon_xmas_256.png',
|
|
'system_icon_xmas_512.png',
|
|
]
|
|
elif eesti_flag:
|
|
WIN_ICON_LIST = [
|
|
'system_icon_eesti_16.png',
|
|
'system_icon_eesti_24.png',
|
|
'system_icon_eesti_32.png',
|
|
'system_icon_eesti_48.png',
|
|
'system_icon_eesti_64.png',
|
|
'system_icon_eesti_128.png',
|
|
'system_icon_eesti_256.png',
|
|
'system_icon_eesti_512.png',
|
|
]
|
|
elif anglo_flag:
|
|
WIN_ICON_LIST = [
|
|
'system_icon_anglo_16.png',
|
|
'system_icon_anglo_24.png',
|
|
'system_icon_anglo_32.png',
|
|
'system_icon_anglo_48.png',
|
|
'system_icon_anglo_64.png',
|
|
'system_icon_anglo_128.png',
|
|
'system_icon_anglo_256.png',
|
|
'system_icon_anglo_512.png',
|
|
]
|
|
else:
|
|
WIN_ICON_LIST = [
|
|
'system_icon_16.png',
|
|
'system_icon_24.png',
|
|
'system_icon_32.png',
|
|
'system_icon_48.png',
|
|
'system_icon_64.png',
|
|
'system_icon_128.png',
|
|
'system_icon_256.png',
|
|
'system_icon_512.png',
|
|
]
|
|
|
|
CONFIG_WIN_ICON_LIST = [
|
|
'config_icon_16.png',
|
|
'config_icon_24.png',
|
|
'config_icon_32.png',
|
|
'config_icon_48.png',
|
|
'config_icon_64.png',
|
|
'config_icon_128.png',
|
|
'config_icon_256.png',
|
|
'config_icon_512.png',
|
|
]
|
|
|
|
def do_translate(config_flag=False):
|
|
|
|
"""Function called for the first time below, setting various values.
|
|
|
|
If mainapp.TartubeApp.load_config() changes the locale to something else,
|
|
called for a second time to update those values.
|
|
|
|
Args:
|
|
|
|
config_flag (bool): False for the initial call, True for the second
|
|
call from mainapp.TartubeApp.load_config()
|
|
|
|
"""
|
|
|
|
global FOLDER_ALL_VIDEOS, FOLDER_BOOKMARKS, FOLDER_FAVOURITE_VIDEOS, \
|
|
FOLDER_LIVESTREAMS, FOLDER_MISSING_VIDEOS, FOLDER_NEW_VIDEOS, \
|
|
FOLDER_RECENT_VIDEOS, FOLDER_WAITING_VIDEOS, FOLDER_TEMPORARY_VIDEOS, \
|
|
FOLDER_UNSORTED_VIDEOS, FOLDER_VIDEO_CLIPS
|
|
|
|
global YTDL_UPDATE_DICT
|
|
|
|
global MAIN_STAGE_QUEUED, MAIN_STAGE_NOT_STARTED, MAIN_STAGE_ACTIVE, \
|
|
MAIN_STAGE_PAUSED, MAIN_STAGE_COMPLETED, MAIN_STAGE_ERROR, \
|
|
MAIN_STAGE_STALLED, ACTIVE_STAGE_PRE_PROCESS, ACTIVE_STAGE_DOWNLOAD, \
|
|
ACTIVE_STAGE_CONCATENATE, ACTIVE_STAGE_POST_PROCESS, \
|
|
ACTIVE_STAGE_CAPTURE, ACTIVE_STAGE_MERGE, ACTIVE_STAGE_CHECKING, \
|
|
COMPLETED_STAGE_FINISHED, COMPLETED_STAGE_WARNING, \
|
|
COMPLETED_STAGE_ALREADY, ERROR_STAGE_ERROR, ERROR_STAGE_STOPPED, \
|
|
ERROR_STAGE_ABORT
|
|
|
|
global TIME_METRIC_TRANS_DICT
|
|
|
|
global FILE_OUTPUT_NAME_DICT, FILE_OUTPUT_CONVERT_DICT
|
|
|
|
global VIDEO_OPTION_LIST, VIDEO_OPTION_DICT
|
|
|
|
# System folder names
|
|
FOLDER_ALL_VIDEOS = _('All Videos')
|
|
FOLDER_BOOKMARKS = _('Bookmarks')
|
|
FOLDER_FAVOURITE_VIDEOS = _('Favourite Videos')
|
|
FOLDER_LIVESTREAMS = _('Livestreams')
|
|
FOLDER_MISSING_VIDEOS = _('Missing Videos')
|
|
FOLDER_NEW_VIDEOS = _('New Videos')
|
|
FOLDER_RECENT_VIDEOS = _('Recent Videos')
|
|
FOLDER_WAITING_VIDEOS = _('Waiting Videos')
|
|
FOLDER_TEMPORARY_VIDEOS = _('Temporary Videos')
|
|
FOLDER_UNSORTED_VIDEOS = _('Unsorted Videos')
|
|
FOLDER_VIDEO_CLIPS = _('Video Clips')
|
|
|
|
# youtube-dl update shell commands
|
|
YTDL_UPDATE_DICT = {
|
|
'ytdl_update_default_path':
|
|
_('Update using default youtube-dl path'),
|
|
'ytdl_update_local_path':
|
|
_('Update using local youtube-dl path'),
|
|
'ytdl_update_custom_path':
|
|
_('Update using custom youtube-dl path'),
|
|
'ytdl_update_pip':
|
|
_('Update using pip'),
|
|
'ytdl_update_pip_no_dependencies':
|
|
_('Update using pip (use --no-dependencies option)'),
|
|
'ytdl_update_pip_omit_user':
|
|
_('Update using pip (omit --user option)'),
|
|
'ytdl_update_pip3':
|
|
_('Update using pip3'),
|
|
'ytdl_update_pip3_no_dependencies':
|
|
_('Update using pip3 (use --no-dependencies option)'),
|
|
'ytdl_update_pip3_omit_user':
|
|
_('Update using pip3 (omit --user option)'),
|
|
'ytdl_update_pip3_recommend':
|
|
_('Update using pip3 (recommended)'),
|
|
'ytdl_update_pypi_path':
|
|
_('Update using PyPI youtube-dl path'),
|
|
'ytdl_update_win_32':
|
|
_('Windows 32-bit update (recommended)'),
|
|
'ytdl_update_win_32_no_dependencies':
|
|
_('Windows 32-bit update (use --no-dependencies option)'),
|
|
'ytdl_update_win_64':
|
|
_('Windows 64-bit update (recommended)'),
|
|
'ytdl_update_win_64_no_dependencies':
|
|
_('Windows 64-bit update (use --no-dependencies option)'),
|
|
'ytdl_update_disabled':
|
|
_('youtube-dl updates are disabled'),
|
|
}
|
|
|
|
# Download operation stages
|
|
MAIN_STAGE_QUEUED = _('Queued')
|
|
MAIN_STAGE_NOT_STARTED = _('Not started')
|
|
MAIN_STAGE_ACTIVE = _('Active')
|
|
MAIN_STAGE_PAUSED = _('Paused') # (not actually used)
|
|
MAIN_STAGE_COMPLETED = _('Completed') # (not actually used)
|
|
MAIN_STAGE_ERROR = _('Error')
|
|
MAIN_STAGE_STALLED = _('Stalled')
|
|
# Sub-stages of the 'Active' stage
|
|
ACTIVE_STAGE_PRE_PROCESS = _('Pre-processing')
|
|
ACTIVE_STAGE_DOWNLOAD = _('Downloading')
|
|
ACTIVE_STAGE_CONCATENATE = _('Concatenating')
|
|
ACTIVE_STAGE_POST_PROCESS = _('Post-processing')
|
|
ACTIVE_STAGE_CHECKING = _('Checking')
|
|
# Sub-stages of the 'Completed' stage
|
|
COMPLETED_STAGE_FINISHED = _('Finished')
|
|
COMPLETED_STAGE_WARNING = _('Warning')
|
|
COMPLETED_STAGE_ALREADY = _('Already downloaded')
|
|
# Sub-stages of the 'Error' stage
|
|
ERROR_STAGE_ERROR = _('Error') # (not actually used)
|
|
ERROR_STAGE_STOPPED = _('Stopped')
|
|
ERROR_STAGE_ABORT = _('Filesize abort')
|
|
|
|
if config_flag:
|
|
|
|
for key in TIME_METRIC_TRANS_DICT:
|
|
TIME_METRIC_TRANS_DICT[key] = _(key)
|
|
|
|
# File output templates use a combination of English words, each of
|
|
# which must be translated
|
|
translate_note = _(
|
|
'TRANSLATOR\'S NOTE: ID refers to a video\'s unique ID on the' \
|
|
+ ' website, e.g. on YouTube "CS9OO0S5w2k"',
|
|
)
|
|
|
|
new_name_dict = {}
|
|
for key in FILE_OUTPUT_NAME_DICT.keys():
|
|
|
|
mod_value \
|
|
= re.sub('Custom', _('Custom'), FILE_OUTPUT_NAME_DICT[key])
|
|
mod_value = re.sub('ID', _('ID'), mod_value)
|
|
mod_value = re.sub('Title', _('Title'), mod_value)
|
|
mod_value = re.sub('Quality', _('Quality'), mod_value)
|
|
mod_value = re.sub('Autonumber', _('Autonumber'), mod_value)
|
|
|
|
new_name_dict[key] = mod_value
|
|
|
|
FILE_OUTPUT_NAME_DICT = new_name_dict
|
|
|
|
# Video/audio formats. A number of them contain 'Any format', which
|
|
# must be translated
|
|
new_list = []
|
|
new_dict = {}
|
|
for item in VIDEO_OPTION_LIST:
|
|
|
|
mod_item = re.sub('Any format', _('Any format'), item)
|
|
new_list.append(mod_item)
|
|
new_dict[mod_item] = VIDEO_OPTION_DICT[item]
|
|
|
|
VIDEO_OPTION_LIST = new_list
|
|
VIDEO_OPTION_DICT = new_dict
|
|
|
|
# End of this function
|
|
return
|
|
|
|
|
|
# Call the function for the first time
|
|
do_translate()
|