jenny

twtxt client that stores twts in a maildir
git clone https://movq.de/git/jenny.git
Log (Feed) - Files - Refs (Feed) - README - LICENSE

README (9001B)


      1      _
      2     (_) ___ _ __  _ __  _   _
      3     | |/ _ \ '_ \| '_ \| | | |
      4     | |  __/ | | | | | | |_| |
      5    _/ |\___|_| |_|_| |_|\__, |
      6   |__/                  |___/
      7   https://uninformativ.de/git/jenny
      8   https://uninformativ.de/bugs.html
      9 
     10 
     11 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     12 
     13 
     14 jenny is a twtxt client. One core feature is that all twts are stored in
     15 a maildir which can be viewed using a programm like mutt.
     16 
     17 Supports the following Yarn.social extensions:
     18 
     19     https://twtxt.dev/exts/twt-hash.html
     20     https://twtxt.dev/exts/twt-subject.html
     21 
     22 The name "jenny" comes from "the spinning jenny", because, you know,
     23 you're working with yarn and threads and stuff:
     24 
     25     https://en.wikipedia.org/wiki/Spinning_jenny
     26 
     27 
     28 Installation
     29 ------------
     30 
     31 You need:
     32 
     33     - Python 3
     34         - dateutil
     35         - requests
     36 
     37 In general, the programs have only been tested on GNU/Linux. Patches for
     38 more portability are welcome!
     39 
     40 
     41 Configuration
     42 -------------
     43 
     44 You need a file called ~/.config/jenny/conf.json. A minimal example:
     45 
     46     {
     47         "maildir_target": "~/Mail/twt",
     48         "local_twtxt_dir": "~/web/my.server.com",
     49         "publish_command": "some-rsync-script"
     50     }
     51 
     52 (The program will prefer $XDG_CONFIG_HOME over a plain ~/.config.)
     53 
     54 `maildir_target` is the path to a local, pre-existing maildir
     55 directory (including the subdirectories "cur", "new", and "tmp"). All
     56 twts -- your own and those written by others -- will be stored here.
     57 
     58 You will probably run jenny on your workstation (as opposed to directly
     59 on your server). This means that we must transfer the files created in
     60 `local_twtxt_dir` to the server after writing entries. jenny cannot know
     61 how to do this, so you are expected to specify a custom script of your
     62 own to do this job. This is `publish_command`. (`publish_command` is
     63 optional.)
     64 
     65 Complete config reference:
     66 
     67     - `announce_me`: Unless you have set `announce_me` to `false` (the
     68       default is `true`), your identity will be announced to those other
     69       feeds when they are fetched. The flags `DONT_ANNOUNCE_ME` or
     70       `ANNOUNCE_ME` can be added to individual lines in your `follow`
     71       file to override that global setting.
     72     - `editor`: Defaults to $VISUAL, or $EDITOR if that is unset, or
     73       `vi` if both are unset. This command is run through `sh -c ...`.
     74       If present, a literal "{}" will be replaced with the filename
     75       (shell-quote), otherwise that path is simply appended.
     76     - `local_twtxt_dir` (REQUIRED): Path to directory where twtxt files
     77       will be stored.
     78     - `local_twtxt_filename_format`: Defaults to `twtxt{}.txt`. The `{}`
     79       will be replaced by an appropriate suffix when your feed gets
     80       rotated.
     81     - `maildir_target` (REQUIRED): Path to maildir directory.
     82     - `max_twts_per_rotation`: Once your main feed ("twtxt.txt") reaches
     83       this many twts, they will be moved to an Archive Feed. Defaults to
     84       1000. Set to 0 to disable feed rotation.
     85     - `mention_marker`: When someone mentions you in their twtxt file,
     86       jenny will put a marker in the mail's "Subject:" line. You can
     87       customize this by setting `mention_marker` to a string of your
     88       liking.
     89     - `publish_command`: Script to run to publish your twtxt file.
     90     - `subject_maxlen`: Truncate the `Subject:` line of mail headers to
     91       this many characters. Defaults to 0, i.e. no truncation.
     92     - `yarn_pods_for_discovery`: When using `--fetch-context` (see Alt+C
     93       in the mutt example), jenny will try to retrieve the missing twt
     94       from the original feeds. If that fails, it can try to retrieve the
     95       twt from some Yarn pods. `yarn_pods_for_discovery` is a list of
     96       strings, e.g.: `"yarn_pods_for_discovery": ["https://twtxt.net"]`.
     97 
     98 Also note that the filename will always be `jenny-posting.eml`. This
     99 allows you to configure your editor to behave differently just for
    100 twtxt postings, e.g. you can do this in Vim:
    101 
    102     au BufRead,BufNewFile jenny-posting.eml setl wrap tw=0 fo-=t nu
    103 
    104 Initially, you must create your "twtxt.txt" manually in
    105 `local_twtxt_dir`. jenny expects some metadata in that file:
    106 
    107     # nick       = my-name
    108     # url        = https://my.server.com/twtxt.txt
    109     # avatar     = https://my.server.com/avatar.png
    110     #
    111     # These are aliases:
    112     # nick_alias = my-old-name-that-I-no-longer-use
    113     # url        = gopher://my.server.com/0/twtxt.txt
    114     #
    115     2020-10-11T10:40:48+02:00	hello world
    116 
    117 It will read your own nickname and the URLs under which your twtxt is
    118 available. The "nick =" line will be used to detect mentions. The
    119 "nick =" line together with the first "url =" line will be used to
    120 construct the user agent, which identifies you to other users.
    121 
    122 If other feeds contain "nick =" metadata as well, jenny will show it.
    123 
    124 "nick_alias =" and multiple "url =" lines can be used when you're
    125 transitioning from one name/URL to another. jenny will use them all to
    126 detect mentions, but it will only ever advertise "nick =" and "url =" to
    127 other servers.
    128 
    129 (An "avatar =" line is optional and not used by jenny, but it's good
    130 practice and might be used by other implementations.)
    131 
    132 For each twt, it will create one file in the configured maildir. The
    133 idea is that you run this as a cron job to create pseudo mail files.
    134 (Either on your workstation or on a server.) The goal is to create a
    135 pseudo mailbox of twts, which you can read using something like
    136 mutt.
    137 
    138 To follow other people, create ~/.config/jenny/follow:
    139 
    140     buckket https://buckket.org/twtxt.txt
    141     dilbert https://twtxt.net/user/dilbert/twtxt.txt DONT_ANNOUNCE_ME
    142     movq    https://www.uninformativ.de/twtxt.txt    ANNOUNCE_ME
    143 
    144 HTTP, HTTPS, Gopher, and Gemini are supported.
    145 
    146 Note that other people will have no idea that you're following them if
    147 you turn off announcing.
    148 
    149 
    150 Running
    151 -------
    152 
    153 Run without arguments to compose a new twt:
    154 
    155     $ jenny
    156 
    157 To reply to an already existing twt, provide the mail file on stdin (for
    158 mutt integration, see below):
    159 
    160     $ cat ~/Mail/twt/cur/zvvdala:2,S | jenny
    161 
    162 In both these cases, `publish_command` will be run once you've left the
    163 editor. However, if you wish to cancel and not publish your new twt, you
    164 have three options:
    165 
    166     1. Save an empty twt.
    167     2. Quit the editor without ever saving anything to the file.
    168     3. Quit the editor with an exit code other than 0 (":cq!" in Vim).
    169 
    170 To edit your twtxt file, run one of the following (`publish_command`
    171 will be run after this):
    172 
    173     $ jenny -e
    174     $ jenny --edit
    175 
    176 To fetch new twts from all the feeds you're following, run either of
    177 those:
    178 
    179     $ jenny -f
    180     $ jenny --fetch
    181 
    182 jenny will take note when a feed was last retrieved. You can show this
    183 database by running:
    184 
    185     $ jenny -l
    186     $ jenny --last-seen
    187 
    188 Or show the dates of the last twt of each feed:
    189 
    190     $ jenny -L
    191     $ jenny --last-twt
    192 
    193 This allows you to spot dead feeds.
    194 
    195 
    196 mutt integration
    197 ----------------
    198 
    199 Here is a full configuration file for mutt:
    200 
    201     # Strictly necessary or highly recommended.
    202     set mbox_type = Maildir
    203     set sort = threads
    204     set sort_aux = date-sent
    205     set strict_threads = yes
    206 
    207     # Optional styling.
    208     color index yellow default ~P
    209     set index_format = "%Z│%-15.15F│%3M│%s %* │%[%Y-%m-%d %H:%M]"
    210 
    211     # To highlight messages sent by you.
    212     alternates cathy
    213 
    214     # Key binds for jenny: Alt+T to write a new twt, Alt+R to reply to
    215     # thread, Alt+F to reply in a forked thread. Alt+C tries to fetch a
    216     # missing root twt (see explanation below).
    217     macro index,pager <esc>T "<shell-escape> jenny<Enter>" "Write new twt"
    218     macro index,pager <esc>R "\
    219     <enter-command> set my_pipe_decode=\$pipe_decode nopipe_decode<Enter>\
    220     <pipe-message> jenny<Enter>\
    221     <enter-command> set pipe_decode=\$my_pipe_decode; unset my_pipe_decode<Enter>" \
    222     "Reply to current twt"
    223     macro index,pager <esc>F "\
    224     <enter-command> set my_pipe_decode=\$pipe_decode nopipe_decode<Enter>\
    225     <pipe-message> jenny -t<Enter>\
    226     <enter-command> set pipe_decode=\$my_pipe_decode; unset my_pipe_decode<Enter>" \
    227     "Reply to current twt (fork conversation)"
    228     macro index,pager <esc>C "\
    229     <enter-command> set my_pipe_decode=\$pipe_decode nopipe_decode<Enter>\
    230     <pipe-message> jenny -c<Enter>\
    231     <enter-command> set pipe_decode=\$my_pipe_decode; unset my_pipe_decode<Enter>" \
    232     "Try to fetch context of current twt, like a missing root twt"
    233 
    234 Regarding Alt+C: It is relatively common that you follow some user and
    235 that user posts a reply to someone else -- but you don't follow that
    236 other person. That results in a broken thread. This function tries to
    237 fetch just that one missing twt, without you having to follow the entire
    238 feed. (See also: `yarn_pods_for_discovery`.)
    239 
    240 If you don't want to change your existing mutt setup (or if you don't
    241 have one yet), you can save this to a new file and launch mutt like
    242 this:
    243 
    244     $ mutt -F ~/.muttrc-jenny -f ~/Mail/twt
    245 
    246 
    247 Running the tests
    248 -----------------
    249 
    250 You need pytest: https://docs.pytest.org/en/stable/index.html
    251 
    252 Just run:
    253 
    254     $ pytest tests/