Skip to content

Commit

Permalink
refactor: 重构项目代码
Browse files Browse the repository at this point in the history
1. 支持更多 TikTok 合辑链接格式
2. 优化 TikTok 合辑 ID 提取逻辑
3. 优化代码复用性

Closes #287
Closes #288
  • Loading branch information
JoeanAmier committed Sep 4, 2024
1 parent 0fe5feb commit eef0673
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 89 deletions.
23 changes: 12 additions & 11 deletions docs/Release_Notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@
2. 使用 rookiepy 替代 browser-cookie3
3. 修复调用 FFmpeg 下载直播功能
4. 优化从浏览器读取 Cookie 功能
5. 修复代理参数测试报错的问题
6. 优化作品文件名称处理逻辑
7. 适配最新版 FFmpeg 命令
8. 日志不再记录请求体数据
9. 捕获中断程序的异常错误
10. 优化重定向链接获取逻辑
11. 新增文件断点续传功能
12. 修复删除下载记录功能
13. 捕获响应码异常的错误
14. 修复其他已知问题
15. 其他细节优化
5. 支持更多 TikTok 合辑链接格式
6. 修复代理参数测试报错的问题
7. 优化作品文件名称处理逻辑
8. 适配最新版 FFmpeg 命令
9. 日志不再记录请求体数据
10. 捕获中断程序的异常错误
11. 优化重定向链接获取逻辑
12. 新增文件断点续传功能
13. 修复删除下载记录功能
14. 捕获响应码异常的错误
15. 修复其他已知问题
16. 其他细节优化

