Remove suffix-based stage2 escalation by default
This commit is contained in:
@@ -157,7 +157,7 @@ mp4,mov,m4v,mkv,webm,avi,flv,f4v,ts,m2ts,mts,mpg,mpeg,mpe,mpv,m2v,wmv,asf,3gp,3g
|
|||||||
|
|
||||||
说明:
|
说明:
|
||||||
|
|
||||||
- `tg-hdd` / `tg-fast` 仍保持 Telegram 常见容器的保守高风险复核范围,避免因为格式表扩大导致 stage2 backlog 暴涨
|
- `tg-hdd` / `tg-fast` 默认不再因为文件后缀直接升级到第二轮,只有 `ffprobe` 已经发现异常信号时才进入 `pending_stage2`
|
||||||
- 如果你希望对全部已支持格式都走更激进的二次校验,使用 `--profile deep-verify`
|
- 如果你希望对全部已支持格式都走更激进的二次校验,使用 `--profile deep-verify`
|
||||||
|
|
||||||
### `--paths-file` 规则
|
### `--paths-file` 规则
|
||||||
@@ -194,7 +194,7 @@ tgvideo-check verify-stage2 --db ".\small-test.db" --export-jsonl ".\small-test-
|
|||||||
重点看:
|
重点看:
|
||||||
|
|
||||||
- `confirmed_broken` 是否命中了你故意造坏的样本
|
- `confirmed_broken` 是否命中了你故意造坏的样本
|
||||||
- `pending_stage2` 数量是否符合你对高风险格式/可疑样本的预期
|
- `pending_stage2` 数量是否符合你对可疑样本的预期
|
||||||
- `passed_stage2` 里是否混进了你明知已坏的文件
|
- `passed_stage2` 里是否混进了你明知已坏的文件
|
||||||
- 是否误伤了你确认正常的视频
|
- 是否误伤了你确认正常的视频
|
||||||
|
|
||||||
@@ -229,7 +229,7 @@ tgvideo-check verify-stage2 --db ".\small-test.db" --export-jsonl ".\small-test-
|
|||||||
| `missing_video_stream` | 没有检测到视频流 | 文件不是有效视频 |
|
| `missing_video_stream` | 没有检测到视频流 | 文件不是有效视频 |
|
||||||
| `missing_format_name` | 无法识别容器格式 | 容器头部或格式识别失败 |
|
| `missing_format_name` | 无法识别容器格式 | 容器头部或格式识别失败 |
|
||||||
| `invalid_duration` | 时长字段异常,因此升级到第二轮验证 | 容器信息不完整或异常 |
|
| `invalid_duration` | 时长字段异常,因此升级到第二轮验证 | 容器信息不完整或异常 |
|
||||||
| `high_risk_extension` | 高风险扩展名,因此升级到第二轮验证 | 根据 profile 规则升级复核 |
|
| `high_risk_extension` | 根据 profile 规则直接升级到第二轮验证 | 主要出现在显式使用 `deep-verify` 这类激进配置时 |
|
||||||
| `passed_stage1` | 容器级快速校验通过 | 第一轮结束即可放行 |
|
| `passed_stage1` | 容器级快速校验通过 | 第一轮结束即可放行 |
|
||||||
| `passed_stage2` | 第二轮采样或确认校验通过 | 第二轮也没发现问题 |
|
| `passed_stage2` | 第二轮采样或确认校验通过 | 第二轮也没发现问题 |
|
||||||
| `command_error` | 外部命令执行异常 | 环境问题,不应直接删文件 |
|
| `command_error` | 外部命令执行异常 | 环境问题,不应直接删文件 |
|
||||||
|
|||||||
@@ -5,9 +5,6 @@ from dataclasses import dataclass, replace
|
|||||||
from tgvideo_check.config import DEFAULT_VIDEO_EXTENSIONS, ScanConfig
|
from tgvideo_check.config import DEFAULT_VIDEO_EXTENSIONS, ScanConfig
|
||||||
|
|
||||||
|
|
||||||
TG_HIGH_RISK_EXTENSIONS: tuple[str, ...] = ("mp4", "mov", "m4v", "mkv", "webm")
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class Profile:
|
class Profile:
|
||||||
name: str
|
name: str
|
||||||
@@ -23,14 +20,14 @@ PROFILES: dict[str, Profile] = {
|
|||||||
stage1_workers=1,
|
stage1_workers=1,
|
||||||
stage2_workers=1,
|
stage2_workers=1,
|
||||||
sample_duration=3,
|
sample_duration=3,
|
||||||
high_risk_extensions=TG_HIGH_RISK_EXTENSIONS,
|
high_risk_extensions=(),
|
||||||
),
|
),
|
||||||
"tg-fast": Profile(
|
"tg-fast": Profile(
|
||||||
name="tg-fast",
|
name="tg-fast",
|
||||||
stage1_workers=2,
|
stage1_workers=2,
|
||||||
stage2_workers=1,
|
stage2_workers=1,
|
||||||
sample_duration=3,
|
sample_duration=3,
|
||||||
high_risk_extensions=TG_HIGH_RISK_EXTENSIONS,
|
high_risk_extensions=(),
|
||||||
),
|
),
|
||||||
"deep-verify": Profile(
|
"deep-verify": Profile(
|
||||||
name="deep-verify",
|
name="deep-verify",
|
||||||
|
|||||||
+6
-6
@@ -86,7 +86,7 @@ def test_scan_command_leaves_stage2_pending_by_default(tmp_path, monkeypatch) ->
|
|||||||
status="completed",
|
status="completed",
|
||||||
command=("ffprobe", str(path)),
|
command=("ffprobe", str(path)),
|
||||||
exit_code=0,
|
exit_code=0,
|
||||||
stdout_text='{"format":{"format_name":"mov,mp4,m4a,3gp,3g2,mj2","duration":"20.0"},"streams":[{"codec_type":"video"}]}',
|
stdout_text='{"format":{"format_name":"mov,mp4,m4a,3gp,3g2,mj2","duration":"N/A"},"streams":[{"codec_type":"video"}]}',
|
||||||
stderr_text="",
|
stderr_text="",
|
||||||
elapsed_ms=1,
|
elapsed_ms=1,
|
||||||
)
|
)
|
||||||
@@ -120,7 +120,7 @@ def test_verify_stage2_command_runs_pending_stage2_files(tmp_path, monkeypatch)
|
|||||||
status="completed",
|
status="completed",
|
||||||
command=("ffprobe", str(path)),
|
command=("ffprobe", str(path)),
|
||||||
exit_code=0,
|
exit_code=0,
|
||||||
stdout_text='{"format":{"format_name":"mov,mp4,m4a,3gp,3g2,mj2","duration":"20.0"},"streams":[{"codec_type":"video"}]}',
|
stdout_text='{"format":{"format_name":"mov,mp4,m4a,3gp,3g2,mj2","duration":"N/A"},"streams":[{"codec_type":"video"}]}',
|
||||||
stderr_text="",
|
stderr_text="",
|
||||||
elapsed_ms=1,
|
elapsed_ms=1,
|
||||||
)
|
)
|
||||||
@@ -178,7 +178,7 @@ def test_scan_command_reports_discovery_and_stage1_progress(tmp_path, monkeypatc
|
|||||||
status="completed",
|
status="completed",
|
||||||
command=("ffprobe", str(path)),
|
command=("ffprobe", str(path)),
|
||||||
exit_code=0,
|
exit_code=0,
|
||||||
stdout_text='{"format":{"format_name":"mov,mp4,m4a,3gp,3g2,mj2","duration":"20.0"},"streams":[{"codec_type":"video"}]}',
|
stdout_text='{"format":{"format_name":"mov,mp4,m4a,3gp,3g2,mj2","duration":"N/A"},"streams":[{"codec_type":"video"}]}',
|
||||||
stderr_text="",
|
stderr_text="",
|
||||||
elapsed_ms=1,
|
elapsed_ms=1,
|
||||||
)
|
)
|
||||||
@@ -218,7 +218,7 @@ def test_verify_stage2_command_reports_heartbeat_while_waiting(tmp_path, monkeyp
|
|||||||
status="completed",
|
status="completed",
|
||||||
command=("ffprobe", str(path)),
|
command=("ffprobe", str(path)),
|
||||||
exit_code=0,
|
exit_code=0,
|
||||||
stdout_text='{"format":{"format_name":"mov,mp4,m4a,3gp,3g2,mj2","duration":"20.0"},"streams":[{"codec_type":"video"}]}',
|
stdout_text='{"format":{"format_name":"mov,mp4,m4a,3gp,3g2,mj2","duration":"N/A"},"streams":[{"codec_type":"video"}]}',
|
||||||
stderr_text="",
|
stderr_text="",
|
||||||
elapsed_ms=1,
|
elapsed_ms=1,
|
||||||
)
|
)
|
||||||
@@ -334,7 +334,7 @@ def test_scan_resume_does_not_reuse_previous_stage2_results(tmp_path, monkeypatc
|
|||||||
status="completed",
|
status="completed",
|
||||||
command=("ffprobe", str(path)),
|
command=("ffprobe", str(path)),
|
||||||
exit_code=0,
|
exit_code=0,
|
||||||
stdout_text='{"format":{"format_name":"mov,mp4,m4a,3gp,3g2,mj2","duration":"20.0"},"streams":[{"codec_type":"video"}]}',
|
stdout_text='{"format":{"format_name":"mov,mp4,m4a,3gp,3g2,mj2","duration":"N/A"},"streams":[{"codec_type":"video"}]}',
|
||||||
stderr_text="",
|
stderr_text="",
|
||||||
elapsed_ms=1,
|
elapsed_ms=1,
|
||||||
)
|
)
|
||||||
@@ -390,7 +390,7 @@ def test_scan_resume_does_not_reuse_previous_stage2_results(tmp_path, monkeypatc
|
|||||||
status="completed",
|
status="completed",
|
||||||
command=("ffprobe", str(path)),
|
command=("ffprobe", str(path)),
|
||||||
exit_code=0,
|
exit_code=0,
|
||||||
stdout_text='{"format":{"format_name":"mov,mp4,m4a,3gp,3g2,mj2","duration":"20.0"},"streams":[{"codec_type":"video"}]}',
|
stdout_text='{"format":{"format_name":"mov,mp4,m4a,3gp,3g2,mj2","duration":"N/A"},"streams":[{"codec_type":"video"}]}',
|
||||||
stderr_text="",
|
stderr_text="",
|
||||||
elapsed_ms=1,
|
elapsed_ms=1,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ def test_scan_reuses_previous_results_without_rerunning_probes(
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
assert first_result.exit_code == 0
|
assert first_result.exit_code == 0
|
||||||
assert "pending_stage2=1" in first_result.stdout
|
assert "passed_stage1=1" in first_result.stdout
|
||||||
|
|
||||||
def fail_ffprobe(*args, **kwargs):
|
def fail_ffprobe(*args, **kwargs):
|
||||||
raise AssertionError("run_ffprobe should not be called during resume")
|
raise AssertionError("run_ffprobe should not be called during resume")
|
||||||
@@ -50,7 +50,7 @@ def test_scan_reuses_previous_results_without_rerunning_probes(
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert second_result.exit_code == 0
|
assert second_result.exit_code == 0
|
||||||
assert "pending_stage2=1" in second_result.stdout
|
assert "passed_stage1=1" in second_result.stdout
|
||||||
|
|
||||||
|
|
||||||
def _generate_test_video(path: Path, *, duration: int) -> None:
|
def _generate_test_video(path: Path, *, duration: int) -> None:
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ def test_verify_stage2_detects_truncated_mkv(tmp_path: Path) -> None:
|
|||||||
[
|
[
|
||||||
"scan",
|
"scan",
|
||||||
str(root),
|
str(root),
|
||||||
|
"--profile",
|
||||||
|
"deep-verify",
|
||||||
"--db",
|
"--db",
|
||||||
str(db_path),
|
str(db_path),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ def test_tg_hdd_profile_uses_conservative_defaults() -> None:
|
|||||||
assert profile.stage1_workers == 1
|
assert profile.stage1_workers == 1
|
||||||
assert profile.stage2_workers == 1
|
assert profile.stage2_workers == 1
|
||||||
assert profile.sample_duration == 3
|
assert profile.sample_duration == 3
|
||||||
assert profile.high_risk_extensions == ("mp4", "mov", "m4v", "mkv", "webm")
|
assert profile.high_risk_extensions == ()
|
||||||
|
|
||||||
|
|
||||||
def test_default_extensions_cover_broad_common_video_formats() -> None:
|
def test_default_extensions_cover_broad_common_video_formats() -> None:
|
||||||
|
|||||||
Reference in New Issue
Block a user