CLI interface to medialist (fossil mirror)
Revisión | 835bc64301fa36da0feb02c20aba4f514691293a (tree) |
---|---|
Tiempo | 2023-03-30 13:05:32 |
Autor | mio <stigma@disr...> |
Commiter | mio |
Update documentation for 0.4 release. Still some work to do.
FossilOrigin-Name: 117419016d47681a3d300e0537450fd80d34f281bd09d2d1572414cf13835f4f
@@ -95,25 +95,35 @@ fields (if any), and what their purpose is. | ||
95 | 95 | |
96 | 96 | The first (and most important) structure is the @samp{MediaList} structure. |
97 | 97 | This structure is passed to all functions that are defined in this package. |
98 | + | |
99 | +It is recommended to create an instance by using the @code{ml_open_list} | |
100 | +function. | |
101 | + | |
98 | 102 | It has the following members: |
99 | 103 | |
100 | 104 | @table @samp |
101 | 105 | @item immutable string filePath |
102 | -The absolute file path to the @dfn{TSV} file. Upon creating a @samp{MediaList} | |
103 | -structure, a check is performed to see if this file exists. If not, it is | |
104 | -created. | |
106 | +The absolute file path to the @dfn{TSV} file. Upon creating a | |
107 | +@samp{MediaList} structure, a check is performed to see if this file exists. | |
108 | +If it doesn't exist, it is created. | |
105 | 109 | |
106 | 110 | @item immutable string listName |
107 | -The name of the ``list''. This is determined by extracting the file name from | |
108 | -the @samp{filePath}. For example, a @samp{filePath} of | |
109 | -@code{/home/user/lists/mylist.tsv} would have the @samp{listName} of | |
111 | +The name of the ``list''. This is determined by extracting the file name | |
112 | +from the @samp{filePath}. For example, if the @samp{filePath} is | |
113 | +@code{/home/user/lists/mylist.tsv}, then the @samp{listName} would be | |
110 | 114 | @samp{mylist}. |
111 | 115 | |
112 | 116 | @item bool isOpen |
113 | 117 | A check to see if the file at @samp{filePath} is open. All of the functions |
114 | 118 | which edit the file will check this before doing anything. By providing |
115 | -public access to this, I hope people can make their own functions to suit there | |
116 | -needs without breaking any of the ones provided in this package. | |
119 | +public access to this, I hope people can make their own functions to suit | |
120 | +there needs without breaking any of the ones provided in this package. | |
121 | + | |
122 | +@cartouche | |
123 | +@strong{NOTE:} The future of this property is being evaluated. It requires | |
124 | +people using this library to remember that it exists, and performing checks | |
125 | +on its value. It is probable that this will be removed in a future version. | |
126 | +@end cartouche | |
117 | 127 | @end table |
118 | 128 | |
119 | 129 | @section MediaListHeader |
@@ -121,8 +131,8 @@ needs without breaking any of the ones provided in this package. | ||
121 | 131 | @pindex struct MediaListHeader |
122 | 132 | |
123 | 133 | Contains information about a particular ``header'' (i.e. column) in the |
124 | -@dfn{TSV} file. Editing these values | |
125 | -@emph{does not change their values in the list}. | |
134 | +@dfn{mTSV} file. Editing these values @emph{does not change their values | |
135 | +in the list}. | |
126 | 136 | |
127 | 137 | @table @samp |
128 | 138 | @item string tsvName |
@@ -130,6 +140,8 @@ The literal column name as written in the @dfn{TSV} file. | ||
130 | 140 | |
131 | 141 | @item string humanFriendlyName |
132 | 142 | The ``human friendly name'' as determined by the comments (@pxref{mTSV}). |
143 | +If this value is set, then it should be used when displaying the header | |
144 | +to people. The default value is @code{null}. | |
133 | 145 | |
134 | 146 | @item size_t column |
135 | 147 | The column number that this header is for. Useful if you want to read from |
@@ -150,21 +162,24 @@ these values @emph{does not change their values in the list}. | ||
150 | 162 | The title of this item in the list. |
151 | 163 | |
152 | 164 | @item string progress |
153 | -The current progress of this item in the list. By default this is @samp{-/-}. | |
165 | +The current progress of this item in the list. By default this is | |
166 | +@samp{-/-}. | |
154 | 167 | |
155 | 168 | @item string status |
156 | -The current status of this item in the list. By default this is @samp{UNKNOWN}. | |
169 | +The current status of this item in the list. By default this is | |
170 | +@samp{UNKNOWN}. | |
157 | 171 | |
158 | 172 | @item string startDate |
159 | 173 | The date that this item was ``started'' on. The format for this is |
160 | -@samp{YYYY-MM-DD}. This value is automatically updated when the @samp{status} | |
161 | -changes from @samp{PLAN-TO-READ} or @samp{PLAN-TO-WATCH} to @samp{READING} or | |
162 | -@samp{WATCHING} respectively. | |
174 | +@samp{YYYY-MM-DD}. This value is automatically updated when the | |
175 | +@samp{status} changes from @samp{PLAN-TO-READ} or @samp{PLAN-TO-WATCH} to | |
176 | +@samp{READING} or @samp{WATCHING} respectively. | |
163 | 177 | |
164 | 178 | @item string endDate |
165 | 179 | The date that this item was ``completed'' on. The format for this is |
166 | -@samp{YYYY-MM-DD}. This value is automatically updated when the @samp{status} | |
167 | -changes from @samp{READING} or @samp{WATCHING} to @samp{COMPLETE}. | |
180 | +@samp{YYYY-MM-DD}. This value is automatically updated when the | |
181 | +@samp{status} changes from @samp{READING} or @samp{WATCHING} to | |
182 | +@samp{COMPLETE}. | |
168 | 183 | |
169 | 184 | @item string lastUpdated |
170 | 185 | The date that this item was last updated on. The format for this is |
@@ -175,21 +190,42 @@ is updated. | ||
175 | 190 | A check to see if this item was initialized correctly upon being fetched. |
176 | 191 | If it is @code{false}, then it failed and the values shouldn't be trusted. |
177 | 192 | |
193 | +@cartouche | |
194 | +@strong{NOTE}: The future of this property is undecided. It requires that | |
195 | +programmers remeber it exists, and to make use of it. With MediaList 0.4, | |
196 | +most functions throw an exception (@xref{x-mlexception,,MLException}) if | |
197 | +there is an error, or return an error type (@xref{x-mlerror,,MLError}) when | |
198 | +an error occurs a ``nothrow'' variant of a function has been called. | |
199 | +@end cartouche | |
200 | + | |
201 | +@item string tsvRepresentation() | |
202 | + | |
203 | +This member function will convert a @samp{MediaListItem} structure in to a | |
204 | +TSV representation. This does @strong{not} add a trailing newline | |
205 | +character. The order follows the MediaList default order: | |
206 | + | |
207 | +@verbatim | |
208 | +title, progress, status, start_date, end_date, last_updated | |
209 | +@end verbatim | |
210 | + | |
178 | 211 | @end table |
179 | 212 | |
180 | -@section MLCommand | |
181 | 213 | @anchor{x-mlcommand} |
214 | +@section MLCommand | |
182 | 215 | |
183 | 216 | @pindex enum MLCommand |
184 | 217 | |
218 | +This enumeration type represents the type of command when sending a list of | |
219 | +arguments to @code{ml_send_command} when updating a @samp{MediaList}. | |
220 | + | |
185 | 221 | @table @code |
186 | 222 | |
187 | 223 | @item add |
188 | 224 | @pindex MLCommand.add |
189 | 225 | |
190 | -By providing the ``add'' command to @code{ml_send_command}, you are indicating | |
191 | -that you want to append a new item to the list. The format of the arguments | |
192 | -(@var{string[] args}) is as follows: | |
226 | +By providing the ``add'' command to @code{ml_send_command}, you are | |
227 | +indicating that you want to append a new item to the list. The format of the | |
228 | +arguments (@var{string[] args}) is as follows: | |
193 | 229 | |
194 | 230 | @verbatim |
195 | 231 | args[0] = The new item's Title |
@@ -203,24 +239,21 @@ defaults (``-/-'' for Progress and ``UNKNOWN'' for Status). | ||
203 | 239 | @item delete_ |
204 | 240 | @pindex MLCommand.delete_ |
205 | 241 | |
206 | -Sending the ``delete'' command a list can have multiple meanings, depending | |
207 | -on the arguments provided. If you provide no arguments, then the entire list | |
208 | -is deleted. If at least one arugment is provided, then only the provided | |
209 | -arguments are deleted. | |
210 | - | |
211 | -For example, to delete an entire list: | |
212 | - | |
213 | -@example | |
214 | -ml_send_command(list, MLCommand.delete_, []); | |
215 | -@end example | |
216 | - | |
217 | -To delete specific items from a list: | |
242 | +By sending the ``delete_'' command to a list, you're saying that each item | |
243 | +ID in the provided arguments should be removed from the list. For example: | |
218 | 244 | |
219 | 245 | @example |
220 | 246 | ml_send_command(list, MLCommand.delete_, ["1", "10", "3"]); |
221 | 247 | @end example |
222 | 248 | |
223 | -Each of the items represents the item ID. The need not be in order. | |
249 | +The order of the IDs does not matter, this will remove the items with IDs 1, | |
250 | +3, and 10. | |
251 | + | |
252 | +@cartouche | |
253 | +@strong{NOTE}: Previously you could send an empty array as an argument to | |
254 | +delete the list file. This behaviour is deprecated and will be removed in | |
255 | +a future version. | |
256 | +@end cartouche | |
224 | 257 | |
225 | 258 | @item update |
226 | 259 | @pindex MLCommand.update |
@@ -234,7 +267,9 @@ args[0] = Item ID (e.g. "1"). | ||
234 | 267 | args[n] = field::value |
235 | 268 | @end verbatim |
236 | 269 | |
237 | -The possible values for "field" are: | |
270 | +The double colons (@samp{::}) acts as a separator. | |
271 | + | |
272 | +The possible values for ``field'' are: | |
238 | 273 | |
239 | 274 | @itemize @bullet |
240 | 275 | @item title |
@@ -244,10 +279,11 @@ The possible values for "field" are: | ||
244 | 279 | @item end_date |
245 | 280 | @end itemize |
246 | 281 | |
247 | -The "value" can include whitespace. | |
282 | +The ``value'' can contain spaces. | |
248 | 283 | |
249 | 284 | @end table |
250 | 285 | |
286 | +@anchor{x-mlerror} | |
251 | 287 | @section MLError |
252 | 288 | |
253 | 289 | @pindex enum MLError |
@@ -258,13 +294,14 @@ The "value" can include whitespace. | ||
258 | 294 | @pindex MLError.success |
259 | 295 | |
260 | 296 | This value indicates that the function worked without any errors. You can |
261 | -proceed as normal. | |
297 | +proceed as normal. The value of @samp{success} is 0. | |
262 | 298 | |
263 | 299 | @item invalidArgs |
264 | 300 | @pindex MLError.invalidArgs |
265 | 301 | |
266 | 302 | This value indicates that the arguments provided weren't sufficient. For |
267 | -example, sending an empty array with the @code{MLCommand.add} command. | |
303 | +example, sending an empty array with the @code{MLCommand.add} command. The | |
304 | +value of @samp{invalidArgs} is 1. | |
268 | 305 | |
269 | 306 | @item fileAlreadyOpen |
270 | 307 | @pindex MLError.fileAlreadyOpen |
@@ -272,23 +309,79 @@ example, sending an empty array with the @code{MLCommand.add} command. | ||
272 | 309 | This error is returned when a @code{MediaList} structure is in an ``open'' |
273 | 310 | state. All the functions provided in this package check the file isn't |
274 | 311 | open before reading/writing. Should you choose to extend this package |
275 | -by writing your own functions, this can prevent accidental read/write errors. | |
312 | +by writing your own functions, this can prevent accidental read/write | |
313 | +errors. The value of @samp{fileAlreadyOpen} is 2. | |
276 | 314 | |
277 | 315 | @item fileReadError |
278 | 316 | @pindex MLError.fileReadError |
279 | 317 | |
280 | -An error was encountered when reading the list file. | |
318 | +An error was encountered when reading the list file. The value for | |
319 | +@samp{fileReadError} is 3. | |
281 | 320 | |
282 | 321 | @item itemNotFound |
283 | 322 | @pindex MLError.itemNotFound |
284 | 323 | |
285 | -A requested item (either @code{ml_fetch_item} or @code{ml_fetch_items}) could | |
286 | -not be found. | |
324 | +A requested item (by @code{ml_fetch_item} or @code{ml_fetch_items}) could | |
325 | +not be found. The value of @samp{itemNotFound} is 4. | |
326 | + | |
327 | +@item permissionError | |
328 | +@pindex MLError.permissionError | |
329 | + | |
330 | +When trying to create or open the file for a @code{MediaList}, we | |
331 | +encountered a permission error and couldn't open the file. The value for | |
332 | +@samp{permissionError} is 5. | |
287 | 333 | |
288 | 334 | @item unknownCommand |
289 | 335 | @pindex MLError.unknownCommand |
290 | 336 | |
291 | -An unknown command was provided to @code{ml_send_command}. | |
337 | +An unknown command was provided to the @var{command} parameter for the | |
338 | +@code{ml_send_command} function. The value of @samp{unknownCommand} is 6. | |
339 | + | |
340 | +@item unspecifiedError | |
341 | +@pindex MLError.unspecifiedError | |
342 | + | |
343 | +An unknown error occurred. This is used as a fallback for operating system | |
344 | +and Phobos exceptions. The value of @samp{unspecifiedError} is always | |
345 | +equal to @code{MLError.max}. | |
346 | + | |
347 | +@end table | |
348 | + | |
349 | +@anchor{x-mlexception} | |
350 | +@section MLException | |
351 | + | |
352 | +@pindex class MLException | |
353 | + | |
354 | +A custom MediaList Exception class which is used for error reporting in | |
355 | +the functions which throw (rather than the @code{nothrow} variants). | |
356 | + | |
357 | +@table @code | |
358 | + | |
359 | +@item MLError error() | |
360 | +@pindex MLException.error | |
361 | + | |
362 | +Returns the underlying @code{MLError} value. | |
363 | + | |
364 | +@item string msg() | |
365 | +@pindex MLException.msg | |
366 | + | |
367 | +Return a string describing the reason for the exception. | |
368 | + | |
369 | +@item this(string msg) | |
370 | +@pindex MLException.this(string msg) | |
371 | + | |
372 | +Construct a new @code{MLException} by providing only an error message. | |
373 | + | |
374 | +@item this(MLError error) | |
375 | +@pindex MLException.this(MLError error) | |
376 | + | |
377 | +Construct a new @code{MLException} by providing a @code{MLError} code. The | |
378 | +error message is determined by this value. | |
379 | + | |
380 | +@item this(string msg, MLError error) | |
381 | +@pindex MLException.this(string msg, MLError error) | |
382 | + | |
383 | +Construct a new @code{MLException} by providing a custom message and error | |
384 | +code. | |
292 | 385 | |
293 | 386 | @end table |
294 | 387 |
@@ -343,26 +436,28 @@ The format of @var{args} depends on what the @var{command} is. | ||
343 | 436 | A simple example that demonstrates most aspects of the library. |
344 | 437 | |
345 | 438 | |
346 | -@verbatim | |
347 | -// I (mio, <stigma@disroot.org>) have release this example to the | |
439 | +@example | |
440 | +// I (mio, <stigma@@disroot.org>) have released this example to the | |
348 | 441 | // public domain. For more information, visit |
349 | 442 | // <http://creativecommons.org/publicdomain/zero/1.0/>. |
350 | -import std.stdio; | |
443 | + | |
444 | +import std.stdio : stderr, writeln, writefln; | |
445 | +import std.file : remove; | |
351 | 446 | |
352 | 447 | import medialist; |
353 | 448 | |
354 | 449 | void print_error(MLError err) |
355 | -{ | |
356 | - writefln("Error: MLError.%s", err); | |
357 | -} | |
450 | +@{ | |
451 | + stderr.writefln("Error: MLError.%s", err); | |
452 | +@} | |
358 | 453 | |
359 | 454 | int main(string[] args) |
360 | -{ | |
455 | +@{ | |
361 | 456 | if (2 > args.length) |
362 | - { | |
457 | + @{ | |
363 | 458 | stderr.writefln("usage: %s <path_to_list.tsv>", args[0]); |
364 | 459 | return 1; |
365 | - } | |
460 | + @} | |
366 | 461 | |
367 | 462 | /* Open a new list for editing, creating the file if needed */ |
368 | 463 | MediaList* list = ml_open_list(args[1]); |
@@ -370,6 +465,9 @@ int main(string[] args) | ||
370 | 465 | /* Make sure the memory is returned when the program exits. */ |
371 | 466 | scope(exit) ml_free_list(list); |
372 | 467 | |
468 | + /* Since we don't want to keep the file for this example. */ | |
469 | + scope(exit) remove(list.filePath); | |
470 | + | |
373 | 471 | /* Error handling */ |
374 | 472 | MLError err; |
375 | 473 |
@@ -380,18 +478,18 @@ int main(string[] args) | ||
380 | 478 | * The second has default status (UNKNOWN). |
381 | 479 | * The third has default progress (-/-). |
382 | 480 | */ |
383 | - err = ml_send_command(list, MLCommand.add, ["Item 1"]); | |
481 | + ml_send_command(list, MLCommand.add, ["Item 1"], err); | |
384 | 482 | if (MLError.success != err) print_error(err); |
385 | 483 | |
386 | - err = ml_send_command(list, MLCommand.add, ["Item 2", "10/100"]); | |
484 | + ml_send_command(list, MLCommand.add, ["Item 2", "10/100"], err); | |
387 | 485 | if (MLError.success != err) print_error(err); |
388 | 486 | |
389 | - err = ml_send_command(list, MLCommand.add, | |
390 | - ["Item 3", null, "PLAN-TO-WATCH"]); | |
487 | + ml_send_command(list, MLCommand.add, ["Item 3", null, "PLAN-TO-WATCH"], | |
488 | + err); | |
391 | 489 | if (MLError.success != err) print_error(err); |
392 | 490 | |
393 | - err = ml_send_command(list, MLCommand.add, | |
394 | - ["Item 4", "10/10", "COMPLETE"]); | |
491 | + ml_send_command(list, MLCommand.add, ["Item 4", "10/10", "COMPLETE"], | |
492 | + err); | |
395 | 493 | |
396 | 494 | |
397 | 495 | /* |
@@ -401,24 +499,24 @@ int main(string[] args) | ||
401 | 499 | * We update the start date and end date of item 4. |
402 | 500 | * We update the title of item 3. |
403 | 501 | */ |
404 | - err = ml_send_command(list, MLCommand.update, | |
405 | - ["1", "progress::0/100", "status::PLAN-TO-READ"]); | |
502 | + ml_send_command(list, MLCommand.update, | |
503 | + ["1", "progress::0/100", "status::PLAN-TO-READ"], err); | |
406 | 504 | if (MLError.success != err) print_error(err); |
407 | 505 | |
408 | - err = ml_send_command(list, MLCommand.update, | |
409 | - ["4", "start_date::2021-11-25", | |
410 | - "end_date::2022-02-13"]); | |
506 | + ml_send_command(list, MLCommand.update, | |
507 | + ["4", "start_date::2021-11-25", "end_date::2022-02-13"], | |
508 | + err); | |
411 | 509 | if (MLError.success != err) print_error(err); |
412 | 510 | |
413 | - err = ml_send_command(list, MLCommand.update, | |
414 | - ["3", "title::The Third Item"]); | |
511 | + ml_send_command(list, MLCommand.update, ["3", "title::The Third Item"], | |
512 | + err); | |
415 | 513 | if (MLError.success != err) print_error(err); |
416 | 514 | |
417 | 515 | /* Fetch an item and write the details out. */ |
418 | - MediaListItem item4 = ml_fetch_item(list, 4, &err); | |
516 | + MediaListItem item4 = ml_fetch_item(list, 4, err); | |
419 | 517 | |
420 | 518 | if (MLError.success == err && true == item4.valid) |
421 | - { | |
519 | + @{ | |
422 | 520 | writeln("Details about item4:"); |
423 | 521 | writefln("Title: %s", item4.title); |
424 | 522 | writefln("Progress: %s", item4.progress); |
@@ -426,26 +524,23 @@ int main(string[] args) | ||
426 | 524 | writefln("Start Date: %s", item4.startDate); |
427 | 525 | writefln("End Date: %s", item4.endDate); |
428 | 526 | writefln("Last Update: %s", item4.lastUpdated); |
429 | - } | |
527 | + @} | |
430 | 528 | else |
431 | - { | |
529 | + @{ | |
432 | 530 | stderr.writefln("Failed to fetch item4: MLError.%s (Valid? %s)", |
433 | 531 | err, item4.valid ? "true" : "false"); |
434 | - } | |
532 | + @} | |
435 | 533 | |
436 | 534 | /* |
437 | - * Delete some items, then delete the list file. | |
535 | + * Delete some items. | |
438 | 536 | */ |
439 | - err = ml_send_command(list, MLCommand.delete_, ["3", "2"]); | |
440 | - if (MLError.success != err) print_error(err); | |
441 | - | |
442 | - err = ml_send_command(list, MLCommand.delete_, []); | |
537 | + ml_send_command(list, MLCommand.delete_, ["3", "2"], err); | |
443 | 538 | if (MLError.success != err) print_error(err); |
444 | 539 | |
445 | 540 | /* Done ! */ |
446 | 541 | return 0; |
447 | -} | |
448 | -@end verbatim | |
542 | +@} | |
543 | +@end example | |
449 | 544 | |
450 | 545 | |
451 | 546 | @node Index |
@@ -141,9 +141,6 @@ struct MediaListItem | ||
141 | 141 | /// |
142 | 142 | /// title, progress, status, start_date, end_date, last_updated. |
143 | 143 | /// |
144 | - /// Params: | |
145 | - /// item = The MediaListItem to convert to a string | |
146 | - /// | |
147 | 144 | /// Returns: A string containing the TSV representation of *item*. |
148 | 145 | /// |
149 | 146 | string tsvRepresentation() const { |
@@ -222,7 +219,7 @@ enum MLCommand | ||
222 | 219 | /// |
223 | 220 | /// If no there are no "Item ID" values in `args`, then the entire |
224 | 221 | /// list is irreversibly deleted. **NOTE**: This functionality has |
225 | - /// been deprecated from version 0.2.0, it'll be removed in a later | |
222 | + /// been deprecated from version 0.4, it'll be removed in a later | |
226 | 223 | /// version. |
227 | 224 | /// |
228 | 225 | delete_, |
@@ -263,12 +260,12 @@ enum MLError | ||
263 | 260 | itemNotFound, |
264 | 261 | /// We don't have permission to edit the list file. |
265 | 262 | permissionError, |
266 | - /// Unknown error has occurred. | |
267 | - unspecifiedError, | |
268 | 263 | /// Unknown value sent to ml_send_command. |
269 | 264 | /// |
270 | 265 | /// Check all values in the `MLCommand` enumeration. |
271 | 266 | unknownCommand, |
267 | + /// Unknown error has occurred. | |
268 | + unspecifiedError, | |
272 | 269 | } |
273 | 270 | |
274 | 271 | private static string[] mlErrorStrings = [ |