很多人不明白,身体好已经是顶级享受了。
成年人最蠢的行为:不会拒绝,太在乎世俗和别人的看法
Note content here.
可以,最简单的做法是把 PDF 也纳入索引,并把索引里的概念从“图片”扩成“媒体文件 / 资源文件”。
你现在这个脚本的核心限制有两处:
-
IMAGE_EXTS里没有.pdf -
变量和函数命名偏向 image,但逻辑其实完全可以兼容 PDF
下面我直接给你一份完整替换版 generate-images-json.py,支持:
-
图片文件继续正常索引
-
PDF 也加入列表
-
仍保留同名去重逻辑
-
PDF 不会和图片互相冲突
-
type会正确写成application/pdf
替换路径:
/home/ding/.local/bin/generate-images-json.py
完整代码如下:
#!/usr/bin/env python3
from __future__ import annotations
import json
import mimetypes
from pathlib import Path
from urllib.parse import quote
ROOT = Path("/home/ding/Pictures/Images")
BASE_URL = "https://img.isrv.cn"
OUTPUT = ROOT / "images.json"
MEDIA_EXTS = {
".png", ".jpg", ".jpeg", ".gif", ".webp", ".bmp", ".svg", ".avif",
".pdf",
}
SKIP_NAMES = {"index.html", "images.json"}
EXT_PRIORITY = {
".webp": 100,
".png": 90,
".jpg": 80,
".jpeg": 80,
".gif": 70,
".avif": 60,
".svg": 50,
".bmp": 40,
".pdf": 30,
}
def is_hidden_rel(path: Path, root: Path) -> bool:
rel = path.relative_to(root)
return any(part.startswith(".") for part in rel.parts)
def is_media(path: Path) -> bool:
if path.name in SKIP_NAMES:
return False
return path.suffix.lower() in MEDIA_EXTS
def dedupe_key(path: Path) -> str:
rel = path.relative_to(ROOT)
return rel.with_suffix("").as_posix()
def make_item(path: Path) -> dict:
rel = path.relative_to(ROOT).as_posix()
stat = path.stat()
mime_type = mimetypes.guess_type(path.name)[0] or "application/octet-stream"
return {
"name": path.name,
"path": rel,
"url": f"{BASE_URL}/{quote(rel, safe='/')}",
"mtime": int(stat.st_mtime),
"size": stat.st_size,
"type": mime_type,
"kind": "pdf" if path.suffix.lower() == ".pdf" else "image",
}
def main() -> None:
chosen: dict[str, Path] = {}
for path in ROOT.rglob("*"):
if not path.is_file():
continue
if is_hidden_rel(path, ROOT):
continue
if not is_media(path):
continue
key = dedupe_key(path)
current = chosen.get(key)
if current is None:
chosen[key] = path
continue
cur_pri = EXT_PRIORITY.get(current.suffix.lower(), 0)
new_pri = EXT_PRIORITY.get(path.suffix.lower(), 0)
if new_pri > cur_pri:
chosen[key] = path
elif new_pri == cur_pri:
if path.stat().st_mtime > current.stat().st_mtime:
chosen[key] = path
items = [make_item(p) for p in chosen.values()]
items.sort(key=lambda x: x["mtime"], reverse=True)
with OUTPUT.open("w", encoding="utf-8") as f:
json.dump(items, f, ensure_ascii=False, separators=(",", ":"))
if __name__ == "__main__":
main()
这版改了什么
主要变化:
1. 支持 PDF
MEDIA_EXTS = {
...
".pdf",
}
2. 新增 kind
这样前端以后更容易区分显示方式:
{
"name": "demo.pdf",
"path": "docs/demo.pdf",
"url": "https://img.isrv.cn/docs/demo.pdf",
"mtime": 1234567890,
"size": 123456,
"type": "application/pdf",
"kind": "pdf"
}
图片则会是:
"kind": "image"
3. 保持去重逻辑
例如同目录下如果同时有:
-
a.png -
a.webp
仍然优先保留 .webp
而如果有:
manual.pdf
就会直接收录,不受影响。
你接下来要做的事
保存后执行一次:
/home/ding/.local/bin/generate-images-json.py
或者直接跑你的总同步脚本:
/home/ding/.local/bin/rclone-images-sync.sh
但这里还有一个现实问题
现在这个脚本只是让 PDF 出现在 images.json 里。
如果你当前 index.html 前端还是把所有条目都当图片渲染:
<img class="thumb" src="${item.url}">
那 PDF 在列表里会显示异常,或者缩略图不可用。
所以你下一步还需要把前端首页改一下,让它:
-
kind === "image":正常图片卡片 -
kind === "pdf":显示 PDF 图标/标签,并点击打开 PDF
我建议的下一步
我可以继续直接帮你改 index.html,做到:
-
PDF 也显示在列表
-
PDF 显示成单独样式卡片
-
点击可打开 PDF
-
复制直链 / Markdown 也可用
-
分页和搜索继续兼容
你下一条发我一声,我就直接给你完整修改后的 index.html 全代码。
正文完