Skip to content

Commit

Permalink
优化默认启动模式设置
Browse files Browse the repository at this point in the history
  • Loading branch information
JoeanAmier committed Feb 25, 2024
1 parent 8e9cc43 commit 6deae86
Show file tree
Hide file tree
Showing 21 changed files with 167 additions and 92 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@
<li>按照提示操作,将 Cookie 写入配置文件</li>
</ol>
</li>
<li>返回程序界面,依次选择 <code>终端交互模式</code> -> <code>批量下载链接作品</code></li>
<li>返回程序界面,依次选择 <code>终端交互模式</code> -> <code>批量下载链接作品(通用)</code></li>
<li>输入抖音或 TikTok 作品链接即可下载作品文件</li>
<li>更多详细说明请查看 <b><a href="https://github.com/JoeanAmier/TikTokDownloader/wiki/Documentation">项目文档</a></b></li>
</ol>
Expand Down
30 changes: 16 additions & 14 deletions docs/TikTokDownloader文档.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
<li>按照提示操作,将 Cookie 写入配置文件</li>
</ol>
</li>
<li>返回程序界面,依次选择 <code>终端交互模式</code> -> <code>批量下载链接作品</code></li>
<li>返回程序界面,依次选择 <code>终端交互模式</code> -> <code>批量下载链接作品(通用)</code></li>
<li>输入抖音或 TikTok 作品链接即可下载作品文件</li>
</ol>
<h1>获取 Cookie</h1>
Expand Down Expand Up @@ -304,8 +304,8 @@
</tr>
<tr>
<td align="center">default_mode</td>
<td align="center">int</td>
<td align="center">程序启动的默认模式</td>
<td align="center">str</td>
<td align="center">设置程序启动的默认模式,相当于模拟用户输入序号(多个序号使用空格分隔)</td>
</tr>
<tr>
<td align="center">ffmpeg</td>
Expand Down Expand Up @@ -368,7 +368,7 @@
"chunk": 10485760,
"max_retry": 10,
"max_pages": 2,
"default_mode": 3,
"default_mode": "4 2 1",
"ffmpeg": "C:\\TikTokDownloader\\ffmpeg.exe"
}
```
Expand Down Expand Up @@ -434,7 +434,7 @@
}
```

<p>代表程序会将下载的文件和记录的数据储存至 <code>C:\TikTokDownloader</code> 文件夹内,链接下载的作品文件会储存至 <code>C:\TikTokDownloader\SOLO</code> 文件夹内。</p>
<p>程序会将下载的文件和记录的数据储存至 <code>C:\TikTokDownloader</code> 文件夹内,链接下载的作品文件会储存至 <code>C:\TikTokDownloader\SOLO</code> 文件夹内。</p>
<h3>文件名称格式</h3>

```json
Expand All @@ -444,7 +444,7 @@
}
```

<p>代表作品文件名称格式为: <code>发布时间 @ 作者UID @ 作品ID</code></p>
<p>作品文件名称格式为: <code>发布时间 @ 作者UID @ 作品ID</code></p>
<ul>
<li>如果作品没有描述,保存时文件名称的描述内容将替换为作品 ID</li>
<li>批量下载链接作品时,如果在 <code>name_format</code> 参数中设置了 <code>mark</code> 字段,程序会自动替换为 <code>nickname</code> 字段</li>
Expand All @@ -457,7 +457,7 @@
}
```

<p>代表发布时间格式为:XXXX年-XX月-XX日,详细设置规则可以 <a href="https://docs.python.org/zh-cn/3/library/time.html?highlight=strftime#time.strftime">查看文档</a></p>
<p>发布时间格式为:XXXX年-XX月-XX日,详细设置规则可以 <a href="https://docs.python.org/zh-cn/3/library/time.html?highlight=strftime#time.strftime">查看文档</a></p>
<h3>数据储存格式</h3>

```json
Expand All @@ -466,7 +466,7 @@
}
```

<p>代表使用 <code>XLSX</code> 格式储存程序采集数据。</p>
<p>使用 <code>XLSX</code> 格式储存程序采集数据。</p>
<h3>文件大小限制</h3>

```json
Expand All @@ -475,7 +475,7 @@
}
```

<p>代表作品文件大小限制为 104857600 字节(100 MB),超过该大小的作品文件会自动跳过下载;直播文件不受限制。</p>
<p>作品文件大小限制为 104857600 字节(100 MB),超过该大小的作品文件会自动跳过下载;直播文件不受限制。</p>
<h3>文件分块下载</h3>

```json
Expand All @@ -484,7 +484,7 @@
}
```

<p>代表下载文件时每次从服务器接收 10485760 字节 (10 MB)的数据块。</p>
<p>下载文件时每次从服务器接收 10485760 字节 (10 MB)的数据块。</p>
<ul>
<li>影响下载速度:较大的 chunk 会增加每次下载的数据量,从而提高下载速度。相反,较小的 chunk 会降低每次下载的数据量,可能导致下载速度稍慢。</li>
<li>影响内存占用:较大的 chunk 会一次性加载更多的数据到内存中,可能导致内存占用增加。相反,较小的 chunk 会减少每次加载的数据量,从而降低内存占用。</li>
Expand All @@ -497,17 +497,18 @@
}
```

