-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdocumentation.lisp
560 lines (385 loc) · 13.4 KB
/
documentation.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
(in-package #:org.shirakumo.multiposter)
;; protocol.lisp
(docs:define-docs
(variable *multiposter*
"The default multiposter instance to use.
See MULTIPOSTER (type)
See LOAD-CONFIG
See SAVE-CONFIG")
(function add-tag
"Add a tag to the post.
The tag is not added if there's an existing tag that matches the new
tag regardless of whitespace and case.
See POST (type)")
(function post
"Post a post to one or more services.
If VERBOSE is non-NIL, extra status information may be printed for the
user.
See POST (type)
See CLIENT (type)
See MULTIPOSTER (type)
See PROFILE (type)
See VERBOSE")
(function ready-p
"Returns true if the CLIENT is ready for posting.
See CLIENT (type)")
(function setup
"Performs the necessary setup for the CLIENT to become ready.
If no ARGS are passed, and the client is not properly configured, an
interactive setup should be started to configure the client.
If ARGS are passed, the client should be reinitialised with those new
arguments.
If the configured client is not READY even after the setup, or the
configuration is somehow invalid, an error should be signalled.
See CLIENT (type)")
(function undo
"Undoes the post and deletes it if possible.
If this is not possible to do, an error is signalled.
See RESULT (type)")
(function failed-p
"Returns true if the result represents a failed post.
A failed result cannot be UNDOne.
See RESULT (type)")
(function add-client
"Add a new client to the multiposter.
A continuable error is signalled if a client with the same NAME exists
already.
A continuable error is signalled if the client cannot be readied.
See CLIENT (type)
See MULTIPOSTER (type)")
(function add-profile
"Add a new profile to the multiposter.
A continuable error is signalled if a client with the same NAME exists
already.
See PROFILE (type)
See MULTIPOSTER (type)")
(function find-profile
"Returns the profile of the given name, if any.
See PROFILE (type)
See MULTIPOSTER (type)")
(function find-client
"Returns the client of the given name, if any.
See PROFILE (type)
See MULTIPOSTER (type)")
(type post
"Superclass for all post types.
A post encapsulates all necessary information to push to a service in
a more structured way. Each client should piece together the
information according to the service's own distinct fields using
COMPOSE-POST.
See TITLE
See HEADER
See FOOTER
See DESCRIPTION
See CONTENT-WARNING
See TAGS
See COMPOSE-POST")
(function title
"Accesses the title of a post.
If the client does not support an explicit title field, the title
should be treated as a paragraph before the header.
See POST (type)")
(function header
"Accesses the header of a post.
The header should be a paragraph to be prepended before the
description.
See PROFILE (type)
See POST (type)")
(function footer
"Accesses the footer of a post.
The footer should be a paragraph to be appended after the
description.
See PROFILE (type)
See POST (type)")
(function description
"Accesses the main description content of a post.
See POST (type)")
(function content-warning
"Accesses the content-warning description of a post.
If set, this will be used as the explanation of why the content in the
post should include a warning disclaimer.
See POST (type)")
(function tags
"Accesses the tags list of a post.
The list of tags should be a set of strings of tags, each of which are
distinct from each other. You should add tags via ADD-TAG rather than
pushing onto this directly.
See ADD-TAG
See PROFILE (type)
See POST (type)")
(function compose-post
"Compose the post content text.
This should be used to compose the main post text, especially if the
client does not support specific fields for the title or tags.
You may pass all arguments permitted by COMPOSE-POST-TEXT. If
EXCLUDE-TITLE is true, the title of the post is not included in the
text. If EXCLUDE-TAGS is true, the tags list of the post is not
included in the text.
See COMPOSE-POST-TEXT
See POST (type)")
(type image-post
"Post representing a set of images.
The number of images allowed is client-specific. The client should
automatically trim down the set of files as needed, preferring earlier
files.
If a client does not support an image type, the client may signal an
error or drop the file from the set. If the set becomes empty, an
error should be signalled.
Each file may also have a description text. If the client does not
support file descriptions, the descriptions should be discarded.
See FILES
See FILE-DESCRIPTIONS
See POST (type)")
(function files
"Accesses the files of a post.
See FILE-DESCRIPTIONS
See IMAGE-POST (type)")
(function file-descriptions
"Accesses the file descriptions of a post.
This must be a list of the same length of FILES.
See FILES
See IMAGE-POST (type)")
(type video-post
"Post representing a video file.
If a client does not support a video type, the client should signal an
error.
See FILE
See POST (type)")
(function file
"Accesses the file of the post.
See VIDEO-POST (type)")
(type link-post
"Post representing a link to another web thing.
See URL
See POST (type)")
(function url
"Accesses the URL of the post.
See LINK-POST (type)")
(type text-post
"Post representing a text post.
The markup language supported is client dependent. The main post text
content is the DESCRIPTION field.
See DESCRIPTION
See POST (type)")
(type client
"Superclass for all clients.
See NAME
See POST-TAGS
See DEFINE-CLIENT
See POST
See READY-P
See SETUP")
(function name
"Returns the name of the client or profile.
See CLIENT (type)")
(function post-tags
"Accessor to the post tags of the client.
This should be a list where each element is a list composed of
the following elements:
POST-TYPE TAG*
Where POST-TYPE corresponds to the type of post to which all of the
following tags should be added when posting to this client.
See CLIENT (type)")
(function define-client
"Define a new client type.
The syntax is identical to DEFCLASS. It will define the class and also
register it in the internal system so that it can be easily accessed
by the user.
See CLIENT (type)")
(type result
"Representation of a POST request result.
See CLIENT
See POST-OBJECT
See URL
See UNDO
See FAILED-P")
(function client
"Accesses the client object to which the POST was made.
See RESULT (type)
See CLIENT (type)")
(function post-object
"Accesses the post object that was posted.
Note that due to modifications made to fit the post to the client's
requirements, this instance may not be EQ to the POST instance that
was passed to the POST function initially.
See RESULT (type)
See POST (type)")
(function url
"Accesses the remote URL of the resulting post, if any.
This may be NIL if the result is a failure.
This may be an empty string if there is no canonical URL to access.
See RESULT (type)")
(type profile
"Representation of a posting profile.
A profile encapsulates certain standard tags to add to each post, as
well as an optional header and footer to append to each post.
You may also set a specific subset of clients to post to when using
the profile.
When POSTing to a profile, it creates a new post that is augmented
with the specified properties of the profile, and then posted to the
set of clients the profile is configured for.
See NAME
See CLIENTS
See TAGS
See HEADER
See FOOTER
See POST")
(function clients
"Accesses the clients associated with the object.
For a PROFILE this is a list of CLIENT instances.
For a MULTIPOSTER this is a hash table of names to cLIENT instances.
See CLIENT (type)
See PROFILE (type)
See MULTIPOSTER (type)")
(type multiposter
"Representation of a multiposter configuration.
See DEFAULT-PROFILE
See ADD-CLIENT
See ADD-PROFILE
See FIND-CLIENT
See FIND-PROFILE
See POST")
(function default-profile
"Accesses the default profile to use.
If this is NIL, posting to the multiposter will post to all
clients. Otherwise it will post to the default profile.
See POST
See PROFILE (type)
See MULTIPOSTER (type)"))
;; config.lisp
(docs:define-docs
(function config-file
"Returns the path to the configuration file.
If MULTIPOSTER_CONFIG is set, that path is used unquestioningly.
Otherwise, if APPDATA or XDG_CONFIG_HOME are set they are used as base
directory, and if not, the USER-HOMEDIR-PATHNAME is used as the base
directory, within which a directory named \"multiposter\" is created,
and within which a file called \"multiposter.lisp\" is created.")
(function load-config
"Loads the configuration file and updates the multiposter with it.
If MULTIPOSTER is NIL, a new multiposter instance is created and
returned. Note that this will not update the *MULTIPOSTER* variable.
See CONFIG-FILE
See MULTIPOSTER (type)")
(function save-config
"Saves the configuration file.
Returns the MULTIPOSTER instance.
See CONFIG-FILE
See MULTIPOSTER (type)"))
;; toolkit.lisp
(docs:define-docs
(variable *image-types*
"Variable used to identify pathname-types that correspond to images.
See FILE-TYPE-P")
(variable *video-types*
"Variable used to identify pathname-types that correspond to videos.
See FILE-TYPE-P")
(function or*
"Like OR except that empty strings are treated as NIL.")
(function file-type-p
"Checks THING against TYPEs and returns T if any match.
See *IMAGE-TYPES*
See *VIDEO-TYPES*")
(function envvar
"Returns the value of the given environment variable if it is not empty.")
(function parse-tags
"Parses the given tag or list of tags by splitting each by commas.")
(function merge-paragraphs
"Merge multiple paragraphs by inserting two newlines between each.
Paragraphs that are NIL or empty strings are ignored. If no paragraphs
are passed that aren't ignored, NIL is returned.")
(function initargs
"Return a list of initargs for the instance.
Users should add methods to this to append initargs that they need to
reconstruct the instance.")
(function make-like
"Create a copy of the object but with the given initargs set.")
(function alphanumeric-p
"Returns T if the character is from the ASCII alphanumeric set.")
(function non-space-p
"Returns T if the character isn't a space.")
(function non-comma-p
"Returns T if the character isn't a comma.")
(function filter-tags
"Ensures that all tags only contain allowed characters.")
(function trim-text
"Trims the text smartly to fit within the char limit.
If the limit is too low for the text to reasonably fit at all, NIL is
returned instead.")
(function compose-post-text
"Compose a single string from the given post parts.
Precedence is given to the post parts in the following order:
1. Tags (only whole tags are dropped)
2. Header (trimmed)
3. Footer (trimmed)
4. Body (trimmed)
Meaning if the limit is small enough, the post text may be reduced to
just tags, or just header and tags, etc.")
(function query
"Prompt the user for some information.
Returns the entered value.
If NULLABLE is T, NIL may be returned.
If DEFAULT is given, the DEFAULT is returned if the user does not
enter a value.
If COERCE is set, the user's value is first run through the COERCE
function to convert/parse its type.
If CHECK is set, the value is only considered valid if the CHECK
function returns true.")
(function verbose
"Prints a log message for informational purposes.")
(function timestamp
"Returns a \"YYYY.MM.DD hh-mm-ss\" formatted timestamp string.")
(function path-url
"Returns a file URL for the given pathname."))
;; clients
(docs:define-docs
(type cohost
"Client that posts to cohost.org
Tags are filtered to not contain any commas.
See CLIENT (type)")
(type dummy
"Dummy client that doesn't do anything.
See CLIENT (type)")
(type file
"File client that saves posts to a directory.
Each post gets its own txt file. Additional files like images and
videos are copied alongside and named similarly to the primary
file. The file name is chosen via timestamp and post title.
See CLIENT (type)")
(type git
"File client that commits to a git repository.
This acts like the FILE client, but also makes sure to pull the
repository before writing files, and instead of generating a txt file
puts the post metadata into the resulting commit instead. After
committing it will also push the repository.
See FILE (type)")
(type lichat
"Client that connects to a Lichat server and posts to a channel.
This will split the post content and optional payloads across multiple
updates. Tags are omitted from the messages.
See CLIENT (type)")
(type mastodon
"Client that posts to a mastodon server of choice.
The post content is truncated automatically to fit within the toot
message limit. Tags are filtered to be alphanumeric only.
See CLIENT (type)
See COMPOSE-POST-TEXT")
(type reader
"Client that posts to a Reader blog.
This only supports TEXT-POSTs.
See CLIENT (type)")
(type studio
"Client that uploads to a Studio gallery.
This only supports IMAGE-POSTs. If the title is unset, will use the
filename of the first file in the image post.
See CLIENT (type)")
(type tumblr
"Client that posts to Tumblr.
Tags are filtered to not contain any commas.
See CLIENT (type)")
(type webdav
"Client that posts to a WebDAV server.
This can use either an Authorization header, or HTTP Basic
authentication. It will upload the files using POST requests, and
remove them on failure using DELETE requests.
See CLIENT (type)"))