Accept single snippet photos and derive post IDs from titles
This commit is contained in:
+18
-7
@@ -1,7 +1,6 @@
|
||||
"""Markdown import with conservative content matching and explicit ID overrides."""
|
||||
from difflib import SequenceMatcher
|
||||
from datetime import date, datetime
|
||||
import hashlib
|
||||
import re
|
||||
import unicodedata
|
||||
|
||||
@@ -28,6 +27,17 @@ def filename_key(filename):
|
||||
return unicodedata.normalize("NFC", filename).casefold()
|
||||
|
||||
|
||||
def title_id(title):
|
||||
slug = re.sub(r"[\W_]+", "-", unicodedata.normalize("NFKC", title).lower()).strip("-")
|
||||
slug = slug[:80].rstrip("-")
|
||||
# Leave room for the date and prefix in the filesystem's byte-length limit.
|
||||
while len(slug.encode("utf-8")) > 160:
|
||||
slug = slug[:-1].rstrip("-")
|
||||
if not slug:
|
||||
raise ValueError("The post title must contain a letter or number")
|
||||
return slug
|
||||
|
||||
|
||||
def parse_upload(filename, raw):
|
||||
if not filename or "/" in filename or "\\" in filename or not filename.lower().endswith((".md", ".markdown")):
|
||||
raise ValueError("Share one .md or .markdown file with a plain filename")
|
||||
@@ -69,7 +79,7 @@ def parse_upload(filename, raw):
|
||||
raise ValueError("date must be an ISO date or timestamp") from None
|
||||
clean["date"] = str(value)
|
||||
explicit_id = clean.pop("post_id", None)
|
||||
if explicit_id is not None and not re.fullmatch(r"[a-zA-Z0-9_-]{1,80}", explicit_id):
|
||||
if explicit_id is not None and (not re.fullmatch(r"[\w-]{1,80}", explicit_id) or len(explicit_id.encode()) > 160):
|
||||
raise ValueError("post_id must be 1–80 letters, digits, underscores, or hyphens")
|
||||
if "permalink" in clean and not re.fullmatch(r"/[\w/-]+/", clean["permalink"]):
|
||||
raise ValueError("permalink must be a local path such as /my-post/")
|
||||
@@ -109,21 +119,22 @@ def publish_post(repo, submission, manifest):
|
||||
candidates.append(scored[0][1:])
|
||||
if len(candidates) > 1:
|
||||
raise ValueError("More than one post matches this post ID")
|
||||
identity = incoming["explicit_id"] or manifest["id"]
|
||||
identity = incoming["explicit_id"] or title_id(incoming["metadata"]["title"])
|
||||
if candidates:
|
||||
entry, metadata = candidates[0]
|
||||
identity = metadata.get("upload_id", identity)
|
||||
identity = metadata.get("upload_id") or metadata.get("post_id") or title_id(metadata.get("title", entry.stem))
|
||||
# Keep the public URL and original publication date during updates.
|
||||
metadata.update({key: value for key, value in incoming["metadata"].items() if key not in {"date", "permalink"}})
|
||||
permalink = metadata.get("permalink") or "/" + re.sub(r"^\d{4}-\d{2}-\d{2}-", "", entry.stem) + "/"
|
||||
else:
|
||||
metadata = dict(incoming["metadata"])
|
||||
metadata.setdefault("date", manifest["date"])
|
||||
slug = re.sub(r"[^\w-]+", "-", incoming["metadata"]["title"].lower()).strip("-")[:80] or "post"
|
||||
permalink = metadata.get("permalink", f"/{slug}-{identity[:8]}/")
|
||||
permalink = metadata.get("permalink", f"/{identity}/")
|
||||
entry = repo / "_posts" / f"{str(metadata['date'])[:10]}-upload-{identity}.md"
|
||||
if entry.exists():
|
||||
raise ValueError("Post identity conflicts with another file")
|
||||
if any(identity in (record.get("upload_id"), record.get("post_id")) for _, record in records):
|
||||
raise ValueError("Another post already uses this title-derived ID; use a different title or explicit post_id")
|
||||
# Avoid taking over another page's URL, including non-post pages.
|
||||
for other in list(repo.glob("*.md")) + list(repo.glob("*.html")):
|
||||
other_metadata, _ = split_markdown(other.read_text())
|
||||
@@ -135,7 +146,7 @@ def publish_post(repo, submission, manifest):
|
||||
if url and str(url).strip("/") == permalink.strip("/"):
|
||||
raise ValueError("Another page already uses this permalink")
|
||||
permalink = "/" + str(permalink).strip("/") + "/"
|
||||
metadata.update(layout="post", permalink=permalink, upload_id=identity,
|
||||
metadata.update(layout="post", permalink=permalink, upload_id=identity, post_id=identity,
|
||||
upload_filename=incoming["key"], upload_revision=manifest["id"],
|
||||
render_with_liquid=False)
|
||||
entry.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
Reference in New Issue
Block a user