<p>代表批量下载账号喜欢作品、收藏作品或者采集作品评论数据时,仅获取前 <code>2</code> 页数据;用于解决批量下载账号喜欢作品、收藏作品需要获取全部数据的问题,以及作品评论数据数量过多的采集问题。</p>
<p>批量下载账号喜欢作品、收藏作品或者采集作品评论数据时,仅获取前 <code>2</code> 页数据;用于解决批量下载账号喜欢作品、收藏作品需要获取全部数据的问题,以及作品评论数据数量过多的采集问题。</p>
<p>不影响批量下载账号发布作品,如需控制账号发布作品数据获取次数,可使用 <code>earliest</code> 和 <code>latest</code> 参数实现。</p>
<h3>默认启动模式</h3>

```json
{
"default_mode": 3
"default_mode": "4 2 1"
}
```

<p>代表运行程序自动进入 <code>终端交互模式</code>,其他示例:<code>4</code> 代表 <code>Web API 接口模式</code>,<code>5</code> 代表 <code>Web UI 交互模式</code>,<code>6</code> 代表 <code>服务器部署模式</code>。</p>
<p>运行程序自动依次进入 <code>终端交互模式</code> -> <code>批量下载账号作品(抖音)</code> -> <code>使用 accounts_urls 参数的账号链接(推荐)</code></p>
<p>其他示例:<code>4 2</code> 代表依次进入 <code>终端交互模式</code> -> <code>批量下载账号作品(抖音)</code>;<code>6</code>代表进入<code>Web API 模式</code></p>
<h3>程序代理设置</h3>

```json
Expand All @@ -516,7 +517,7 @@
}
```

<p>代表程序获取网络数据时使用 <code>http://127.0.0.1:9999</code> 作为代理;程序会自动验证代理是否可用,如果代理不可用,则 <code>proxies</code> 参数不生效。</p>
<p>程序获取网络数据时使用 <code>http://127.0.0.1:9999</code> 作为代理;程序会自动验证代理是否可用,如果代理不可用,则 <code>proxies</code> 参数不生效。</p>
<p>如果您的电脑使用了代理工具且未修改默认端口,可以尝试以下设置:</p>
<ul>
<li>Clash: <code>http://127.0.0.1:7890</code></li>
Expand Down Expand Up @@ -550,6 +551,7 @@
<h2><del>扫码登录获取 Cookie</del></h2>
<p><del>程序自动获取抖音登录二维码,随后会在终端输出二维码,并使用系统默认图片浏览器打开二维码图片,使用者通过抖音 APP 扫码并登录账号,操作后关闭二维码图片窗口,程序会自动检查登录结果并将登录后的 Cookie 写入配置文件。</del></p>
<p><del><b>注意:</b>扫码登录获取的 Cookie 有效期更短,且频繁扫码登录容易导致账号被风控!</del></p>
<p>当前已失效,未来可能修复或移除!</p>
<h2>终端交互模式</h2>
<p>功能最全面的模式,支持全部功能。</p>
<h3>批量下载账号作品(TikTok)</h3>
Expand Down
2 changes: 1 addition & 1 deletion src/DataAcquirer.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ class Link:

# TikTok 链接
works_link_tiktok = compile(
r"\S*?https://www\.tiktok\.com/@\S+?/video/(\d{19})\S*?") # 作品链接
r"\S*?https://www\.tiktok\.com/@\S+?/(?:video|photo)/(\d{19})\S*?") # 作品链接

