Initial lektor documentation
Getty Ritter
10 years ago
| 1 | # Lektor: A Standard for Feed Readers | |
| 2 | ||
| 3 | **NOTE:** The entirety of this file is tentative, and subject to change | |
| 4 | at any time. | |
| 5 | ||
| 6 | There are two main tasks for a feed reader: _fetching_ and _viewing_. | |
| 7 | These two tasks, in the `lektor` system, are split apart into different | |
| 8 | components, mediated by a `lektordir` system. There are two main parts | |
| 9 | to the `lektor` architecture: the `lektor-dir` format and the | |
| 10 | `lektor-entry` format. | |
| 11 | ||
| 12 | ## `lektor-feed` | |
| 13 | ||
| 14 | A given `feed` consists of at least a `name` (which is human-readable) | |
| 15 | and an `id` which unambiguously identifies the `feed` (which is | |
| 16 | a URI). Information about `feed`s is stored in the `src` directory | |
| 17 | inside a `lektor-dir`. Information about a given feed is stored inside | |
| 18 | `src/$hash`, where `$hash` is the SHA-1 hash of of the `feed`'s `id`. | |
| 19 | ||
| 20 | Obligatory elements include: | |
| 21 | ||
| 22 | - `id`: The URI which identifies the feed. In the case of | |
| 23 | RSS/Atom/ActivityStream feeds, this will generally be the URL at | |
| 24 | which the feed is hosted. For other things—for example, for | |
| 25 | services which may not have a web equivalent—it might instead be | |
| 26 | a tag URI or some other opaque identifier. | |
| 27 | - `name`: The human-readable name of the feed. This is | |
| 28 | produced by the fetcher and should not be changed by a viewer. | |
| 29 | ||
| 30 | Optional elements include: | |
| 31 | ||
| 32 | - `description`: A human-readable description describing | |
| 33 | the feed. | |
| 34 | - `language`: The language the feed is written in. | |
| 35 | - `image`: An image that can be optionally displayed with | |
| 36 | the channel. | |
| 37 | - `copyright`: The copyright notice for the feed. | |
| 38 | - `author`: Authorship information for the feed. | |
| 39 | ||
| 40 | ### Feed example | |
| 41 | ||
| 42 | A minimal feed might look like | |
| 43 | ||
| 44 | ```.bash | |
| 45 | cd $LEKTORDIR | |
| 46 | HASH=$(printf 'http://example.com/rss.xml' | sha1sum) | |
| 47 | mkdir -p $HASH | |
| 48 | ||
| 49 | echo http://example.com/rss.xml >$HASH/id | |
| 50 | echo Example Feed >$HASH/name | |
| 51 | ``` | |
| 52 | ||
| 53 | A feed with more entries might look like | |
| 54 | ||
| 55 | ```.bash | |
| 56 | cd $LEKTORDIR | |
| 57 | HASH=$(printf 'http://example.com/rss.xml' | sha1sum) | |
| 58 | mkdir -p $HASH | |
| 59 | ||
| 60 | echo http://example.com/rss.xml >$HASH/id | |
| 61 | echo Example Feed >$HASH/name | |
| 62 | echo 'An example feed.' >$HASH/description | |
| 63 | echo en-us >$HASH/language | |
| 64 | echo http://example.com/image.png >$HASH/image | |
| 65 | echo Copyright 2015, Getty Ritter >$HASH/copyright | |
| 66 | echo 'Getty Ritter <gdritter@gmail.com>' >$HASH/author | |
| 67 | ``` | |
| 68 | ||
| 69 | ## `lektor-entry` | |
| 70 | ||
| 71 | In contrast to `maildir`, entries in a `lektor-dir` are not files | |
| 72 | but directories adhering to a particular structure. | |
| 73 | ||
| 74 | Obligatory elements include: | |
| 75 | ||
| 76 | - `title`: The title of the entry. | |
| 77 | - `id`: The URI which identifies the entry. This will often be a | |
| 78 | URL at which the resource corresponding to the entry is available, | |
| 79 | but may also be an opaque identifier. | |
| 80 | - `content`: TBD | |
| 81 | - `feed`: A directory that contains all the information about the | |
| 82 | source `feed`. This will generally be a symlink | |
| 83 | ||
| 84 | Optional elements include: | |
| 85 | ||
| 86 | - `author`: Names and email addressess of the authors of the entry. | |
| 87 | - `pubdate`: When the entry was published. | |
| 88 | ||
| 89 | ## `lektor-dir` | |
| 90 | ||
| 91 | A `lektordir` is a directory with at least four subdirectories: `tmp`, | |
| 92 | `new`, `cur`, and `src`. A _fetcher_ is responsible for examining a feed | |
| 93 | and adding new entries the `lektordir` according to the following process: | |
| 94 | ||
| 95 | - The fetcher `chdir()`s to the `lektordir` directory. | |
| 96 | - The fetcher `stat()`s the name `tmp/$feed/$time.$pid.$host`, where | |
| 97 | `$feed` is the hash of the feed's `id` value, `$time` | |
| 98 | is the number of seconds since the beginning of 1970 GMT, `$pid` is the | |
| 99 | program's process ID, and `$host` is its host name. | |
| 100 | - If `stat()` returned anything other than `ENOENT`, the program sleeps | |
| 101 | for two seconds, updates `$time`, and tries the `stat()` again, a limited | |
| 102 | number of times. | |
| 103 | - The fetcher creates the directory `tmp/$feed/$time.$pid.$host`. | |
| 104 | - The fetcher writes the entry contents (according to the `lektor-entry` | |
| 105 | format) to the directory. | |
| 106 | - The fetcher `link()`s the file to `new/$feed/$time.$pid.$host`. At that | |
| 107 | instant, the entry has been successfully created. | |
| 108 | ||
| 109 | A _viewer_ is responsible for displaying new feed entries to a user | |
| 110 | through some mechanism. A viewer looks through the `new` directory for | |
| 111 | new entries. If there is a new entry, `new/$feed/$unique`, the viewer may: | |
| 112 | ||
| 113 | - Display the contents of `new/$feed/$unique` | |
| 114 | - Delete `new/$feed/$unique` | |
| 115 | - Rename `new/$feed/$unique`. | |
| 116 | ||
| 117 | A `lektordir` can contain arbitrary other directories, but for the sake | |
| 118 | of compatibility, these should attempt to adhere to the following | |
| 119 | schema: | |
| 120 | ||
| 121 | - If the extra directory contains configuration or other information | |
| 122 | for a given feed, it |