From: Lady Date: Fri, 15 Dec 2023 03:13:43 +0000 (-0500) Subject: Put yyyy-mm URLs inside statuses X-Git-Tag: 0.2.0~1 X-Git-Url: https://git.ladys.computer/x_status_git/commitdiff_plain/b07270ecbc9ca480c69b7085cf445a0358e22df4 Put yyyy-mm URLs inside statuses --- diff --git a/Caddyfile b/Caddyfile index b4bcbff..03420b8 100644 --- a/Caddyfile +++ b/Caddyfile @@ -18,6 +18,11 @@ status.site.example { expression {re.matcher.suffix} == "" } + handle / { + rewrite * /index.html + header Link ;rel=meta;type="application/ld+json" + } + handle /about { rewrite * /.about.html header Link ;rel=meta;type="application/ld+json" @@ -32,51 +37,39 @@ status.site.example { header Link ;rel=meta;type="application/ld+json" } - @statusroot { - path_regexp matcher ^/statuses/(?P.*) - not path_regexp ^/statuses/index\. - } - - handle @statusroot { - handle /statuses/ { - redir * /statuses - } - - handle { - redir * /{re.matcher.path} - } - } + redir /statuses/ /statuses rewrite /statuses.jsonld /statuses/index.jsonld @dated { - path_regexp matcher ^/(?P\d{4}-\d{2})(?P/[^/.]+)?(?:\..*|/)?$ + path_regexp matcher ^/statuses/(?P\d{4}-\d{2})(?P/[^/.]+)?(?:\..*|/)?$ + not path_regexp ^/statuses/index[/.]? } handle @dated { handle @empty { handle @bare { rewrite * /.topic.html - header Link ;rel=meta;type="application/ld+json" + header Link ;rel=meta;type="application/ld+json" } handle @slash { - redir * /{re.matcher.ym} + redir * /statuses/{re.matcher.ym} } handle @jsonld { - rewrite * /{re.matcher.ym}/index.jsonld + rewrite * /statuses/{re.matcher.ym}/index.jsonld } } handle { handle @bare { rewrite * /.status.html - header Link ;rel=meta;type="application/ld+json" + header Link ;rel=meta;type="application/ld+json" } handle @slash { - redir * /{re.matcher.ym}{re.matcher.suffix} + redir * /statuses/{re.matcher.ym}{re.matcher.suffix} } } } @@ -91,7 +84,7 @@ status.site.example { rewrite /topics.jsonld /topics/index.jsonld @topics { - path_regexp matcher ^/(?:topics/(?P[0-9A-Za-z_-]+))(?P/[^/.]+)?(?:\..*|/)?$ + path_regexp matcher ^/topics/(?P[0-9A-Za-z_-]+)(?P/[^/.]+)?(?:\..*|/)?$ not path_regexp ^/topics/index[/.]? } diff --git a/README.markdown b/README.markdown index 9cd2346..8a29e73 100644 --- a/README.markdown +++ b/README.markdown @@ -99,13 +99,13 @@ Note that these paths **do not** have a trailing slash. `;rel=meta;type="application/ld+json"` (or equivalent) **must** be provided. - + **`GET /$YYYY-MM`** (where `$YYYY-MM` is an `xsd:gYearMonth`): + + **`GET /statuses/$YYYY-MM`** (where `$YYYY-MM` is an `xsd:gYearMonth`): Serve the file at `/.topic.html`. A `Link` header with the value `;rel=meta;type="application/ld+json"` (or equivalent) **must** be provided. - + **`GET /$YYYY-MM/*`** (where `$YYYY-MM` is an `xsd:gYearMonth`): + + **`GET /statuses/$YYYY-MM/*`** (where `$YYYY-MM` is an `xsd:gYearMonth`): Serve the file at `/.status.html`. A `Link` header with the value `;rel=meta;type="application/ld+json"` (or @@ -143,7 +143,7 @@ In all cases, for `/$PATH.jsonld`, this just serves the file at + **`GET /statuses.jsonld`**: Serve the file at `/statuses/index.jsonld`. - + **`GET /$YYYY-MM.jsonld`** (where `$YYYY-MM` is an + + **`GET /statuses/$YYYY-MM.jsonld`** (where `$YYYY-MM` is an `xsd:gYearMonth`): Serve the file at `/$YYYY-MM/index.jsonld`. diff --git a/post-receive b/post-receive index e1da847..f631236 100755 --- a/post-receive +++ b/post-receive @@ -88,7 +88,7 @@ if stdin.read().split()[-1] == f"refs/heads/{LIVE_BRANCH}": identifier = "" if identifier_path: identifier = identifier_path.name[2:] - status["@id"] = f"{PUBLIC_URL}/topics/{topic}/{identifier}" if topic else f"{PUBLIC_URL}/{datetime[0:7]}/{identifier}" + status["@id"] = f"{PUBLIC_URL}/topics/{topic}/{identifier}" if topic else f"{PUBLIC_URL}/statuses/{datetime[0:7]}/{identifier}" with identifier_path.open("r", encoding="utf-8") as text: status["identifier"] = text.read().strip() else: @@ -118,12 +118,12 @@ if stdin.read().split()[-1] == f"refs/heads/{LIVE_BRANCH}": if "subject" in status: topic = status["subject"] if topic not in topics: - topics[topic] = { "@context": { "@language": LANG, "activity": "https://www.w3.org/ns/activitystreams#", "dct": "http://purl.org/dc/terms/", "foaf": "http://xmlns.com/foaf/0.1/", "sioc": "http://rdfs.org/sioc/ns#", "sioct": "http://rdfs.org/sioc/types#", "OrderedCollection": "activity:OrderedCollection", "Thread": "sioc:Thread", "MicroblogPost": "sioct:MicroblogPost", "items": { "@id": "activity:items", "@type": "@id", "@container": "@list" }, "created": { "@id": "dct:created", "@type": "http://www.w3.org/2001/XMLSchema#dateTime" }, "creator": { "@id": "dct:creator", "@type": "@id" }, "identifier": { "@id": "dct:identifier", "@type": "http://www.w3.org/2001/XMLSchema#anyURI" }, "subject": "dct:subject", "name": "foaf:name", "content": { "@id": "sioc:content", "@type": "http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral" } }, "@id": f"{PUBLIC_URL}/topics/{topic}", "@type": ["OrderedCollection", "Thread"], "items": [], "subject": topic } + topics[topic] = { "@context": { "@language": LANG, "activity": "https://www.w3.org/ns/activitystreams#", "dct": "http://purl.org/dc/terms/", "foaf": "http://xmlns.com/foaf/0.1/", "sioc": "http://rdfs.org/sioc/ns#", "sioct": "http://rdfs.org/sioc/types#", "OrderedCollection": "activity:OrderedCollection", "Thread": "sioc:Thread", "MicroblogPost": "sioct:MicroblogPost", "items": { "@id": "activity:items", "@type": "@id", "@container": "@list" }, "created": { "@id": "dct:created", "@type": "http://www.w3.org/2001/XMLSchema#dateTime" }, "creator": { "@id": "dct:creator", "@type": "@id" }, "identifier": { "@id": "dct:identifier", "@type": "http://www.w3.org/2001/XMLSchema#anyURI" }, "subject": "dct:subject", "name": "foaf:name", "title": "dct:title", "content": { "@id": "sioc:content", "@type": "http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral" } }, "@id": f"{PUBLIC_URL}/topics/{topic}", "@type": ["OrderedCollection", "Thread"], "items": [], "subject": topic } topics[topic]["items"].append(status) else: yyyy_mm = datetime[0:7] if yyyy_mm not in months: - months[yyyy_mm] = { "@context": { "@language": LANG, "activity": "https://www.w3.org/ns/activitystreams#", "dct": "http://purl.org/dc/terms/", "foaf": "http://xmlns.com/foaf/0.1/", "sioc": "http://rdfs.org/sioc/ns#", "sioct": "http://rdfs.org/sioc/types#", "OrderedCollectionPage": "activity:OrderedCollectionPage", "Thread": "sioc:Thread", "MicroblogPost": "sioct:MicroblogPost", "current": { "@id": "activity:current", "@type": "@id" }, "first": { "@id": "activity:first", "@type": "@id" }, "items": { "@id": "activity:items", "@type": "@id", "@container": "@list" }, "partOf": { "@id": "activity:partOf", "@type": "@id" }, "prev": { "@id": "activity:prev", "@type": "@id" }, "next": { "@id": "activity:next", "@type": "@id" }, "created": { "@id": "dct:created", "@type": "http://www.w3.org/2001/XMLSchema#dateTime" }, "creator": { "@id": "dct:creator", "@type": "@id" }, "identifier": { "@id": "dct:identifier", "@type": "http://www.w3.org/2001/XMLSchema#anyURI" }, "name": "foaf:name", "content": { "@id": "sioc:content", "@type": "http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral" } }, "@id": f"{PUBLIC_URL}/{yyyy_mm}", "@type": ["OrderedCollectionPage", "Thread"], "items": [], "partOf": f"{PUBLIC_URL}/statuses" } + months[yyyy_mm] = { "@context": { "@language": LANG, "activity": "https://www.w3.org/ns/activitystreams#", "dct": "http://purl.org/dc/terms/", "foaf": "http://xmlns.com/foaf/0.1/", "sioc": "http://rdfs.org/sioc/ns#", "sioct": "http://rdfs.org/sioc/types#", "OrderedCollectionPage": "activity:OrderedCollectionPage", "Thread": "sioc:Thread", "MicroblogPost": "sioct:MicroblogPost", "current": { "@id": "activity:current", "@type": "@id" }, "first": { "@id": "activity:first", "@type": "@id" }, "items": { "@id": "activity:items", "@type": "@id", "@container": "@list" }, "partOf": { "@id": "activity:partOf", "@type": "@id" }, "prev": { "@id": "activity:prev", "@type": "@id" }, "next": { "@id": "activity:next", "@type": "@id" }, "created": { "@id": "dct:created", "@type": "http://www.w3.org/2001/XMLSchema#dateTime" }, "creator": { "@id": "dct:creator", "@type": "@id" }, "identifier": { "@id": "dct:identifier", "@type": "http://www.w3.org/2001/XMLSchema#anyURI" }, "name": "foaf:name", "title": "dct:title", "content": { "@id": "sioc:content", "@type": "http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral" } }, "@id": f"{PUBLIC_URL}/statuses/{yyyy_mm}", "@type": ["OrderedCollectionPage", "Thread"], "items": [], "partOf": f"{PUBLIC_URL}/statuses" } months[yyyy_mm]["items"].append(status) # Set up the public directory. @@ -146,22 +146,22 @@ if stdin.read().split()[-1] == f"refs/heads/{LIVE_BRANCH}": json.dump({ "@context": { "@language": LANG, "activity": "https://www.w3.org/ns/activitystreams#", "sioc": "http://rdfs.org/sioc/ns#", "sioct": "http://rdfs.org/sioc/types#", "Forum": "sioc:Forum", "Thread": "sioc:Thread", "Microblog": "sioct:Microblog", "streams": { "@id": "activity:streams", "@type": "@id" } }, "@id": f"{PUBLIC_URL}", "@type": "Microblog", "streams": [{ "@id": f"{PUBLIC_URL}/statuses", "@type": "Thread" }, { "@id": f"{PUBLIC_URL}/topics", "@type": "Forum" }] }, f, ensure_ascii=False, allow_nan=False) # Output month‐based listings and the non‐topic index + if not exists(f"{PUBLIC_DIRECTORY}/statuses"): + mkdir(f"{PUBLIC_DIRECTORY}/statuses") statuspairs = list(enumerate(months.items())) for (index, (yyyy_mm, ld)) in statuspairs: - if not exists(f"{PUBLIC_DIRECTORY}/{yyyy_mm}"): - mkdir(f"{PUBLIC_DIRECTORY}/{yyyy_mm}") - ld["first"] = f"{PUBLIC_URL}/{statuspairs[0][1][0]}" - ld["current"] = f"{PUBLIC_URL}/{statuspairs[-1][1][0]}" + if not exists(f"{PUBLIC_DIRECTORY}/statuses/{yyyy_mm}"): + mkdir(f"{PUBLIC_DIRECTORY}/statuses/{yyyy_mm}") + ld["first"] = f"{PUBLIC_URL}/statuses/{statuspairs[0][1][0]}" + ld["current"] = f"{PUBLIC_URL}/statuses/{statuspairs[-1][1][0]}" if index > 0: - ld["prev"] = f"{PUBLIC_URL}/{statuspairs[index - 1][1][0]}" + ld["prev"] = f"{PUBLIC_URL}/statuses/{statuspairs[index - 1][1][0]}" if index < len(statuspairs) - 1: - ld["next"] = f"{PUBLIC_URL}/{statuspairs[index + 1][1][0]}" - with open(f"{PUBLIC_DIRECTORY}/{yyyy_mm}/index.jsonld", "w", encoding="utf-8") as f: + ld["next"] = f"{PUBLIC_URL}/statuses/{statuspairs[index + 1][1][0]}" + with open(f"{PUBLIC_DIRECTORY}/statuses/{yyyy_mm}/index.jsonld", "w", encoding="utf-8") as f: json.dump(ld, f, ensure_ascii=False, allow_nan=False) - if not exists(f"{PUBLIC_DIRECTORY}/statuses"): - mkdir(f"{PUBLIC_DIRECTORY}/statuses") with open(f"{PUBLIC_DIRECTORY}/statuses/index.jsonld", "w", encoding="utf-8") as f: - json.dump({ "@context": { "@language": LANG, "activity": "https://www.w3.org/ns/activitystreams#", "sioc": "http://rdfs.org/sioc/ns#", "OrderedCollection": "activity:OrderedCollection", "Thread": "sioc:Thread", "current": { "@id": "activity:current", "@type": "@id" }, "first": { "@id": "activity:first", "@type": "@id" }, "has_parent": { "@id": "sioc:has_parent", "@type": "id" } }, "@id": f"{PUBLIC_URL}/statuses", "@type": ["OrderedCollection", "Thread"], "first": f"{PUBLIC_URL}/{statuspairs[0][1][0]}", "current": f"{PUBLIC_URL}/{statuspairs[-1][1][0]}", "has_parent": f"{PUBLIC_URL}" }, f, ensure_ascii=False, allow_nan=False) + json.dump({ "@context": { "@language": LANG, "activity": "https://www.w3.org/ns/activitystreams#", "sioc": "http://rdfs.org/sioc/ns#", "OrderedCollection": "activity:OrderedCollection", "Thread": "sioc:Thread", "current": { "@id": "activity:current", "@type": "@id" }, "first": { "@id": "activity:first", "@type": "@id" }, "has_parent": { "@id": "sioc:has_parent", "@type": "id" } }, "@id": f"{PUBLIC_URL}/statuses", "@type": ["OrderedCollection", "Thread"], "first": f"{PUBLIC_URL}/statuses/{statuspairs[0][1][0]}", "current": f"{PUBLIC_URL}/statuses/{statuspairs[-1][1][0]}", "has_parent": f"{PUBLIC_URL}" }, f, ensure_ascii=False, allow_nan=False) # Output topic‐based listings and the topic index if not exists(f"{PUBLIC_DIRECTORY}/topics"): diff --git a/topic.html b/topic.html index 3a08a13..f0a4a9e 100644 --- a/topic.html +++ b/topic.html @@ -10,12 +10,6 @@ body{ Display: Grid; Box-Sizing: Border-Box; Margin: Auto; Padding-Inline: 1REM; const nav = document.body.querySelector("nav") const dl = nav.querySelector("dl") const parser = new DOMParser -if (location.pathname.startsWith("/topics/")) { - const a = nav - .insertBefore(document.createElement("p"), dl) - .appendChild(document.createElement("a")) - a.href = "/topics/" - a.textContent = "Topics" } fetch(`${location}.jsonld`) .then($ => $.json()) .then(meta => { @@ -24,6 +18,12 @@ fetch(`${location}.jsonld`) document.body.querySelector("h1").textContent = "subject" in meta ? `#${topic}` : `@${topic}` + if ("subject" in meta) { + const a = nav + .insertBefore(document.createElement("p"), dl) + .appendChild(document.createElement("a")) + a.href = "/topics" + a.textContent = "Topics" } const { first, prev, next, current, items } = meta if (first && first != location && first != prev) { const a = nav