def __init__(self, params: Parameter):
self.share = Share(params.logger, params.proxies, params.max_retry)
Expand Down
15 changes: 10 additions & 5 deletions src/application/TikTokDownloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,13 @@
from src.module import Browser
from src.module import ColorfulConsole
from src.module import Cookie
from src.module import CookieTikTok
from src.module import Register
from src.record import BaseLogger
from src.record import LoggerManager
from src.tools import FileSwitch
from src.tools import choose
from src.tools import safe_pop
from .main_api_server import APIServer
from .main_complete import TikTok
from .main_server import Server
Expand Down Expand Up @@ -97,13 +99,15 @@ def __init__(self):
self.x_bogus = XBogus()
self.settings = Settings(PROJECT_ROOT, self.console)
self.cookie = Cookie(self.settings, self.console)
self.cookie_tiktok = CookieTikTok(self.settings, self.console)
self.register = Register(
self.settings,
self.console,
self.x_bogus,
)
self.parameter = None
self.running = True
self.default_mode = None
self.event = Event()
self.cookie_task = Thread(target=self.periodic_update_cookie)
self.backup_task = None
Expand Down Expand Up @@ -215,11 +219,11 @@ def check_update(self):
self.console.print("检测新版本失败", style=ERROR)
self.console.print()

def main_menu(self, default_mode="0"):
def main_menu(self, default_mode=None):
"""选择运行模式"""
while self.running:
self.__update_menu()
if default_mode not in {"3", "4", "5", "6", "7"}:
if not default_mode:
default_mode = choose(
"请选择 TikTokDownloader 运行模式",
[i for i, _ in self.__function],
Expand All @@ -228,15 +232,15 @@ def main_menu(self, default_mode="0"):
2,
7))
self.compatible(default_mode)
default_mode = "0"
default_mode = None

@start_cookie_task
def complete(self):
"""终端交互模式"""
example = TikTok(self.parameter)
register(self.blacklist.close)
try:
example.run()
example.run(self.default_mode)
self.running = example.running
except KeyboardInterrupt:
self.running = False
Expand Down Expand Up @@ -316,6 +320,7 @@ def check_settings(self):
**self.settings.read(),
blacklist=self.blacklist,
)
self.default_mode = self.parameter.default_mode.copy()
self.parameter.cleaner.set_rule(TEXT_REPLACEMENT, True)

def run(self):
Expand All @@ -324,7 +329,7 @@ def run(self):
self.check_update()
self.check_settings()
if self.disclaimer():
self.main_menu(self.parameter.default_mode)
self.main_menu(safe_pop(self.default_mode))
self.close()

@staticmethod
Expand Down
59 changes: 33 additions & 26 deletions src/application/main_complete.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from src.storage import RecordManager
from src.tools import TikTokAccount
from src.tools import choose
from src.tools import safe_pop

__all__ = [
"TikTok",
Expand Down Expand Up @@ -95,6 +96,7 @@ class TikTok:
}

def __init__(self, parameter):
self.default_mode = None
self.parameter = parameter
self.console = parameter.console
self.logger = parameter.logger
Expand Down Expand Up @@ -143,7 +145,7 @@ def _inquire_input(self, url: str = None, tip: str = None) -> str:
return ""
return text

def account_acquisition_interactive_tiktok(self):
def account_acquisition_interactive_tiktok(self, *args, **kwargs):
root, params, logger = self.record.run(self.parameter)
while path := self._inquire_input(tip="请输入 TikTok 主页 HTML 文件(夹)路径: "):
items = TikTokAccount(path).run()
Expand Down Expand Up @@ -221,11 +223,12 @@ def __check_post_tiktok(self, uid: str, nickname: str, item: list[dict]):
self.logger.error(f"发生异常: {uid, uid_, nickname, nickname_}")
return False

def account_acquisition_interactive(self):
def account_acquisition_interactive(self, select=None, *args, **kwargs):
root, params, logger = self.record.run(self.parameter)
select = choose("请选择账号链接来源",
("使用 accounts_urls 参数的账号链接(推荐)",
"手动输入待采集的账号链接"), self.console)
if not select:
select = choose("请选择账号链接来源",
("使用 accounts_urls 参数的账号链接(推荐)",
"手动输入待采集的账号链接"), self.console)
if select == "1":
self.account_works_batch(root, params, logger)
elif select == "2":
Expand Down Expand Up @@ -415,7 +418,7 @@ def download_account_works(
title=title,
)

