mirror of https://github.com/jumpserver/jumpserver
				
				
				
			perf: 添加进度条
							parent
							
								
									f0dfff0625
								
							
						
					
					
						commit
						1cec27ed70
					
				
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -1,199 +1,201 @@
 | 
			
		|||
{
 | 
			
		||||
    "ACL reject login asset": "アクセス制御ポリシーの制限により、このログインは拒否されました",
 | 
			
		||||
    "ACL reject login asset": "このログインはアクセス制御ポリシーの制限により拒否されました",
 | 
			
		||||
    "Account info": "アカウント情報",
 | 
			
		||||
    "Account not found": "アカウントが見つかりません",
 | 
			
		||||
    "Account: ": "アカウント: {{value}}",
 | 
			
		||||
    "Action: ": "アクション: ",
 | 
			
		||||
    "Advanced option": "上級オプション",
 | 
			
		||||
    "All sessions": "すべてのセッション",
 | 
			
		||||
    "Applet": "アプレット",
 | 
			
		||||
    "Applet connect method": "アプレット接続方法",
 | 
			
		||||
    "Are you sure to reconnect it?(RDP not support)": "本当に再接続しますか? (RDPは一時的にサポートしていない)",
 | 
			
		||||
    "Asset disabled": "この資産はすでに無効になっている場合、管理者に連絡してください",
 | 
			
		||||
    "Asset not found or You have no permission to access it, please refresh asset tree": "アセットが見つからないか、アクセスする権限がありません。アセット ツリーを更新してください",
 | 
			
		||||
    "Asset tree loading method": "資産ツリーのロード方法の設定",
 | 
			
		||||
    "Asset: ": "アセット: {{value}}",
 | 
			
		||||
    "Assignees": "受信者",
 | 
			
		||||
    "Automatic login next": "次回の自動登録 (右クリック資産接続は再選択できます)",
 | 
			
		||||
    "Backspace as Ctrl+H": "文字端末backspacas Ctrl H",
 | 
			
		||||
    "Batch actions": "バッチ操作",
 | 
			
		||||
    "Batch connect": "バッチ接続",
 | 
			
		||||
    "Belgian French keyboard layout": "Belgian French (Azerty)",
 | 
			
		||||
    "Action: ": "操作:",
 | 
			
		||||
    "Advanced option": "高度なオプション",
 | 
			
		||||
    "All sessions": "全セッション",
 | 
			
		||||
    "Applet": "リモートアプリケーション",
 | 
			
		||||
    "Applet connect method": "リモートアプリケーションの接続方法",
 | 
			
		||||
    "Are you sure to reconnect it?(RDP not support)": "再接続しますか?(RDPは暫定的にサポートしていません)",
 | 
			
		||||
    "Asset disabled": "この資産は無効化されています、管理者に連絡してください",
 | 
			
		||||
    "Asset not found or You have no permission to access it, please refresh asset tree": "資産が見つからないか、あなたがアクセスする権限がない、資産ツリーをリフレッシュしてください",
 | 
			
		||||
    "Asset tree loading method": "資産ツリーの読み込み方法を設定",
 | 
			
		||||
    "Asset: ": "資産: {{value}}",
 | 
			
		||||
    "Assignees": "受付人",
 | 
			
		||||
    "Automatic login next": "次回は自動ログイン(アセットリンクを右クリックすると再選択できます)",
 | 
			
		||||
    "Backspace as Ctrl+H": "バックスペースキーをCtrl+Hとして使用",
 | 
			
		||||
    "Batch actions": "一括操作",
 | 
			
		||||
    "Batch connect": "一括接続",
 | 
			
		||||
    "Belgian French keyboard layout": "Belgian French(Azerty)",
 | 
			
		||||
    "CLI": "コマンドライン",
 | 
			
		||||
    "CLI font size": "文字端末のフォントサイズ",
 | 
			
		||||
    "CLI font size": "キャラクターターミナルのフォントサイズ",
 | 
			
		||||
    "Cancel": "キャンセル",
 | 
			
		||||
    "Charset": "文字セット",
 | 
			
		||||
    "Checkbox": "複数選択",
 | 
			
		||||
    "Choose a User": "ユーザーを選択します",
 | 
			
		||||
    "Click to copy": "クリックしてコピーする",
 | 
			
		||||
    "Client": "お客様",
 | 
			
		||||
    "Clone Connect": "コピーウィンドウ",
 | 
			
		||||
    "Close": "閉鎖",
 | 
			
		||||
    "Close All Tabs": "すべてを閉じる",
 | 
			
		||||
    "Close Current Tab": "現在を閉じる",
 | 
			
		||||
    "Checkbox": "複数選択 ",
 | 
			
		||||
    "Choose a User": "ユーザーを選択",
 | 
			
		||||
    "Click to copy": "クリックしてコピー",
 | 
			
		||||
    "Client": "クライアント",
 | 
			
		||||
    "Clone Connect": "ウィンドウをコピー",
 | 
			
		||||
    "Close": "閉じる",
 | 
			
		||||
    "Close All Tabs": "全て閉じる",
 | 
			
		||||
    "Close Current Tab": "現在のウィンドウを閉じる",
 | 
			
		||||
    "Close Left Tabs": "左側を閉じる",
 | 
			
		||||
    "Close Other Tabs": "その他を閉じる",
 | 
			
		||||
    "Close Other Tabs": "それ以外を閉じる",
 | 
			
		||||
    "Close Right Tabs": "右側を閉じる",
 | 
			
		||||
    "Close split connect": "分割表示を閉じる",
 | 
			
		||||
    "Close split connect": "分割画面を閉じる",
 | 
			
		||||
    "Command Line": "コマンドライン",
 | 
			
		||||
    "Command line": "命令行",
 | 
			
		||||
    "Command line": "コマンドラインに接続",
 | 
			
		||||
    "Confirm": "確認",
 | 
			
		||||
    "Connect": "接続",
 | 
			
		||||
    "Connect Method": "接続方法",
 | 
			
		||||
    "Connect checked": "接続済み",
 | 
			
		||||
    "Connect command line": "接続コマンドライン",
 | 
			
		||||
    "Copied": "複製済み",
 | 
			
		||||
    "Copy link": "リンクをコピーする",
 | 
			
		||||
    "Connect checked": "選択した接続",
 | 
			
		||||
    "Connect command line": "コマンドラインへの接続",
 | 
			
		||||
    "Copied": "コピー済み",
 | 
			
		||||
    "Copy link": "リンクをコピー",
 | 
			
		||||
    "Current online": "現在オンライン",
 | 
			
		||||
    "Current session": "現在のセッション",
 | 
			
		||||
    "Database": "データベース",
 | 
			
		||||
    "Database disabled": "このリンク方式をサポートしていない、管理者に連絡してください",
 | 
			
		||||
    "Database info": "データベース接続情報",
 | 
			
		||||
    "Database token help text": "  クライアントが接続するデータベースの種類のトークンは、コンポーネントによって5分間キャッシュされます。つまり、トークンは使用後すぐに無効になるわけではありませんが、クライアントが切断されてから5分後に無効になります",
 | 
			
		||||
    "Database connect info": "データベース接続情報",
 | 
			
		||||
    "Database disabled": "この種類の接続はサポートされていません, 管理者に連絡してください",
 | 
			
		||||
    "Database info": "データベース情報",
 | 
			
		||||
    "Database token help text": "データベース型のトークンは5分間キャッシュされます。つまり、トークンを使用してから、すぐには無効にならず、クライアントが切断されてから5分後に、このトークンは完全に無効になります。",
 | 
			
		||||
    "Databases": "データベース",
 | 
			
		||||
    "Directly": "直接接続",
 | 
			
		||||
    "Disable auto completion": "自動補完の無効化",
 | 
			
		||||
    "Disconnect": "リンクを切断",
 | 
			
		||||
    "Disfavor": "コレクションをキャンセル",
 | 
			
		||||
    "Directly": "ユーザー名は、指定された資産とアカウントに接続します",
 | 
			
		||||
    "Disable auto completion": "オートコンプリートを無効にする",
 | 
			
		||||
    "Disconnect": "接続を切断",
 | 
			
		||||
    "Disfavor": "お気に入り解除",
 | 
			
		||||
    "Do not close this page": "このページを閉じないでください",
 | 
			
		||||
    "Document": "ドキュメント",
 | 
			
		||||
    "Don't prompt again": "次回は提示しない",
 | 
			
		||||
    "Document": "文書",
 | 
			
		||||
    "Don't prompt again": "次回から表示しない",
 | 
			
		||||
    "Download": "ダウンロード",
 | 
			
		||||
    "Download the latest client": "最新クライアントのダウンロード",
 | 
			
		||||
    "Driver redirect": "ディスクマウント",
 | 
			
		||||
    "Download the latest client": "最新のクライアントをダウンロード",
 | 
			
		||||
    "Driver redirect": "ディスクのマウント",
 | 
			
		||||
    "Expand": "展開",
 | 
			
		||||
    "Expand all": "すべて展開",
 | 
			
		||||
    "Expand all asset": "現在のノードの下にあるすべてのアセットを展開",
 | 
			
		||||
    "Expire time": "期限切れ",
 | 
			
		||||
    "Failed to open address": "アドレスを開くことができませんでした",
 | 
			
		||||
    "Favorite": "コレクション",
 | 
			
		||||
    "Expand all": "全て展開",
 | 
			
		||||
    "Expand all asset": "全ての資産を展開",
 | 
			
		||||
    "Expire time": "有効期限",
 | 
			
		||||
    "Failed to open address": "アドレスの開封に失敗",
 | 
			
		||||
    "Favorite": "お気に入り",
 | 
			
		||||
    "File Manager": "ファイル管理",
 | 
			
		||||
    "Fold": "折りたたみ",
 | 
			
		||||
    "Fold all": "すべて折りたたみ",
 | 
			
		||||
    "Force refresh": "強制更新",
 | 
			
		||||
    "Fold": "折りたたむ",
 | 
			
		||||
    "Fold all": "全て折りたたむ",
 | 
			
		||||
    "Force refresh": "強制的に更新",
 | 
			
		||||
    "Found": "発見",
 | 
			
		||||
    "French keyboard layout": "French (Azerty)",
 | 
			
		||||
    "French keyboard layout": "フレンチ(アゼルティ)",
 | 
			
		||||
    "Full Screen": "全画面表示",
 | 
			
		||||
    "Full screen": "全画面",
 | 
			
		||||
    "GUI": "グラフィカル",
 | 
			
		||||
    "General": "基本構成",
 | 
			
		||||
    "Full screen": "フルスクリーン",
 | 
			
		||||
    "GUI": "視覚化",
 | 
			
		||||
    "General": "基本設定",
 | 
			
		||||
    "Help": "ヘルプ",
 | 
			
		||||
    "Help or download": "ヘルプ → ダウンロード",
 | 
			
		||||
    "Help text": "します",
 | 
			
		||||
    "Hide left manager": "左サイドバーを非表示",
 | 
			
		||||
    "Help or download": "メニューヘルプ → ダウンロード",
 | 
			
		||||
    "Help text": "説明",
 | 
			
		||||
    "Hide left manager": "左のサイドバーを隠す",
 | 
			
		||||
    "Host": "ホスト",
 | 
			
		||||
    "Info": "ヒント",
 | 
			
		||||
    "InstallClientMsg": "JumpServerクライアントがインストールされていない、今ダウンロードしてインストールしますか?",
 | 
			
		||||
    "Japanese keyboard layout": "Japanese (Qwerty)",
 | 
			
		||||
    "InstallClientMsg": "JumpServerクライアントがインストールされていません、今すぐダウンロードしてインストールしますか?",
 | 
			
		||||
    "Japanese keyboard layout": "日本語 (Qwerty)",
 | 
			
		||||
    "Keyboard keys": "Option + Left / Option + Right",
 | 
			
		||||
    "Keyboard layout": "キーボードレイアウト",
 | 
			
		||||
    "Keyboard switch session": "セッションの切り替え → ショートカットキー",
 | 
			
		||||
    "Keyboard switch session": "会話を切り替え → ショートカット",
 | 
			
		||||
    "Kubernetes": "Kubernetes",
 | 
			
		||||
    "Language": "言語",
 | 
			
		||||
    "Last login": "前回ログイン",
 | 
			
		||||
    "Launch Program": "起動プログラム",
 | 
			
		||||
    "LeftInfo": "コマンドログをクリックして迅速に定位できるビデオ",
 | 
			
		||||
    "Load tree async": "アセットツリーの非同期ロード",
 | 
			
		||||
    "Loading": "ロード中",
 | 
			
		||||
    "Log out": "ログインを終了",
 | 
			
		||||
    "Last login": "前回のログイン",
 | 
			
		||||
    "Launch Program": "プログラムを開始",
 | 
			
		||||
    "LeftInfo": "コマンドレコードをクリックすると、録画を素早く見つけられます",
 | 
			
		||||
    "Load tree async": "非同期でアセットツリーを読み込む",
 | 
			
		||||
    "Loading": "読み込み中",
 | 
			
		||||
    "Log out": "ログアウト",
 | 
			
		||||
    "Login reminder": "ログインリマインダー",
 | 
			
		||||
    "Login review approved": "ログイン監査に合格し、アセットを接続しています...",
 | 
			
		||||
    "LoginExpireMsg": "ログインが期限切れになりました。ログインし直してください",
 | 
			
		||||
    "Login review approved": "ログイン審査が通過しました, 資産へ接続中...",
 | 
			
		||||
    "LoginExpireMsg": "ログインが期限切れです。再度ログインしてください。",
 | 
			
		||||
    "Manual accounts": "手動アカウント",
 | 
			
		||||
    "Module": "ユニット",
 | 
			
		||||
    "Multi Screen": "マルチスクリーン",
 | 
			
		||||
    "My applications": "私の応用",
 | 
			
		||||
    "My assets": "マイ資産",
 | 
			
		||||
    "Name": "めいしょう",
 | 
			
		||||
    "Module": "モジュール",
 | 
			
		||||
    "Multi Screen": "マルチスクリーン表示",
 | 
			
		||||
    "My applications": "マイアプリ",
 | 
			
		||||
    "My assets": "私の資産",
 | 
			
		||||
    "Name": "名前",
 | 
			
		||||
    "Native": "クライアント",
 | 
			
		||||
    "Need review for login asset": "このログインは手動で確認する必要があります。続行しますか?",
 | 
			
		||||
    "Need to use": "使用する必要がある",
 | 
			
		||||
    "No": "いいえ",
 | 
			
		||||
    "No account available": "アカウントがありません",
 | 
			
		||||
    "No available connect method": "接続方法がありません",
 | 
			
		||||
    "No matching found": "マッチがありません",
 | 
			
		||||
    "Need review for login asset": "今回のログインは人間によるオーディットが必要です、続行しますか?",
 | 
			
		||||
    "Need to use": "使用が必要",
 | 
			
		||||
    "No": "否",
 | 
			
		||||
    "No account available": "使用可能なアカウントがありません",
 | 
			
		||||
    "No available connect method": "利用可能な接続方法がありません",
 | 
			
		||||
    "No matching found": "該当する項目はありません",
 | 
			
		||||
    "No permission": "権限がありません",
 | 
			
		||||
    "No protocol available": "利用可能なプロトコルがありません",
 | 
			
		||||
    "Normal accounts": "通常のログインアカウント",
 | 
			
		||||
    "Not quick command": "非高速コマンド",
 | 
			
		||||
    "Open in new window": "新しいウィンドウが開きます",
 | 
			
		||||
    "Not quick command": "ショートカットコマンドはありません",
 | 
			
		||||
    "Open in new window": "新しいウィンドウで開く",
 | 
			
		||||
    "Password": "パスワード",
 | 
			
		||||
    "Password is token password on the table": "パスワードは、テーブルのトークンパスワードです",
 | 
			
		||||
    "Password is your password login to system": "パスワードは、システムにログインするためのパスワードです",
 | 
			
		||||
    "Pause": "タスクを一時停止",
 | 
			
		||||
    "Pause task has been send": "一時停止タスクが送信されました",
 | 
			
		||||
    "Password is token password on the table": "パスワードは表のトークンパスワードです",
 | 
			
		||||
    "Password is your password login to system": "パスワードはあなたのログインシステムのパスワードです",
 | 
			
		||||
    "Pause": "一時停止",
 | 
			
		||||
    "Pause task has been send": "一時停止タスクは送信されました",
 | 
			
		||||
    "Please choose an account": "ユーザーを選択してください",
 | 
			
		||||
    "Please input password": "パスワードを入力してください",
 | 
			
		||||
    "Port": "ポート",
 | 
			
		||||
    "Protocol": "プロトコル",
 | 
			
		||||
    "Protocol": "規約",
 | 
			
		||||
    "Protocol: ": "プロトコル: {{value}}",
 | 
			
		||||
    "RDP Client": "RDPクライアント",
 | 
			
		||||
    "RDP File": "RDPファイル",
 | 
			
		||||
    "RDP client options": "RDPクライアントオプション",
 | 
			
		||||
    "RDP color quality": "RDP 色品質",
 | 
			
		||||
    "RDP resolution": "RDP 解像度",
 | 
			
		||||
    "RDP smart size": "RDP スマート・サイズ",
 | 
			
		||||
    "Re-use for a long time after opening": "開いた後、長い間再利用する",
 | 
			
		||||
    "RDP color quality": "RDP色品質",
 | 
			
		||||
    "RDP resolution": "RDP解像度",
 | 
			
		||||
    "RDP smart size": "RDPスマートサイズ",
 | 
			
		||||
    "Re-use for a long time after opening": "有効にした後、この接続情報を長期間、何度でも使用できます",
 | 
			
		||||
    "Reconnect": "再接続",
 | 
			
		||||
    "Refresh": "リフレッシュ",
 | 
			
		||||
    "Remember password": "パスワードを覚える",
 | 
			
		||||
    "Remember select": "選択を覚える",
 | 
			
		||||
    "Refresh": "更新",
 | 
			
		||||
    "Remember password": "パスワードを保持",
 | 
			
		||||
    "Remember select": "選択を記憶",
 | 
			
		||||
    "Remote apps": "リモートアプリケーション",
 | 
			
		||||
    "Reselect connection method": "資産の接続方法の再選択",
 | 
			
		||||
    "Resume": "タスクを再開",
 | 
			
		||||
    "Resume task has been send": "タスクが再開されました",
 | 
			
		||||
    "Right click asset": "右クリック資産",
 | 
			
		||||
    "Right click node": "右クリックノード",
 | 
			
		||||
    "Right mouse quick paste": "右クイック貼り付け",
 | 
			
		||||
    "Run it by client": "クライアントで実行する",
 | 
			
		||||
    "Reselect connection method": "接続方法を再選択可能",
 | 
			
		||||
    "Resume": "回復",
 | 
			
		||||
    "Resume task has been send": "復旧タスクが送信されました",
 | 
			
		||||
    "Right click asset": "資産を右クリック → 接続",
 | 
			
		||||
    "Right click node": "ノードを右クリック→全て展開",
 | 
			
		||||
    "Right mouse quick paste": "右クリックで速やかにペースト",
 | 
			
		||||
    "Run it by client": "クライアントで実行",
 | 
			
		||||
    "SQL Client": "SQLクライアント",
 | 
			
		||||
    "Save command": "保存コマンド",
 | 
			
		||||
    "Save success": "保存に成功",
 | 
			
		||||
    "Save command": "コマンドを保存",
 | 
			
		||||
    "Save success": "保存が成功しました",
 | 
			
		||||
    "Search": "検索",
 | 
			
		||||
    "Select account": "システムユーザーの選択",
 | 
			
		||||
    "Select account": "アカウントを選択",
 | 
			
		||||
    "Send command": "コマンドを送信",
 | 
			
		||||
    "Send text to all ssh terminals": "すべてのssh端末にテキストを送信します",
 | 
			
		||||
    "Set reusable": "再利用可能な",
 | 
			
		||||
    "Send text to all ssh terminals": "全てのssh端末にテキストを送信",
 | 
			
		||||
    "Set reusable": "再利用を開始",
 | 
			
		||||
    "Setting": "設定",
 | 
			
		||||
    "Settings or basic settings": "設定 → 基本設定",
 | 
			
		||||
    "Show left manager": "左サイドバーを表示",
 | 
			
		||||
    "Settings or basic settings": "メニュー設定 → 基本設定",
 | 
			
		||||
    "Show left manager": "左側のバーを表示",
 | 
			
		||||
    "Skip": "スキップ",
 | 
			
		||||
    "Skip manual password": "手動パスワードウィンドウをスキップします",
 | 
			
		||||
    "Special account": "特別なアカウント",
 | 
			
		||||
    "Special accounts": "特別ログインアカウント",
 | 
			
		||||
    "Speed": "スピード",
 | 
			
		||||
    "Split connect": "スクリーン接続",
 | 
			
		||||
    "Split connect number": "1つのセッションで最大3つの画面分割接続をサポート",
 | 
			
		||||
    "Split vertically": "垂直分割",
 | 
			
		||||
    "Start Time: ": "開始時間: {{value}}",
 | 
			
		||||
    "Stop": "Stop",
 | 
			
		||||
    "Skip manual password": "手動パスワードウィンドウをスキップ",
 | 
			
		||||
    "Special accounts": "特別なアカウント",
 | 
			
		||||
    "Speed": "速度",
 | 
			
		||||
    "Split connect": "スプリット画面で接続",
 | 
			
		||||
    "Split connect number": "1セッションに最大3つの分割接続が可能",
 | 
			
		||||
    "Split vertically": "垂直分割スクリーン",
 | 
			
		||||
    "Start Time: ": "開始時間:{{value}}",
 | 
			
		||||
    "Stop": "停止",
 | 
			
		||||
    "Support": "サポート",
 | 
			
		||||
    "Swiss French keyboard layout": "Swiss French (Qwertz)",
 | 
			
		||||
    "Switch to input command": "入力コマンドに切り替え",
 | 
			
		||||
    "Switch to quick command": "クイックコマンドに切り替え",
 | 
			
		||||
    "Swiss French keyboard layout": "スイスフレンチ(Qwertz)",
 | 
			
		||||
    "Switch to input command": "コマンド入力に切り替え",
 | 
			
		||||
    "Switch to quick command": "ショートカットコマンドに切り替え",
 | 
			
		||||
    "Tab List": "ウィンドウリスト",
 | 
			
		||||
    "The connection method is invalid, please refresh the page": "接続方法が無効です。ページを更新してください",
 | 
			
		||||
    "Ticket review closed for login asset": "このログイン レビューは終了しており、アセットを接続できません",
 | 
			
		||||
    "Ticket review pending for login asset": "ログイン アプリケーションが送信され、承認者が確認するのを待っています。リンクをコピーして承認者に送信することもできます。",
 | 
			
		||||
    "Ticket review rejected for login asset": "このログイン レビューは拒否されたため、アセットを接続できません",
 | 
			
		||||
    "The connection method is invalid, please refresh the page": "接続方法が無効になりました、ページを更新してください",
 | 
			
		||||
    "Ticket review approved for login asset": "このログイン審査は通過しました, 資産に接続しますか?",
 | 
			
		||||
    "Ticket review closed for login asset": "このログイン監査は閉じられ、リソースに接続できません",
 | 
			
		||||
    "Ticket review pending for login asset": "ログイン申請が提出され、審査者の審査を待っています。リンクをコピーして彼に送ることもできます",
 | 
			
		||||
    "Ticket review rejected for login asset": "今回のログイン審査は拒否され、資産に接続できません",
 | 
			
		||||
    "Tips": "ヒント",
 | 
			
		||||
    "Token expired": "トークンの有効期限が切れました",
 | 
			
		||||
    "Tool download": "ツールダウンロード",
 | 
			
		||||
    "Turkey keyboard layout": "Turkish-Q (Qwerty)",
 | 
			
		||||
    "Token expired": "トークンの有効期限が切れました、再接続してください",
 | 
			
		||||
    "Tool download": "ツールのダウンロード",
 | 
			
		||||
    "Turkey keyboard layout": "Turkish-Q(Qwerty)",
 | 
			
		||||
    "Type tree": "タイプツリー",
 | 
			
		||||
    "UK English keyboard layout": "UK English (Qwerty)",
 | 
			
		||||
    "UK English keyboard layout": "イギリス英語 (Qwerty)",
 | 
			
		||||
    "US English keyboard layout": "US English (Qwerty)",
 | 
			
		||||
    "User": "ユーザー",
 | 
			
		||||
    "User: ": "ユーザー: {{value}}",
 | 
			
		||||
    "Username": "ユーザー名",
 | 
			
		||||
    "Username@Domain": "ユーザー名 @ ADドメイン",
 | 
			
		||||
    "Username@Domain": "ユーザ名@ADドメイン",
 | 
			
		||||
    "Users": "ユーザー",
 | 
			
		||||
    "Using token": "トークンを使用する",
 | 
			
		||||
    "Using token": "トークンを使用",
 | 
			
		||||
    "View": "ビュー",
 | 
			
		||||
    "VirtualApp": "仮想アプリケーション",
 | 
			
		||||
    "Web Terminal": "Web端末",
 | 
			
		||||
    "Website": "公式サイト",
 | 
			
		||||
    "Website": "公式ウェブサイト",
 | 
			
		||||
    "With secret accounts": "ホストアカウント",
 | 
			
		||||
    "Yes": "はい",
 | 
			
		||||
    "asset": "資産",
 | 
			
		||||
    "asset": "アセット",
 | 
			
		||||
    "cols": "列数",
 | 
			
		||||
    "confirm": "確認",
 | 
			
		||||
    "connect info": "接続情報",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,12 @@
 | 
			
		|||
import os
 | 
			
		||||
 | 
			
		||||
LOCALE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 | 
			
		||||
 | 
			
		||||
RED = "\033[91m"
 | 
			
		||||
BLUE = "\033[94m"
 | 
			
		||||
CYAN = "\033[96m"
 | 
			
		||||
RESET = "\033[0m"
 | 
			
		||||
GREEN = "\033[92m"
 | 
			
		||||
WHITE = "\033[97m"
 | 
			
		||||
YELLOW = "\033[93m"
 | 
			
		||||
MAGENTA = "\033[95m"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
import asyncio
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
from apps.locale.translate import LOCALE_DIR
 | 
			
		||||
from apps.locale.translate import LOCALE_DIR, RED
 | 
			
		||||
from apps.locale.translate.manager import OtherTranslateManager, CoreTranslateManager
 | 
			
		||||
from apps.locale.translate.utils import OpenAITranslate
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -25,7 +25,7 @@ class Translate:
 | 
			
		|||
        _dir = os.path.join(LOCALE_DIR, dir_name)
 | 
			
		||||
        zh_file = os.path.join(_dir, 'zh', 'LC_MESSAGES', 'django.po')
 | 
			
		||||
        if not os.path.exists(zh_file):
 | 
			
		||||
            print(f'File: {zh_file} not exists.')
 | 
			
		||||
            print(f'{RED}File: {zh_file} not exists.{RED}')
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        await CoreTranslateManager(_dir, self.oai_trans).run()
 | 
			
		||||
| 
						 | 
				
			
			@ -34,7 +34,7 @@ class Translate:
 | 
			
		|||
        _dir = os.path.join(LOCALE_DIR, dir_name)
 | 
			
		||||
        zh_file = os.path.join(_dir, 'zh.json')
 | 
			
		||||
        if not os.path.exists(zh_file):
 | 
			
		||||
            print(f'File: {zh_file} not exists.')
 | 
			
		||||
            print(f'{RED}File: {zh_file} not exists.{RED}\n')
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        await OtherTranslateManager(_dir, self.oai_trans).run()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,10 @@
 | 
			
		|||
import asyncio
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
from tqdm import tqdm
 | 
			
		||||
 | 
			
		||||
from apps.locale.translate import RED, GREEN, RESET
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BaseTranslateManager:
 | 
			
		||||
    bulk_size = 30
 | 
			
		||||
| 
						 | 
				
			
			@ -12,6 +16,7 @@ class BaseTranslateManager:
 | 
			
		|||
    def __init__(self, dir_path, oai_trans_instance):
 | 
			
		||||
        self.oai_trans = oai_trans_instance
 | 
			
		||||
        self._dir = dir_path
 | 
			
		||||
        self.dir_name = os.path.basename(self._dir)
 | 
			
		||||
        if not os.path.exists(self._dir):
 | 
			
		||||
            os.makedirs(self._dir)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -37,16 +42,25 @@ class BaseTranslateManager:
 | 
			
		|||
            translated_texts = translated_text.split(self.SEPARATOR)
 | 
			
		||||
            return dict(zip(keys, translated_texts))
 | 
			
		||||
        except Exception as e:
 | 
			
		||||
            print(f"Error during translation task: {e}")
 | 
			
		||||
            print(f"{RED}Error during translation task: {e}{RED}")
 | 
			
		||||
            return {}
 | 
			
		||||
 | 
			
		||||
    async def bulk_translate(self, need_trans_dict, target_lang):
 | 
			
		||||
        split_data = self.split_dict_into_chunks(need_trans_dict, self.bulk_size)
 | 
			
		||||
 | 
			
		||||
        tasks = [self.create_translate_task(batch, target_lang) for batch in split_data]
 | 
			
		||||
        translated_results = await asyncio.gather(*tasks)
 | 
			
		||||
        number_of_tasks = len(tasks)
 | 
			
		||||
        translated_dict = {}
 | 
			
		||||
        for result in translated_results:
 | 
			
		||||
            translated_dict.update(result)
 | 
			
		||||
        bar_format = "{l_bar}%s{bar}%s{r_bar}" % (GREEN, RESET)
 | 
			
		||||
        desc = f"{target_lang} translate"
 | 
			
		||||
        with tqdm(
 | 
			
		||||
                total=number_of_tasks, ncols=100,
 | 
			
		||||
                desc=desc, bar_format=bar_format
 | 
			
		||||
        ) as pbar:
 | 
			
		||||
            for task in asyncio.as_completed(tasks):
 | 
			
		||||
                pbar.set_description_str(f"{GREEN}{desc}{RESET}")
 | 
			
		||||
                result = await task
 | 
			
		||||
                translated_dict.update(result)
 | 
			
		||||
                pbar.update(1)
 | 
			
		||||
 | 
			
		||||
        return translated_dict
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,7 @@ import os
 | 
			
		|||
 | 
			
		||||
import polib
 | 
			
		||||
 | 
			
		||||
from apps.locale.translate import RED, MAGENTA, GREEN
 | 
			
		||||
from .base import BaseTranslateManager
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -21,14 +22,14 @@ class CoreTranslateManager(BaseTranslateManager):
 | 
			
		|||
        try:
 | 
			
		||||
            for entry in trans_po.untranslated_entries() + trans_po.fuzzy_entries():
 | 
			
		||||
                if entry.msgid not in data:
 | 
			
		||||
                    print(f'msgid: {entry.msgid} not in data.')
 | 
			
		||||
                    print(f'{MAGENTA}msgid: {entry.msgid} not in data.{MAGENTA}')
 | 
			
		||||
                    continue
 | 
			
		||||
                entry.flags = []
 | 
			
		||||
                entry.previous_msgid = None
 | 
			
		||||
                entry.msgstr = data[entry.msgid]
 | 
			
		||||
            trans_po.save()
 | 
			
		||||
        except Exception as e:
 | 
			
		||||
            print(f'File save error: {e}')
 | 
			
		||||
            print(f'{RED}File save error: {e}{RED}')
 | 
			
		||||
 | 
			
		||||
    async def run(self):
 | 
			
		||||
        po_file_path = os.path.join(self._dir, 'zh', 'LC_MESSAGES', 'django.po')
 | 
			
		||||
| 
						 | 
				
			
			@ -39,9 +40,9 @@ class CoreTranslateManager(BaseTranslateManager):
 | 
			
		|||
            po_file_path = os.path.join(self._dir, file_prefix, 'LC_MESSAGES', 'django.po')
 | 
			
		||||
            trans_po = polib.pofile(po_file_path)
 | 
			
		||||
            need_trans_dict = self.get_need_trans_dict(zh_dict, trans_po)
 | 
			
		||||
            print(f'File: {file_prefix}.json need to translate: {len(need_trans_dict)}')
 | 
			
		||||
            print(f'{GREEN}Translate: {self.dir_name} {file_prefix} '
 | 
			
		||||
                  f'django.po need to translate {len(need_trans_dict)}{GREEN}\n')
 | 
			
		||||
            if not need_trans_dict:
 | 
			
		||||
                print(f'File: {file_prefix}.json is already translated.')
 | 
			
		||||
                continue
 | 
			
		||||
            translated_dict = await self.bulk_translate(need_trans_dict, target_lang)
 | 
			
		||||
            self.save_translations_to_po(translated_dict, trans_po)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
import json
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
from apps.locale.translate import RED, GREEN
 | 
			
		||||
from .base import BaseTranslateManager
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -20,7 +21,7 @@ class OtherTranslateManager(BaseTranslateManager):
 | 
			
		|||
            with open(file_path, 'r', encoding='utf-8') as f:
 | 
			
		||||
                return json.load(f)
 | 
			
		||||
        except Exception as e:
 | 
			
		||||
            print(f'File: {file_path} load error: {e}')
 | 
			
		||||
            print(f'{RED}File: {file_path} load error: {e}{RED}')
 | 
			
		||||
            return {}
 | 
			
		||||
 | 
			
		||||
    def save_dict_as_json(self, data, file_prefix='ja'):
 | 
			
		||||
| 
						 | 
				
			
			@ -29,7 +30,7 @@ class OtherTranslateManager(BaseTranslateManager):
 | 
			
		|||
            with open(file_path, 'w', encoding='utf-8') as f:
 | 
			
		||||
                json.dump(data, f, ensure_ascii=False, sort_keys=True, indent=4)
 | 
			
		||||
        except Exception as e:
 | 
			
		||||
            print(f'File: {file_path} save error: {e}')
 | 
			
		||||
            print(f'{RED}File: {file_path} save error: {e}{RED}')
 | 
			
		||||
 | 
			
		||||
    async def run(self):
 | 
			
		||||
        zh_dict = self.load_json_as_dict()
 | 
			
		||||
| 
						 | 
				
			
			@ -37,9 +38,9 @@ class OtherTranslateManager(BaseTranslateManager):
 | 
			
		|||
        for file_prefix, target_lang in self.LANG_MAPPER.items():
 | 
			
		||||
            other_dict = self.load_json_as_dict(file_prefix)
 | 
			
		||||
            need_trans_dict = self.get_need_trans_dict(zh_dict, other_dict)
 | 
			
		||||
            print(f'File: {file_prefix}.json need to translate: {len(need_trans_dict)}')
 | 
			
		||||
            print(f'{GREEN}Translate: {self.dir_name} {file_prefix} need to translate '
 | 
			
		||||
                  f'{len(need_trans_dict)}{GREEN}\n')
 | 
			
		||||
            if not need_trans_dict:
 | 
			
		||||
                print(f'File: {file_prefix}.json is already translated.')
 | 
			
		||||
                continue
 | 
			
		||||
            translated_dict = await self.bulk_translate(need_trans_dict, target_lang)
 | 
			
		||||
            other_dict.update(translated_dict)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,8 +2,8 @@ from openai import AsyncOpenAI
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
class OpenAITranslate:
 | 
			
		||||
    def __init__(self, key: str | None = None):
 | 
			
		||||
        self.client = AsyncOpenAI(api_key=key)
 | 
			
		||||
    def __init__(self, key: str | None = None, base_url: str | None = None):
 | 
			
		||||
        self.client = AsyncOpenAI(api_key=key, base_url=base_url)
 | 
			
		||||
 | 
			
		||||
    async def translate_text(self, text, target_lang="English") -> str | None:
 | 
			
		||||
        try:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7827,4 +7827,4 @@ reference = "tsinghua"
 | 
			
		|||
[metadata]
 | 
			
		||||
lock-version = "2.0"
 | 
			
		||||
python-versions = "^3.11"
 | 
			
		||||
content-hash = "86fd825091e6032ad4a48f595a627555822618f8a1a0ed1f314f024e54d190d0"
 | 
			
		||||
content-hash = "5474eb8b2e55c714fc812ea637bf83fe40c5acaadebccc10072e30101ab9ba13"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -147,6 +147,7 @@ mistune = "2.0.3"
 | 
			
		|||
openai = "^1.3.7"
 | 
			
		||||
xlsxwriter = "^3.1.9"
 | 
			
		||||
polib = "^1.2.0"
 | 
			
		||||
tqdm = "^4.66.1"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[tool.poetry.group.xpack.dependencies]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue