]> Lady’s Gitweb - x_status_git/blob - README.markdown
Support lookup by identifier
[x_status_git] / README.markdown
1 # x_status_git
2
3 A minimal git‐based microblog.
4
5 ## What It Is
6
7 + A Python script, `post-receive`, suitable for use as a post‐receive
8 Git hook, which generates a number of `.jsonld` files from a
9 source repository of text posts.
10
11 + A small collection of H·T·M·L files designed to display the
12 generated `.jsonld` in a human‐readable fashion.
13
14 ## What It Is Not
15
16 + A server or server configuration (you will need to supply these
17 yourself; see below).
18
19 + Suitable for deployment on a simple filesystem server like
20 NeoCities or GitHub Pages (it requires both Git hooks and H·T·T·P
21 routing).
22
23 + Interactive in any way (i·e “social media”).
24
25 + Compatible with the ActivityPub fediverse (or any other push‐based
26 social media platform).
27
28 ## Script Configuration
29
30 You will need to edit the `post-receive` script to adjust the following
31 constants to match your setup :—
32
33 + **`GIT_DIRECTORY`**:
34 The absolute path to this Git repository on your server.
35 It is expected that this will be a bare repository (ending in
36 `.git`).
37
38 + **`BUILD_DIRECTORY`**:
39 In order to access the files when you push, the repository will be
40 checked out here.
41 **This directory will be deleted on every push.**
42
43 + **`PUBLIC_DIRECTORY`**:
44 The directory that your server serves files from.
45 **This directory will be deleted on every push,** so if you need to
46 serve additional files (i·e those not generated by this script),
47 you should place those files in a different directory and adjust
48 your server configuration accordingly.
49 Note that the `post-receive` script and associted H·T·M·L files
50 provided by this repository expect a certain server configuration
51 described below.
52
53 + **`PUBLIC_URL`**:
54 The U·R·L that you are serving your site from (with no trailing
55 slash).
56 You cannot serve Status.git from a subdirectory.
57
58 A `Makefile` is provided to make installing the `post-receive` script
59 on your server easy (assuming you have `ssh` access).
60 You’ll need to supply some variables there, too :—
61
62 + **`USERNAME`**:
63 Your SSH username.
64
65 + **`DOMAIN`**:
66 The domain or other address of your site.
67
68 + **`GIT_REPOSITORY`**:
69 The absolute path to this Git repository, as above.
70
71 ## Server Configuration
72
73 Your server should be configured to serve the following files from the
74 provided `PUBLIC_DIRECTORY` in response to the following requests.
75 For people using Caddy to serve their content, a sample `Caddyfile` is
76 included in this repository.
77
78 ### H·T·M·L responses
79
80 These responses **must** be served with a `Content-Type` of
81 `text/html;charset=UTF-8` (or equivalent).
82 Note that these paths **do not** have a trailing slash.
83
84 + **`GET /`**:
85 Serve the file at `/index.html`.
86 A `Link` header with the value
87 `</about.jsonld>;rel=meta;type="application/ld+json"` (or
88 equivalent) **must** be provided.
89
90 + **`GET /about`**:
91 Serve the file at `/.about.html`.
92 A `Link` header with the value
93 `</about.jsonld>;rel=meta;type="application/ld+json"` (or
94 equivalent) **must** be provided.
95
96 + **`GET /statuses`**:
97 Serve the file at `/.statuses.html`.
98 A `Link` header with the value
99 `</statuses.jsonld>;rel=meta;type="application/ld+json"` (or
100 equivalent) **must** be provided.
101
102 + **`GET /statuses/$YYYY-MM`** (where `$YYYY-MM` is an `xsd:gYearMonth`):
103 Serve the file at `/.topic.html`.
104 A `Link` header with the value
105 `</$YYYY-MM.jsonld>;rel=meta;type="application/ld+json"` (or
106 equivalent) **must** be provided.
107
108 + **`GET /statuses/$YYYY-MM/*`** (where `$YYYY-MM` is an `xsd:gYearMonth`):
109 Serve the file at `/.status.html`.
110 A `Link` header with the value
111 `</$YYYY-MM.jsonld>;rel=meta;type="application/ld+json"` (or
112 equivalent) **must** be provided.
113
114 + **`GET /topics`**:
115 Serve the file at `/.topics.html`.
116 A `Link` header with the value
117 `</topics.jsonld>;rel=meta;type="application/ld+json"` (or
118 equivalent) **must** be provided.
119
120 + **`GET /topics/$TOPIC`** (where `$TOPIC` matches `[0-9A-Za-z_-]+`):
121 Serve the file at `/.topic.html`.
122 A `Link` header with the value
123 `</$TOPIC.jsonld>;rel=meta;type="application/ld+json"` (or
124 equivalent) **must** be provided.
125
126 + **`GET /topics/$TOPIC/*`** (where `$TOPIC` matches
127 `[0-9A-Za-z_-]+`):
128 Serve the file at `/.status.html`.
129 A `Link` header with the value
130 `</$TOPIC.jsonld>;rel=meta;type="application/ld+json"` (or
131 equivalent) **must** be provided.
132
133 ### X·H·T·M·L responses
134
135 These responses **must** be served with a `Content-Type` of
136 `application/xhtml+xml` (or equivalent).
137 Note that these paths **do not** have a trailing slash.
138
139 + **`GET /$IRI`** (where `$IRI` contains a colon and no slash):
140 Serve the file at `/.lookup.xhtml`.
141 This can be used to look up statuses by their identifier.
142
143 ### Json‐L·D responses
144
145 These responses **should** be served with a `Content-Type` of
146 `application/ld+json`.
147 In all cases, for `/$PATH.jsonld`, this just serves the file at
148 `/$PATH/index.jsonld`.
149
150 + **`GET /about.jsonld`**:
151 Serve the file at `/about/index.jsonld`.
152
153 + **`GET /statuses.jsonld`**:
154 Serve the file at `/statuses/index.jsonld`.
155
156 + **`GET /statuses/$YYYY-MM.jsonld`** (where `$YYYY-MM` is an
157 `xsd:gYearMonth`):
158 Serve the file at `/$YYYY-MM/index.jsonld`.
159
160 + **`GET /topics.jsonld`**:
161 Serve the file at `/topics/index.jsonld`.
162
163 + **`GET /topics/$TOPIC.jsonld`** (where `$TOPIC` matches
164 `[0-9A-Za-z_-]+`):
165 Serve the file at `/topics/$TOPIC/index.jsonld`.
166
167 ### Atom responses
168
169 These responses **should** be served with a `Content-Type` of
170 `application/atom+xml`.
171 In all cases, for `/$PATH.atom`, this just serves the file at
172 `/$PATH/index.atom`.
173
174 + **`GET /statuses.atom`**:
175 Serve the file at `/statuses/index.atom`.
176
177 + **`GET /statuses/$YYYY-MM.atom`** (where `$YYYY-MM` is an
178 `xsd:gYearMonth`):
179 Serve the file at `/$YYYY-MM/index.atom`.
180
181 + **`GET /topics/$TOPIC.atom`** (where `$TOPIC` matches
182 `[0-9A-Za-z_-]+`):
183 Serve the file at `/topics/$TOPIC/index.atom`.
184
185 ### Other Headers
186
187 All responses **should** have a `Access-Control-Allow-Origin` header
188 with a value of `*` (assuming your server does not use credentials
189 and is not being served behind a firewall).
190
191 ## Committing Statuses To Git
192
193 The `post-receive` script will run whenever you make a commit to the
194 `live` branch, which should be set as your default.
195 Statuses are represented by a small collection of files committed to
196 particular locations in this repository :—
197
198 + Files committed to `/YYYY/MM/DD/HH.MM.SSZ/` (the final component
199 can actually take any form but a time is **recommended**) are
200 ordinary statuses.
201
202 + Files committed to `/topic/TOPICNAME/a/b/c/d/xxxx` (where `a`, `b`,
203 `c`, and `d` are lowercase hexadecimal digits and `xxxx` can be
204 anything) is a status posted to a specific topic (`TOPICNAME`).
205 It is **recommended** that you make `a/b/c/d` the first four digits
206 of an MD5 hash of the status content and `xxxx` the remaining
207 digits (security is not an issue here, so MD5 is fine).
208 `TOPICNAME` should have the form `[0-9A-Za-z_-]+`.
209
210 The intent is that “ordinary statuses” are a bit more ephemeral whereas
211 “topic statuses” can serve as reference material.
212 Using an MD5 hash for topic statuses ensures you don’t post the same
213 thing twice.
214
215 The files which represent a status are as follows :—
216
217 + **`text`**:
218 The text of the status.
219 Blank lines separate paragraphs; linebreaks will be preserved.
220 There is a special markup for links: `<https://link.example>`, or
221 `<https://link.example>="link text"` if you want to supply link
222 text.
223 At present, no other markup is supported.
224
225 + **`0=x_status_git_1.0`**:
226 This file is **optional** and not currently used for anything, but
227 indicates that the post follows the `1.0` format.
228 The contents of this file, if present, **must** be
229 `x_status_git_1.0`, optionally followed by a trailing newline.
230
231 + **`1=NAME`** (where `NAME` might be anything):
232 This file is **recommended** and indicates the author of the
233 status.
234 Only one author is currently supported.
235 The value of `NAME` **must** give the name of the author of the
236 status.
237 The contents of this file **must** give the author’s URL,
238 optionally followed by a trailing newline.
239
240 + **`2=TITLE`** (where `TITLE` might be anything):
241 This file is **optional** and indicates the title of the status.
242 The value of `TITLE` **should** be a file·system‐friendly version
243 of the title, but is ignored.
244 The contents of this file **must** give the title of the status,
245 optionally followed by a trailing newline.
246
247 + **`3=YYYY-MM-DD`** (where `YYYY-MM-DD` is a date):
248 This file is **required** and indicates the date of the status.
249 Only one date is currently supported.
250 The value of `YYYY-MM-DD` **should** give the date of the status,
251 although this is not used (in favour of the full timestamp).
252 The contents of this file **must** give the full `xsd:dateTime`
253 timestamp of the status, optionally followed by a trailing
254 newline.
255
256 + **`4=IDENTIFIER`** (where `IDENTIFIER` might be anything):
257 This file is **required** and provides an identifier for the
258 status.
259 Only one identifier is currently supported.
260 The contents of this file **must** be an I·R·I which uniquely
261 identifies the status (for example, a U·U·I·D or `tag:` URI).
262 The value of `IDENTIFIER` **must** be a locally‐unique identifier
263 for the status and **should** resemble the contents where
264 possible.
265 (Note, however, that `IDENTIFIER` cannot contain slashes and need
266 not be a valid I·R·I.)
267
268 Files with names that begin with the strings `2=` or `x_status_git_`
269 are reserved for backwards‐compatible extensions.
270
271 x_status_git has no opinion on how these files make their way into the
272 Git repository, except that all the files for a single status should
273 be added in the same commit.
274 The intention is that the simple nature of these files will make them
275 easy to automate.
276
277 ## I Am Computer, How Do I Get Status?
278
279 Assume you are given a U·R·L `resource_url` which you think points to
280 some kind of x_status_git resource.
281 Start by resolving it as follows :—
282
283 01. Make a `HEAD` request to `resource_url`.
284
285 02. If there is a `Link` header with a `rel` of `meta` and a `type` of
286 `application/ld+json`, set `resource_url` to the URL provided in
287 that header and restart these steps from step 1.
288
289 03. Make a `GET` request to `resource_url` and let `response` be the
290 response.
291
292 04. Set `document` as follows :—
293
294 01. If the `Content-Type` header of `response` has a type of `text`
295 and subtype of `html`, let `document` be the result of
296 processing the body of `response` into a D·O·M tree as an
297 H·T·M·L document .
298 It is an error if this process fails.
299
300 02. If the `Content-Type` header of `response` has a type of
301 `application` and a subtype which is `xml` or which ends in
302 `+xml`, let `document` be the result of processing the body
303 of `response` into a D·O·M tree as an X·M·L document .
304 It is an error if this process fails.
305
306 03. Otherwise, let `document` be null.
307
308 05. If `document` is not null :—
309
310 01. If there is a `<link>` element in either the H·T·M·L namespace
311 or the Atom namespace in `document` with a `rel` of `meta`
312 and a `type` of `application/ld+json`, set `resource_url` to
313 the `href` of that `<link>` element and restart these steps
314 from step 1.
315 If multiple such elements exist, choose the first one.
316
317 02. Otherwise, it is an error.
318
319 06. If the body of `response` is not a Json document, it is an error.
320
321 Assuming the U·R·L you were given was valid, you will end this
322 algorithm with a Json‐L·D response, and you can use the `@type`
323 attribute to determine the response type.
324 `@type` will be either a string or an array.
325
326 + If the `@type` is or contains `Forum`, the resource is a collection
327 of topics.
328
329 + If the `@type` is or contains `Thread`, the resource is a
330 collection of statuses.
331
332 + If the `@type` is or contains `Microblog`, the resource describes
333 this site as a whole.
334 The `streams` property will contain a list of available `Forum`s
335 and `Thread`s, as objects with an `@id` and `@type`.
336
337 The items in the collection (`Forum` or `Thread`) may be determined
338 through one of the following methods :—
339
340 + If the `@type` is or contains `CollectionPage` or
341 `OrderedCollectionPage`, then its `items` will contain resources.
342 This is a partial collection, and the `prev` and `next` properties
343 can be used to access further items from the parent collection
344 (indicated by `partOf`).
345 `first` and `current`, in this scenario, point “horizontally” to
346 the first and latest pages of items, not to subpages.
347
348 + If the `@type` is or contains `Collection` or `OrderedCollection`
349 and the resource has `first` and/or `current` properties, then
350 the `items` property will not be present.
351 `first` and `current` can be accessed to provide
352 `OrderedCollectionPage`s listing the items of the collection.
353
354 + Otherwise, the `items` property will contain every item in the
355 collection.
356
357 Statuses themselves have the following properties :—
358
359 + **`@id`**:
360 The identifier of the status.
361
362 + **`@type`**:
363 The value `MicroblogPost`.
364
365 + **`created`** [`dcterms:created`]:
366 The creation date for the status, as an `xsd:dateTime`.
367
368 + **`creator`** [`dcterms:creator`] (optional):
369 The author of the status, as an object with an `@id` and `name`
370 [`foaf:name`].
371
372 + **`identifier`** [`dcterms:identifier`]:
373 An I·R·I which uniquely identifies the status.
374 This differs from the `@id` in that it is not expected to be
375 dereferenceable.
376
377 + **`subject`** [`dcterms:subject`] (optional):
378 The topic of the status, for topic statuses.
379
380 + **`title`** [`dcterms:title`] (optional):
381 The title of the status.
382
383 + **`content`** [`sioc:content`]:
384 The content of the status, as an `rdf:XMLLiteral`.
This page took 0.06461 seconds and 5 git commands to generate.