def works_interactive(self):
def works_interactive(self, *args, **kwargs):
root, params, logger = self.record.run(self.parameter)
with logger(root, console=self.console, **params) as record:
while url := self._inquire_input("作品"):
Expand Down Expand Up @@ -474,7 +477,7 @@ def _choice_live_quality(
return None
return list(flv_items.values())[i], list(m3u8_items.values())[i]

def live_interactive(self):
def live_interactive(self, *args, **kwargs):
while url := self._inquire_input("直播"):
params = self._generate_live_params(*self.links.live(url))
if not params:
Expand Down Expand Up @@ -528,7 +531,7 @@ def show_live_stream_url(self, item: dict, tasks: list):
item["hls_pull_url_map"])) else u)

@check_storage_format
def comment_interactive(self):
def comment_interactive(self, *args, **kwargs):
root, params, logger = self.record.run(self.parameter, type_="comment")
while url := self._inquire_input("作品"):
tiktok, ids = self.links.works(url)
Expand All @@ -547,11 +550,12 @@ def comment_interactive(self):
self.logger.warning("采集评论数据失败")
self.logger.info("已退出采集作品评论数据模式")

def mix_interactive(self):
def mix_interactive(self, select=None, *args, **kwargs):
root, params, logger = self.record.run(self.parameter, type_="mix")
select = choose("请选择合集链接来源",
("使用 mix_urls 参数的合集链接(推荐)",
"手动输入待采集的合集/作品链接"), self.console)
if not select:
select = choose("请选择合集链接来源",
("使用 mix_urls 参数的合集链接(推荐)",
"手动输入待采集的合集/作品链接"), self.console)
if select == "1":
self.mix_batch(root, params, logger)
elif select == "2":
Expand Down Expand Up @@ -686,11 +690,12 @@ def _deal_user_data(
return data

@check_storage_format
def user_interactive(self):
select = choose(
"请选择账号链接来源",
("使用 accounts_urls 参数的账号链接",
"手动输入待采集的账号链接"), self.console)
def user_interactive(self, select=None, *args, **kwargs):
if not select:
select = choose(
"请选择账号链接来源",
("使用 accounts_urls 参数的账号链接",
"手动输入待采集的账号链接"), self.console)
if select == "1":
self.user_batch()
elif select == "2":
Expand Down Expand Up @@ -742,7 +747,7 @@ def _extract_integer(page: str) -> int:
return 1

@check_storage_format
def search_interactive(self):
def search_interactive(self, *args, **kwargs):
while True:
if isinstance(c := self._enter_search_criteria(), tuple):
self._deal_search_data(*c)
Expand Down Expand Up @@ -809,7 +814,7 @@ def _deal_search_data(
return search_data

@check_storage_format
def hot_interactive(self):
def hot_interactive(self, *args, **kwargs):
self._deal_hot_data()
self.logger.info("已退出采集抖音热榜数据模式")

Expand All @@ -830,7 +835,7 @@ def _deal_hot_data(self, source=False):
# print(time_, data, source) # 调试代码
return time_, data

def collection_interactive(self):
def collection_interactive(self, *args, **kwargs):
root, params, logger = self.record.run(self.parameter)
if not (sec_user_id := self.check_sec_user_id(self.owner.url)):
self.logger.warning(
Expand Down Expand Up @@ -871,16 +876,18 @@ def _deal_collection_data(
api=api,
addition="收藏作品", )

def run(self):
def run(self, default_mode: list):
self.default_mode = default_mode
with suppress(ValueError):
while self.running:
select = choose(
"请选择采集功能",
[i for i, _ in self.__function],
self.console)
if not (select := safe_pop(self.default_mode)):
select = choose(
"请选择采集功能",
[i for i, _ in self.__function],
self.console)
if select in {"Q", "q"}:
self.running = False
elif not select:
break
elif (n := int(select) - 1) in range(len(self.__function)):
self.__function[n][1]()
self.__function[n][1](safe_pop(self.default_mode))
Empty file removed src/cli_edition/__init__.py
Empty file.
Loading

0 comments on commit 6deae86

Please sign in to comment.