ttyplayer 0.3.0__py3-none-any.whl

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.
ttyplayer/history.py ADDED
@@ -0,0 +1,64 @@
1
+ """What has been played, one JSON object per line, newest at the bottom."""
2
+
3
+ import json
4
+ from datetime import datetime, timezone
5
+ from pathlib import Path
6
+
7
+ from ttyplayer.models import Video
8
+ from ttyplayer.utils import data_path
9
+
10
+
11
+ def history_path() -> Path:
12
+ return data_path("history.jsonl")
13
+
14
+
15
+ def record(video: Video, path: Path | None = None):
16
+ path = path or history_path()
17
+ path.parent.mkdir(parents=True, exist_ok=True)
18
+ entry = {
19
+ "id": video.id,
20
+ "title": video.title,
21
+ "uploader": video.uploader,
22
+ "duration": video.duration,
23
+ "played_at": datetime.now(timezone.utc).isoformat(timespec="seconds"),
24
+ }
25
+ with path.open("a", encoding="utf-8") as f:
26
+ f.write(json.dumps(entry) + "\n")
27
+
28
+
29
+ def clear(path: Path | None = None) -> int:
30
+ """Forget everything. Returns how many entries were there."""
31
+ path = path or history_path()
32
+ if not path.exists():
33
+ return 0
34
+ count = len(path.read_text(encoding="utf-8").splitlines())
35
+ path.unlink()
36
+ return count
37
+
38
+
39
+ def load(path: Path | None = None, limit: int = 20) -> list[Video]:
40
+ """Most recently played first, each video once, at most `limit` of them."""
41
+ path = path or history_path()
42
+ if not path.exists():
43
+ return []
44
+ seen = set()
45
+ videos = []
46
+ for line in reversed(path.read_text(encoding="utf-8").splitlines()):
47
+ try:
48
+ entry = json.loads(line)
49
+ except json.JSONDecodeError:
50
+ continue
51
+ if entry.get("id") in seen or "id" not in entry:
52
+ continue
53
+ seen.add(entry["id"])
54
+ videos.append(
55
+ Video(
56
+ id=entry["id"],
57
+ title=entry.get("title") or "Untitled",
58
+ uploader=entry.get("uploader") or "Unknown",
59
+ duration=entry.get("duration"),
60
+ )
61
+ )
62
+ if len(videos) == limit:
63
+ break
64
+ return videos
ttyplayer/models.py ADDED
@@ -0,0 +1,13 @@
1
+ from dataclasses import dataclass
2
+
3
+
4
+ @dataclass
5
+ class Video:
6
+ id: str
7
+ title: str
8
+ uploader: str
9
+ duration: int | None # seconds; None for live streams or when yt-dlp does not know
10
+
11
+ @property
12
+ def url(self):
13
+ return f"https://www.youtube.com/watch?v={self.id}"