Skip to content

Commit

Permalink
feat: 新增英语语言支持
Browse files Browse the repository at this point in the history
  • Loading branch information
JoeanAmier committed Dec 24, 2024
1 parent d2b47f6 commit 49d113b
Show file tree
Hide file tree
Showing 16 changed files with 922 additions and 508 deletions.
Binary file added locale/en_US/LC_MESSAGES/tk.mo
Binary file not shown.
848 changes: 517 additions & 331 deletions locale/en_US/LC_MESSAGES/tk.po

Large diffs are not rendered by default.

200 changes: 147 additions & 53 deletions locale/tk.pot

Large diffs are not rendered by default.

Binary file added locale/zh_CN/LC_MESSAGES/tk.mo
Binary file not shown.
232 changes: 169 additions & 63 deletions locale/zh_CN/LC_MESSAGES/tk.po

Large diffs are not rendered by default.

60 changes: 35 additions & 25 deletions src/application/TikTokDownloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
from src.record import LoggerManager
from src.tools import Browser
from src.tools import ColorfulConsole
from src.tools import TikTokDownloaderError
from src.tools import choose
from src.tools import remove_empty_directories
from src.tools import safe_pop
Expand All @@ -58,10 +59,6 @@ class TikTokDownloader:
"cookie",
"cookie_tiktok",
)
FUNCTION_OPTIONS = {
1: "禁用",
0: "启用",
}
NAME = PROJECT_NAME
WIDTH = 50
LINE = ">" * WIDTH
Expand Down Expand Up @@ -107,6 +104,10 @@ async def __aexit__(self, exc_type, exc_val, exc_tb):
self.close()

def __update_menu(self):
options = {
1: _("禁用"),
0: _("启用"),
}
self.__function_menu = (
(_("复制粘贴写入 Cookie (抖音)"), self.write_cookie),
(_("从浏览器获取 Cookie (抖音)"), self.browser_cookie),
Expand All @@ -122,11 +123,11 @@ def __update_menu(self):
# (_("Web UI 模式"), self.__web_ui_object),
# (_("服务器部署模式"), self.__server_object),
(_("{}作品下载记录").format(
self.FUNCTION_OPTIONS[self.config["Record"]]
options[self.config["Record"]]
), self.__modify_record),
(_("删除作品下载记录"), self.delete_works_ids),
(_("{}运行日志记录").format(
self.FUNCTION_OPTIONS[self.config["Logger"]]
options[self.config["Logger"]]
), self.__modify_logging),
(_("检查程序版本更新"), self.check_update),
(_("切换语言"), self._switch_language),
Expand All @@ -151,29 +152,22 @@ async def __modify_logging(self):
await self.change_config("Logger")

async def _switch_language(self, ):
def create_language_toggler():
languages = ["zh_CN", "en_US"]
index = 0

def toggle():
nonlocal index
language = languages[index]
index = 1 - index # 切换索引:0 -> 1, 1 -> 0
return language

return toggle

# 创建语言切换器
toggle_language = create_language_toggler()

current_language = toggle_language()
if self.option["Language"] == "zh_CN":
language = "en_US"
elif self.option["Language"] == "en_US":
language = "zh_CN"
else:
raise TikTokDownloaderError
await self._update_language(language)

self.option["Language"] = current_language
await self.database.update_option_data("Language", current_language)
self.set_language(current_language)
async def _update_language(self, language: str) -> None:
self.option["Language"] = language
await self.database.update_option_data("Language", language)
self.set_language(language)

async def disclaimer(self):
if not self.config["Disclaimer"]:
await self.__init_language()
self.console.print(
_("免责声明\n"),
style=MASTER)
Expand All @@ -184,6 +178,22 @@ async def disclaimer(self):
self.console.print()
return True

async def __init_language(self):
languages = (
("简体中文", "zh_CN",),
("English", "en_US",),
)
language = choose(
"请选择语言(Please Select Language)",
[i[0] for i in languages],
self.console,
)
try:
language = languages[int(language) - 1][1]
await self._update_language(language)
except ValueError:
await self.__init_language()

def project_info(self):
self.console.print(f"{self.LINE}\n\n\n{self.NAME.center(
self.WIDTH)}\n\n\n{self.LINE}\n", style=MASTER)
Expand Down
24 changes: 12 additions & 12 deletions src/application/main_complete.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,12 +197,12 @@ async def account_acquisition_interactive_tiktok(
)
self.logger.info(_("已退出批量下载账号作品(TikTok)模式"))

