-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfetch.py
More file actions
137 lines (114 loc) · 4.06 KB
/
fetch.py
File metadata and controls
137 lines (114 loc) · 4.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
"""CLI for downstream agents: look up a rendered publication by date.
Prints an absolute path (one per line), exits 0 on success. Agents can
``cp``/``cat`` the path or read it directly.
Usage:
python -m fetch latest # path to latest PDF
python -m fetch latest --format jpeg # latest JPEG
python -m fetch --date 2026-04-19 # specific date, PDF
python -m fetch --date 2026-04-19 --format md
python -m fetch list # list all available dates
python -m fetch list --format jpeg # list dates that have a JPEG
Formats: pdf (default), jpeg, md, html.
Exit codes:
0 ok
1 not found
2 usage error
"""
from __future__ import annotations
import argparse
import sys
from datetime import date
from pathlib import Path
from typing import Optional
PROJECT_ROOT = Path(__file__).resolve().parent
RENDERS_DIR = PROJECT_ROOT / "data" / "renders"
PUBLICATIONS_DIR = PROJECT_ROOT / "data" / "publications"
FORMAT_TO_FILENAME = {
"pdf": "publication.pdf",
"jpeg": "publication.jpeg",
"jpg": "publication.jpeg",
"html": "publication.html",
"md": None, # sourced from PUBLICATIONS_DIR instead of RENDERS_DIR
}
def _path_for(target_date: date, fmt: str) -> Path:
fmt = fmt.lower()
if fmt not in FORMAT_TO_FILENAME:
raise SystemExit(f"Unknown format: {fmt!r}. Choose from: pdf / jpeg / md / html.")
if fmt == "md":
return PUBLICATIONS_DIR / f"{target_date.isoformat()}.md"
return RENDERS_DIR / target_date.isoformat() / FORMAT_TO_FILENAME[fmt]
def _all_dates(fmt: str) -> list[str]:
"""Dates that have a file for the given format, newest first."""
fmt = fmt.lower()
if fmt == "md":
if not PUBLICATIONS_DIR.exists():
return []
stems: list[str] = []
for p in PUBLICATIONS_DIR.glob("*.md"):
try:
date.fromisoformat(p.stem)
stems.append(p.stem)
except ValueError:
continue
return sorted(stems, reverse=True)
if not RENDERS_DIR.exists():
return []
filename = FORMAT_TO_FILENAME[fmt]
out: list[str] = []
for child in RENDERS_DIR.iterdir():
if not child.is_dir():
continue
try:
date.fromisoformat(child.name)
except ValueError:
continue
if (child / filename).exists():
out.append(child.name)
return sorted(out, reverse=True)
def cmd_latest(fmt: str) -> int:
dates = _all_dates(fmt)
if not dates:
print(f"No publication found for format {fmt!r}.", file=sys.stderr)
return 1
path = _path_for(date.fromisoformat(dates[0]), fmt)
print(path)
return 0
def cmd_date(target_date: date, fmt: str) -> int:
path = _path_for(target_date, fmt)
if not path.exists():
print(f"Not found: {path}", file=sys.stderr)
return 1
print(path)
return 0
def cmd_list(fmt: str) -> int:
for d in _all_dates(fmt):
print(d)
return 0
def main(argv: Optional[list[str]] = None) -> int:
parser = argparse.ArgumentParser(
description="Fetch a rendered publication path by date.",
formatter_class=argparse.RawDescriptionHelpFormatter,
)
parser.add_argument(
"action",
nargs="?",
default="latest",
choices=["latest", "list"],
help="`latest` (default) or `list`. Omit when passing --date.",
)
parser.add_argument("--date", type=lambda s: date.fromisoformat(s),
help="Specific date (YYYY-MM-DD). Overrides action.")
parser.add_argument("--format", default="pdf",
choices=["pdf", "jpeg", "jpg", "md", "html"],
help="Output format (default: pdf).")
args = parser.parse_args(argv)
if args.date:
return cmd_date(args.date, args.format)
if args.action == "latest":
return cmd_latest(args.format)
if args.action == "list":
return cmd_list(args.format)
parser.error("unreachable")
return 2
if __name__ == "__main__":
sys.exit(main())