From c41d69f59cf749b60402718416c9a38d8e4dc358 Mon Sep 17 00:00:00 2001 From: MrS0m30n3 Date: Sat, 28 Feb 2015 14:28:40 +0200 Subject: [PATCH] Add localization CHANGES ======= setup.py Add youtube_dl_gui/locale file on the installation script __init__.py Add localization via gettext Move optionsmanager, logmanager initialization out of the main() function mainframe.py Add the gettext _() function to translate the strings optiosframe.py Add the gettext _() function to translate the strings Add LocalizationTab optionsmanager.py Add new option 'locale_name' utils.py Add get_locale_file() function NEW FILES ========= locale_build: Contains scripts to auto create locale files youtube_dl_gui/locale: Contains locale files for youtube-dlg --- locale_build/build_locale.bat | 35 ++ locale_build/build_locale.sh | 32 ++ locale_build/youtube_dl_gui.po | 428 ++++++++++++++++++ setup.py | 33 +- youtube_dl_gui/__init__.py | 37 +- .../en_US/LC_MESSAGES/youtube_dl_gui.mo | Bin 0 -> 361 bytes .../en_US/LC_MESSAGES/youtube_dl_gui.po | 428 ++++++++++++++++++ youtube_dl_gui/mainframe.py | 54 +-- youtube_dl_gui/optionsframe.py | 215 +++++---- youtube_dl_gui/optionsmanager.py | 5 +- youtube_dl_gui/utils.py | 33 ++ 11 files changed, 1182 insertions(+), 118 deletions(-) create mode 100644 locale_build/build_locale.bat create mode 100755 locale_build/build_locale.sh create mode 100644 locale_build/youtube_dl_gui.po create mode 100644 youtube_dl_gui/locale/en_US/LC_MESSAGES/youtube_dl_gui.mo create mode 100644 youtube_dl_gui/locale/en_US/LC_MESSAGES/youtube_dl_gui.po diff --git a/locale_build/build_locale.bat b/locale_build/build_locale.bat new file mode 100644 index 0000000..3f1d6c9 --- /dev/null +++ b/locale_build/build_locale.bat @@ -0,0 +1,35 @@ +@echo off + +REM Author: Sotiris Papadopoulos +REM Last-Edited: 25/02/2015 +REM Script to auto-create a locale file. + +REM Usage: build_locale.bat +REM Example: build_locale.bat gr_GR gr.po + +REM To create a new locale file copy youtube_dl_gui.po +REM to a new locale file (e.g. gr.po) edit it with your +REM favorite editor and then run this script. + +REM You also need to install gettext for Windows + +set FILENAME=youtube_dl_gui + +set /a args=0 +for %%A in (%*) do set /a args+=1 + +if not %args% == 2 ( + echo Usage: %~n0.bat "locale" "locale_file" + echo Example: %~n0.bat gr_GR gr.po +) else ( + mkdir ..\%FILENAME%\locale\%1\LC_MESSAGES + + msgfmt.exe --output-file %FILENAME%.mo %2 + + move %2 ..\%FILENAME%\locale\%1\LC_MESSAGES\%FILENAME%.po 1>NUL + move %FILENAME%.mo ..\%FILENAME%\locale\%1\LC_MESSAGES\ 1>NUL + + tree /F ..\%FILENAME%\locale\%1 + + echo Done +) diff --git a/locale_build/build_locale.sh b/locale_build/build_locale.sh new file mode 100755 index 0000000..4b18953 --- /dev/null +++ b/locale_build/build_locale.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +# Author: Sotiris Papadopoulos +# Last-Edited: 25/02/2015 +# Script to auto-create a locale file. + +# Usage: ./build_locale.sh +# Example: ./build_locale.sh gr_GR gr.po + +# To create a new locale file copy youtube_dl_gui.po +# to a new locale file (e.g. gr.po) edit it with your +# favorite editor and then run this script. + + +FILENAME="youtube_dl_gui" + +if [ "$#" -ne 2 ]; then + echo "Usage: $0 " + echo "Example: $0 gr_GR gr.po" + exit 1 +fi + +mkdir -p "../$FILENAME/locale/$1/LC_MESSAGES/" + +msgfmt --output-file "$FILENAME.mo" "$2" + +mv "$2" "../$FILENAME/locale/$1/LC_MESSAGES/$FILENAME.po" +mv "$FILENAME.mo" "../$FILENAME/locale/$1/LC_MESSAGES/" + +tree "../$FILENAME/locale/$1" + +echo "Done" diff --git a/locale_build/youtube_dl_gui.po b/locale_build/youtube_dl_gui.po new file mode 100644 index 0000000..fd1e9ea --- /dev/null +++ b/locale_build/youtube_dl_gui.po @@ -0,0 +1,428 @@ +# Youtube-dlG localization file. +# FIRST AUTHOR: Sotiris Papadopoulos , 2015. +# +msgid "" +msgstr "" +"Project-Id-Version: 0.3.6\n" +"POT-Creation-Date: 2015-02-25 22:38+EET\n" +"PO-Revision-Date: 2015-02-25 22:38+EET\n" +"Last-Translator: Sotiris Papadopoulos \n" +"Language-Team: en\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: pygettext.py 1.5\n" + + +#: mainframe.py:77 +msgid "URLs" +msgstr "" + +#: mainframe.py:78 +msgid "Download" +msgstr "" + +#: mainframe.py:79 +msgid "Update" +msgstr "" + +#: mainframe.py:80 optionsframe.py:40 +msgid "Options" +msgstr "" + +#: mainframe.py:81 +msgid "Error" +msgstr "" + +#: mainframe.py:82 +msgid "Stop" +msgstr "" + +#: mainframe.py:83 +msgid "Info" +msgstr "" + +#: mainframe.py:84 +msgid "Welcome" +msgstr "" + +#: mainframe.py:85 +msgid "Successfully downloaded {0} url(s) in {1} day(s) {2} hour(s) {3} minute(s) {4} second(s)" +msgstr "" + +#: mainframe.py:87 +msgid "Download completed" +msgstr "" + +#: mainframe.py:88 +msgid "Downloading {0} url(s)" +msgstr "" + +#: mainframe.py:89 +msgid "Stopping downloads" +msgstr "" + +#: mainframe.py:90 +msgid "Downloads stopped" +msgstr "" + +#: mainframe.py:91 +msgid "You need to provide at least one url" +msgstr "" + +#: mainframe.py:92 +msgid "Download started" +msgstr "" + +#: mainframe.py:94 +msgid "Downloading latest youtube-dl. Please wait..." +msgstr "" + +#: mainframe.py:95 +msgid "Youtube-dl download failed [{0}]" +msgstr "" + +#: mainframe.py:96 +msgid "Youtube-dl downloaded correctly" +msgstr "" + +#: mainframe.py:98 +msgid "Title" +msgstr "" + +#: mainframe.py:99 +msgid "Size" +msgstr "" + +#: mainframe.py:100 +msgid "Percent" +msgstr "" + +#: mainframe.py:101 +msgid "ETA" +msgstr "" + +#: mainframe.py:102 +msgid "Speed" +msgstr "" + +#: mainframe.py:103 +msgid "Status" +msgstr "" + +#: optionsframe.py:42 +msgid "General" +msgstr "" + +#: optionsframe.py:43 +msgid "Video" +msgstr "" + +#: optionsframe.py:44 +msgid "Audio" +msgstr "" + +#: optionsframe.py:45 +msgid "Playlist" +msgstr "" + +#: optionsframe.py:46 +msgid "Output" +msgstr "" + +#: optionsframe.py:47 +msgid "Subtitles" +msgstr "" + +#: optionsframe.py:48 +msgid "Filesystem" +msgstr "" + +#: optionsframe.py:49 +msgid "Shutdown" +msgstr "" + +#: optionsframe.py:50 +msgid "Authentication" +msgstr "" + +#: optionsframe.py:51 +msgid "Connection" +msgstr "" + +#: optionsframe.py:52 +msgid "Log" +msgstr "" + +#: optionsframe.py:53 +msgid "Commands" +msgstr "" + +#: optionsframe.py:54 +msgid "Localization" +msgstr "" + +#: optionsframe.py:372 +msgid "Enable Log" +msgstr "" + +#: optionsframe.py:373 +msgid "Write Time" +msgstr "" + +#: optionsframe.py:374 +msgid "Clear Log" +msgstr "" + +#: optionsframe.py:375 +msgid "View Log" +msgstr "" + +#: optionsframe.py:376 +msgid "Path: {0}" +msgstr "" + +#: optionsframe.py:377 +msgid "Log Size: {0} Bytes" +msgstr "" + +#: optionsframe.py:378 optionsframe.py:1390 +msgid "Restart" +msgstr "" + +#: optionsframe.py:379 +msgid "Please restart {0}" +msgstr "" + +#: optionsframe.py:487 +msgid "Shutdown when finished" +msgstr "" + +#: optionsframe.py:488 +msgid "SUDO password" +msgstr "" + +#: optionsframe.py:540 +msgid "Playlist Start" +msgstr "" + +#: optionsframe.py:541 +msgid "Playlist Stop" +msgstr "" + +#: optionsframe.py:542 +msgid "Max Downloads" +msgstr "" + +#: optionsframe.py:600 +msgid "Retries" +msgstr "" + +#: optionsframe.py:601 +msgid "User Agent" +msgstr "" + +#: optionsframe.py:602 +msgid "Referer" +msgstr "" + +#: optionsframe.py:603 +msgid "Proxy" +msgstr "" + +#: optionsframe.py:677 +msgid "Username" +msgstr "" + +#: optionsframe.py:678 +msgid "Password" +msgstr "" + +#: optionsframe.py:679 +msgid "Video Password (vimeo, smotri)" +msgstr "" + +#: optionsframe.py:737 +msgid "high" +msgstr "" + +#: optionsframe.py:737 +msgid "low" +msgstr "" + +#: optionsframe.py:737 +msgid "mid" +msgstr "" + +#: optionsframe.py:740 +msgid "Convert to Audio" +msgstr "" + +#: optionsframe.py:741 +msgid "Keep Video" +msgstr "" + +#: optionsframe.py:742 +msgid "Audio Format" +msgstr "" + +#: optionsframe.py:743 +msgid "Audio Quality" +msgstr "" + +#: optionsframe.py:860 +msgid "default" +msgstr "" + +#: optionsframe.py:861 +msgid "none" +msgstr "" + +#: optionsframe.py:865 +msgid "Video Format" +msgstr "" + +#: optionsframe.py:866 +msgid "Mix Format" +msgstr "" + +#: optionsframe.py:925 +msgid "Restrict filenames (ASCII)" +msgstr "" + +#: optionsframe.py:926 +msgid "ID as Name" +msgstr "" + +#: optionsframe.py:927 +msgid "Title as Name" +msgstr "" + +#: optionsframe.py:928 +msgid "Custom Template (youtube-dl)" +msgstr "" + +#: optionsframe.py:1022 +msgid "Ignore Errors" +msgstr "" + +#: optionsframe.py:1023 +msgid "Open destination folder" +msgstr "" + +#: optionsframe.py:1024 +msgid "Write info to (.json) file" +msgstr "" + +#: optionsframe.py:1025 +msgid "Write description to file" +msgstr "" + +#: optionsframe.py:1026 +msgid "Write thumbnail to disk" +msgstr "" + +#: optionsframe.py:1027 +msgid "Filesize" +msgstr "" + +#: optionsframe.py:1028 +msgid "Min" +msgstr "" + +#: optionsframe.py:1029 +msgid "Max" +msgstr "" + +#: optionsframe.py:1142 +msgid "English" +msgstr "" + +#: optionsframe.py:1143 +msgid "Greek" +msgstr "" + +#: optionsframe.py:1144 +msgid "Portuguese" +msgstr "" + +#: optionsframe.py:1145 +msgid "French" +msgstr "" + +#: optionsframe.py:1146 +msgid "Italian" +msgstr "" + +#: optionsframe.py:1147 +msgid "Russian" +msgstr "" + +#: optionsframe.py:1148 +msgid "Spanish" +msgstr "" + +#: optionsframe.py:1149 +msgid "German" +msgstr "" + +#: optionsframe.py:1152 +msgid "Download subtitle file by language" +msgstr "" + +#: optionsframe.py:1153 +msgid "Download all available subtitles" +msgstr "" + +#: optionsframe.py:1154 +msgid "Download automatic subtitle file (YOUTUBE ONLY)" +msgstr "" + +#: optionsframe.py:1155 +msgid "Embed subtitles in the video (only for mp4 videos)" +msgstr "" + +#: optionsframe.py:1156 +msgid "Subtitles Language" +msgstr "" + +#: optionsframe.py:1250 +msgid "About" +msgstr "" + +#: optionsframe.py:1251 +msgid "Open" +msgstr "" + +#: optionsframe.py:1252 +msgid "Reset Options" +msgstr "" + +#: optionsframe.py:1253 +msgid "Save Path" +msgstr "" + +#: optionsframe.py:1254 +msgid "Settings File: {0}" +msgstr "" + +#: optionsframe.py:1255 +msgid "Choose Directory" +msgstr "" + +#: optionsframe.py:1340 +msgid "Command line arguments (e.g. --help)" +msgstr "" + +#: optionsframe.py:1391 +msgid "Localization Language" +msgstr "" + +#: optionsframe.py:1392 +msgid "In order for the changes to take effect please restart {0}" +msgstr "" + +#: optionsframe.py:1439 +msgid "Log Viewer" +msgstr "" + diff --git a/setup.py b/setup.py index f72a994..13b30b3 100644 --- a/setup.py +++ b/setup.py @@ -33,6 +33,7 @@ ICONS_TEMPLATE = 'youtube_dl_gui/icons/youtube-dl-gui_{size}.png' ICONS_LIST = [ICONS_TEMPLATE.format(size=size) for size in ICONS_SIZES] + # Set icons path PY2EXE_ICONS = 'icons' WINDOWS_ICONS = os.path.join(get_python_lib(), 'youtube_dl_gui', 'icons') @@ -41,12 +42,36 @@ LINUX_ICONS = '/usr/share/icons/hicolor/' LINUX_FALLBACK_ICONS = '/usr/share/pixmaps/' +# Set localization files path +LOCALE_PATH = os.path.join('youtube_dl_gui', 'locale') + +PY2EXE_LOCALE_DIR = 'locale' +WIN_LOCALE_DIR = os.path.join(get_python_lib(), 'youtube_dl_gui', 'locale') +LINUX_LOCALE_DIR = '/usr/share/{app_name}/locale/'.format(app_name=__appname__.lower()) + + def create_scripts(): if not os.path.exists('build/_scripts/'): os.makedirs('build/_scripts') shutil.copyfile('youtube_dl_gui/__main__.py', 'build/_scripts/youtube-dl-gui') + +def set_locale_files(data_files): + for directory in os.listdir(LOCALE_PATH): + locale_lang = os.path.join(directory, 'LC_MESSAGES') + + src = os.path.join(LOCALE_PATH, locale_lang, 'youtube_dl_gui.mo') + + if PY2EXE: + dst = os.path.join(PY2EXE_LOCALE_DIR, locale_lang) + elif os.name == 'nt': + dst = os.path.join(WIN_LOCALE_DIR, locale_lang) + else: + dst = os.path.join(LINUX_LOCALE_DIR, locale_lang) + + data_files.append((dst, [src])) + def py2exe_setup(): py2exe_dependencies = [ @@ -60,6 +85,8 @@ def py2exe_setup(): (PY2EXE_ICONS, ICONS_LIST) ] + set_locale_files(py2exe_data_files) + py2exe_options = { 'includes': ['wx.lib.pubsub.*', 'wx.lib.pubsub.core.*', @@ -87,6 +114,8 @@ def normal_setup(): icons_dir = (WINDOWS_ICONS, ICONS_LIST) data_files.append(icons_dir) + set_locale_files(data_files) + params = {'data_files': data_files} else: # Create all the hicolor icons @@ -99,7 +128,9 @@ def normal_setup(): # Add the 48x48 icon as fallback fallback_icon = (LINUX_FALLBACK_ICONS, [ICONS_LIST[2]]) data_files.append(fallback_icon) - + + set_locale_files(data_files) + create_scripts() params = {'data_files': data_files, 'scripts': ['build/_scripts/youtube-dl-gui']} diff --git a/youtube_dl_gui/__init__.py b/youtube_dl_gui/__init__.py index 3c46818..05beab9 100644 --- a/youtube_dl_gui/__init__.py +++ b/youtube_dl_gui/__init__.py @@ -15,6 +15,7 @@ Example: import sys import os.path +import gettext try: import wx @@ -35,28 +36,40 @@ from .info import ( __descriptionfull__, ) -from .mainframe import MainFrame from .logmanager import LogManager from .optionsmanager import OptionsManager -from .utils import get_config_path +from .utils import ( + get_config_path, + get_locale_file +) + +# Set config path and create options and log managers +config_path = os.path.join(get_config_path(), __appname__.lower()) -def main(): - """The real main. +opt_manager = OptionsManager(config_path) +log_manager = None - Sets configuration path, enables the managers like OptionsManager, - LogManager, etc.. and creates the main app window. +if opt_manager.options['enable_log']: + log_manager = LogManager(config_path, opt_manager.options['log_time']) - """ - config_path = os.path.join(get_config_path(), __appname__.lower()) +# Set gettext before MainFrame import +# because the GUI strings are class level attributes +locale_dir = get_locale_file() - opt_manager = OptionsManager(config_path) - log_manager = None +try: + gettext.translation('youtube_dl_gui', locale_dir, [opt_manager.options['locale_name']]).install(unicode=True) +except IOError: + opt_manager.options['locale_name'] = 'en_US' + gettext.install('youtube_dl_gui') + + +from .mainframe import MainFrame - if opt_manager.options['enable_log']: - log_manager = LogManager(config_path, opt_manager.options['log_time']) +def main(): + """The real main. Creates and calls the main app windows. """ app = wx.App() frame = MainFrame(opt_manager, log_manager) frame.Centre() diff --git a/youtube_dl_gui/locale/en_US/LC_MESSAGES/youtube_dl_gui.mo b/youtube_dl_gui/locale/en_US/LC_MESSAGES/youtube_dl_gui.mo new file mode 100644 index 0000000000000000000000000000000000000000..903be076cab51b45556a99c27d1c0e30ff95bda8 GIT binary patch literal 361 zcmaKn&rXCe5XRT&iKAx^J$Tcyzy^c$PmC*?O?D$u^gatC)5; z%B4pjev@}Vs6-OQsf-etq#{YwB0I_Rl6~?CKlL>FpKT32$3dj)M|@ z(cHD5&4sAm!S_g4FXg?=cD^ae8+w_W%GTO6N@QD2!2=rfd~7XmM, 2015. +# +msgid "" +msgstr "" +"Project-Id-Version: 0.3.6\n" +"POT-Creation-Date: 2015-02-25 22:38+EET\n" +"PO-Revision-Date: 2015-02-25 22:38+EET\n" +"Last-Translator: Sotiris Papadopoulos \n" +"Language-Team: en\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: pygettext.py 1.5\n" + + +#: mainframe.py:77 +msgid "URLs" +msgstr "" + +#: mainframe.py:78 +msgid "Download" +msgstr "" + +#: mainframe.py:79 +msgid "Update" +msgstr "" + +#: mainframe.py:80 optionsframe.py:40 +msgid "Options" +msgstr "" + +#: mainframe.py:81 +msgid "Error" +msgstr "" + +#: mainframe.py:82 +msgid "Stop" +msgstr "" + +#: mainframe.py:83 +msgid "Info" +msgstr "" + +#: mainframe.py:84 +msgid "Welcome" +msgstr "" + +#: mainframe.py:85 +msgid "Successfully downloaded {0} url(s) in {1} day(s) {2} hour(s) {3} minute(s) {4} second(s)" +msgstr "" + +#: mainframe.py:87 +msgid "Download completed" +msgstr "" + +#: mainframe.py:88 +msgid "Downloading {0} url(s)" +msgstr "" + +#: mainframe.py:89 +msgid "Stopping downloads" +msgstr "" + +#: mainframe.py:90 +msgid "Downloads stopped" +msgstr "" + +#: mainframe.py:91 +msgid "You need to provide at least one url" +msgstr "" + +#: mainframe.py:92 +msgid "Download started" +msgstr "" + +#: mainframe.py:94 +msgid "Downloading latest youtube-dl. Please wait..." +msgstr "" + +#: mainframe.py:95 +msgid "Youtube-dl download failed [{0}]" +msgstr "" + +#: mainframe.py:96 +msgid "Youtube-dl downloaded correctly" +msgstr "" + +#: mainframe.py:98 +msgid "Title" +msgstr "" + +#: mainframe.py:99 +msgid "Size" +msgstr "" + +#: mainframe.py:100 +msgid "Percent" +msgstr "" + +#: mainframe.py:101 +msgid "ETA" +msgstr "" + +#: mainframe.py:102 +msgid "Speed" +msgstr "" + +#: mainframe.py:103 +msgid "Status" +msgstr "" + +#: optionsframe.py:42 +msgid "General" +msgstr "" + +#: optionsframe.py:43 +msgid "Video" +msgstr "" + +#: optionsframe.py:44 +msgid "Audio" +msgstr "" + +#: optionsframe.py:45 +msgid "Playlist" +msgstr "" + +#: optionsframe.py:46 +msgid "Output" +msgstr "" + +#: optionsframe.py:47 +msgid "Subtitles" +msgstr "" + +#: optionsframe.py:48 +msgid "Filesystem" +msgstr "" + +#: optionsframe.py:49 +msgid "Shutdown" +msgstr "" + +#: optionsframe.py:50 +msgid "Authentication" +msgstr "" + +#: optionsframe.py:51 +msgid "Connection" +msgstr "" + +#: optionsframe.py:52 +msgid "Log" +msgstr "" + +#: optionsframe.py:53 +msgid "Commands" +msgstr "" + +#: optionsframe.py:54 +msgid "Localization" +msgstr "" + +#: optionsframe.py:372 +msgid "Enable Log" +msgstr "" + +#: optionsframe.py:373 +msgid "Write Time" +msgstr "" + +#: optionsframe.py:374 +msgid "Clear Log" +msgstr "" + +#: optionsframe.py:375 +msgid "View Log" +msgstr "" + +#: optionsframe.py:376 +msgid "Path: {0}" +msgstr "" + +#: optionsframe.py:377 +msgid "Log Size: {0} Bytes" +msgstr "" + +#: optionsframe.py:378 optionsframe.py:1390 +msgid "Restart" +msgstr "" + +#: optionsframe.py:379 +msgid "Please restart {0}" +msgstr "" + +#: optionsframe.py:487 +msgid "Shutdown when finished" +msgstr "" + +#: optionsframe.py:488 +msgid "SUDO password" +msgstr "" + +#: optionsframe.py:540 +msgid "Playlist Start" +msgstr "" + +#: optionsframe.py:541 +msgid "Playlist Stop" +msgstr "" + +#: optionsframe.py:542 +msgid "Max Downloads" +msgstr "" + +#: optionsframe.py:600 +msgid "Retries" +msgstr "" + +#: optionsframe.py:601 +msgid "User Agent" +msgstr "" + +#: optionsframe.py:602 +msgid "Referer" +msgstr "" + +#: optionsframe.py:603 +msgid "Proxy" +msgstr "" + +#: optionsframe.py:677 +msgid "Username" +msgstr "" + +#: optionsframe.py:678 +msgid "Password" +msgstr "" + +#: optionsframe.py:679 +msgid "Video Password (vimeo, smotri)" +msgstr "" + +#: optionsframe.py:737 +msgid "high" +msgstr "" + +#: optionsframe.py:737 +msgid "low" +msgstr "" + +#: optionsframe.py:737 +msgid "mid" +msgstr "" + +#: optionsframe.py:740 +msgid "Convert to Audio" +msgstr "" + +#: optionsframe.py:741 +msgid "Keep Video" +msgstr "" + +#: optionsframe.py:742 +msgid "Audio Format" +msgstr "" + +#: optionsframe.py:743 +msgid "Audio Quality" +msgstr "" + +#: optionsframe.py:860 +msgid "default" +msgstr "" + +#: optionsframe.py:861 +msgid "none" +msgstr "" + +#: optionsframe.py:865 +msgid "Video Format" +msgstr "" + +#: optionsframe.py:866 +msgid "Mix Format" +msgstr "" + +#: optionsframe.py:925 +msgid "Restrict filenames (ASCII)" +msgstr "" + +#: optionsframe.py:926 +msgid "ID as Name" +msgstr "" + +#: optionsframe.py:927 +msgid "Title as Name" +msgstr "" + +#: optionsframe.py:928 +msgid "Custom Template (youtube-dl)" +msgstr "" + +#: optionsframe.py:1022 +msgid "Ignore Errors" +msgstr "" + +#: optionsframe.py:1023 +msgid "Open destination folder" +msgstr "" + +#: optionsframe.py:1024 +msgid "Write info to (.json) file" +msgstr "" + +#: optionsframe.py:1025 +msgid "Write description to file" +msgstr "" + +#: optionsframe.py:1026 +msgid "Write thumbnail to disk" +msgstr "" + +#: optionsframe.py:1027 +msgid "Filesize" +msgstr "" + +#: optionsframe.py:1028 +msgid "Min" +msgstr "" + +#: optionsframe.py:1029 +msgid "Max" +msgstr "" + +#: optionsframe.py:1142 +msgid "English" +msgstr "" + +#: optionsframe.py:1143 +msgid "Greek" +msgstr "" + +#: optionsframe.py:1144 +msgid "Portuguese" +msgstr "" + +#: optionsframe.py:1145 +msgid "French" +msgstr "" + +#: optionsframe.py:1146 +msgid "Italian" +msgstr "" + +#: optionsframe.py:1147 +msgid "Russian" +msgstr "" + +#: optionsframe.py:1148 +msgid "Spanish" +msgstr "" + +#: optionsframe.py:1149 +msgid "German" +msgstr "" + +#: optionsframe.py:1152 +msgid "Download subtitle file by language" +msgstr "" + +#: optionsframe.py:1153 +msgid "Download all available subtitles" +msgstr "" + +#: optionsframe.py:1154 +msgid "Download automatic subtitle file (YOUTUBE ONLY)" +msgstr "" + +#: optionsframe.py:1155 +msgid "Embed subtitles in the video (only for mp4 videos)" +msgstr "" + +#: optionsframe.py:1156 +msgid "Subtitles Language" +msgstr "" + +#: optionsframe.py:1250 +msgid "About" +msgstr "" + +#: optionsframe.py:1251 +msgid "Open" +msgstr "" + +#: optionsframe.py:1252 +msgid "Reset Options" +msgstr "" + +#: optionsframe.py:1253 +msgid "Save Path" +msgstr "" + +#: optionsframe.py:1254 +msgid "Settings File: {0}" +msgstr "" + +#: optionsframe.py:1255 +msgid "Choose Directory" +msgstr "" + +#: optionsframe.py:1340 +msgid "Command line arguments (e.g. --help)" +msgstr "" + +#: optionsframe.py:1391 +msgid "Localization Language" +msgstr "" + +#: optionsframe.py:1392 +msgid "In order for the changes to take effect please restart {0}" +msgstr "" + +#: optionsframe.py:1439 +msgid "Log Viewer" +msgstr "" + diff --git a/youtube_dl_gui/mainframe.py b/youtube_dl_gui/mainframe.py index e9aef1b..a0a8663 100644 --- a/youtube_dl_gui/mainframe.py +++ b/youtube_dl_gui/mainframe.py @@ -2,6 +2,8 @@ """Youtubedlg module responsible for the main app window. """ +import gettext + import wx from wx.lib.pubsub import setuparg1 from wx.lib.pubsub import pub as Publisher @@ -72,33 +74,33 @@ class MainFrame(wx.Frame): SIZE_5 = 5 # Labels area - URLS_LABEL = "URLs" - DOWNLOAD_LABEL = "Download" - UPDATE_LABEL = "Update" - OPTIONS_LABEL = "Options" - ERROR_LABEL = "Error" - STOP_LABEL = "Stop" - INFO_LABEL = "Info" - WELCOME_MSG = "Welcome" - SUCC_REPORT_MSG = ("Successfully downloaded {0} url(s) in {1} " + URLS_LABEL = _("URLs") + DOWNLOAD_LABEL = _("Download") + UPDATE_LABEL = _("Update") + OPTIONS_LABEL = _("Options") + ERROR_LABEL = _("Error") + STOP_LABEL = _("Stop") + INFO_LABEL = _("Info") + WELCOME_MSG = _("Welcome") + SUCC_REPORT_MSG = _("Successfully downloaded {0} url(s) in {1} " "day(s) {2} hour(s) {3} minute(s) {4} second(s)") - DL_COMPLETED_MSG = "Download completed" - URL_REPORT_MSG = "Downloading {0} url(s)" - CLOSING_MSG = "Stopping downloads" - CLOSED_MSG = "Downloads stopped" - PROVIDE_URL_MSG = "You need to provide at least one url" - DOWNLOAD_STARTED = "Download started" - - UPDATING_MSG = "Downloading latest youtube-dl. Please wait..." - UPDATE_ERR_MSG = "Youtube-dl download failed [{0}]" - UPDATE_SUCC_MSG = "Youtube-dl downloaded correctly" - - VIDEO_LABEL = "Video" - SIZE_LABEL = "Size" - PERCENT_LABEL = "Percent" - ETA_LABEL = "ETA" - SPEED_LABEL = "Speed" - STATUS_LABEL = "Status" + DL_COMPLETED_MSG = _("Download completed") + URL_REPORT_MSG = _("Downloading {0} url(s)") + CLOSING_MSG = _("Stopping downloads") + CLOSED_MSG = _("Downloads stopped") + PROVIDE_URL_MSG = _("You need to provide at least one url") + DOWNLOAD_STARTED = _("Download started") + + UPDATING_MSG = _("Downloading latest youtube-dl. Please wait...") + UPDATE_ERR_MSG = _("Youtube-dl download failed [{0}]") + UPDATE_SUCC_MSG = _("Youtube-dl downloaded correctly") + + VIDEO_LABEL = _("Title") + SIZE_LABEL = _("Size") + PERCENT_LABEL = _("Percent") + ETA_LABEL = _("ETA") + SPEED_LABEL = _("Speed") + STATUS_LABEL = _("Status") ################################# STATUSLIST_COLUMNS = ( diff --git a/youtube_dl_gui/optionsframe.py b/youtube_dl_gui/optionsframe.py index 561ced4..ac1bc79 100644 --- a/youtube_dl_gui/optionsframe.py +++ b/youtube_dl_gui/optionsframe.py @@ -3,6 +3,7 @@ """Youtubedlg module responsible for the options window. """ import os +import gettext import wx @@ -36,20 +37,21 @@ class OptionsFrame(wx.Frame): FRAME_SIZE = (640, 270) - FRAME_TITLE = "Options" - - GENERAL_TAB = "General" - VIDEO_TAB = "Video" - AUDIO_TAB = "Audio" - PLAYLIST_TAB = "Playlist" - OUTPUT_TAB = "Output" - SUBTITLES_TAB = "Subtitles" - FILESYS_TAB = "Filesystem" - SHUTDOWN_TAB = "Shutdown" - AUTH_TAB = "Authentication" - CONNECTION_TAB = "Connection" - LOG_TAB = "Log" - CMD_TAB = "Commands" + FRAME_TITLE = _("Options") + + GENERAL_TAB = _("General") + VIDEO_TAB = _("Video") + AUDIO_TAB = _("Audio") + PLAYLIST_TAB = _("Playlist") + OUTPUT_TAB = _("Output") + SUBTITLES_TAB = _("Subtitles") + FILESYS_TAB = _("Filesystem") + SHUTDOWN_TAB = _("Shutdown") + AUTH_TAB = _("Authentication") + CONNECTION_TAB = _("Connection") + LOG_TAB = _("Log") + CMD_TAB = _("Commands") + LOCALIZATION_TAB = _("Localization") def __init__(self, parent): wx.Frame.__init__(self, parent, title=self.FRAME_TITLE, size=self.FRAME_SIZE) @@ -79,7 +81,8 @@ class OptionsFrame(wx.Frame): (AuthenticationTab(*tab_args), self.AUTH_TAB), (ConnectionTab(*tab_args), self.CONNECTION_TAB), (LogTab(*tab_args), self.LOG_TAB), - (CMDTab(*tab_args), self.CMD_TAB) + (CMDTab(*tab_args), self.CMD_TAB), + (LocalizationTab(*tab_args), self.LOCALIZATION_TAB) ) # Add tabs on notebook @@ -91,7 +94,7 @@ class OptionsFrame(wx.Frame): panel.SetSizer(sizer) self.Bind(wx.EVT_CLOSE, self._on_close) - + self.load_all_options() def _on_close(self, event): @@ -366,14 +369,14 @@ class LogTab(TabPanel): """ - ENABLE_LABEL = "Enable Log" - WRITE_LABEL = "Write Time" - CLEAR_LABEL = "Clear Log" - VIEW_LABEL = "View Log" - PATH_LABEL = "Path: {0}" - LOGSIZE_LABEL = "Log Size: {0} Bytes" - RESTART_LABEL = "Restart" - RESTART_MSG = "Please restart {0}" + ENABLE_LABEL = _("Enable Log") + WRITE_LABEL = _("Write Time") + CLEAR_LABEL = _("Clear Log") + VIEW_LABEL = _("View Log") + PATH_LABEL = _("Path: {0}") + LOGSIZE_LABEL = _("Log Size: {0} Bytes") + RESTART_LABEL = _("Restart") + RESTART_MSG = _("Please restart {0}") def __init__(self, *args, **kwargs): super(LogTab, self).__init__(*args, **kwargs) @@ -481,8 +484,8 @@ class ShutdownTab(TabPanel): TEXTCTRL_SIZE = (250, 25) - SHUTDOWN_LABEL = "Shutdown when finished" - SUDO_LABEL = "SUDO password" + SHUTDOWN_LABEL = _("Shutdown when finished") + SUDO_LABEL = _("SUDO password") def __init__(self, *args, **kwargs): super(ShutdownTab, self).__init__(*args, **kwargs) @@ -534,9 +537,9 @@ class PlaylistTab(TabPanel): """ - START_LABEL = "Playlist Start" - STOP_LABEL = "Playlist Stop" - MAX_LABEL = "Max Downloads" + START_LABEL = _("Playlist Start") + STOP_LABEL = _("Playlist Stop") + MAX_LABEL = _("Max Downloads") def __init__(self, *args, **kwargs): super(PlaylistTab, self).__init__(*args, **kwargs) @@ -594,10 +597,10 @@ class ConnectionTab(TabPanel): SPINCTRL_SIZE = (60, -1) - RETRIES_LABEL = "Retries" - USERAGENT_LABEL = "User Agent" - REF_LABEL = "Referer" - PROXY_LABEL = "Proxy" + RETRIES_LABEL = _("Retries") + USERAGENT_LABEL = _("User Agent") + REF_LABEL = _("Referer") + PROXY_LABEL = _("Proxy") def __init__(self, *args, **kwargs): super(ConnectionTab, self).__init__(*args, **kwargs) @@ -671,9 +674,9 @@ class AuthenticationTab(TabPanel): TEXTCTRL_SIZE = (250, 25) - USERNAME_LABEL = "Username" - PASSWORD_LABEL = "Password" - VIDEOPASS_LABEL = "Video Password (vimeo, smotri)" + USERNAME_LABEL = _("Username") + PASSWORD_LABEL = _("Password") + VIDEOPASS_LABEL = _("Video Password (vimeo, smotri)") def __init__(self, *args, **kwargs): super(AuthenticationTab, self).__init__(*args, **kwargs) @@ -731,13 +734,13 @@ class AudioTab(TabPanel): *_LABEL (string): Constant string label for the widgets. """ - AUDIO_QUALITY = twodict([("0", "high"), ("5", "mid"), ("9", "low")]) + AUDIO_QUALITY = twodict([("0", _("high")), ("5", _("mid")), ("9", _("low"))]) AUDIO_FORMATS = ["mp3", "wav", "aac", "m4a", "vorbis"] - TO_AUDIO_LABEL = "Convert to Audio" - KEEP_VIDEO_LABEL = "Keep Video" - AUDIO_FORMAT_LABEL = "Audio Format" - AUDIO_QUALITY_LABEL = "Audio Quality" + TO_AUDIO_LABEL = _("Convert to Audio") + KEEP_VIDEO_LABEL = _("Keep Video") + AUDIO_FORMAT_LABEL = _("Audio Format") + AUDIO_QUALITY_LABEL = _("Audio Quality") def __init__(self, *args, **kwargs): super(AudioTab, self).__init__(*args, **kwargs) @@ -854,13 +857,13 @@ class VideoTab(TabPanel): ("172", "webm 256k (DASH AUDIO)") ]) - VIDEO_FORMATS = ["default"] + FORMATS.values() - SECOND_VIDEO_FORMATS = ["none"] + FORMATS.values() + VIDEO_FORMATS = [_("default")] + FORMATS.values() + SECOND_VIDEO_FORMATS = [_("none")] + FORMATS.values() COMBOBOX_SIZE = (200, 30) - VIDEO_FORMAT_LABEL = "Video Format" - SEC_VIDEOFORMAT_LABEL = "Mix Format" + VIDEO_FORMAT_LABEL = _("Video Format") + SEC_VIDEOFORMAT_LABEL = _("Mix Format") def __init__(self, *args, **kwargs): super(VideoTab, self).__init__(*args, **kwargs) @@ -919,10 +922,10 @@ class OutputTab(TabPanel): TEXTCTRL_SIZE = (300, 20) - RESTRICT_LABEL = "Restrict filenames (ASCII)" - ID_AS_NAME = "ID as Name" - TITLE_AS_NAME = "Title as Name" - CUST_TITLE = "Custom Template (youtube-dl)" + RESTRICT_LABEL = _("Restrict filenames (ASCII)") + ID_AS_NAME = _("ID as Name") + TITLE_AS_NAME = _("Title as Name") + CUST_TITLE = _("Custom Template (youtube-dl)") def __init__(self, *args, **kwargs): super(OutputTab, self).__init__(*args, **kwargs) @@ -1016,14 +1019,14 @@ class FilesystemTab(TabPanel): ("y", "Yottabytes") ]) - IGN_ERR_LABEL = "Ignore Errors" - OPEN_DIR_LABEL = "Open destination folder" - WRT_INFO_LABEL = "Write info to (.json) file" - WRT_DESC_LABEL = "Write description to file" - WRT_THMB_LABEL = "Write thumbnail to disk" - FILESIZE_LABEL = "Filesize" - MIN_LABEL = "Min" - MAX_LABEL = "Max" + IGN_ERR_LABEL = _("Ignore Errors") + OPEN_DIR_LABEL = _("Open destination folder") + WRT_INFO_LABEL = _("Write info to (.json) file") + WRT_DESC_LABEL = _("Write description to file") + WRT_THMB_LABEL = _("Write thumbnail to disk") + FILESIZE_LABEL = _("Filesize") + MIN_LABEL = _("Min") + MAX_LABEL = _("Max") def __init__(self, *args, **kwargs): super(FilesystemTab, self).__init__(*args, **kwargs) @@ -1136,21 +1139,21 @@ class SubtitlesTab(TabPanel): """ SUBS_LANG = twodict([ - ("en", "English"), - ("gr", "Greek"), - ("pt", "Portuguese"), - ("fr", "French"), - ("it", "Italian"), - ("ru", "Russian"), - ("es", "Spanish"), - ("de", "German") + ("en", _("English")), + ("gr", _("Greek")), + ("pt", _("Portuguese")), + ("fr", _("French")), + ("it", _("Italian")), + ("ru", _("Russian")), + ("es", _("Spanish")), + ("de", _("German")) ]) - DL_SUBS_LABEL = "Download subtitle file by language" - DL_ALL_SUBS_LABEL = "Download all available subtitles" - DL_AUTO_SUBS_LABEL = "Download automatic subtitle file (YOUTUBE ONLY)" - EMBED_SUBS_LABEL = "Embed subtitles in the video (only for mp4 videos)" - SUBS_LANG_LABEL = "Subtitles Language" + DL_SUBS_LABEL = _("Download subtitle file by language") + DL_ALL_SUBS_LABEL = _("Download all available subtitles") + DL_AUTO_SUBS_LABEL = _("Download automatic subtitle file (YOUTUBE ONLY)") + EMBED_SUBS_LABEL = _("Embed subtitles in the video (only for mp4 videos)") + SUBS_LANG_LABEL = _("Subtitles Language") def __init__(self, *args, **kwargs): super(SubtitlesTab, self).__init__(*args, **kwargs) @@ -1244,12 +1247,12 @@ class GeneralTab(TabPanel): BUTTONS_SIZE = (110, 40) - ABOUT_LABEL = "About" - OPEN_LABEL = "Open" - RESET_LABEL = "Reset Options" - SAVEPATH_LABEL = "Save Path" - SETTINGS_DIR_LABEL = "Settings File: {0}" - PICK_DIR_LABEL = "Choose Directory" + ABOUT_LABEL = _("About") + OPEN_LABEL = _("Open") + RESET_LABEL = _("Reset Options") + SAVEPATH_LABEL = _("Save Path") + SETTINGS_DIR_LABEL = _("Settings File: {0}") + PICK_DIR_LABEL = _("Choose Directory") def __init__(self, *args, **kwargs): super(GeneralTab, self).__init__(*args, **kwargs) @@ -1334,7 +1337,7 @@ class CMDTab(TabPanel): """ - CMD_LABEL = "Command line arguments (e.g. --help)" + CMD_LABEL = _("Command line arguments (e.g. --help)") def __init__(self, *args, **kwargs): super(CMDTab, self).__init__(*args, **kwargs) @@ -1362,7 +1365,63 @@ class CMDTab(TabPanel): def save_options(self): self.opt_manager.options['cmd_args'] = self.cmd_args_box.GetValue() + + +class LocalizationTab(TabPanel): + + """Options frame localization tab. + Attributes: + COMBOBOX_SIZE (tuple): Tuple that contains the size(width, height) + of the combobox widget. + + LOCALE_NAMES (TwoWayOrderedDict): Stores the locale names. + + *_LABEL (string): Constant string label for the widgets. + + """ + + COMBOBOX_SIZE = (150, 30) + + LOCALE_NAMES = twodict([ + ('en_US', 'English') + ]) + + RESTART_LABEL = _("Restart") + LOCALE_LABEL = _("Localization Language") + RESTART_MSG = _("In order for the changes to take effect please restart {0}") + + def __init__(self, *args, **kwargs): + super(LocalizationTab, self).__init__(*args, **kwargs) + + self.locale_text = self.create_statictext(self.LOCALE_LABEL) + self.locale_box = self.create_combobox(self.LOCALE_NAMES.values(), self.COMBOBOX_SIZE, self._on_locale) + + self._set_sizer() + + def _set_sizer(self): + main_sizer = wx.BoxSizer(wx.VERTICAL) + + main_sizer.AddSpacer(self.SIZE_50) + main_sizer.Add(self.locale_text, flag=wx.ALIGN_CENTER_HORIZONTAL) + + main_sizer.AddSpacer(self.SIZE_10) + main_sizer.Add(self.locale_box, flag=wx.ALIGN_CENTER_HORIZONTAL) + + self.SetSizer(main_sizer) + + def _on_locale(self, event): + """Event handler for the self.locale_box widget. """ + self.create_popup(self.RESTART_MSG.format(__appname__), + self.RESTART_LABEL, + wx.OK | wx.ICON_INFORMATION) + + def load_options(self): + self.locale_box.SetValue(self.LOCALE_NAMES[self.opt_manager.options['locale_name']]) + + def save_options(self): + self.opt_manager.options['locale_name'] = self.LOCALE_NAMES[self.locale_box.GetValue()] + class LogGUI(wx.Frame): @@ -1377,7 +1436,7 @@ class LogGUI(wx.Frame): """ - TITLE = "Log Viewer" + TITLE = _("Log Viewer") FRAME_SIZE = (650, 200) def __init__(self, parent=None): diff --git a/youtube_dl_gui/optionsmanager.py b/youtube_dl_gui/optionsmanager.py index 963aaef..3264d29 100644 --- a/youtube_dl_gui/optionsmanager.py +++ b/youtube_dl_gui/optionsmanager.py @@ -178,6 +178,8 @@ class OptionsManager(object): workers_number (int): Number of download workers that download manager will spawn. Must be greater than zero. + + locale_name (string): Locale name (e.g. ru_RU). """ self.options = { @@ -221,7 +223,8 @@ class OptionsManager(object): 'cmd_args': '', 'enable_log': True, 'log_time': False, - 'workers_number': 3 + 'workers_number': 3, + 'locale_name': 'en_US' } def load_from_file(self): diff --git a/youtube_dl_gui/utils.py b/youtube_dl_gui/utils.py index f87ed16..b019916 100644 --- a/youtube_dl_gui/utils.py +++ b/youtube_dl_gui/utils.py @@ -14,6 +14,8 @@ import os import sys import subprocess +from .info import __appname__ + _RANDOM_OBJECT = object() @@ -108,6 +110,37 @@ def get_time(seconds): return dtime + +def get_locale_file(): + """Search for youtube-dlg locale file. + + Returns: + The path to youtube-dlg locale file if exists else None. + + Note: + Paths that get_locale_file() func searches: + + Windows: __main__ dir. + Linux: __main__ dir, /usr/share/youtube-dlg + + """ + DIR_NAME = 'locale' + + # __main__ dir + directory = os.path.join(absolute_path(sys.argv[0]), DIR_NAME) + + if os.path.isdir(directory): + return directory + + if os.name != 'nt': + # /usr/share/youtube-dlg + directory = os.path.join('/usr', 'share', __appname__.lower(), DIR_NAME) + + if os.path.isdir(directory): + return directory + + return None + def get_icon_file(): """Search for youtube-dlg app icon.