Skip to content

Commit 552954a

Browse files
committed
release: v0.3.4 (Markdown auto-chapters); docs updated
1 parent bdffddb commit 552954a

File tree

6 files changed

+68
-7
lines changed

6 files changed

+68
-7
lines changed

docs/RELEASE_NOTES.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,8 @@ v0.3.3 (2025-09-08)
5151
--------------------
5252
- fix(cache): correct cache directory parsing (`<root>/<video>/<engine>/<model>/<hash>`) when deriving `video_id`, ensuring cache listings and exports find entries.
5353
- test(cache): add test to validate video_id parsing and cache scanning.
54+
55+
v0.3.4 (2025-09-08)
56+
--------------------
57+
- feat(export-md): auto-chapters synthesis when missing (`--md-auto-chapters-min N`), generating a chapter outline at fixed intervals.
58+
- docs: README updated with auto-chapters option.

docs/release_github_v0.3.2.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# TubeScribe v0.3.2 — Export from Cache Fixes
2+
3+
## Fixes
4+
- cache: `scan_cache` and artifact checks now accept legacy `<video_id>.json/.srt` alongside canonical `transcript.json/captions.srt`.
5+
- cli(export): when `transcript.json` is missing, fall back to `<video_id>.json` for cached export.
6+
7+
## Upgrade
8+
`pipx upgrade tubescribe` or `pip install -U tubescribe`
9+
10+
## Notes
11+
This unblocks `ytx export --video-id <id> --to md --output-dir ./notes` on older caches.
12+

docs/release_github_v0.3.4.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# TubeScribe v0.3.4 — Auto‑Chapters for Markdown
2+
3+
## Feature
4+
- Markdown export can now synthesize chapters when a video has none.
5+
- CLI: `--md-auto-chapters-min N` adds a chapter outline every N minutes.
6+
- Works alongside existing features: frontmatter, summary/bullets, transcript.
7+
8+
## Example
9+
`ytx export --video-id <id> --to md --output-dir ./notes --md-frontmatter --md-auto-chapters-min 5`
10+
11+
## Upgrade
12+
`pipx upgrade tubescribe` or `pip install -U tubescribe`
13+

ytx/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "tubescribe"
3-
version = "0.3.3"
3+
version = "0.3.4"
44
description = "CLI to transcribe YouTube audio via Whisper (local) or Gemini (cloud)"
55
readme = "README.md"
66
authors = [

ytx/src/ytx/cache.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,8 @@ def artifacts_exist(paths: ArtifactPaths) -> bool:
177177
return True
178178
# fallback to <video_id>.json/.srt
179179
try:
180-
vid = paths.dir.parents[3].name
180+
# <root>/<video_id>/<engine>/<model>/<hash>
181+
vid = paths.dir.parents[2].name
181182
except Exception:
182183
vid = None
183184
if vid:
@@ -231,10 +232,14 @@ def read_transcript_doc(paths: ArtifactPaths) -> "TranscriptDoc":
231232
raw = _read_json_bytes(paths.transcript_json)
232233
except CacheError:
233234
# Fallback to <video_id>.json if present
235+
vid = None
234236
try:
235-
vid = paths.dir.parents[3].name
237+
vid = paths.dir.parents[2].name
238+
except Exception:
239+
pass
240+
if vid:
236241
raw = _read_json_bytes(paths.dir / f"{vid}.json")
237-
except Exception as e:
242+
else:
238243
raise
239244
try:
240245
payload = _loads_json(raw)
@@ -418,9 +423,10 @@ def scan_cache(root: Path | None = None) -> list[CacheEntry]:
418423
entries: list[CacheEntry] = []
419424
for d in iter_artifact_dirs(root):
420425
try:
421-
video_id = d.parents[3].name
422-
engine = d.parents[2].name
423-
model = d.parents[1].name
426+
# <root>/<video_id>/<engine>/<model>/<hash>
427+
video_id = d.parents[2].name
428+
engine = d.parents[1].name
429+
model = d.parents[0].name
424430
cfg_hash = d.name
425431
except Exception:
426432
continue
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from pathlib import Path
2+
from datetime import datetime, timezone
3+
4+
from ytx.cache import scan_cache, build_artifact_paths, write_meta, build_meta_payload
5+
from ytx.config import AppConfig
6+
from ytx.models import VideoMetadata
7+
8+
9+
def test_scan_cache_reads_correct_video_id(tmp_path: Path):
10+
# Arrange: create canonical files under <root>/<vid>/<engine>/<model>/<hash>/
11+
vid = "TLSSVT1GI2Y"
12+
cfg = AppConfig(engine="whisper", model="small")
13+
paths = build_artifact_paths(video_id=vid, engine=cfg.engine, model=cfg.model, config_hash="deadbeef", root=tmp_path, create=True)
14+
# Create minimal artifacts
15+
(paths.transcript_json).write_text("{}", encoding="utf-8")
16+
(paths.captions_srt).write_text("1\n00:00:00,000 --> 00:00:00,500\nHi\n", encoding="utf-8")
17+
vm = VideoMetadata(id=vid, title="t", duration=1.0, url=f"https://youtu.be/{vid}")
18+
write_meta(paths, build_meta_payload(video_id=vid, config=cfg, source=vm, provider=cfg.engine))
19+
20+
# Act
21+
entries = scan_cache(root=tmp_path)
22+
23+
# Assert
24+
assert any(e.video_id == vid for e in entries)
25+

0 commit comments

Comments
 (0)