def __summarize_results(self, count: SimpleNamespace, name="账号"):
def __summarize_results(self, count: SimpleNamespace, name=_("账号")):
time_ = time() - count.time
self.logger.info(
_("程序共处理 {0} 个{1},成功 {2} 个,失败 {3} 个,耗时 {4} 分钟 {5} 秒").format(
count.success + count.failed,
_(name),
name,
count.success,
count.failed,
int(time_ // 60),
Expand All @@ -221,15 +221,15 @@ async def account_acquisition_interactive(

async def __secondary_menu(
self,
problem="请选择账号链接来源",
problem=_("请选择账号链接来源"),
function=...,
select: str | int = ...,
*args,
**kwargs,
):
if not select:
select = choose(
_(problem),
problem,
[i[0] for i in function],
self.console,
)
Expand Down Expand Up @@ -684,7 +684,7 @@ async def download_detail_batch(

async def detail_interactive(self, select="", ):
await self.__secondary_menu(
"请选择作品链接来源",
_("请选择作品链接来源"),
self.__function_detail,
select or safe_pop(self.run_command),
)
Expand Down Expand Up @@ -955,7 +955,7 @@ async def comment_interactive_tiktok(self, select="", *args, **kwargs):
@check_storage_format
async def comment_interactive(self, select="", ):
await self.__secondary_menu(
"请选择作品链接来源",
_("请选择作品链接来源"),
self.__function_comment,
select or safe_pop(self.run_command),
)
Expand Down Expand Up @@ -1016,15 +1016,15 @@ async def __comment_handle(

async def mix_interactive(self, select="", ):
await self.__secondary_menu(
"请选择合集链接来源",
_("请选择合集链接来源"),
self.__function_mix,
select or safe_pop(self.run_command),
)
self.logger.info(_("已退出批量下载合集作品(抖音)模式"))

async def mix_interactive_tiktok(self, select="", ):
await self.__secondary_menu(
"请选择合集链接来源",
_("请选择合集链接来源"),
self.__function_mix_tiktok,
select or safe_pop(self.run_command),
)
Expand Down Expand Up @@ -1069,7 +1069,7 @@ def input_download_index(self, data: list[dict]) -> list[str] | None:
def __input_download_index(
self,
data: list[dict],
text="收藏合集",
text=_("收藏合集"),
key="title",
) -> list[dict] | None:
self.console.print(_("{text}列表:").format(text=_(text)))
Expand Down Expand Up @@ -1137,7 +1137,7 @@ async def __mix_handle(
count.success += 1
if index != len(ids):
await suspend(index, self.console)
self.__summarize_results(count, "合集")
self.__summarize_results(count, _("合集"))

async def mix_batch(self, ):
await self.__mix_batch(
Expand Down Expand Up @@ -1186,7 +1186,7 @@ async def __mix_batch(
count.success += 1
if index != len(mix):
await suspend(index, self.console)
self.__summarize_results(count, "合集")
self.__summarize_results(count, _("合集"))

async def _deal_mix_detail(
self,
Expand Down Expand Up @@ -1504,7 +1504,7 @@ async def __get_collects_list(
if source:
return collects
data = self.extractor.extract_collects_info(collects)
return self.__input_download_index(data, "收藏夹", key, )
return self.__input_download_index(data, _("收藏夹"), key, )

async def __check_owner_url(self, tiktok=False, ):
if not (sec_user_id := await self.check_sec_user_id(self.owner.url)):
Expand Down
4 changes: 2 additions & 2 deletions src/config/parameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,12 +361,12 @@ def __check_proxy(
self,
proxy: str | None | dict,
url="https://www.douyin.com/?recommend=1",
remark="抖音",
remark=_("抖音"),
) -> str | None:
if proxy:
# 暂时兼容旧版配置;未来将会移除
if isinstance(proxy, dict):
self.console.warning(f"{remark}代理参数应为字符串格式,未来不再支持字典格式")
self.console.warning(_("{remark}代理参数应为字符串格式,未来不再支持字典格式").format(remark=remark))
if not (proxy := proxy.get("https://")):
return
try:
Expand Down
12 changes: 6 additions & 6 deletions src/downloader/download.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,14 +261,14 @@ async def batch_processing(
"temp_root": temp_root,
"actual_root": actual_root
}
if (t := item["type"]) == "图集":
if (t := item["type"]) == _("图集"):
await self.download_image(**params)
elif t == "视频":
elif t == _("视频"):
await self.download_video(**params)
elif t == "实况":
elif t == _("实况"):
await self.download_image(
suffix="mp4",
type_="实况",
type_=_("实况"),
**params,
)
else:
Expand Down Expand Up @@ -330,7 +330,7 @@ async def download_image(
temp_root: Path,
actual_root: Path,
suffix: str = "jpeg",
type_: str = "图集",
type_: str = _("图集"),
) -> None:
for index, img in enumerate(
item["downloads"],
Expand Down Expand Up @@ -366,7 +366,7 @@ async def download_video(
temp_root: Path,
actual_root: Path,
suffix: str = "mp4",
type_: str = "视频",
type_: str = _("视频"),
) -> None:
if await self.is_skip(
id_,
Expand Down
6 changes: 3 additions & 3 deletions src/extract/extractor.py
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ def __extract_image_info(
images: list[SimpleNamespace],
) -> None:
if self.safe_extract(images[-1], "video"):
self.__set_blank_data(item, data, "实况", )
self.__set_blank_data(item, data, _("实况"), )
item["downloads"] = [
self.safe_extract(
i,
Expand Down Expand Up @@ -393,7 +393,7 @@ def __set_blank_data(
self,
item: dict,
data: SimpleNamespace,
type_="图集",
type_=_("图集"),
):
item["type"] = type_
item["duration"] = "00:00:00"
Expand All @@ -419,7 +419,7 @@ def __extract_video_info_tiktok(
self,
item: dict,
data: SimpleNamespace,
type_="视频",
type_=_("视频"),
) -> None:
item["type"] = type_
item["downloads"] = self.safe_extract(
Expand Down
8 changes: 4 additions & 4 deletions src/interface/hot.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,22 @@
class Hot(API):
board_params = (
SimpleNamespace(
name="抖音热榜",
name=_("抖音热榜"),
type=0,
sub_type="",
),
SimpleNamespace(
name="娱乐榜",
name=_("娱乐榜"),
type=2,
sub_type=2,
),
SimpleNamespace(
name="社会榜",
name=_("社会榜"),
type=2,
sub_type=4,
),
SimpleNamespace(
name="挑战榜",
name=_("挑战榜"),
type=2,
sub_type="hotspot_challenge",
),
Expand Down
8 changes: 4 additions & 4 deletions src/interface/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,28 @@
class Search(API):
search_params = (
SimpleNamespace(
note="综合搜索",
note=_("综合搜索"),
api=f"{API.domain}aweme/v1/web/general/search/single/",
channel="aweme_general",
type="general",
key="data",
),
SimpleNamespace(
note="视频搜索",
note=_("视频搜索"),
api=f"{API.domain}aweme/v1/web/search/item/",
channel="aweme_video_web",
type="video",
key="data",
),
SimpleNamespace(
note="用户搜索",
note=_("用户搜索"),
api=f"{API.domain}aweme/v1/web/discover/search/",
channel="aweme_user_web",
type="user",
key="user_list",
),
SimpleNamespace(
note="直播搜索",
note=_("直播搜索"),
api=f"{API.domain}aweme/v1/web/live/search/",
channel="aweme_live",
type="live",
Expand Down
6 changes: 3 additions & 3 deletions src/manager/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def __rename_folder(
mark: str,
):
new_folder = self.root.joinpath(f"{prefix}{id_}_{mark}_{suffix}")
self.__rename(old_folder, new_folder, "文件夹")
self.__rename(old_folder, new_folder, _("文件夹"))
self.log.info(f"文件夹 {old_folder} 已重命名为 {new_folder}", False)

def __rename_works_folder(self,
Expand All @@ -117,7 +117,7 @@ def __rename_works_folder(self,
if (s := data[key]) in old_.name:
new_ = old_.parent / old_.name.replace(
s, {"name": name, "mark": mark}[key], 1)
self.__rename(old_, new_, "文件夹")
self.__rename(old_, new_, _("文件夹"))
self.log.info(f"文件夹 {old_} 重命名为 {new_}", False)
return new_
return old_
Expand Down Expand Up @@ -174,7 +174,7 @@ def __rename_file(
return True

@PrivateRetry.retry_limited
def __rename(self, old_: Path, new_: Path, type_="文件") -> bool:
def __rename(self, old_: Path, new_: Path, type_=_("文件")) -> bool:
try:
old_.rename(new_)
return True
Expand Down
2 changes: 1 addition & 1 deletion src/tools/browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class Browser:
}
PLATFORM = {
False: SimpleNamespace(
name="抖音",
name=_("抖音"),
domain=[
"douyin.com",
],
Expand Down
5 changes: 4 additions & 1 deletion src/tools/error.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
from ..translation import _


class TikTokDownloaderError(Exception):
def __init__(self, message="项目代码错误"):
def __init__(self, message=_("项目代码错误")):
self.message = message
super().__init__(self.message)

Expand Down
Loading

0 comments on commit 49d113b

Please sign in to comment.