<p><strong>注意:Mac OS 平台可执行文件 <code>main</code> 可能需要从终端命令行启动;受设备限制,Mac OS 平台可执行文件尚未经过测试,无法保证可用性!</strong></p>
5 changes: 5 additions & 0 deletions docs/TikTokDownloader文档.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@
<td align="center">合辑</td>
</tr>
<tr>
<td align="center"><code>https://www.tiktok.com/@TikTok号/collection/合辑信息</code></td>
<td align="center">合辑</td>
</tr>
<tr>
<td align="center"><code>https://www.tiktok.com/@TikTok号/video/作品ID</code></td>
<td align="center">账号、视频、图集</td>
</tr>
Expand Down Expand Up @@ -900,6 +904,7 @@ https://www.douyin.com/note/123456789
<ul>
<li><code>https://vt.tiktok.com/分享码/</code></li>
<li><code>https://www.tiktok.com/@TikTok号/playlist/合辑信息</code></li>
<li><code>https://www.tiktok.com/@TikTok号/collection/合辑信息</code></li>
</ul>
<p>如果需要大批量采集合集作品,建议启用 <code>src/custom/function.py</code> 文件的 <code>suspend</code> 函数。</p>
<p>如果当前合集标题或合集标识不是有效的文件夹名称时,程序会提示用户输入临时的合集标识,以便程序继续处理合集。</p>
Expand Down
131 changes: 55 additions & 76 deletions src/application/main_complete.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,64 +293,59 @@ async def __secondary_menu(
if n in range(len(function)):
await function[n][1](*args, **kwargs, )

async def account_detail_batch(
async def account_detail_batch(self, *args, ):
await self.__account_detail_batch(
self.accounts,
"accounts_urls",
False,
)

async def account_detail_batch_tiktok(self, *args, ):
await self.__account_detail_batch(
self.accounts_tiktok,
"accounts_urls_tiktok",
True,
)

async def __account_detail_batch(
self,
*args,
):
accounts: list[SimpleNamespace],
params_name: str,
tiktok: bool,
) -> None:
count = SimpleNamespace(time=time(), success=0, failed=0)
self.logger.info(f"共有 {len(self.accounts)} 个账号的作品等待下载")
for index, data in enumerate(self.accounts, start=1):
self.logger.info(f"共有 {len(accounts)} 个账号的作品等待下载")
for index, data in enumerate(accounts, start=1):
if hasattr(data, "enable") and not data.enable:
continue
if not (sec_user_id := await self.check_sec_user_id(data.url)):
if not (sec_user_id := await self.check_sec_user_id(
data.url,
tiktok,
)):
self.logger.warning(
f"配置文件 accounts_urls 参数"
f"配置文件 {params_name} 参数"
f"第 {index} 条数据的 url {data.url} 错误,提取 sec_user_id 失败")
count.failed += 1
continue
if not await self.deal_account_detail(
index,
**vars(data) | {"sec_user_id": sec_user_id},
tiktok=tiktok,
):
count.failed += 1
if index != len(self.accounts) and failure_handling():
continue
break
# break # 调试代码
count.success += 1
if index != len(self.accounts):
await suspend(index, self.console)
self.__summarize_results(count)

async def account_detail_batch_tiktok(self, *args, ):
count = SimpleNamespace(time=time(), success=0, failed=0)
self.logger.info(f"共有 {len(self.accounts_tiktok)} 个账号的作品等待下载")
for index, data in enumerate(self.accounts_tiktok, start=1):
if hasattr(data, "enable") and not data.enable:
continue
if not (sec_user_id := await self.links_tiktok.run(data.url, "user")):
self.logger.warning(
f"配置文件 accounts_urls_tiktok 参数"
f"第 {index} 条数据的 url {data.url} 错误,提取 sec_user_id 失败")
count.failed += 1
continue
if not await self.deal_account_detail(
index,
**vars(data) | {"sec_user_id": sec_user_id[0]},
tiktok=True,
):
count.failed += 1
if index != len(self.accounts_tiktok) and failure_handling():
continue
break
# break # 调试代码
count.success += 1
if index != len(self.accounts_tiktok):
if index != len(accounts):
await suspend(index, self.console)
self.__summarize_results(count)

async def check_sec_user_id(self, sec_user_id: str) -> str:
sec_user_id = await self.links.run(sec_user_id, "user")
async def check_sec_user_id(self, sec_user_id: str, tiktok=False, ) -> str:
match tiktok:
case True:
sec_user_id = await self.links_tiktok.run(sec_user_id, "user")
case False:
sec_user_id = await self.links.run(sec_user_id, "user")
return sec_user_id[0] if len(sec_user_id) > 0 else ""

async def account_detail_inquire(self, *args, ):
Expand Down Expand Up @@ -420,9 +415,7 @@ async def __account_detail_handle(
**kwargs,
):
count.failed += 1
if index != len(links) and failure_handling():
continue
break
continue
count.success += 1
if index != len(links):
await suspend(index, self.console)
Expand Down Expand Up @@ -731,7 +724,10 @@ async def detail_interactive(self, select="", ):
self.logger.info("已退出批量下载链接作品(抖音)模式")

async def detail_interactive_tiktok(self, select="", ):
await self.__detail_secondary_menu(self.__function_detail_tiktok, select)
await self.__detail_secondary_menu(
self.__function_detail_tiktok,
select,
)
self.logger.info("已退出批量下载链接作品(TikTok)模式")

async def __detail_secondary_menu(self, menu, select="", *args, **kwargs):
Expand Down Expand Up @@ -762,7 +758,7 @@ async def __detail_inquire(self, tiktok=False, ):
self.console.print(f"共提取到 {len(ids)} 个作品,开始处理!")
await self._handle_detail(ids, tiktok, record, )

async def __detail_inquire_tiktok(self, record, tiktok=True, ):
async def __detail_inquire_tiktok(self, tiktok=True, ):
await self.__detail_inquire(tiktok, )

async def __detail_txt(self, tiktok=False, ):
Expand Down Expand Up @@ -1057,7 +1053,7 @@ async def mix_interactive(self, select="", ):
async def mix_interactive_tiktok(self, select="", ):
await self.__secondary_menu(
"请选择合集链接来源",
self.__function_mix,
self.__function_mix_tiktok,
select,
)
self.logger.info("已退出批量下载合集作品(TikTok)模式")
Expand All @@ -1074,26 +1070,26 @@ async def __mix_interactive(self, function, select="", tiktok=False, *args, **kw
def _generate_mix_params(mix: bool, id_: str) -> dict:
return {"mix_id": id_, } if mix else {"detail_id": id_, }

async def mix_inquire(self, root, params, logger):
async def mix_inquire(self, ):
while url := self._inquire_input("合集或作品"):
mix_id, ids = await self.links.run(url, type_="mix")
if not ids:
self.logger.warning(f"{url} 获取作品 ID 或合集 ID 失败")
continue
await self.__mix_handle(root, params, logger, mix_id, ids)
await self.__mix_handle(mix_id, ids)

async def mix_inquire_tiktok(self, root, params, logger):
async def mix_inquire_tiktok(self, ):
while url := self._inquire_input("合集或作品"):
_, ids, title = await self.links_tiktok.run(url, type_="mix")
if not ids:
self.logger.warning(f"{url} 获取合集 ID 失败")
continue
await self.__mix_handle(root, params, logger, True, ids, True, title, )
await self.__mix_handle(True, ids, True, title, )

@check_cookie_state(tiktok=False)
async def mix_collection(self, root, params, logger):
async def mix_collection(self, ):
if id_ := await self.mix_inquire_collection():
await self.__mix_handle(root, params, logger, True, id_)
await self.__mix_handle(True, id_)

async def mix_inquire_collection(self) -> list[str]:
data = await CollectsMix(self.parameter).run()
Expand Down Expand Up @@ -1125,29 +1121,26 @@ def __input_download_index(self,
self.console.print(f"{text}序号输入错误!", style=WARNING)
return []

async def mix_txt(self, root, params, logger):
async def mix_txt(self, ):
if not (url := self.txt_inquire()):
return
mix_id, ids = await self.links.run(url, type_="mix")
if not ids:
self.logger.warning("从文本文档提取作品 ID 或合集 ID 失败")
return
await self.__mix_handle(root, params, logger, mix_id, ids)
await self.__mix_handle(mix_id, ids)

async def mix_txt_tiktok(self, root, params, logger):
async def mix_txt_tiktok(self, ):
if not (url := self.txt_inquire()):
return
_, ids, title = await self.links_tiktok.run(url, type_="mix")
if not ids:
self.logger.warning("从文本文档提取合集 ID 失败")
return
await self.__mix_handle(root, params, logger, True, ids, True, title, )
await self.__mix_handle(True, ids, True, title, )

async def __mix_handle(
self,
root,
params,
logger,
mix_id: bool,
ids: list[str],
tiktok=False,
Expand All @@ -1156,9 +1149,6 @@ async def __mix_handle(
count = SimpleNamespace(time=time(), success=0, failed=0)
for index, i in enumerate(ids, start=1):
if not await self._deal_mix_detail(
root,
params,
logger,
mix_id,
i,
num=index,
Expand All @@ -1174,7 +1164,7 @@ async def __mix_handle(
await suspend(index, self.console)
self.__summarize_results(count, "合集")

async def mix_batch(self, root, params, logger):
async def mix_batch(self, ):
count = SimpleNamespace(time=time(), success=0, failed=0)
for index, data in enumerate(self.mix, start=1):
if hasattr(data, "enable") and not data.enable:
Expand All @@ -1187,13 +1177,11 @@ async def mix_batch(self, root, params, logger):
count.failed += 1
continue
if not await self._deal_mix_detail(
root,
params,
logger,
mix_id,
id_,
data.mark,
index):
index,
):
count.failed += 1
if index != len(self.mix) and failure_handling():
continue
Expand All @@ -1203,7 +1191,7 @@ async def mix_batch(self, root, params, logger):
await suspend(index, self.console)
self.__summarize_results(count, "合集")

async def mix_batch_tiktok(self, root, params, logger):
async def mix_batch_tiktok(self, ):
count = SimpleNamespace(time=time(), success=0, failed=0)
for index, data in enumerate(self.mix_tiktok, start=1):
if hasattr(data, "enable") and not data.enable:
Expand All @@ -1217,9 +1205,6 @@ async def mix_batch_tiktok(self, root, params, logger):
continue
id_, title = ids[0], title[0]
if not await self._deal_mix_detail(
root,
params,
logger,
True,
id_,
data.mark,
Expand All @@ -1237,9 +1222,6 @@ async def mix_batch_tiktok(self, root, params, logger):
self.__summarize_results(count, "合集")

async def _deal_mix_detail(self,
root,
params,
logger,
mix_id: bool = None,
id_: str = None,
mark="",
Expand Down Expand Up @@ -1274,9 +1256,6 @@ async def _deal_mix_detail(self,
mix_data
if source
else await self._batch_process_detail(
root,
params,
logger,
mix_data,
mode="mix",
mix_id=mix_obj.mix_id,
Expand Down
4 changes: 2 additions & 2 deletions src/link/extractor.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ def extract_info(pattern, urls: str, index=1) -> list[str]:
class ExtractorTikTok(Extractor):
SEC_UID = compile(r'"secUid":"([a-zA-Z0-9_-]+)"')
ROOD_ID = compile(r'"roomId":"(\d+)"')
MIX_ID = compile(r'"playlistId":"(\d{19})"')
MIX_ID = compile(r'"canonical":"\S+?(\d{19})"')

account_link = compile(r"\S*?(https://www\.tiktok\.com/@[^\s/]+)\S*?")

Expand All @@ -127,7 +127,7 @@ class ExtractorTikTok(Extractor):
) # 作品链接

mix_link = compile(
r"\S*?https://www\.tiktok\.com/@\S+/playlist/(.+?)-(\d{19})\?\S*?"
r"\S*?https://www\.tiktok\.com/@\S+/(?:playlist|collection)/(.+?)-(\d{19})\S*?"
) # 合集链接

live_link = compile(
Expand Down

0 comments on commit eef0673

Please sign in to comment.