From f85e3a6a8311dda29a4306904f092a5163cc03b2 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 2 Oct 2025 18:28:04 +0300 Subject: [PATCH] Add Japanese localization and update language support Added a new Japanese translation file (ja.json) and updated all language files to include Japanese in the language selection. Updated quality label color detection in ytsage_gui_format_table.py to support Japanese terms, and registered Japanese in the default language list in ytsage_localization.py. --- languages/ar.json | 1 + languages/de.json | 1 + languages/en.json | 1 + languages/es.json | 3 +- languages/fr.json | 1 + languages/hi.json | 1 + languages/id.json | 1 + languages/it.json | 1 + languages/ja.json | 338 +++++++++++++++++++++++++++++ languages/pl.json | 1 + languages/pt.json | 1 + languages/ru.json | 1 + languages/tr.json | 1 + languages/zh.json | 1 + src/gui/ytsage_gui_format_table.py | 10 +- src/utils/ytsage_localization.py | 3 +- 16 files changed, 359 insertions(+), 7 deletions(-) create mode 100644 languages/ja.json diff --git a/languages/ar.json b/languages/ar.json index d235e30..95cf234 100644 --- a/languages/ar.json +++ b/languages/ar.json @@ -17,6 +17,7 @@ "polish": "البولندية", "italian": "الإيطالية", "arabic": "العربية", + "japanese": "اليابانية", "help_text": "اختر اللغة المفضلة للواجهة.", "restart_notice": "سيتم تطبيق تغيير اللغة بعد إعادة تشغيل التطبيق." }, diff --git a/languages/de.json b/languages/de.json index 1056157..e2afb9e 100644 --- a/languages/de.json +++ b/languages/de.json @@ -17,6 +17,7 @@ "polish": "Polnisch", "italian": "Italienisch", "arabic": "Arabisch", + "japanese": "Japanisch", "help_text": "Wählen Sie Ihre bevorzugte Sprache für die Benutzeroberfläche.", "restart_notice": "Die Sprachänderung wird nach dem Neustart der Anwendung wirksam." }, diff --git a/languages/en.json b/languages/en.json index 67070f2..f515192 100644 --- a/languages/en.json +++ b/languages/en.json @@ -17,6 +17,7 @@ "polish": "Polski (Polish)", "italian": "Italiano (Italian)", "arabic": "العربية (Arabic)", + "japanese": "日本語 (Japanese)", "help_text": "Select your preferred language for the interface.", "restart_notice": "Language change will take effect after restarting the application." }, diff --git a/languages/es.json b/languages/es.json index 86b4f5e..68ce558 100644 --- a/languages/es.json +++ b/languages/es.json @@ -16,7 +16,8 @@ "turkish": "Turco", "polish": "Polaco", "italian": "Italiano", - "arabic": "Árabe" + "arabic": "Árabe", + "japanese": "Japonés" }, "app": { "title": "YTSage", diff --git a/languages/fr.json b/languages/fr.json index 9296916..be3cc05 100644 --- a/languages/fr.json +++ b/languages/fr.json @@ -17,6 +17,7 @@ "polish": "Polonais", "italian": "Italien", "arabic": "Arabe", + "japanese": "Japonais", "help_text": "Sélectionnez votre langue préférée pour l'interface.", "restart_notice": "Le changement de langue prendra effet après le redémarrage de l'application." }, diff --git a/languages/hi.json b/languages/hi.json index 9c3762a..0daaa7a 100644 --- a/languages/hi.json +++ b/languages/hi.json @@ -17,6 +17,7 @@ "polish": "पोलिश", "italian": "इतालवी", "arabic": "अरबी", + "japanese": "जापानी", "help_text": "इंटरफेस के लिए अपनी पसंदीदा भाषा चुनें।", "restart_notice": "भाषा परिवर्तन एप्लिकेशन पुनरारंभ के बाद प्रभावी होगा।" }, diff --git a/languages/id.json b/languages/id.json index b97a885..1e0cebf 100644 --- a/languages/id.json +++ b/languages/id.json @@ -17,6 +17,7 @@ "polish": "Bahasa Polandia", "italian": "Bahasa Italia", "arabic": "Bahasa Arab", + "japanese": "Bahasa Jepang", "help_text": "Pilih bahasa yang diinginkan untuk antarmuka.", "restart_notice": "Perubahan bahasa akan berlaku setelah memulai ulang aplikasi." }, diff --git a/languages/it.json b/languages/it.json index 52c5311..379661b 100644 --- a/languages/it.json +++ b/languages/it.json @@ -17,6 +17,7 @@ "polish": "Polacco", "italian": "Italiano", "arabic": "Arabo", + "japanese": "Giapponese", "help_text": "Seleziona la lingua preferita per l'interfaccia.", "restart_notice": "Il cambio di lingua avrà effetto dopo il riavvio dell'applicazione." }, diff --git a/languages/ja.json b/languages/ja.json new file mode 100644 index 0000000..4736feb --- /dev/null +++ b/languages/ja.json @@ -0,0 +1,338 @@ +{ + "language": { + "display_name": "日本語 (Japanese)", + "select_language": "言語を選択:", + "current_language": "現在の言語: {language}", + "restart_required": "言語の変更はアプリケーションの再起動後に有効になります。", + "english": "英語", + "spanish": "スペイン語", + "portuguese": "ポルトガル語", + "russian": "ロシア語", + "chinese": "中国語", + "german": "ドイツ語", + "french": "フランス語", + "hindi": "ヒンディー語", + "indonesian": "インドネシア語", + "turkish": "トルコ語", + "polish": "ポーランド語", + "italian": "イタリア語", + "arabic": "アラビア語", + "japanese": "日本語", + "help_text": "インターフェースの言語を選択してください。", + "restart_notice": "言語の変更はアプリケーションの再起動後に有効になります。" + }, + "app": { + "title": "YTSage", + "version": "v{version}", + "ready": "準備完了" + }, + "formats": { + "show_formats": "フォーマットを表示:", + "video_format": "動画フォーマット:", + "audio_format": "音声フォーマット:", + "no_formats": "利用可能なフォーマットがありません", + "loading": "フォーマットを読み込み中...", + "select": "選択", + "quality": "品質", + "extension": "拡張子", + "resolution": "解像度", + "file_size": "ファイルサイズ", + "codec": "コーデック", + "audio": "音声", + "notes": "備考", + "will_merge_audio": "音声が結合されます", + "has_audio": "✓ 音声あり", + "audio_only": "音声のみ", + "large_size": "大サイズ", + "medium_size": "中サイズ", + "standard_size": "標準サイズ", + "compatible": "互換性あり", + "efficient": "効率的", + "high_quality": "高品質", + "best_4k": "最高 (4K)", + "best_2k": "最高 (2K)", + "high_1080p": "高 (1080p)", + "high_720p": "高 (720p)", + "medium_480p": "中 (480p)", + "low_quality": "低品質", + "best_audio": "最高音質", + "high_audio": "高音質", + "medium_audio": "中音質", + "low_audio": "低音質", + "audio_only_resolution": "音声のみ" + }, + "buttons": { + "download": "ダウンロード", + "pause": "一時停止", + "resume": "再開", + "cancel": "キャンセル", + "browse": "参照", + "clear": "クリア", + "ok": "OK", + "apply": "適用", + "close": "閉じる", + "run_command": "コマンド実行", + "custom_command_help": "ヘルプ", + "about": "バージョン情報", + "analyze": "解析", + "paste_url": "URLを貼り付け", + "select_videos": "動画を選択...", + "video": "動画", + "audio_only": "音声のみ", + "custom_options": "カスタムオプション", + "trim_video": "動画をトリミング", + "download_settings": "ダウンロード設定", + "update": "yt-dlpを更新", + "select_defaults": "デフォルトを選択", + "select_all": "すべて選択", + "deselect_all": "すべて解除" + }, + "dialogs": { + "custom_options": "カスタムオプション", + "settings": "設定", + "select_folder": "ダウンロードフォルダを選択", + "sponsorblock_categories": "SponsorBlockカテゴリ", + "sponsorblock_description": "ダウンロード時に自動的に削除する動画セグメントの種類を選択してください。\nSponsorBlockはコミュニティ提供のデータを使用してこれらのセグメントを識別します。", + "select_subtitles": "字幕を選択", + "filter_languages_placeholder": "言語でフィルタ (例: ja, en)...", + "no_subtitles_available": "利用可能な字幕がありません", + "matching": "一致" + }, + "tabs": { + "cookies": "Cookieでログイン", + "custom_command": "カスタムコマンド", + "proxy": "プロキシ", + "language": "言語" + }, + "cookies": { + "help_text": "認証用のCookieを提供する方法を選択してください。\nこれにより、プライベート動画や高品質の音声ファイルをダウンロードできます。", + "cookie_source": "Cookieソース", + "use_cookie_file": "Cookieファイルを使用", + "extract_from_browser": "ブラウザから抽出", + "cookie_file": "Cookieファイル", + "cookie_file_placeholder": "cookies.txtへのパス...", + "browser_selection": "ブラウザ選択", + "browser_help": "Cookieを抽出するブラウザを選択してください:", + "browser_label": "ブラウザ:", + "profile_label": "プロファイル:", + "profile_placeholder": "デフォルト", + "browser_extract_message": "ブラウザのCookieは適用後に抽出されます", + "file_selected_message": "Cookieファイルが選択されました - OKをクリックして適用", + "select_file_title": "Cookieファイルを選択", + "file_filter": "Cookieファイル (*.txt *.lwp)" + }, + "custom_command": { + "help_text": "以下にカスタムyt-dlpコマンドを入力してください。現在のURLは自動的に追加されます。

オプションの完全なリストと使用例については、こちらをクリックしてyt-dlp公式ドキュメントを参照してください

注: ダウンロードパスとファイル名テンプレートは自動的に処理されます。", + "input_label": "yt-dlp引数:", + "input_placeholder": "yt-dlp引数をここに入力...\n\n例: --extract-audio --audio-format mp3", + "output_label": "コマンド出力:", + "output_placeholder": "コマンド出力がここに表示されます...", + "command_placeholder": "カスタムyt-dlpコマンドを入力...", + "command_help": "使用可能なプレースホルダー:\n{url} - 動画URL\n{output} - 出力フォルダ\n\n例: --write-info-json --write-thumbnail", + "full_command": "🔧 完全なコマンド: {command}", + "command_success": "✅ カスタムコマンドが正常に実行されました!", + "command_failed": "❌ コマンドが終了コード{code}で失敗しました", + "command_error": "❌ カスタムコマンドの実行エラー: {error}" + }, + "proxy": { + "help_text": "ダウンロード用のプロキシ設定を構成します。直接接続の場合は空白のままにしてください。", + "main_proxy": "メインプロキシ", + "main_proxy_help": "すべてのダウンロード用のメインプロキシサーバー。HTTP/HTTPSおよびSOCKS5プロトコルをサポートします。", + "proxy_url_label": "プロキシURL:", + "proxy_url_placeholder": "http://proxy:port または socks5://proxy:port", + "proxy_examples": "例:\n• HTTP: http://proxy.example.com:8080\n• SOCKS5: socks5://proxy.example.com:1080", + "geo_proxy": "地域制限回避プロキシ", + "geo_proxy_help": "地域制限を回避するための追加プロキシ。", + "geo_proxy_url_label": "地域制限回避プロキシURL:", + "geo_proxy_url_placeholder": "http://geo-proxy:port", + "clear_main_proxy": "メインプロキシをクリア", + "clear_geo_proxy": "地域プロキシをクリア", + "proxy_url": "プロキシURL", + "proxy_placeholder": "http://proxy:port または socks5://proxy:port", + "geo_bypass": "地域制限回避プロキシ (地域制限用)", + "geo_bypass_placeholder": "http://proxy:port 地域ブロック回避用", + "invalid_main_url": "メインプロキシのURL形式が無効です", + "invalid_geo_url": "地域プロキシのURL形式が無効です", + "main_configured": "メインプロキシが設定されました", + "geo_configured": "地域プロキシが設定されました" + }, + "download": { + "preparing": "ダウンロードを準備中...", + "please_enter_url": "最初にURLを入力してください。", + "please_set_path": "最初にダウンロードパスを設定してください。", + "please_enter_url_and_path": "URLを入力してダウンロードパスを設定してください。", + "please_select_format": "最初にフォーマットを選択してください。" + }, + "update": { + "title": "yt-dlpを更新", + "checking": "アップデートを確認中...", + "update_available": "アップデートが利用可能です!\n現在のバージョン: {current}\n最新バージョン: {latest}", + "up_to_date": "yt-dlpは最新です (バージョン {version})", + "could_not_determine": "バージョンを確認できませんでした。", + "error_comparing": "バージョン比較エラー: {error}", + "update_available_failed": "アップデートが利用可能です!(比較失敗)\n現在: {current}\n最新: {latest}", + "updating": "更新中...", + "initializing": "🚀 更新プロセスを初期化中...", + "checking_current": "🔍 現在のインストールを確認中...", + "found_at": "📍 yt-dlpが見つかりました: {path}", + "error_getting_path": "❌ yt-dlpパスの取得エラー: {error}", + "updating_binary": "📦 アプリ管理のyt-dlpバイナリを更新中...", + "updating_pip": "🐍 pipでシステムyt-dlpを更新中...", + "update_failed": "❌ yt-dlpの更新に失敗しました。もう一度試すか、インターネット接続を確認してください。", + "binary_updated": "✅ バイナリが正常に更新されました!", + "update_failed_stderr": "❌ yt-dlpの更新に失敗しました: {error}", + "update_timeout": "❌ yt-dlp更新がタイムアウトしました。", + "unexpected_error": "❌ 更新中に予期しないエラーが発生しました: {error}", + "checking_pip": "🔍 現在のpipインストールを確認中...", + "current_version": "📋 現在のバージョン: {version}", + "not_found_pip": "⚠️ pipでyt-dlpが見つかりません、インストールを試みています...", + "checking_latest": "🌐 最新バージョンを確認中...", + "failed_check_updates": "❌ アップデートの確認に失敗しました", + "latest_version": "🆕 最新バージョン: {version}", + "updating_from_to": "⬆️ {current}から{latest}に更新中...", + "running_pip_install": "📦 pip install --upgradeを実行中...", + "pip_completed": "✅ pipの更新が正常に完了しました!", + "pip_failed": "❌ pipの更新に失敗しました: {error}" + }, + "about": { + "title": "YTSageについて", + "version": "バージョン {version}", + "description": "クリーンなPySide6インターフェースを備えたモダンなYouTubeダウンローダー。", + "author": "作成者: {author}", + "github": "GitHub: {repo}", + "system_info": "システム情報", + "loading": "🔄 システム情報を読み込み中...", + "refresh": "🔄", + "refreshing": "🔄 更新中...", + "refresh_failed": "更新に失敗しました", + "refresh_failed_message": "バージョン情報を更新できませんでした。", + "detected": "✓ 検出済み", + "missing": "✗ 不足", + "not_available": "利用不可" + }, + "time_range": { + "title": "動画をトリミング", + "time_range_group": "時間範囲", + "start_time": "開始時間 (HH:MM:SS)", + "end_time": "終了時間 (HH:MM:SS)", + "start_placeholder": "00:00:00", + "end_placeholder": "00:00:00", + "start_time_placeholder": "開始時間 (HH:MM:SS)", + "end_time_placeholder": "終了時間 (HH:MM:SS)", + "force_keyframes": "カットポイントでキーフレームを強制", + "help_text": "動画をトリミングするには開始時間と終了時間を設定してください。\n完全な動画をダウンロードする場合は空白のままにしてください。", + "invalid_format": "時間フォーマットが無効です。HH:MM:SSフォーマットを使用してください。", + "start_after_end": "開始時間を終了時間より後にすることはできません。" + }, + "settings": { + "title": "ダウンロード設定", + "download_path": "ダウンロードパス", + "browse": "参照...", + "speed_limit": "速度制限", + "speed_limit_placeholder": "なし", + "auto_update_ytdlp": "yt-dlp自動更新", + "enable_auto_updates": "yt-dlp自動更新を有効化", + "update_frequency": "更新頻度:", + "check_startup": "起動時に毎回確認 (チェック間隔は最低1時間)", + "check_daily": "毎日確認", + "check_weekly": "毎週確認", + "check_updates_now": "今すぐ更新を確認", + "update_check_title": "更新確認", + "could_not_determine_version": "yt-dlpの現在のバージョンを確認できませんでした。", + "update_available_dialog": "アップデートが利用可能です!\n\n現在: {current}\n最新: {latest}\n\nメインウィンドウの「yt-dlpを更新」ボタンを使用して更新してください。", + "up_to_date_dialog": "yt-dlpは最新です!\n\n現在のバージョン: {version}", + "error_checking_updates": "更新確認エラー: {error}", + "settings_saved_title": "設定を保存しました", + "settings_saved_message": "自動更新設定が正常に保存されました!", + "error_title": "エラー", + "failed_save_settings": "自動更新設定の保存に失敗しました。", + "error_saving_settings": "自動更新設定の保存エラー: {error}", + "auto_update_title": "自動更新設定", + "auto_update_header": "🔄 自動更新設定", + "auto_update_description": "yt-dlpの自動更新を設定して、最新の機能とバグ修正を確実に入手してください。", + "current_status": "現在のステータス", + "current_version_label": "現在のyt-dlpバージョン: 確認中...", + "last_check_label": "最終更新確認: なし", + "next_check_label": "次回確認: 設定に基づく", + "manual_check_button": "🔍 今すぐ更新を確認", + "update_frequency_group": "更新頻度", + "save_settings": "設定を保存", + "settings_saved_successfully": "✅ 設定が正常に保存されました!", + "error_saving": "❌ 設定の保存エラー: {error}" + }, + "main_ui": { + "url_placeholder": "YouTubeの動画URLまたはプレイリストURLを入力", + "merge_subtitles": "字幕を結合", + "save_thumbnail": "サムネイルを保存", + "save_description": "説明を保存", + "embed_chapters": "チャプターを埋め込む", + "subtitles_selected": "{count}個選択", + "all_selected": "すべて選択済み", + "select_videos_all": "動画を選択... (すべて選択済み)", + "please_enter_url": "最初にURLを入力してください", + "cookie_file_selected_title": "Cookieファイルが選択されました", + "cookie_file_selected_message": "選択されたCookieファイル: {path}", + "browser_cookies_selected_title": "ブラウザCookieが選択されました", + "browser_cookies_selected_message": "ブラウザCookieが抽出されます: {browser}", + "error_no_format_info": "エラー: 利用可能なフォーマット情報がありません。", + "error_extract_info": "エラー: 基本的な動画情報を抽出できませんでした。リンクを確認してください。", + "analyzing_preparing": "解析中 (0%)... リクエストを準備中", + "analyzing_extracting_basic": "解析中 (15%)... 基本情報を抽出中", + "analyzing_extracting_detailed": "解析中 (30%)... 詳細情報を抽出中", + "analyzing_processing_video": "解析中 (45%)... 動画データを処理中", + "analyzing_processing_formats": "解析中 (60%)... フォーマットを処理中", + "analyzing_loading_thumbnail": "解析中 (75%)... サムネイルを読み込み中", + "analyzing_processing_subtitles": "解析中 (85%)... 字幕を処理中", + "analyzing_updating_table": "解析中 (95%)... フォーマットテーブルを更新中", + "analysis_complete": "解析完了!", + "analyzing_extracting_ytdlp": "解析中 (30%)... yt-dlp実行ファイルを使用して情報を抽出中", + "analyzing_processing_data": "解析中 (60%)... データを処理中", + "analyzing_processing_formats_ytdlp": "解析中 (75%)... フォーマットを処理中", + "analyzing_loading_thumbnail_ytdlp": "解析中 (85%)... サムネイルを読み込み中", + "analyzing_processing_subtitles_ytdlp": "解析中 (90%)... 字幕を処理中", + "select_subtitles": "字幕を選択...", + "sponsorblock_categories": "SponsorBlockカテゴリ..." + }, + "sponsorblock": { + "sponsor": "スポンサー", + "sponsor_desc": "有料広告、有料推薦、直接広告", + "selfpromo": "無報酬/自己宣伝", + "selfpromo_desc": "クリエイター自身のコンテンツの無報酬プロモーション", + "interaction": "インタラクションリマインダー", + "interaction_desc": "視聴者に「いいね」、登録、ソーシャルメディアでのフォローを求める", + "intro": "イントロ", + "intro_desc": "スキップ可能な動画のイントロ", + "outro": "アウトロ/エンドカード", + "outro_desc": "エンドクレジットまたは動画の終了", + "preview": "プレビュー/要約", + "preview_desc": "前回の動画の短い要約または今後のコンテンツのプレビュー", + "music_offtopic": "非音楽セクション", + "music_offtopic_desc": "音楽動画のみ。非音楽セクションを示す", + "filler": "余談フィラー", + "filler_desc": "フィラーやユーモアのためだけに追加された余談シーン" + }, + "video_info": { + "channel": "チャンネル", + "views": "視聴回数", + "likes": "いいね", + "upload_date": "アップロード日", + "duration": "長さ", + "unknown_channel": "不明なチャンネル", + "unknown_date": "不明な日付", + "unknown_title": "不明なタイトル" + }, + "command": { + "running": "実行中...", + "run_command": "コマンド実行" + }, + "selection": { + "none_selected": "0個選択", + "one_selected": "1カテゴリ選択", + "count_selected": "{count}個選択" + }, + "status": { + "ready": "準備完了", + "file_exists": "⚠️ ファイルが既に存在します", + "cancelling": "ダウンロードをキャンセル中..." + } +} \ No newline at end of file diff --git a/languages/pl.json b/languages/pl.json index 8ab0bbb..9ac5bf3 100644 --- a/languages/pl.json +++ b/languages/pl.json @@ -17,6 +17,7 @@ "polish": "Polski", "italian": "Włoski", "arabic": "Arabski", + "japanese": "Japoński", "help_text": "Wybierz preferowany język interfejsu.", "restart_notice": "Zmiana języka zostanie zastosowana po ponownym uruchomieniu aplikacji." }, diff --git a/languages/pt.json b/languages/pt.json index 6a9dd93..3e2bfd3 100644 --- a/languages/pt.json +++ b/languages/pt.json @@ -17,6 +17,7 @@ "polish": "Polonês", "italian": "Italiano", "arabic": "Árabe", + "japanese": "Japonês", "help_text": "Selecione seu idioma preferido para a interface.", "restart_notice": "A alteração de idioma terá efeito após reiniciar a aplicação." }, diff --git a/languages/ru.json b/languages/ru.json index f3c3030..21bc797 100644 --- a/languages/ru.json +++ b/languages/ru.json @@ -17,6 +17,7 @@ "polish": "Польский", "italian": "Итальянский", "arabic": "Арабский", + "japanese": "Японский", "help_text": "Выберите предпочитаемый язык для интерфейса.", "restart_notice": "Изменение языка вступит в силу после перезапуска приложения." }, diff --git a/languages/tr.json b/languages/tr.json index e06b6d6..78a075e 100644 --- a/languages/tr.json +++ b/languages/tr.json @@ -17,6 +17,7 @@ "polish": "Lehçe", "italian": "İtalyanca", "arabic": "Arapça", + "japanese": "Japonca", "help_text": "Arayüz için tercih ettiğiniz dili seçin.", "restart_notice": "Dil değişikliği uygulamayı yeniden başlattıktan sonra geçerli olacaktır." }, diff --git a/languages/zh.json b/languages/zh.json index 39702f1..e49884f 100644 --- a/languages/zh.json +++ b/languages/zh.json @@ -17,6 +17,7 @@ "polish": "波兰语", "italian": "意大利语", "arabic": "阿拉伯语", + "japanese": "日语", "help_text": "选择您喜欢的界面语言。", "restart_notice": "语言更改将在重启应用程序后生效。" }, diff --git a/src/gui/ytsage_gui_format_table.py b/src/gui/ytsage_gui_format_table.py index b4c79ec..c4f0467 100644 --- a/src/gui/ytsage_gui_format_table.py +++ b/src/gui/ytsage_gui_format_table.py @@ -264,15 +264,15 @@ class FormatTableMixin: # Column 1: Quality (Always shown) quality_text = self.get_quality_label(f) quality_item = QTableWidgetItem(quality_text) - # Set color based on quality (check English, Spanish, Portuguese, Russian, Chinese, German, French, Hindi, Indonesian, Turkish, Polish, Italian, and Arabic terms) + # Set color based on quality (check English, Spanish, Portuguese, Russian, Chinese, German, French, Hindi, Indonesian, Turkish, Polish, Italian, Arabic, and Japanese terms) quality_lower = quality_text.lower() # Make comparison case-insensitive - if any(term.lower() in quality_lower for term in ["Best", "Óptima", "Mejor", "Melhor", "Лучшее", "最佳", "Beste", "Meilleure", "सर्वोत्तम", "Terbaik", "En iyi", "Najlepsza", "Najlepszy", "Najlepsze", "Migliore", "Miglior", "الأفضل", "أفضل"]): + if any(term.lower() in quality_lower for term in ["Best", "Óptima", "Mejor", "Melhor", "Лучшее", "最佳", "Beste", "Meilleure", "सर्वोत्तम", "Terbaik", "En iyi", "Najlepsza", "Najlepszy", "Najlepsze", "Migliore", "Miglior", "الأفضل", "أفضل", "最高"]): quality_item.setForeground(QColor("#00ff00")) # Green for best quality - elif any(term.lower() in quality_lower for term in ["High", "Alta", "Alto", "Áudio Alto", "Audio Alto", "Высокое", "高清", "高质量", "Hoch", "Haute", "Élevé", "Audio élevé", "उच्च", "उच्च ऑडियो", "Tinggi", "Audio tinggi", "Yüksek", "Yüksek ses", "Wysoka", "Wysoki", "Wysokie", "Alta", "Audio alto", "عالية", "عالي", "صوت عالي"]): + elif any(term.lower() in quality_lower for term in ["High", "Alta", "Alto", "Áudio Alto", "Audio Alto", "Высокое", "高清", "高质量", "Hoch", "Haute", "Élevé", "Audio élevé", "उच्च", "उच्च ऑडियो", "Tinggi", "Audio tinggi", "Yüksek", "Yüksek ses", "Wysoka", "Wysoki", "Wysokie", "Alta", "Audio alto", "عالية", "عالي", "صوت عالي", "高", "高音質"]): quality_item.setForeground(QColor("#00cc00")) # Light green for high quality - elif any(term.lower() in quality_lower for term in ["Medium", "Media", "Medio", "Média", "Áudio Médio", "Audio Medio", "Среднее", "中等", "Mittel", "Moyenne", "Audio moyen", "मध्यम", "मध्यम ऑडियो", "Sedang", "Audio sedang", "Orta", "Orta ses", "Średnia", "Średni", "Średnie", "Media", "Audio medio", "متوسطة", "متوسط", "صوت متوسط"]): + elif any(term.lower() in quality_lower for term in ["Medium", "Media", "Medio", "Média", "Áudio Médio", "Audio Medio", "Среднее", "中等", "Mittel", "Moyenne", "Audio moyen", "मध्यम", "मध्यम ऑडियो", "Sedang", "Audio sedang", "Orta", "Orta ses", "Średnia", "Średni", "Średnie", "Media", "Audio medio", "متوسطة", "متوسط", "صوت متوسط", "中", "中音質"]): quality_item.setForeground(QColor("#ffaa00")) # Orange for medium quality - elif any(term.lower() in quality_lower for term in ["Low", "Baja", "Bajo", "Baixa", "Áudio Baixo", "Audio Bajo", "Низкое", "低质量", "Niedrig", "Niedriges Audio", "Faible", "Audio faible", "Qualité faible", "निम्न", "निम्न ऑडियो", "निम्न गुणवत्ता", "Rendah", "Audio rendah", "Kualitas rendah", "Düşük", "Düşük ses", "Düşük kalite", "Niska", "Niski", "Niskie", "Bassa", "Audio basso", "Bassa qualità", "منخفضة", "منخفض", "صوت منخفض", "جودة منخفضة"]): + elif any(term.lower() in quality_lower for term in ["Low", "Baja", "Bajo", "Baixa", "Áudio Baixo", "Audio Bajo", "Низкое", "低质量", "Niedrig", "Niedriges Audio", "Faible", "Audio faible", "Qualité faible", "निम्न", "निम्न ऑडियो", "निम्न गुणवत्ता", "Rendah", "Audio rendah", "Kualitas rendah", "Düşük", "Düşük ses", "Düşük kalite", "Niska", "Niski", "Niskie", "Bassa", "Audio basso", "Bassa qualità", "منخفضة", "منخفض", "صوت منخفض", "جودة منخفضة", "低", "低音質", "低品質"]): quality_item.setForeground(QColor("#ff5555")) # Red for low quality self.format_table.setItem(row, 1, quality_item) diff --git a/src/utils/ytsage_localization.py b/src/utils/ytsage_localization.py index 48544b9..1116fb5 100644 --- a/src/utils/ytsage_localization.py +++ b/src/utils/ytsage_localization.py @@ -92,7 +92,8 @@ class LocalizationManager: "turkish": "Türkçe (Turkish)", "polish": "Polski (Polish)", "italian": "Italiano (Italian)", - "arabic": "العربية (Arabic)" + "arabic": "العربية (Arabic)", + "japanese": "日本語 (Japanese)" }, "download": { "preparing": "🚀 Preparing your download...",