bilisum 1.13.2 → 1.13.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/bin/bilisum.js +157 -76
- package/package.json +7 -2
- package/runtime/VERSION +1 -0
- package/runtime/apps/service/pyproject.toml +29 -0
- package/runtime/apps/service/src/video_sum_service/__init__.py +1 -0
- package/runtime/apps/service/src/video_sum_service/__main__.py +5 -0
- package/runtime/apps/service/src/video_sum_service/app.py +480 -0
- package/runtime/apps/service/src/video_sum_service/context.py +24 -0
- package/runtime/apps/service/src/video_sum_service/integrations.py +264 -0
- package/runtime/apps/service/src/video_sum_service/knowledge/__init__.py +5 -0
- package/runtime/apps/service/src/video_sum_service/knowledge/index_service.py +408 -0
- package/runtime/apps/service/src/video_sum_service/knowledge/local_llm.py +319 -0
- package/runtime/apps/service/src/video_sum_service/knowledge/rag_service.py +492 -0
- package/runtime/apps/service/src/video_sum_service/knowledge/tag_service.py +242 -0
- package/runtime/apps/service/src/video_sum_service/main.py +31 -0
- package/runtime/apps/service/src/video_sum_service/repository.py +942 -0
- package/runtime/apps/service/src/video_sum_service/routers/__init__.py +1 -0
- package/runtime/apps/service/src/video_sum_service/routers/knowledge.py +272 -0
- package/runtime/apps/service/src/video_sum_service/routers/system.py +280 -0
- package/runtime/apps/service/src/video_sum_service/routers/tasks.py +287 -0
- package/runtime/apps/service/src/video_sum_service/routers/videos.py +766 -0
- package/runtime/apps/service/src/video_sum_service/runtime_support.py +1007 -0
- package/runtime/apps/service/src/video_sum_service/schemas.py +418 -0
- package/runtime/apps/service/src/video_sum_service/settings_manager.py +130 -0
- package/runtime/apps/service/src/video_sum_service/task_artifacts.py +102 -0
- package/runtime/apps/service/src/video_sum_service/task_exports.py +108 -0
- package/runtime/apps/service/src/video_sum_service/transcribe_worker.py +9 -0
- package/runtime/apps/service/src/video_sum_service/video_assets.py +623 -0
- package/runtime/apps/service/src/video_sum_service/worker.py +381 -0
- package/runtime/apps/web/static/apple-touch-icon.png +0 -0
- package/runtime/apps/web/static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/runtime/apps/web/static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/runtime/apps/web/static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/runtime/apps/web/static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/runtime/apps/web/static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/runtime/apps/web/static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/runtime/apps/web/static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/runtime/apps/web/static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/runtime/apps/web/static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/runtime/apps/web/static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/runtime/apps/web/static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/runtime/apps/web/static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/runtime/apps/web/static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/runtime/apps/web/static/assets/icons/icon-180.png +0 -0
- package/runtime/apps/web/static/assets/icons/icon-512.png +0 -0
- package/runtime/apps/web/static/assets/icons/icon.svg +17 -0
- package/runtime/apps/web/static/assets/index-Cj5PVjQg.js +388 -0
- package/runtime/apps/web/static/assets/index-DU2t4_7s.css +1 -0
- package/runtime/apps/web/static/favicon-32x32.png +0 -0
- package/runtime/apps/web/static/favicon.ico +0 -0
- package/runtime/apps/web/static/favicon.svg +17 -0
- package/runtime/apps/web/static/index.html +19 -0
- package/runtime/apps/web/static/js/api.js +123 -0
- package/runtime/apps/web/static/js/main.js +932 -0
- package/runtime/apps/web/static/js/state.js +28 -0
- package/runtime/apps/web/static/js/utils.js +81 -0
- package/runtime/apps/web/static/js/views/home.js +604 -0
- package/runtime/apps/web/static/js/views/settings.js +477 -0
- package/runtime/apps/web/static/styles.css +2206 -0
- package/runtime/packages/core/pyproject.toml +18 -0
- package/runtime/packages/core/src/video_sum_core/__init__.py +1 -0
- package/runtime/packages/core/src/video_sum_core/errors.py +22 -0
- package/runtime/packages/core/src/video_sum_core/markdown_exports.py +154 -0
- package/runtime/packages/core/src/video_sum_core/models/__init__.py +1 -0
- package/runtime/packages/core/src/video_sum_core/models/tasks.py +70 -0
- package/runtime/packages/core/src/video_sum_core/pipeline/__init__.py +1 -0
- package/runtime/packages/core/src/video_sum_core/pipeline/base.py +46 -0
- package/runtime/packages/core/src/video_sum_core/pipeline/real.py +3467 -0
- package/runtime/packages/core/src/video_sum_core/transcribe_subprocess.py +173 -0
- package/runtime/packages/core/src/video_sum_core/utils.py +127 -0
- package/runtime/packages/infra/pyproject.toml +16 -0
- package/runtime/packages/infra/src/video_sum_infra/__init__.py +1 -0
- package/runtime/packages/infra/src/video_sum_infra/app.py +39 -0
- package/runtime/packages/infra/src/video_sum_infra/config.py +393 -0
- package/runtime/packages/infra/src/video_sum_infra/db.py +34 -0
- package/runtime/packages/infra/src/video_sum_infra/logging.py +54 -0
- package/runtime/packages/infra/src/video_sum_infra/paths.py +6 -0
- package/runtime/packages/infra/src/video_sum_infra/runtime.py +485 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Literal
|
|
6
|
+
|
|
7
|
+
from fastapi import HTTPException
|
|
8
|
+
|
|
9
|
+
from video_sum_core.models.tasks import TaskStatus
|
|
10
|
+
from video_sum_core.markdown_exports import build_export_filename, build_task_markdown_export
|
|
11
|
+
from video_sum_infra.config import ServiceSettings
|
|
12
|
+
|
|
13
|
+
from video_sum_service.repository import SqliteTaskRepository
|
|
14
|
+
from video_sum_service.schemas import TaskMarkdownExportResponse
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def export_task_markdown(
|
|
18
|
+
repository: SqliteTaskRepository,
|
|
19
|
+
current_settings: ServiceSettings,
|
|
20
|
+
task_id: str,
|
|
21
|
+
*,
|
|
22
|
+
target: Literal["markdown", "obsidian"] = "obsidian",
|
|
23
|
+
) -> TaskMarkdownExportResponse:
|
|
24
|
+
normalized_target = str(target or "obsidian").strip().lower()
|
|
25
|
+
if normalized_target not in {"markdown", "obsidian"}:
|
|
26
|
+
raise HTTPException(status_code=400, detail="仅支持导出 markdown 或 obsidian 格式。")
|
|
27
|
+
|
|
28
|
+
record = repository.get_task(task_id)
|
|
29
|
+
if record is None:
|
|
30
|
+
raise HTTPException(status_code=404, detail="Task not found.")
|
|
31
|
+
if record.status != TaskStatus.COMPLETED or record.result is None:
|
|
32
|
+
raise HTTPException(status_code=400, detail="仅已完成且有结果的任务可以导出 Markdown。")
|
|
33
|
+
|
|
34
|
+
result = record.result
|
|
35
|
+
if not result.knowledge_note_markdown.strip():
|
|
36
|
+
raise HTTPException(status_code=400, detail="当前任务缺少知识笔记,暂时无法导出 Markdown。")
|
|
37
|
+
|
|
38
|
+
output_dir_raw = str(current_settings.output_dir or "").strip()
|
|
39
|
+
if not output_dir_raw:
|
|
40
|
+
raise HTTPException(status_code=400, detail="请先在设置中配置输出目录,再导出 Markdown / Obsidian 笔记。")
|
|
41
|
+
|
|
42
|
+
export_directory = Path(output_dir_raw).expanduser()
|
|
43
|
+
export_directory.mkdir(parents=True, exist_ok=True)
|
|
44
|
+
|
|
45
|
+
video = repository.get_video_asset(record.video_id) if record.video_id else None
|
|
46
|
+
export_time = datetime.now().astimezone()
|
|
47
|
+
title = (
|
|
48
|
+
str(record.task_input.title or "").strip()
|
|
49
|
+
or str(video.title if video else "").strip()
|
|
50
|
+
or "BiliSum 知识笔记"
|
|
51
|
+
)
|
|
52
|
+
preferred_file_name = build_export_filename(title, export_time)
|
|
53
|
+
platform = str(video.platform if video else record.task_input.platform_hint or "").strip().lower() or "unknown"
|
|
54
|
+
tags = ["bilisum", platform, "video-summary"]
|
|
55
|
+
markdown = build_task_markdown_export(
|
|
56
|
+
title=title,
|
|
57
|
+
overview=result.overview,
|
|
58
|
+
knowledge_note_markdown=result.knowledge_note_markdown,
|
|
59
|
+
key_points=result.key_points,
|
|
60
|
+
timeline=result.timeline,
|
|
61
|
+
source_url=str(video.source_url if video else record.task_input.source or ""),
|
|
62
|
+
platform=platform,
|
|
63
|
+
video_id=record.video_id,
|
|
64
|
+
canonical_id=str(video.canonical_id) if video else None,
|
|
65
|
+
task_id=record.task_id,
|
|
66
|
+
created_at=record.created_at,
|
|
67
|
+
exported_at=export_time,
|
|
68
|
+
tags=tags,
|
|
69
|
+
target=normalized_target,
|
|
70
|
+
mindmap_path=result.mindmap_artifact_path or result.artifacts.get("mindmap_path"),
|
|
71
|
+
)
|
|
72
|
+
export_path, had_name_conflict = _write_markdown_export(export_directory, preferred_file_name, markdown)
|
|
73
|
+
|
|
74
|
+
artifact_key = "obsidian_note_path" if normalized_target == "obsidian" else "markdown_note_path"
|
|
75
|
+
refreshed_result = result.model_copy(
|
|
76
|
+
update={
|
|
77
|
+
"artifacts": {
|
|
78
|
+
**result.artifacts,
|
|
79
|
+
artifact_key: str(export_path),
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
)
|
|
83
|
+
repository.save_result(task_id, refreshed_result)
|
|
84
|
+
return TaskMarkdownExportResponse(
|
|
85
|
+
task_id=task_id,
|
|
86
|
+
target_format=normalized_target,
|
|
87
|
+
path=str(export_path),
|
|
88
|
+
directory=str(export_directory),
|
|
89
|
+
file_name=export_path.name,
|
|
90
|
+
overwritten=had_name_conflict,
|
|
91
|
+
artifact_key=artifact_key,
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def _write_markdown_export(directory: Path, file_name: str, content: str) -> tuple[Path, bool]:
|
|
96
|
+
base_candidate = directory / file_name
|
|
97
|
+
suffix = base_candidate.suffix or ".md"
|
|
98
|
+
stem = base_candidate.stem
|
|
99
|
+
counter = 1
|
|
100
|
+
while True:
|
|
101
|
+
candidate = base_candidate if counter == 1 else directory / f"{stem} ({counter}){suffix}"
|
|
102
|
+
try:
|
|
103
|
+
with candidate.open("x", encoding="utf-8") as handle:
|
|
104
|
+
handle.write(content)
|
|
105
|
+
except FileExistsError:
|
|
106
|
+
counter += 1
|
|
107
|
+
continue
|
|
108
|
+
return candidate, counter > 1
|