From: Lady Date: Sat, 27 Aug 2022 22:55:00 +0000 (-0700) Subject: From X-Git-Url: https://git.ladys.computer/Status/commitdiff_plain/d1f61cae690e87cf2a64747b788eb1d9285f17f8?ds=sidebyside From This commit squashes all of the commits in the upstream `x_status_git` repository to ensure that this repository remains focused on status content and local changes. See there for further commit history. --- d1f61cae690e87cf2a64747b788eb1d9285f17f8 diff --git a/Caddyfile b/Caddyfile new file mode 100644 index 0000000..95fed0e --- /dev/null +++ b/Caddyfile @@ -0,0 +1,164 @@ +status.site.example { + root * /home/USERNAME/status.site.example/public + + @slash { + path_regexp slash /$ + } + + @jsonld { + path_regexp jsonld \.jsonld$ + } + + @atom { + path_regexp atom \.atom$ + } + + @bare { + not path_regexp /$ + not path_regexp \.jsonld$ + not path_regexp \.atom$ + } + + @empty { + expression {re.matcher.suffix} == "" + } + + handle / { + rewrite * /index.html + header Link ;rel=meta;type="application/ld+json" + header Link ;rel=alternate;type="application/atom+xml" + } + + @iri { + path_regexp matcher ^/(?P[^/:]+:[^/]+)/?$ + } + + handle @iri { + handle @bare { + rewrite * /.lookup.xhtml + header Cache-Control max-age=0 + } + + handle @slash { + redir * /{re.matcher.iri} + } + } + + handle /about { + rewrite * /.about.html + header Link ;rel=meta;type="application/ld+json" + header Link ;rel=alternate;type="application/atom+xml" + } + + redir /about/ /about + + rewrite /about.jsonld /about/index.jsonld + + handle /statuses { + rewrite * /.statuses.html + header Link ;rel=meta;type="application/ld+json" + header Link ;rel=alternate;type="application/atom+xml" + } + + redir /statuses/ /statuses + + rewrite /statuses.jsonld /statuses/index.jsonld + + rewrite /statuses.atom /statuses/index.atom + + @dated { + 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=alternate;type="application/atom+xml" + } + + handle @slash { + redir * /statuses/{re.matcher.ym} + } + + handle @jsonld { + rewrite * /statuses/{re.matcher.ym}/index.jsonld + } + + handle @atom { + rewrite * /statuses/{re.matcher.ym}/index.atom + } + } + + handle { + handle @bare { + rewrite * /.status.html + header Link ;rel=meta;type="application/ld+json" + header Link ;rel=alternate;type="application/atom+xml" + } + + handle @slash { + redir * /statuses/{re.matcher.ym}{re.matcher.suffix} + } + } + } + + handle /topics { + rewrite * /.topics.html + header Link ;rel=meta;type="application/ld+json" + } + + redir /topics/ /topics + + rewrite /topics.jsonld /topics/index.jsonld + + @topics { + path_regexp matcher ^/topics/(?P[0-9A-Za-z_-]+)(?P/[^/.]+)?(?:\..*|/)?$ + not path_regexp ^/topics/index[/.]? + } + + handle @topics { + handle @empty { + handle @bare { + rewrite * /.topic.html + header Link ;rel=meta;type="application/ld+json" + header Link ;rel=alternate;type="application/atom+xml" + } + + handle @slash { + redir * /topics/{re.matcher.topic} + } + + handle @jsonld { + rewrite * /topics/{re.matcher.topic}/index.jsonld + } + + handle @atom { + rewrite * /topics/{re.matcher.topic}/index.atom + } + } + + handle { + handle @bare { + rewrite * /.status.html + header Link ;rel=meta;type="application/ld+json" + header Link ;rel=alternate;type="application/atom+xml" + } + + handle @slash { + redir * /topics/{re.matcher.topic}{re.matcher.suffix} + } + } + } + + header { + Access-Control-Allow-Origin "*" + ?Cache-Control max-age=3600 + } + + file_server { + index index.xml index.xhtml index.html index.rdf index.txt + } +} diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6e6d778 --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +USERNAME := USERNAME +DOMAIN := DOMAIN +GIT_REPOSITORY := /home/$(USERNAME)/Status.git + +nothing: + @echo 'Type `make remote` to update the remote post-receive script.' + +remote: + scp post-receive $(USERNAME)@$(DOMAIN):$(GIT_REPOSITORY)/hooks/post-receive + +.PHONY: nothing remote ; diff --git a/README.markdown b/README.markdown new file mode 100644 index 0000000..0d7d027 --- /dev/null +++ b/README.markdown @@ -0,0 +1,384 @@ +# x_status_git + +A minimal git‐based microblog. + +## What It Is + + + A Python script, `post-receive`, suitable for use as a post‐receive + Git hook, which generates a number of `.jsonld` files from a + source repository of text posts. + + + A small collection of H·T·M·L files designed to display the + generated `.jsonld` in a human‐readable fashion. + +## What It Is Not + + + A server or server configuration (you will need to supply these + yourself; see below). + + + Suitable for deployment on a simple filesystem server like + NeoCities or GitHub Pages (it requires both Git hooks and H·T·T·P + routing). + + + Interactive in any way (i·e “social media”). + + + Compatible with the ActivityPub fediverse (or any other push‐based + social media platform). + +## Script Configuration + +You will need to edit the `post-receive` script to adjust the following + constants to match your setup :— + + + **`GIT_DIRECTORY`**: + The absolute path to this Git repository on your server. + It is expected that this will be a bare repository (ending in + `.git`). + + + **`BUILD_DIRECTORY`**: + In order to access the files when you push, the repository will be + checked out here. + **This directory will be deleted on every push.** + + + **`PUBLIC_DIRECTORY`**: + The directory that your server serves files from. + **This directory will be deleted on every push,** so if you need to + serve additional files (i·e those not generated by this script), + you should place those files in a different directory and adjust + your server configuration accordingly. + Note that the `post-receive` script and associted H·T·M·L files + provided by this repository expect a certain server configuration + described below. + + + **`PUBLIC_URL`**: + The U·R·L that you are serving your site from (with no trailing + slash). + You cannot serve Status.git from a subdirectory. + +A `Makefile` is provided to make installing the `post-receive` script + on your server easy (assuming you have `ssh` access). +You’ll need to supply some variables there, too :— + + + **`USERNAME`**: + Your SSH username. + + + **`DOMAIN`**: + The domain or other address of your site. + + + **`GIT_REPOSITORY`**: + The absolute path to this Git repository, as above. + +## Server Configuration + +Your server should be configured to serve the following files from the + provided `PUBLIC_DIRECTORY` in response to the following requests. +For people using Caddy to serve their content, a sample `Caddyfile` is + included in this repository. + +### H·T·M·L responses + +These responses **must** be served with a `Content-Type` of + `text/html;charset=UTF-8` (or equivalent). +Note that these paths **do not** have a trailing slash. + + + **`GET /`**: + Serve the file at `/index.html`. + A `Link` header with the value + `;rel=meta;type="application/ld+json"` (or + equivalent) **must** be provided. + + + **`GET /about`**: + Serve the file at `/.about.html`. + A `Link` header with the value + `;rel=meta;type="application/ld+json"` (or + equivalent) **must** be provided. + + + **`GET /statuses`**: + Serve the file at `/.statuses.html`. + A `Link` header with the value + `;rel=meta;type="application/ld+json"` (or + equivalent) **must** be provided. + + + **`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 /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 + equivalent) **must** be provided. + + + **`GET /topics`**: + Serve the file at `/.topics.html`. + A `Link` header with the value + `;rel=meta;type="application/ld+json"` (or + equivalent) **must** be provided. + + + **`GET /topics/$TOPIC`** (where `$TOPIC` matches `[0-9A-Za-z_-]+`): + Serve the file at `/.topic.html`. + A `Link` header with the value + `;rel=meta;type="application/ld+json"` (or + equivalent) **must** be provided. + + + **`GET /topics/$TOPIC/*`** (where `$TOPIC` matches + `[0-9A-Za-z_-]+`): + Serve the file at `/.status.html`. + A `Link` header with the value + `;rel=meta;type="application/ld+json"` (or + equivalent) **must** be provided. + +### X·H·T·M·L responses + +These responses **must** be served with a `Content-Type` of + `application/xhtml+xml` (or equivalent). +Note that these paths **do not** have a trailing slash. + + + **`GET /$IRI`** (where `$IRI` contains a colon and no slash): + Serve the file at `/.lookup.xhtml`. + This can be used to look up statuses by their identifier. + +### Json‐L·D responses + +These responses **should** be served with a `Content-Type` of + `application/ld+json`. +In all cases, for `/$PATH.jsonld`, this just serves the file at + `/$PATH/index.jsonld`. + + + **`GET /about.jsonld`**: + Serve the file at `/about/index.jsonld`. + + + **`GET /statuses.jsonld`**: + Serve the file at `/statuses/index.jsonld`. + + + **`GET /statuses/$YYYY-MM.jsonld`** (where `$YYYY-MM` is an + `xsd:gYearMonth`): + Serve the file at `/$YYYY-MM/index.jsonld`. + + + **`GET /topics.jsonld`**: + Serve the file at `/topics/index.jsonld`. + + + **`GET /topics/$TOPIC.jsonld`** (where `$TOPIC` matches + `[0-9A-Za-z_-]+`): + Serve the file at `/topics/$TOPIC/index.jsonld`. + +### Atom responses + +These responses **should** be served with a `Content-Type` of + `application/atom+xml`. +In all cases, for `/$PATH.atom`, this just serves the file at + `/$PATH/index.atom`. + + + **`GET /statuses.atom`**: + Serve the file at `/statuses/index.atom`. + + + **`GET /statuses/$YYYY-MM.atom`** (where `$YYYY-MM` is an + `xsd:gYearMonth`): + Serve the file at `/$YYYY-MM/index.atom`. + + + **`GET /topics/$TOPIC.atom`** (where `$TOPIC` matches + `[0-9A-Za-z_-]+`): + Serve the file at `/topics/$TOPIC/index.atom`. + +### Other Headers + +All responses **should** have a `Access-Control-Allow-Origin` header + with a value of `*` (assuming your server does not use credentials + and is not being served behind a firewall). + +## Committing Statuses To Git + +The `post-receive` script will run whenever you make a commit to the + `live` branch, which should be set as your default. +Statuses are represented by a small collection of files committed to + particular locations in this repository :— + + + Files committed to `/YYYY/MM/DD/HH.MM.SSZ/` (the final component + can actually take any form but a time is **recommended**) are + ordinary statuses. + + + Files committed to `/topic/TOPICNAME/a/b/c/d/xxxx` (where `a`, `b`, + `c`, and `d` are lowercase hexadecimal digits and `xxxx` can be + anything) is a status posted to a specific topic (`TOPICNAME`). + It is **recommended** that you make `a/b/c/d` the first four digits + of an MD5 hash of the status content and `xxxx` the remaining + digits (security is not an issue here, so MD5 is fine). + `TOPICNAME` should have the form `[0-9A-Za-z_-]+`. + +The intent is that “ordinary statuses” are a bit more ephemeral whereas + “topic statuses” can serve as reference material. +Using an MD5 hash for topic statuses ensures you don’t post the same + thing twice. + +The files which represent a status are as follows :— + + + **`text`**: + The text of the status. + Blank lines separate paragraphs; linebreaks will be preserved. + There is a special markup for links: ``, or + `="link text"` if you want to supply link + text. + At present, no other markup is supported. + + + **`0=x_status_git_1.0`**: + This file is **optional** and not currently used for anything, but + indicates that the post follows the `1.0` format. + The contents of this file, if present, **must** be + `x_status_git_1.0`, optionally followed by a trailing newline. + + + **`1=NAME`** (where `NAME` might be anything): + This file is **recommended** and indicates the author of the + status. + Only one author is currently supported. + The value of `NAME` **must** give the name of the author of the + status. + The contents of this file **must** give the author’s URL, + optionally followed by a trailing newline. + + + **`2=TITLE`** (where `TITLE` might be anything): + This file is **optional** and indicates the title of the status. + The value of `TITLE` **should** be a file·system‐friendly version + of the title, but is ignored. + The contents of this file **must** give the title of the status, + optionally followed by a trailing newline. + + + **`3=YYYY-MM-DD`** (where `YYYY-MM-DD` is a date): + This file is **required** and indicates the date of the status. + Only one date is currently supported. + The value of `YYYY-MM-DD` **should** give the date of the status, + although this is not used (in favour of the full timestamp). + The contents of this file **must** give the full `xsd:dateTime` + timestamp of the status, optionally followed by a trailing + newline. + + + **`4=IDENTIFIER`** (where `IDENTIFIER` might be anything): + This file is **required** and provides an identifier for the + status. + Only one identifier is currently supported. + The contents of this file **must** be an I·R·I which uniquely + identifies the status (for example, a U·U·I·D or `tag:` URI). + The value of `IDENTIFIER` **must** be a locally‐unique identifier + for the status and **should** resemble the contents where + possible. + (Note, however, that `IDENTIFIER` cannot contain slashes and need + not be a valid I·R·I.) + +Files with names that begin with the strings `2=` or `x_status_git_` + are reserved for backwards‐compatible extensions. + +x_status_git has no opinion on how these files make their way into the + Git repository, except that all the files for a single status should + be added in the same commit. +The intention is that the simple nature of these files will make them + easy to automate. + +## I Am Computer, How Do I Get Status? + +Assume you are given a U·R·L `resource_url` which you think points to + some kind of x_status_git resource. +Start by resolving it as follows :— + +01. Make a `HEAD` request to `resource_url`. + +02. If there is a `Link` header with a `rel` of `meta` and a `type` of + `application/ld+json`, set `resource_url` to the URL provided in + that header and restart these steps from step 1. + +03. Make a `GET` request to `resource_url` and let `response` be the + response. + +04. Set `document` as follows :— + + 01. If the `Content-Type` header of `response` has a type of `text` + and subtype of `html`, let `document` be the result of + processing the body of `response` into a D·O·M tree as an + H·T·M·L document . + It is an error if this process fails. + + 02. If the `Content-Type` header of `response` has a type of + `application` and a subtype which is `xml` or which ends in + `+xml`, let `document` be the result of processing the body + of `response` into a D·O·M tree as an X·M·L document . + It is an error if this process fails. + + 03. Otherwise, let `document` be null. + +05. If `document` is not null :— + + 01. If there is a `` element in either the H·T·M·L namespace + or the Atom namespace in `document` with a `rel` of `meta` + and a `type` of `application/ld+json`, set `resource_url` to + the `href` of that `` element and restart these steps + from step 1. + If multiple such elements exist, choose the first one. + + 02. Otherwise, it is an error. + +06. If the body of `response` is not a Json document, it is an error. + +Assuming the U·R·L you were given was valid, you will end this + algorithm with a Json‐L·D response, and you can use the `@type` + attribute to determine the response type. +`@type` will be either a string or an array. + + + If the `@type` is or contains `Forum`, the resource is a collection + of topics. + + + If the `@type` is or contains `Thread`, the resource is a + collection of statuses. + + + If the `@type` is or contains `Microblog`, the resource describes + this site as a whole. + The `streams` property will contain a list of available `Forum`s + and `Thread`s, as objects with an `@id` and `@type`. + +The items in the collection (`Forum` or `Thread`) may be determined + through one of the following methods :— + + + If the `@type` is or contains `CollectionPage` or + `OrderedCollectionPage`, then its `items` will contain resources. + This is a partial collection, and the `prev` and `next` properties + can be used to access further items from the parent collection + (indicated by `partOf`). + `first` and `current`, in this scenario, point “horizontally” to + the first and latest pages of items, not to subpages. + + + If the `@type` is or contains `Collection` or `OrderedCollection` + and the resource has `first` and/or `current` properties, then + the `items` property will not be present. + `first` and `current` can be accessed to provide + `OrderedCollectionPage`s listing the items of the collection. + + + Otherwise, the `items` property will contain every item in the + collection. + +Statuses themselves have the following properties :— + + + **`@id`**: + The identifier of the status. + + + **`@type`**: + The value `MicroblogPost`. + + + **`created`** [`dcterms:created`]: + The creation date for the status, as an `xsd:dateTime`. + + + **`creator`** [`dcterms:creator`] (optional): + The author of the status, as an object with an `@id` and `name` + [`foaf:name`]. + + + **`identifier`** [`dcterms:identifier`]: + An I·R·I which uniquely identifies the status. + This differs from the `@id` in that it is not expected to be + dereferenceable. + + + **`subject`** [`dcterms:subject`] (optional): + The topic of the status, for topic statuses. + + + **`title`** [`dcterms:title`] (optional): + The title of the status. + + + **`content`** [`sioc:content`]: + The content of the status, as an `rdf:XMLLiteral`. diff --git a/about.html b/about.html new file mode 100644 index 0000000..c12dfa5 --- /dev/null +++ b/about.html @@ -0,0 +1,26 @@ + + +About + +

About

+ + diff --git a/index.html b/index.html new file mode 100644 index 0000000..4be8239 --- /dev/null +++ b/index.html @@ -0,0 +1,88 @@ + + +Index + +

Index

+
+
+
+

Topics

+
+