hoardy-web 0.14.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1574 @@
1
+ Metadata-Version: 2.1
2
+ Name: hoardy-web
3
+ Version: 0.14.1
4
+ Summary: A tool for displaying and manipulating Web Request+Response (WRR) files of `Hoardy-Web` WebExtension
5
+ Author-email: Jan Malakhovski <oxij@oxij.org>
6
+ License: GPL-3.0-or-later
7
+ Project-URL: Homepage, https://oxij.org/software/hoardy-web/
8
+ Project-URL: GitHub, https://github.com/Own-Data-Privateer/hoardy-web
9
+ Project-URL: Support Development, https://oxij.org/#support
10
+ Keywords: HTTP,HTTPS,web,archive,download,wayback,wayback machine
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
14
+ Classifier: Intended Audience :: End Users/Desktop
15
+ Classifier: Topic :: Internet :: WWW/HTTP
16
+ Classifier: Topic :: Internet :: WWW/HTTP :: Indexing/Search
17
+ Classifier: Topic :: System :: Archiving
18
+ Classifier: Topic :: System :: Archiving :: Backup
19
+ Classifier: Topic :: System :: Archiving :: Mirroring
20
+ Classifier: Topic :: System :: Logging
21
+ Classifier: Topic :: Internet :: Log Analysis
22
+ Classifier: Operating System :: POSIX
23
+ Classifier: Environment :: Console
24
+ Requires-Python: >=3.10
25
+ Description-Content-Type: text/markdown
26
+ Requires-Dist: kisstdlib
27
+ Requires-Dist: cbor2
28
+ Requires-Dist: idna
29
+ Requires-Dist: html5lib
30
+
31
+ # What is `hoardy-web`?
32
+
33
+ `hoardy-web` is a tool for displaying, programmatically manipulating, organizing, importing, and exporting Web Request+Response (WRR) files produced by [`Hoardy-Web` WebExtension](https://github.com/Own-Data-Privateer/hoardy-web/tree/master/) (also [there](https://oxij.org/software/hoardy-web/tree/master/)).
34
+
35
+ # Quickstart
36
+
37
+ ## Installation
38
+
39
+ - Install with:
40
+ ```bash
41
+ pip install hoardy-web
42
+ ```
43
+ and run as
44
+ ```bash
45
+ hoardy-web --help
46
+ ```
47
+ - Alternatively, install it via Nix
48
+ ```bash
49
+ nix-env -i -f ./default.nix
50
+ hoardy-web --help
51
+ ```
52
+ - Alternatively, run without installing:
53
+ ```bash
54
+ alias hoardy-web="python3 -m hoardy_web"
55
+ hoardy-web --help
56
+ ```
57
+
58
+ ## Supported input file formats
59
+
60
+ ### Simple WRR-dumps (`*.wrr`)
61
+
62
+ When you use [the `Hoardy-Web` WebExtension](../extension/) together with [`hoardy-web-sas` archiving server](../simple_server/), the latter writes [WRR-dumps `Hoardy-Web` WebExtension generates](../doc/data-on-disk.md) into separate `.wrr` files (aka "WRR files") in its dumping directory.
63
+ No further actions to use that data are required.
64
+
65
+ The situation is similar if you instead use `Hoardy-Web` WebExtension with "Export via `saveAs`" option enabled but `saveAs`-bundling option disabled (max bundle size set to zero).
66
+ The only difference is that WRR files will be put into `~/Downloads` or similar.
67
+
68
+ ```bash
69
+ ls ~/Downloads/Hoardy-Web-export-*
70
+ ```
71
+
72
+ ### Bundles of WRR-dumps (`*.wrrb`)
73
+
74
+ However, if instead of using any of the above you use `Hoardy-Web` WebExtension with both "Export via `saveAs`" and bundling options enabled, then, at the moment, you will need to `import` those `.wrrb` files (aka WRR-bundles) into separate WRR files first:
75
+
76
+ ```bash
77
+ hoardy-web import bundle --to ~/hoardy-web/raw ~/Downloads/Hoardy-Web-export-*
78
+ ```
79
+
80
+ Note that `hoardy-web` can parse `.wrr` files as single-dump `.wrrb` files, so the above will work even when some of the exported dumps are simple `.wrr` files (`Hoardy-Web` generates those when exporting an only available per-bucket dump or when exporting dumps larger than set maximum bundle size).
81
+ So, essentially, the above command is equivalent to
82
+
83
+ ```bash
84
+ hoardy-web organize --copy --to ~/hoardy-web/raw ~/Downloads/Hoardy-Web-export-*.wrr
85
+ hoardy-web import bundle --to ~/hoardy-web/raw ~/Downloads/Hoardy-Web-export-*.wrrb
86
+ ```
87
+
88
+ ### Other file formats
89
+
90
+ `hoardy-web` can also use some other file formats as inputs.
91
+ See the documentation of the `hoardy-web import` sub-command below for more info.
92
+
93
+ ## How to merge multiple archive directories
94
+
95
+ To merge multiple input directories into one you can simply `hoardy-web organize` them `--to` a new directory.
96
+ `hoardy-web` will automatically deduplicate all the files in the generated result.
97
+
98
+ That is to say, for `hoardy-web organize` (see the documentation below for more info):
99
+
100
+ - `--move` is de-duplicating when possible,
101
+ - while `--copy`, `--hardlink`, and `--symlink` are non-duplicating when possible.
102
+
103
+ For example, if you duplicate an input directory via `--copy` or `--hardlink`:
104
+
105
+ ```bash
106
+ hoardy-web organize --copy --to ~/hoardy-web/copy1 ~/hoardy-web/original
107
+ hoardy-web organize --hardlink --to ~/hoardy-web/copy2 ~/hoardy-web/original
108
+ ```
109
+
110
+ (In real-life use different copies usually end up on in different backup drives or some such.)
111
+
112
+ Then, repeating the same command would a noop:
113
+
114
+ ```bash
115
+ # noops
116
+ hoardy-web organize --copy --to ~/hoardy-web/copy1 ~/hoardy-web/original
117
+ hoardy-web organize --hardlink --to ~/hoardy-web/copy2 ~/hoardy-web/original
118
+ ```
119
+
120
+ And running the opposite command would also be a noop:
121
+
122
+ ```bash
123
+ # noops
124
+ hoardy-web organize --hardlink --to ~/hoardy-web/copy1 ~/hoardy-web/original
125
+ hoardy-web organize --copy --to ~/hoardy-web/copy2 ~/hoardy-web/original
126
+ ```
127
+
128
+ And copying between copies is also a noop:
129
+
130
+ ```bash
131
+ # noops
132
+ hoardy-web organize --hardlink --to ~/hoardy-web/copy2 ~/hoardy-web/copy1
133
+ hoardy-web organize --copy --to ~/hoardy-web/copy2 ~/hoardy-web/copy1
134
+ ```
135
+
136
+ But doing `hoardy-web organize --move` while supplying directories that have the same data will deduplicate the results:
137
+
138
+ ```bash
139
+ hoardy-web organize --move --to ~/hoardy-web/all ~/hoardy-web/copy1 ~/hoardy-web/copy2
140
+ # `~/hoardy-web/all` will have each file only once
141
+ find ~/hoardy-web/copy1 ~/hoardy-web/copy2 -type f
142
+ # the output will be empty
143
+
144
+ hoardy-web organize --move --to ~/hoardy-web/original ~/hoardy-web/all
145
+ # `~/hoardy-web/original` will not change iff it is already organized using `--output default`
146
+ # otherwise, some files there will be duplicated
147
+ find ~/hoardy-web/all -type f
148
+ # the output will be empty
149
+ ```
150
+
151
+ Similarly, `hoardy-web organize --symlink` resolves its input symlinks and deduplicates its output symlinks:
152
+
153
+ ```bash
154
+ hoardy-web organize --symlink --output hupq_msn --to ~/hoardy-web/pointers ~/hoardy-web/original
155
+ hoardy-web organize --symlink --output shupq_msn --to ~/hoardy-web/schemed ~/hoardy-web/original
156
+
157
+ # noop
158
+ hoardy-web organize --symlink --output hupq_msn --to ~/hoardy-web/pointers ~/hoardy-web/original ~/hoardy-web/schemed
159
+ ```
160
+
161
+ I.e. the above will produce `~/hoardy-web/pointers` with unique symlinks pointing to each file in `~/hoardy-web/original` only once.
162
+
163
+ ## How to build a file system tree of latest versions of all hoarded URLs
164
+
165
+ Assuming you keep your WRR-dumps in `~/hoardy-web/raw` you can generate a hierarchy of symlinks for each URL pointing from under `~/hoardy-web/latest` to the most recent WRR file that contains `200 OK` response in `~/hoardy-web/raw` via:
166
+
167
+ ```bash
168
+ hoardy-web organize --symlink --latest --output hupq --to ~/hoardy-web/latest --and "status|~= .200C" ~/hoardy-web/raw
169
+ ```
170
+
171
+ Personally, I prefer `flat_mhs` (see the documentation of the `--output` below) format as I dislike deep file hierarchies, using it also simplifies filtering in my `ranger` file browser, so I do this:
172
+
173
+ ```bash
174
+ hoardy-web organize --symlink --latest --output flat_mhs --and "status|~= .200C" --to ~/hoardy-web/latest ~/hoardy-web/raw
175
+ ```
176
+
177
+ ### Update the tree incrementally, in real time
178
+
179
+ The above commands rescan the whole contents of `~/hoardy-web/raw` and so can take a while to complete.
180
+
181
+ If you have a lot of WRR files and you want to keep your symlink tree updated in near-real-time you will need to use a two-stage pipeline by giving the output of `hoardy-web organize --zero-terminated` to `hoardy-web organize --stdin0` to perform complex updates.
182
+
183
+ E.g. the following will rename new reqres from `../simple_server/pwebarc-dump` to `~/hoardy-web/raw` renaming them with `--output default` (the `for` loop is there to preserve buckets/profiles):
184
+
185
+ ```bash
186
+ for arg in ../simple_server/pwebarc-dump/* ; do
187
+ hoardy-web organize --zero-terminated --to ~/hoardy-web/raw/"$(basename "$arg")" "$arg"
188
+ done > changes
189
+ ```
190
+
191
+ Then, you can reuse the paths saved in `changes` file to update the symlink tree, like in the above:
192
+
193
+ ```
194
+ hoardy-web organize --stdin0 --symlink --latest --output flat_mhs --and "status|~= .200C" --to ~/hoardy-web/latest ~/hoardy-web/raw < changes
195
+ ```
196
+
197
+ Then, optionally, you can reuse `changes` file again to symlink all new files from `~/hoardy-web/raw` to `~/hoardy-web/all`, showing all URL versions, by using `--output hupq_msn` format:
198
+
199
+ ```bash
200
+ hoardy-web organize --stdin0 --symlink --output hupq_msn --to ~/hoardy-web/all < changes
201
+ ```
202
+
203
+ ## <span id="mirror"/>How to generate a local offline website mirror like `wget -mpk`
204
+
205
+ If you want to render your WRR files into a local offline website mirror containing interlinked HTML files and their resources a-la `wget -mpk` (`wget --mirror --page-requisites --convert-links`), run one of the above `--symlink --latest` commands, and then do something like this:
206
+
207
+ ```bash
208
+ hoardy-web export mirror --to ~/hoardy-web/mirror1 ~/hoardy-web/latest/archiveofourown.org
209
+ ```
210
+
211
+ on completion `~/hoardy-web/mirror1` will contain a bunch of interlinked minimized HTML files, their resources, and everything else available from WRR files living under `~/hoardy-web/latest/archiveofourown.org`.
212
+
213
+ The above command might fail if the set of WRR-dumps you are trying to export contains two or more dumps with distinct URLs that map to the same `--output` path.
214
+ This will produce an error since `hoardy` does not permit file overwrites.
215
+ With the default `--output hupq` format this can happen, for instance, when the URLs recorded in the reqres are long and so they end up truncated into the same file system paths.
216
+
217
+ In this case you can either switch to a more verbose `--output` format
218
+
219
+ ```bash
220
+ hoardy-web export mirror --output hupq_n --to ~/hoardy-web/mirror1 ~/hoardy-web/latest/archiveofourown.org
221
+ ```
222
+
223
+ or skip all reqres that would cause overwrites
224
+
225
+ ```bash
226
+ hoardy-web export mirror --skip-existing --to ~/hoardy-web/mirror1 ~/hoardy-web/latest/archiveofourown.org
227
+ ```
228
+
229
+ or, almost equivalently for this use case, skip all export errors (which includes "no overwrites allowed" error)
230
+
231
+ ```bash
232
+ hoardy-web export mirror --errors skip --to ~/hoardy-web/mirror1 ~/hoardy-web/latest/archiveofourown.org
233
+ ```
234
+
235
+ The latter command would also skip reqres that fail to be exported for other reasons.
236
+
237
+ By default, *all* the links in exported HTML files will be remapped to local files (even if source WRR files for those would-be exported files are missing in `~/hoardy-web/latest/archiveofourown.org`, see the documentation for the `--remap-*` options below for more info), and those HTML files will also be stripped of all JavaScript, CSS, and other stuff of various levels of evil (see the documentation for the `scrub` function below for more info).
238
+
239
+ On the plus side, the result will be completely self-contained and safe to view with a dumb unconfigured browser.
240
+
241
+ If you are unhappy with this behaviour and, for instance, want to keep the CSS and produce human-readable HTML, run the following instead:
242
+
243
+ ```bash
244
+ hoardy-web export mirror \
245
+ -e 'response.body|eb|scrub response +all_refs,-actions,+styles,+pretty' \
246
+ --to ~/hoardy-web/mirror2 ~/hoardy-web/latest/archiveofourown.org
247
+ ```
248
+
249
+ Note, however, that CSS resource filtering and remapping is not implemented yet.
250
+
251
+ If you also want to keep links that point to not yet hoarded Internet URLs to still point those URLs in the exported files instead of them pointing to non-existent local files, similarly to what `wget -mpk` does, run `hoardy-web export mirror` with `--remap-open`, e.g.:
252
+
253
+ ```bash
254
+ hoardy-web export mirror \
255
+ -e 'response.body|eb|scrub response +all_refs,-actions,+styles,+pretty' \
256
+ --remap-open \
257
+ --to ~/hoardy-web/mirror3 ~/hoardy-web/latest/archiveofourown.org
258
+ ```
259
+
260
+ Finally, if you want a mirror made of raw files without any content censorship or link conversions, run:
261
+
262
+ ```bash
263
+ hoardy-web export mirror -e 'response.body|eb' --to ~/hoardy-web/mirror-raw ~/hoardy-web/latest/archiveofourown.org
264
+ ```
265
+
266
+ The later command will render your mirror pretty quickly, but the other above-mentioned commands will call the `scrub` function, and that will be pretty slow (as in avg ~5Mb, ~3 files per second on my 2013-era laptop), mostly because `html5lib` that `hoardy-web` uses for paranoid HTML parsing and filtering is fairly slow.
267
+
268
+ ### Using `--root` and `--depth`
269
+
270
+ As an alternative to (or in combination with) keeping a symlink hierarchy of latest versions, you can load (an index of) an assortment of WRR files into `hoardy-web`'s memory but then `export mirror` only select URLs (and all resources needed to properly render those pages) by running something like:
271
+
272
+ ```
273
+ hoardy-web export mirror \
274
+ --root 'https://archiveofourown.org/works/3733123?view_adult=true&view_full_work=true' \
275
+ --root 'https://archiveofourown.org/works/30186441?view_adult=true&view_full_work=true' \
276
+ --to ~/hoardy-web/mirror4 ~/hoardy-web/raw/*/2023
277
+ ```
278
+
279
+ (`hoardy-web` loads (indexes) WRR files pretty fast, so if you are running from an SSD, you can totally feed it years of WRR files and then only export a couple of URLs, and it will take a couple of seconds to finish anyway.)
280
+
281
+ There is also `--depth` option, which works similarly to `wget`'s `--level` option in that it will follow all jump (`a href`) and action links accessible with no more than `--depth` browser navigations from recursion `--root`s and then `export mirror` all those URLs (and their resources) too.
282
+
283
+ When using `--root` options, `--remap-open` works exactly like `wget`'s `--convert-links` in that it will only remap the URLs that are going to be exported and will keep the rest as-is.
284
+ Similarly, `--remap-closed` will consider only the URLs reachable from the `--root`s in no more that `--depth` jumps as available.
285
+
286
+ ## <span id="mitmproxy-mirror"/>How to generate local offline website mirrors like `wget -mpk` from you old `mitmproxy` stream dumps
287
+
288
+ Assuming `mitmproxy.001.dump`, `mitmproxy.002.dump`, etc are files that were produced by running something like
289
+
290
+ ```bash
291
+ mitmdump -w +mitmproxy.001.dump
292
+ ```
293
+
294
+ at some point, you can generate website mirrors from them by first importing them all to WRR
295
+
296
+ ```bash
297
+ hoardy-web import mitmproxy --to ~/hoardy-web/mitmproxy mitmproxy.*.dump
298
+ ```
299
+
300
+ and then `export mirror` like above, e.g. to generate mirrors for all URLs:
301
+
302
+ ```bash
303
+ hoardy-web export mirror --to ~/hoardy-web/mirror ~/hoardy-web/mitmproxy
304
+ ```
305
+
306
+ ## How to generate previews for WRR files, listen to them via TTS, open them with `xdg-open`, etc
307
+
308
+ See [`script` sub-directory](./script/) for examples that show how to use `pandoc` and/or `w3m` to turn WRR files into previews and readable plain-text that can viewed or listened to via other tools, or dump them into temporary raw data files that can then be immediately fed to `xdg-open` for one-click viewing.
309
+
310
+ # Usage
311
+
312
+ ## hoardy-web
313
+
314
+ A tool to pretty-print, compute and print values from, search, organize (programmatically rename/move/symlink/hardlink files), import, export, (WIP: check, deduplicate, and edit) `Hoardy-Web`'s WRR (Web Request+Response) archive files.
315
+
316
+ Terminology: a `reqres` (`Reqres` when a Python type) is an instance of a structure representing HTTP request+response pair with some additional metadata.
317
+
318
+ - options:
319
+ - `--version`
320
+ : show program's version number and exit
321
+ - `-h, --help`
322
+ : show this help message and exit
323
+ - `--markdown`
324
+ : show help messages formatted in Markdown
325
+
326
+ - subcommands:
327
+ - `{pprint,get,run,stream,find,organize,import,export}`
328
+ - `pprint`
329
+ : pretty-print given WRR files
330
+ - `get`
331
+ : print values produced by computing given expressions on a given WRR file
332
+ - `run`
333
+ : spawn a process with generated temporary files produced by given expressions computed on given WRR files as arguments
334
+ - `stream`
335
+ : produce a stream of structured lists containing values produced by computing given expressions on given WRR files, a generalized `hoardy-web get`
336
+ - `find`
337
+ : print paths of WRR files matching specified criteria
338
+ - `organize`
339
+ : programmatically rename/move/hardlink/symlink WRR files based on their contents
340
+ - `import`
341
+ : convert other HTTP archive formats into WRR
342
+ - `export`
343
+ : convert WRR archives into other formats
344
+
345
+ ### hoardy-web pprint
346
+
347
+ Pretty-print given WRR files to stdout.
348
+
349
+ - positional arguments:
350
+ - `PATH`
351
+ : inputs, can be a mix of files and directories (which will be traversed recursively)
352
+
353
+ - options:
354
+ - `-u, --unabridged`
355
+ : print all data in full
356
+ - `--abridged`
357
+ : shorten long strings for brevity, useful when you want to visually scan through batch data dumps; default
358
+ - `--stdin0`
359
+ : read zero-terminated `PATH`s from stdin, these will be processed after `PATH`s specified as command-line arguments
360
+
361
+ - error handling:
362
+ - `--errors {fail,skip,ignore}`
363
+ : when an error occurs:
364
+ - `fail`: report failure and stop the execution; default
365
+ - `skip`: report failure but skip the reqres that produced it from the output and continue
366
+ - `ignore`: `skip`, but don't report the failure
367
+
368
+ - filters; both can be specified at the same time, both can be specified multiple times, both use the same expression format as `hoardy-web get --expr` (which see), the resulting logical expression that will checked is `(O1 or O2 or ... or (A1 and A2 and ...))`, where `O1`, `O2`, ... are the arguments to `--or`s and `A1`, `A2`, ... are the arguments to `--and`s:
369
+ - `--or EXPR`
370
+ : only print reqres which match any of these expressions
371
+ - `--and EXPR`
372
+ : only print reqres which match all of these expressions
373
+
374
+ - MIME type sniffing:
375
+ - `--naive`
376
+ : populate "potentially" lists like `hoardy-web (get|run|export) --expr '(request|response).body|eb|scrub \2 defaults'` does; default
377
+ - `--paranoid`
378
+ : populate "potentially" lists in the output using paranoid MIME type sniffing like `hoardy-web (get|run|export) --expr '(request|response).body|eb|scrub \2 +paranoid'` does; this exists to answer "Hey! Why did it censor out my data?!" questions
379
+
380
+ - file system path ordering:
381
+ - `--paths-given-order`
382
+ : `argv` and `--stdin0` `PATH`s are processed in the order they are given; default
383
+ - `--paths-sorted`
384
+ : `argv` and `--stdin0` `PATH`s are processed in lexicographic order
385
+ - `--paths-reversed`
386
+ : `argv` and `--stdin0` `PATH`s are processed in reverse lexicographic order
387
+ - `--walk-fs-order`
388
+ : recursive file system walk is done in the order `readdir(2)` gives results
389
+ - `--walk-sorted`
390
+ : recursive file system walk is done in lexicographic order; default
391
+ - `--walk-reversed`
392
+ : recursive file system walk is done in reverse lexicographic order
393
+
394
+ ### hoardy-web get
395
+
396
+ Compute output values by evaluating expressions `EXPR`s on a given reqres stored at `PATH`, then print them to stdout terminating each value as specified.
397
+
398
+ - positional arguments:
399
+ - `PATH`
400
+ : input WRR file path
401
+
402
+ - expression evaluation:
403
+ - `--expr-fd INT`
404
+ : file descriptor to which the results of evaluations of the following `--expr`s computations should be written; can be specified multiple times, thus separating different `--expr`s into different output streams; default: `1`, i.e. `stdout`
405
+ - `-e EXPR, --expr EXPR`
406
+ : an expression to compute; can be specified multiple times in which case computed outputs will be printed sequentially; see also "printing" options below; default: `response.body|eb`, which will dump the HTTP response body; each `EXPR` describes a state-transformer (pipeline) which starts from value `None` and evaluates a script built from the following:
407
+ - constants and functions:
408
+ - `es`: replace `None` value with an empty string `""`
409
+ - `eb`: replace `None` value with an empty byte string `b""`
410
+ - `false`: replace `None` value with `False`
411
+ - `true`: replace `None` value with `True`
412
+ - `missing`: `True` if the value is `None`
413
+ - `0`: replace `None` value with `0`
414
+ - `1`: replace `None` value with `1`
415
+ - `not`: apply logical `not` to value
416
+ - `len`: apply `len` to value
417
+ - `str`: cast value to `str` or fail
418
+ - `bytes`: cast value to `bytes` or fail
419
+ - `bool`: cast value to `bool` or fail
420
+ - `int`: cast value to `int` or fail
421
+ - `float`: cast value to `float` or fail
422
+ - `echo`: replace the value with the given string
423
+ - `quote`: URL-percent-encoding quote value
424
+ - `quote_plus`: URL-percent-encoding quote value and replace spaces with `+` symbols
425
+ - `unquote`: URL-percent-encoding unquote value
426
+ - `unquote_plus`: URL-percent-encoding unquote value and replace `+` symbols with spaces
427
+ - `to_ascii`: encode `str` value into `bytes` with "ascii" codec
428
+ - `to_utf8`: encode `str` value into `bytes` with "utf-8" codec
429
+ - `sha256`: replace `bytes` value with its `sha256` hex digest (`hex(sha256(value))`)
430
+ - `~=`: check if the current value matches the regular exprission `arg`
431
+ - `==`: apply `== arg`, `arg` is cast to the same type as the current value
432
+ - `!=`: apply `!= arg`, similarly
433
+ - `<`: apply `< arg`, similarly
434
+ - `<=`: apply `<= arg`, similarly
435
+ - `>`: apply `> arg`, similarly
436
+ - `>=`: apply `>= arg`, similarly
437
+ - `add_prefix`: add prefix to the current value
438
+ - `add_suffix`: add suffix to the current value
439
+ - `take_prefix`: take first `arg` characters or list elements from the current value
440
+ - `take_suffix`: take last `arg` characters or list elements from the current value
441
+ - `abbrev`: leave the current value as-is if if its length is less or equal than `arg` characters, otherwise take first `arg/2` followed by last `arg/2` characters
442
+ - `abbrev_each`: `abbrev arg` each element in a value `list`
443
+ - `replace`: replace all occurences of the first argument in the current value with the second argument, casts arguments to the same type as the current value
444
+ - `pp_to_path`: encode `path_parts` `list` into a POSIX path, quoting as little as needed
445
+ - `qsl_urlencode`: encode parsed `query` `list` into a URL's query component `str`
446
+ - `qsl_to_path`: encode `query` `list` into a POSIX path, quoting as little as needed
447
+ - `scrub`: scrub the value by optionally rewriting links and/or removing dynamic content from it; what gets done depends on `--remap-*` command line options, the MIME type of the value itself, and the scrubbing options described below; this fuction takes two arguments:
448
+ - the first must be either of `request|response`, it controls which HTTP headers `scrub` should inspect to help it detect the MIME type;
449
+ - the second is either `defaults` or ","-separated string of `(+|-)(paranoid|unknown|jumps|actions|srcs|all_refs|scripts|iframes|styles|iepragmas|prefetches|tracking|dyndoc|all_dyns|verbose|whitespace|optional_tags|indent|pretty|debug)` tokens which control the scrubbing behaviour:
450
+ - `+paranoid` will assume the server is lying in its `Content-Type` and `X-Content-Type-Options` HTTP headers, sniff the contents of `(request|response).body` to determine what it actually contains regardless of what the server said, and then use the most paranoid interpretation of both the HTTP headers and the sniffed possible MIME types to decide what should be kept and what sholuld be removed by the options below; i.e., this will make `-unknown`, `-scripts`, and `-styles` options below to censor out more things, in particular, at the moment, most plain text files will get censored out as potential JavaScript; the default is `-paranoid`;
451
+ - `(+|-)unknown` controls if the data with unknown content types should passed to the output unchanged or censored out (respectively); the default is `+unknown`, which will keep data of unknown content types as-is;
452
+ - `(+|-)(jumps|actions|srcs)` control which kinds of references to other documents should be remapped or censored out (respectively); i.e. it controls whether jump-links (HTML `a href`, `area href`, and similar), action-links (HTML `a ping`, `form action`, and similar), and/or resource references (HTML `img src`, `iframe src`, CSS `url` references, and similar) should be remapped using the specified `--remap-*` option (which see) or censored out similarly to how `--remap-void` will do it; the default is `+jumps,-actions,-srcs` which will produce a self-contained result that can be fed into another tool --- be it a web browser or `pandoc` --- without that tool trying to access the Internet;
453
+ - `(+|-)all_refs` is equivalent to enabling or disabling all of the above options simultaneously;
454
+ - `(+|-)(scripts|iframes|styles|iepragmas|prefetches|tracking)` control which things should be kept or censored out w.r.t. to HTML, CSS, and JavaScript, i.e. it controls whether JavaScript (both separate files and HTML tags and attributes), `<iframe>` HTML tags, CSS (both separate files and HTML tags and attributes; why? because CSS is Turing-complete), HTML Internet-Explorer pragmas, HTML content prefetch `link` tags, and other tracking HTML tags and attributes (like `a ping` attributes), should be respectively kept in or censored out from the input; the default is `-scripts,-iframes,-styles,-iepragmas,-prefetches,-tracking` which ensures the result will not produce any prefetch and tracking requests when loaded in a web browser, and that the whole result is simple data, not a program in some Turing-complete language, thus making it safe to feed the result to other tools too smart for their own users' good;
455
+ - `(+|-)all_dyns` is equivalent to enabling or disabling all of the above (`scripts|...`) options simultaneously;
456
+ - `(+|-)verbose` controls whether tag censoring controlled by the above options is to be reported in the output (as comments) or stuff should be wiped from existence without evidence instead; the default is `-verbose`;
457
+ - `(+|-)whitespace` controls whether HTML renderer should keep the original HTML whitespace as-is or collapse it away (respectively); the default is `-whitespace`;
458
+ - `(+|-)optional_tags` controls whether HTML renderer should put optional HTML tags into the output or skip them (respectively); the default is `+optional_tags` (because many tools fail to parse minimized HTML properly);
459
+ - `(+|-)indent` controls whether HTML renderer should indent HTML elements (where whitespace placement in the original markup allows for it) or not (respectively); the default is `-indent`;
460
+ - `+pretty` is an alias for `+verbose,-whitespace,+indent` which produces the prettiest possible human-readable output that keeps the original whitespace semantics; `-pretty` is an alias for `+verbose,+whitespace,-indent` which produces the approximation of the original markup with censoring applied; neither is the default;
461
+ - `+debug` is an alias for `+pretty` that also uses a much more aggressive version of `indent` that ignores the semantics of original whitespace placement, i.e. it will indent `<p>not<em>sep</em>arated</p>` as if there was whitespace before and after `p`, `em`, `/em`, and `/p` tags; this is useful for debugging custom mutations; `-debug` is noop, which is the default;
462
+ - reqres fields, these work the same way as constants above, i.e. they replace current value of `None` with field's value, if reqres is missing the field in question, which could happen for `response*` fields, the result is `None`:
463
+ - `version`: WEBREQRES format version; int
464
+ - `source`: `+`-separated list of applications that produced this reqres; str
465
+ - `protocol`: protocol; e.g. `"HTTP/1.1"`, `"HTTP/2.0"`; str
466
+ - `request.started_at`: request start time in seconds since 1970-01-01 00:00; Epoch
467
+ - `request.method`: request HTTP method; e.g. `"GET"`, `"POST"`, etc; str
468
+ - `request.url`: request URL, including the fragment/hash part; str
469
+ - `request.headers`: request headers; list[tuple[str, bytes]]
470
+ - `request.complete`: is request body complete?; bool
471
+ - `request.body`: request body; bytes
472
+ - `response.started_at`: response start time in seconds since 1970-01-01 00:00; Epoch
473
+ - `response.code`: HTTP response code; e.g. `200`, `404`, etc; int
474
+ - `response.reason`: HTTP response reason; e.g. `"OK"`, `"Not Found"`, etc; usually empty for Chromium and filled for Firefox; str
475
+ - `response.headers`: response headers; list[tuple[str, bytes]]
476
+ - `response.complete`: is response body complete?; bool
477
+ - `response.body`: response body; Firefox gives raw bytes, Chromium gives UTF-8 encoded strings; bytes | str
478
+ - `finished_at`: request completion time in seconds since 1970-01-01 00:00; Epoch
479
+ - `websocket`: a list of WebSocket frames
480
+ - derived attributes:
481
+ - `fs_path`: file system path for the WRR file containing this reqres; str | bytes | None
482
+ - `qtime`: aliast for `request.started_at`; mnemonic: "reQuest TIME"; seconds since UNIX epoch; decimal float
483
+ - `qtime_ms`: `qtime` in milliseconds rounded down to nearest integer; milliseconds since UNIX epoch; int
484
+ - `qtime_msq`: three least significant digits of `qtime_ms`; int
485
+ - `qyear`: year number of `gmtime(qtime)` (UTC year number of `qtime`); int
486
+ - `qmonth`: month number of `gmtime(qtime)`; int
487
+ - `qday`: day of the month of `gmtime(qtime)`; int
488
+ - `qhour`: hour of `gmtime(qtime)` in 24h format; int
489
+ - `qminute`: minute of `gmtime(qtime)`; int
490
+ - `qsecond`: second of `gmtime(qtime)`; int
491
+ - `stime`: `response.started_at` if there was a response, `finished_at` otherwise; mnemonic: "reSponse TIME"; seconds since UNIX epoch; decimal float
492
+ - `stime_ms`: `stime` in milliseconds rounded down to nearest integer; milliseconds since UNIX epoch, int
493
+ - `stime_msq`: three least significant digits of `stime_msq`; int
494
+ - `syear`: similar to `syear`, but for `stime`; int
495
+ - `smonth`: similar to `smonth`, but for `stime`; int
496
+ - `sday`: similar to `sday`, but for `stime`; int
497
+ - `shour`: similar to `shour`, but for `stime`; int
498
+ - `sminute`: similar to `sminute`, but for `stime`; int
499
+ - `ssecond`: similar to `ssecond`, but for `stime`; int
500
+ - `ftime`: aliast for `finished_at`; seconds since UNIX epoch; decimal float
501
+ - `ftime_ms`: `ftime` in milliseconds rounded down to nearest integer; milliseconds since UNIX epoch; int
502
+ - `ftime_msq`: three least significant digits of `ftime_msq`; int
503
+ - `fyear`: similar to `syear`, but for `ftime`; int
504
+ - `fmonth`: similar to `smonth`, but for `ftime`; int
505
+ - `fday`: similar to `sday`, but for `ftime`; int
506
+ - `fhour`: similar to `shour`, but for `ftime`; int
507
+ - `fminute`: similar to `sminute`, but for `ftime`; int
508
+ - `fsecond`: similar to `ssecond`, but for `ftime`; int
509
+ - `status`: `"I"` or `"C"` depending on the value of `request.complete` (`false` or `true`, respectively) followed by either `"N"`, whene `response == None`, or `str(response.code)` followed by `"I"` or `"C"` depending on the value of `response.complete`; str
510
+ - `method`: aliast for `request.method`; str
511
+ - `raw_url`: aliast for `request.url`; str
512
+ - `net_url`: `raw_url` with Punycode UTS46 IDNA encoded hostname, unsafe characters quoted, and without the fragment/hash part; this is the URL that actually gets sent to the server; str
513
+ - `pretty_url`: `raw_url`, but using `hostname`, `mq_path`, and `mq_query`; str
514
+ - `pretty_nurl`: `raw_url`, but using `hostname`, `mq_path`, and `mq_nquery`; str
515
+ - `scheme`: scheme part of `raw_url`; e.g. `http`, `https`, etc; str
516
+ - `raw_hostname`: hostname part of `raw_url` as it is recorded in the reqres; str
517
+ - `net_hostname`: hostname part of `raw_url`, encoded as Punycode UTS46 IDNA; this is what actually gets sent to the server; ASCII str
518
+ - `hostname`: `net_hostname` decoded back into UNICODE; this is the canonical hostname representation for which IDNA-encoding and decoding are bijective; UNICODE str
519
+ - `rhostname`: `hostname` with the order of its parts reversed; e.g. `"www.example.org"` -> `"com.example.www"`; str
520
+ - `port`: port part of `raw_url`; str
521
+ - `netloc`: netloc part of `raw_url`; i.e., in the most general case, `<username>:<password>@<hostname>:<port>`; str
522
+ - `raw_path`: raw path part of `raw_url` as it is recorded is the reqres; e.g. `"https://www.example.org"` -> `""`, `"https://www.example.org/"` -> `"/"`, `"https://www.example.org/index.html"` -> `"/index.html"`; str
523
+ - `path_parts`: component-wise unquoted "/"-split `raw_path` with empty components removed and dots and double dots interpreted away; e.g. `"https://www.example.org"` -> `[]`, `"https://www.example.org/"` -> `[]`, `"https://www.example.org/index.html"` -> `["index.html"]` , `"https://www.example.org/skipped/.//../used/"` -> `["used"]`; list[str]
524
+ - `mq_path`: `path_parts` turned back into a minimally-quoted string; str
525
+ - `filepath_parts`: `path_parts` transformed into components usable as an exportable file name; i.e. `path_parts` with an optional additional `"index"` appended, depending on `raw_url` and `response` MIME type; extension will be stored separately in `filepath_ext`; e.g. for HTML documents `"https://www.example.org/"` -> `["index"]`, `"https://www.example.org/test.html"` -> `["test"]`, `"https://www.example.org/test"` -> `["test", "index"]`, `"https://www.example.org/test.json"` -> `["test.json", "index"]`, but if it has a JSON MIME type then `"https://www.example.org/test.json"` -> `["test"]` (and `filepath_ext` will be set to `".json"`); this is similar to what `wget -mpk` does, but a bit smarter; list[str]
526
+ - `filepath_ext`: extension of the last component of `filepath_parts` for recognized MIME types, `".data"` otherwise; str
527
+ - `raw_query`: query part of `raw_url` (i.e. everything after the `?` character and before the `#` character) as it is recorded in the reqres; str
528
+ - `query_parts`: parsed (and component-wise unquoted) `raw_query`; list[tuple[str, str]]
529
+ - `query_ne_parts`: `query_parts` with empty query parameters removed; list[tuple[str, str]]
530
+ - `mq_query`: `query_parts` turned back into a minimally-quoted string; str
531
+ - `mq_nquery`: `query_ne_parts` turned back into a minimally-quoted string; str
532
+ - `oqm`: optional query mark: `?` character if `query` is non-empty, an empty string otherwise; str
533
+ - `fragment`: fragment (hash) part of the url; str
534
+ - `ofm`: optional fragment mark: `#` character if `fragment` is non-empty, an empty string otherwise; str
535
+ - a compound expression built by piping (`|`) the above, for example:
536
+ - `response.body|eb` (the default for `get`) will print raw `response.body` or an empty byte string, if there was no response;
537
+ - `response.body|eb|scrub response defaults` will take the above value, `scrub` it using default content scrubbing settings which will censor out all action and resource reference URLs;
538
+ - `response.body|eb|scrub response +all_refs,-actions` (the default for `export`) will remap all `href` jump-links and `src` resource references to local files while still censoring out all action URLs (since those don't make sense for a static mirror);
539
+ - `response.complete` will print the value of `response.complete` or `None`, if there was no response;
540
+ - `response.complete|false` will print `response.complete` or `False`;
541
+ - `net_url|to_ascii|sha256` will print `sha256` hash of the URL that was actually sent over the network;
542
+ - `net_url|to_ascii|sha256|take_prefix 4` will print the first 4 characters of the above;
543
+ - `path_parts|take_prefix 3|pp_to_path` will print first 3 path components of the URL, minimally quoted to be used as a path;
544
+ - `query_ne_parts|take_prefix 3|qsl_to_path|abbrev 128` will print first 3 non-empty query parameters of the URL, abbreviated to 128 characters or less, minimally quoted to be used as a path;
545
+
546
+ - URL remapping; used by `scrub` atom of `--expr`:
547
+ - `--remap-id`
548
+ : remap all URLs with an identity function; i.e. don't remap anything; default
549
+ - `--remap-void`
550
+ : remap all jump-link and action URLs to `javascript:void(0)` and all resource URLs into empty `data:` URLs; resulting web pages will be self-contained
551
+
552
+ - printing:
553
+ - `--not-separated`
554
+ : print values without separating them with anything, just concatenate them
555
+ - `-l, --lf-separated`
556
+ : print values separated with `\n` (LF) newline characters; default
557
+ - `-z, --zero-separated`
558
+ : print values separated with `\0` (NUL) bytes
559
+
560
+ ### hoardy-web run
561
+
562
+ Compute output values by evaluating expressions `EXPR`s for each of `NUM` reqres stored at `PATH`s, dump the results into into newly generated temporary files terminating each value as specified, spawn a given `COMMAND` with given arguments `ARG`s and the resulting temporary file paths appended as the last `NUM` arguments, wait for it to finish, delete the temporary files, exit with the return code of the spawned process.
563
+
564
+ - positional arguments:
565
+ - `COMMAND`
566
+ : command to spawn
567
+ - `ARG`
568
+ : additional arguments to give to the `COMMAND`
569
+ - `PATH`
570
+ : input WRR file paths to be mapped into new temporary files
571
+
572
+ - options:
573
+ - `-n NUM, --num-args NUM`
574
+ : number of `PATH`s; default: `1`
575
+
576
+ - expression evaluation:
577
+ - `-e EXPR, --expr EXPR`
578
+ : an expression to compute, same expression format and semantics as `hoardy-web get --expr` (which see); can be specified multiple times; default: `response.body|eb`, which will dump the HTTP response body
579
+
580
+ - URL remapping; used by `scrub` atom of `--expr`:
581
+ - `--remap-id`
582
+ : remap all URLs with an identity function; i.e. don't remap anything; default
583
+ - `--remap-void`
584
+ : remap all jump-link and action URLs to `javascript:void(0)` and all resource URLs into empty `data:` URLs; resulting web pages will be self-contained
585
+
586
+ - printing:
587
+ - `--not-separated`
588
+ : print values without separating them with anything, just concatenate them
589
+ - `-l, --lf-separated`
590
+ : print values separated with `\n` (LF) newline characters; default
591
+ - `-z, --zero-separated`
592
+ : print values separated with `\0` (NUL) bytes
593
+
594
+ ### hoardy-web stream
595
+
596
+ Compute given expressions for each of given WRR files, encode them into a requested format, and print the result to stdout.
597
+
598
+ - positional arguments:
599
+ - `PATH`
600
+ : inputs, can be a mix of files and directories (which will be traversed recursively)
601
+
602
+ - options:
603
+ - `-u, --unabridged`
604
+ : print all data in full
605
+ - `--abridged`
606
+ : shorten long strings for brevity, useful when you want to visually scan through batch data dumps; default
607
+ - `--format {py,cbor,json,raw}`
608
+ : generate output in:
609
+ - py: Pythonic Object Representation aka `repr`; default
610
+ - cbor: CBOR (RFC8949)
611
+ - json: JavaScript Object Notation aka JSON; **binary data can't be represented, UNICODE replacement characters will be used**
612
+ - raw: concatenate raw values; termination is controlled by `*-terminated` options
613
+ - `--stdin0`
614
+ : read zero-terminated `PATH`s from stdin, these will be processed after `PATH`s specified as command-line arguments
615
+
616
+ - error handling:
617
+ - `--errors {fail,skip,ignore}`
618
+ : when an error occurs:
619
+ - `fail`: report failure and stop the execution; default
620
+ - `skip`: report failure but skip the reqres that produced it from the output and continue
621
+ - `ignore`: `skip`, but don't report the failure
622
+
623
+ - filters; both can be specified at the same time, both can be specified multiple times, both use the same expression format as `hoardy-web get --expr` (which see), the resulting logical expression that will checked is `(O1 or O2 or ... or (A1 and A2 and ...))`, where `O1`, `O2`, ... are the arguments to `--or`s and `A1`, `A2`, ... are the arguments to `--and`s:
624
+ - `--or EXPR`
625
+ : only print reqres which match any of these expressions
626
+ - `--and EXPR`
627
+ : only print reqres which match all of these expressions
628
+
629
+ - expression evaluation:
630
+ - `-e EXPR, --expr EXPR`
631
+ : an expression to compute, same expression format and semantics as `hoardy-web get --expr` (which see); can be specified multiple times; default: `.`, which will dump the whole reqres structure
632
+
633
+ - URL remapping; used by `scrub` atom of `--expr`:
634
+ - `--remap-id`
635
+ : remap all URLs with an identity function; i.e. don't remap anything; default
636
+ - `--remap-void`
637
+ : remap all jump-link and action URLs to `javascript:void(0)` and all resource URLs into empty `data:` URLs; resulting web pages will be self-contained
638
+
639
+ - `--format=raw` output printing:
640
+ - `--not-terminated`
641
+ : print `--format=raw` output values without terminating them with anything, just concatenate them
642
+ - `-l, --lf-terminated`
643
+ : print `--format=raw` output values terminated with `\n` (LF) newline characters; default
644
+ - `-z, --zero-terminated`
645
+ : print `--format=raw` output values terminated with `\0` (NUL) bytes
646
+
647
+ - file system path ordering:
648
+ - `--paths-given-order`
649
+ : `argv` and `--stdin0` `PATH`s are processed in the order they are given; default
650
+ - `--paths-sorted`
651
+ : `argv` and `--stdin0` `PATH`s are processed in lexicographic order
652
+ - `--paths-reversed`
653
+ : `argv` and `--stdin0` `PATH`s are processed in reverse lexicographic order
654
+ - `--walk-fs-order`
655
+ : recursive file system walk is done in the order `readdir(2)` gives results
656
+ - `--walk-sorted`
657
+ : recursive file system walk is done in lexicographic order; default
658
+ - `--walk-reversed`
659
+ : recursive file system walk is done in reverse lexicographic order
660
+
661
+ ### hoardy-web find
662
+
663
+ Print paths of WRR files matching specified criteria.
664
+
665
+ - positional arguments:
666
+ - `PATH`
667
+ : inputs, can be a mix of files and directories (which will be traversed recursively)
668
+
669
+ - options:
670
+ - `--stdin0`
671
+ : read zero-terminated `PATH`s from stdin, these will be processed after `PATH`s specified as command-line arguments
672
+
673
+ - error handling:
674
+ - `--errors {fail,skip,ignore}`
675
+ : when an error occurs:
676
+ - `fail`: report failure and stop the execution; default
677
+ - `skip`: report failure but skip the reqres that produced it from the output and continue
678
+ - `ignore`: `skip`, but don't report the failure
679
+
680
+ - filters; both can be specified at the same time, both can be specified multiple times, both use the same expression format as `hoardy-web get --expr` (which see), the resulting logical expression that will checked is `(O1 or O2 or ... or (A1 and A2 and ...))`, where `O1`, `O2`, ... are the arguments to `--or`s and `A1`, `A2`, ... are the arguments to `--and`s:
681
+ - `--or EXPR`
682
+ : only print paths to reqres which match any of these expressions
683
+ - `--and EXPR`
684
+ : only print paths to reqres which match all of these expressions
685
+
686
+ - found files printing:
687
+ - `-l, --lf-terminated`
688
+ : print absolute paths of matching WRR files terminated with `\n` (LF) newline characters; default
689
+ - `-z, --zero-terminated`
690
+ : print absolute paths of matching WRR files terminated with `\0` (NUL) bytes
691
+
692
+ - file system path ordering:
693
+ - `--paths-given-order`
694
+ : `argv` and `--stdin0` `PATH`s are processed in the order they are given; default
695
+ - `--paths-sorted`
696
+ : `argv` and `--stdin0` `PATH`s are processed in lexicographic order
697
+ - `--paths-reversed`
698
+ : `argv` and `--stdin0` `PATH`s are processed in reverse lexicographic order
699
+ - `--walk-fs-order`
700
+ : recursive file system walk is done in the order `readdir(2)` gives results
701
+ - `--walk-sorted`
702
+ : recursive file system walk is done in lexicographic order; default
703
+ - `--walk-reversed`
704
+ : recursive file system walk is done in reverse lexicographic order
705
+
706
+ ### hoardy-web organize
707
+
708
+ Parse given WRR files into their respective reqres and then rename/move/hardlink/symlink each file to `DESTINATION` with the new path derived from each reqres' metadata.
709
+
710
+ Operations that could lead to accidental data loss are not permitted.
711
+ E.g. `hoardy-web organize --move` will not overwrite any files, which is why the default `--output` contains `%(num)d`.
712
+
713
+ - positional arguments:
714
+ - `PATH`
715
+ : inputs, can be a mix of files and directories (which will be traversed recursively)
716
+
717
+ - options:
718
+ - `--dry-run`
719
+ : perform a trial run without actually performing any changes
720
+ - `-q, --quiet`
721
+ : don't log computed updates to stderr
722
+ - `--stdin0`
723
+ : read zero-terminated `PATH`s from stdin, these will be processed after `PATH`s specified as command-line arguments
724
+
725
+ - error handling:
726
+ - `--errors {fail,skip,ignore}`
727
+ : when an error occurs:
728
+ - `fail`: report failure and stop the execution; default
729
+ - `skip`: report failure but skip the reqres that produced it from the output and continue
730
+ - `ignore`: `skip`, but don't report the failure
731
+
732
+ - filters; both can be specified at the same time, both can be specified multiple times, both use the same expression format as `hoardy-web get --expr` (which see), the resulting logical expression that will checked is `(O1 or O2 or ... or (A1 and A2 and ...))`, where `O1`, `O2`, ... are the arguments to `--or`s and `A1`, `A2`, ... are the arguments to `--and`s:
733
+ - `--or EXPR`
734
+ : only work on reqres which match any of these expressions
735
+ - `--and EXPR`
736
+ : only work on reqres which match all of these expressions
737
+
738
+ - action:
739
+ - `--move`
740
+ : move source files under `DESTINATION`; default
741
+ - `--copy`
742
+ : copy source files to files under `DESTINATION`
743
+ - `--hardlink`
744
+ : create hardlinks from source files to paths under `DESTINATION`
745
+ - `--symlink`
746
+ : create symlinks from source files to paths under `DESTINATION`
747
+
748
+ - file outputs:
749
+ - `-t DESTINATION, --to DESTINATION`
750
+ : destination directory; when unset each source `PATH` must be a directory which will be treated as its own `DESTINATION`
751
+ - `-o FORMAT, --output FORMAT`
752
+ : format describing generated output paths, an alias name or "format:" followed by a custom pythonic %-substitution string:
753
+ - available aliases and corresponding %-substitutions:
754
+ - `default` : `%(syear)d/%(smonth)02d/%(sday)02d/%(shour)02d%(sminute)02d%(ssecond)02d%(stime_msq)03d_%(qtime_ms)s_%(method)s_%(net_url|to_ascii|sha256|take_prefix 4)s_%(status)s_%(hostname)s_%(num)d`; the default
755
+ - `https://example.org` -> `1970/01/01/001640000_0_GET_50d7_C200C_example.org_0`
756
+ - `https://example.org/` -> `1970/01/01/001640000_0_GET_8198_C200C_example.org_0`
757
+ - `https://example.org/index.html` -> `1970/01/01/001640000_0_GET_f0dc_C200C_example.org_0`
758
+ - `https://example.org/media` -> `1970/01/01/001640000_0_GET_086d_C200C_example.org_0`
759
+ - `https://example.org/media/` -> `1970/01/01/001640000_0_GET_3fbb_C200C_example.org_0`
760
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `1970/01/01/001640000_0_GET_5658_C200C_example.org_0`
761
+ - `https://königsgäßchen.example.org/index.html` -> `1970/01/01/001640000_0_GET_4f11_C200C_königsgäßchen.example.org_0`
762
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `1970/01/01/001640000_0_GET_c4ae_C200C_ジャジェメント.ですの.example.org_0`
763
+ - `short` : `%(syear)d/%(smonth)02d/%(sday)02d/%(stime_ms)d_%(qtime_ms)s_%(num)d`
764
+ - `https://example.org`, `https://example.org/`, `https://example.org/index.html`, `https://example.org/media`, `https://example.org/media/`, `https://example.org/view?one=1&two=2&three=&three=3#fragment`, `https://königsgäßchen.example.org/index.html`, `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `1970/01/01/1000000_0_0`
765
+ - `surl` : `%(scheme)s/%(netloc)s/%(mq_path)s%(oqm)s%(mq_query)s`
766
+ - `https://example.org`, `https://example.org/` -> `https/example.org/`
767
+ - `https://example.org/index.html` -> `https/example.org/index.html`
768
+ - `https://example.org/media`, `https://example.org/media/` -> `https/example.org/media`
769
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `https/example.org/view?one=1&two=2&three&three=3`
770
+ - `https://königsgäßchen.example.org/index.html` -> `https/königsgäßchen.example.org/index.html`
771
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `https/ジャジェメント.ですの.example.org/испытание/is`
772
+ - `surl_msn` : `%(scheme)s/%(netloc)s/%(mq_path)s%(oqm)s%(mq_query)s__%(method)s_%(status)s_%(num)d`
773
+ - `https://example.org`, `https://example.org/` -> `https/example.org/__GET_C200C_0`
774
+ - `https://example.org/index.html` -> `https/example.org/index.html__GET_C200C_0`
775
+ - `https://example.org/media`, `https://example.org/media/` -> `https/example.org/media__GET_C200C_0`
776
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `https/example.org/view?one=1&two=2&three&three=3__GET_C200C_0`
777
+ - `https://königsgäßchen.example.org/index.html` -> `https/königsgäßchen.example.org/index.html__GET_C200C_0`
778
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `https/ジャジェメント.ですの.example.org/испытание/is__GET_C200C_0`
779
+ - `shupq` : `%(scheme)s/%(hostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_query|abbrev 120)s%(filepath_ext)s`
780
+ - `https://example.org`, `https://example.org/` -> `https/example.org/index.htm`
781
+ - `https://example.org/index.html` -> `https/example.org/index.html`
782
+ - `https://example.org/media`, `https://example.org/media/` -> `https/example.org/media/index.htm`
783
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `https/example.org/view/index?one=1&two=2&three&three=3.htm`
784
+ - `https://königsgäßchen.example.org/index.html` -> `https/königsgäßchen.example.org/index.html`
785
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `https/ジャジェメント.ですの.example.org/испытание/is/index.htm`
786
+ - `shupq_n` : `%(scheme)s/%(hostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_query|abbrev 120)s.%(num)d%(filepath_ext)s`
787
+ - `https://example.org`, `https://example.org/` -> `https/example.org/index.0.htm`
788
+ - `https://example.org/index.html` -> `https/example.org/index.0.html`
789
+ - `https://example.org/media`, `https://example.org/media/` -> `https/example.org/media/index.0.htm`
790
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `https/example.org/view/index?one=1&two=2&three&three=3.0.htm`
791
+ - `https://königsgäßchen.example.org/index.html` -> `https/königsgäßchen.example.org/index.0.html`
792
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `https/ジャジェメント.ですの.example.org/испытание/is/index.0.htm`
793
+ - `shupq_msn` : `%(scheme)s/%(hostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_query|abbrev 100)s.%(method)s_%(status)s_%(num)d%(filepath_ext)s`
794
+ - `https://example.org`, `https://example.org/` -> `https/example.org/index.GET_C200C_0.htm`
795
+ - `https://example.org/index.html` -> `https/example.org/index.GET_C200C_0.html`
796
+ - `https://example.org/media`, `https://example.org/media/` -> `https/example.org/media/index.GET_C200C_0.htm`
797
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `https/example.org/view/index?one=1&two=2&three&three=3.GET_C200C_0.htm`
798
+ - `https://königsgäßchen.example.org/index.html` -> `https/königsgäßchen.example.org/index.GET_C200C_0.html`
799
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `https/ジャジェメント.ですの.example.org/испытание/is/index.GET_C200C_0.htm`
800
+ - `shupnq` : `%(scheme)s/%(hostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_nquery|abbrev 120)s%(filepath_ext)s`
801
+ - `https://example.org`, `https://example.org/` -> `https/example.org/index.htm`
802
+ - `https://example.org/index.html` -> `https/example.org/index.html`
803
+ - `https://example.org/media`, `https://example.org/media/` -> `https/example.org/media/index.htm`
804
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `https/example.org/view/index?one=1&two=2&three=3.htm`
805
+ - `https://königsgäßchen.example.org/index.html` -> `https/königsgäßchen.example.org/index.html`
806
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `https/ジャジェメント.ですの.example.org/испытание/is/index.htm`
807
+ - `shupnq_n` : `%(scheme)s/%(hostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_nquery|abbrev 120)s.%(num)d%(filepath_ext)s`
808
+ - `https://example.org`, `https://example.org/` -> `https/example.org/index.0.htm`
809
+ - `https://example.org/index.html` -> `https/example.org/index.0.html`
810
+ - `https://example.org/media`, `https://example.org/media/` -> `https/example.org/media/index.0.htm`
811
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `https/example.org/view/index?one=1&two=2&three=3.0.htm`
812
+ - `https://königsgäßchen.example.org/index.html` -> `https/königsgäßchen.example.org/index.0.html`
813
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `https/ジャジェメント.ですの.example.org/испытание/is/index.0.htm`
814
+ - `shupnq_msn` : `%(scheme)s/%(hostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_nquery|abbrev 100)s.%(method)s_%(status)s_%(num)d%(filepath_ext)s`
815
+ - `https://example.org`, `https://example.org/` -> `https/example.org/index.GET_C200C_0.htm`
816
+ - `https://example.org/index.html` -> `https/example.org/index.GET_C200C_0.html`
817
+ - `https://example.org/media`, `https://example.org/media/` -> `https/example.org/media/index.GET_C200C_0.htm`
818
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `https/example.org/view/index?one=1&two=2&three=3.GET_C200C_0.htm`
819
+ - `https://königsgäßchen.example.org/index.html` -> `https/königsgäßchen.example.org/index.GET_C200C_0.html`
820
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `https/ジャジェメント.ですの.example.org/испытание/is/index.GET_C200C_0.htm`
821
+ - `shupnq_mhs` : `%(scheme)s/%(hostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_nquery|abbrev 120)s.%(method)s_%(net_url|to_ascii|sha256|take_prefix 4)s_%(status)s%(filepath_ext)s`
822
+ - `https://example.org` -> `https/example.org/index.GET_50d7_C200C.htm`
823
+ - `https://example.org/` -> `https/example.org/index.GET_8198_C200C.htm`
824
+ - `https://example.org/index.html` -> `https/example.org/index.GET_f0dc_C200C.html`
825
+ - `https://example.org/media` -> `https/example.org/media/index.GET_086d_C200C.htm`
826
+ - `https://example.org/media/` -> `https/example.org/media/index.GET_3fbb_C200C.htm`
827
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `https/example.org/view/index?one=1&two=2&three=3.GET_5658_C200C.htm`
828
+ - `https://königsgäßchen.example.org/index.html` -> `https/königsgäßchen.example.org/index.GET_4f11_C200C.html`
829
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `https/ジャジェメント.ですの.example.org/испытание/is/index.GET_c4ae_C200C.htm`
830
+ - `shupnq_mhsn` : `%(scheme)s/%(hostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_nquery|abbrev 100)s.%(method)s_%(net_url|to_ascii|sha256|take_prefix 4)s_%(status)s_%(num)d%(filepath_ext)s`
831
+ - `https://example.org` -> `https/example.org/index.GET_50d7_C200C_0.htm`
832
+ - `https://example.org/` -> `https/example.org/index.GET_8198_C200C_0.htm`
833
+ - `https://example.org/index.html` -> `https/example.org/index.GET_f0dc_C200C_0.html`
834
+ - `https://example.org/media` -> `https/example.org/media/index.GET_086d_C200C_0.htm`
835
+ - `https://example.org/media/` -> `https/example.org/media/index.GET_3fbb_C200C_0.htm`
836
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `https/example.org/view/index?one=1&two=2&three=3.GET_5658_C200C_0.htm`
837
+ - `https://königsgäßchen.example.org/index.html` -> `https/königsgäßchen.example.org/index.GET_4f11_C200C_0.html`
838
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `https/ジャジェメント.ですの.example.org/испытание/is/index.GET_c4ae_C200C_0.htm`
839
+ - `srhupq` : `%(scheme)s/%(rhostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_query|abbrev 120)s%(filepath_ext)s`
840
+ - `https://example.org`, `https://example.org/` -> `https/org.example/index.htm`
841
+ - `https://example.org/index.html` -> `https/org.example/index.html`
842
+ - `https://example.org/media`, `https://example.org/media/` -> `https/org.example/media/index.htm`
843
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `https/org.example/view/index?one=1&two=2&three&three=3.htm`
844
+ - `https://königsgäßchen.example.org/index.html` -> `https/org.example.königsgäßchen/index.html`
845
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `https/org.example.ですの.ジャジェメント/испытание/is/index.htm`
846
+ - `srhupq_n` : `%(scheme)s/%(rhostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_query|abbrev 120)s.%(num)d%(filepath_ext)s`
847
+ - `https://example.org`, `https://example.org/` -> `https/org.example/index.0.htm`
848
+ - `https://example.org/index.html` -> `https/org.example/index.0.html`
849
+ - `https://example.org/media`, `https://example.org/media/` -> `https/org.example/media/index.0.htm`
850
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `https/org.example/view/index?one=1&two=2&three&three=3.0.htm`
851
+ - `https://königsgäßchen.example.org/index.html` -> `https/org.example.königsgäßchen/index.0.html`
852
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `https/org.example.ですの.ジャジェメント/испытание/is/index.0.htm`
853
+ - `srhupq_msn` : `%(scheme)s/%(rhostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_query|abbrev 100)s.%(method)s_%(status)s_%(num)d%(filepath_ext)s`
854
+ - `https://example.org`, `https://example.org/` -> `https/org.example/index.GET_C200C_0.htm`
855
+ - `https://example.org/index.html` -> `https/org.example/index.GET_C200C_0.html`
856
+ - `https://example.org/media`, `https://example.org/media/` -> `https/org.example/media/index.GET_C200C_0.htm`
857
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `https/org.example/view/index?one=1&two=2&three&three=3.GET_C200C_0.htm`
858
+ - `https://königsgäßchen.example.org/index.html` -> `https/org.example.königsgäßchen/index.GET_C200C_0.html`
859
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `https/org.example.ですの.ジャジェメント/испытание/is/index.GET_C200C_0.htm`
860
+ - `srhupnq` : `%(scheme)s/%(rhostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_nquery|abbrev 120)s%(filepath_ext)s`
861
+ - `https://example.org`, `https://example.org/` -> `https/org.example/index.htm`
862
+ - `https://example.org/index.html` -> `https/org.example/index.html`
863
+ - `https://example.org/media`, `https://example.org/media/` -> `https/org.example/media/index.htm`
864
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `https/org.example/view/index?one=1&two=2&three=3.htm`
865
+ - `https://königsgäßchen.example.org/index.html` -> `https/org.example.königsgäßchen/index.html`
866
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `https/org.example.ですの.ジャジェメント/испытание/is/index.htm`
867
+ - `srhupnq_n` : `%(scheme)s/%(rhostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_nquery|abbrev 120)s.%(num)d%(filepath_ext)s`
868
+ - `https://example.org`, `https://example.org/` -> `https/org.example/index.0.htm`
869
+ - `https://example.org/index.html` -> `https/org.example/index.0.html`
870
+ - `https://example.org/media`, `https://example.org/media/` -> `https/org.example/media/index.0.htm`
871
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `https/org.example/view/index?one=1&two=2&three=3.0.htm`
872
+ - `https://königsgäßchen.example.org/index.html` -> `https/org.example.königsgäßchen/index.0.html`
873
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `https/org.example.ですの.ジャジェメント/испытание/is/index.0.htm`
874
+ - `srhupnq_msn` : `%(scheme)s/%(rhostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_nquery|abbrev 100)s.%(method)s_%(status)s_%(num)d%(filepath_ext)s`
875
+ - `https://example.org`, `https://example.org/` -> `https/org.example/index.GET_C200C_0.htm`
876
+ - `https://example.org/index.html` -> `https/org.example/index.GET_C200C_0.html`
877
+ - `https://example.org/media`, `https://example.org/media/` -> `https/org.example/media/index.GET_C200C_0.htm`
878
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `https/org.example/view/index?one=1&two=2&three=3.GET_C200C_0.htm`
879
+ - `https://königsgäßchen.example.org/index.html` -> `https/org.example.königsgäßchen/index.GET_C200C_0.html`
880
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `https/org.example.ですの.ジャジェメント/испытание/is/index.GET_C200C_0.htm`
881
+ - `srhupnq_mhs` : `%(scheme)s/%(rhostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_nquery|abbrev 120)s.%(method)s_%(net_url|to_ascii|sha256|take_prefix 4)s_%(status)s%(filepath_ext)s`
882
+ - `https://example.org` -> `https/org.example/index.GET_50d7_C200C.htm`
883
+ - `https://example.org/` -> `https/org.example/index.GET_8198_C200C.htm`
884
+ - `https://example.org/index.html` -> `https/org.example/index.GET_f0dc_C200C.html`
885
+ - `https://example.org/media` -> `https/org.example/media/index.GET_086d_C200C.htm`
886
+ - `https://example.org/media/` -> `https/org.example/media/index.GET_3fbb_C200C.htm`
887
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `https/org.example/view/index?one=1&two=2&three=3.GET_5658_C200C.htm`
888
+ - `https://königsgäßchen.example.org/index.html` -> `https/org.example.königsgäßchen/index.GET_4f11_C200C.html`
889
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `https/org.example.ですの.ジャジェメント/испытание/is/index.GET_c4ae_C200C.htm`
890
+ - `srhupnq_mhsn`: `%(scheme)s/%(rhostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_nquery|abbrev 100)s.%(method)s_%(net_url|to_ascii|sha256|take_prefix 4)s_%(status)s_%(num)d%(filepath_ext)s`
891
+ - `https://example.org` -> `https/org.example/index.GET_50d7_C200C_0.htm`
892
+ - `https://example.org/` -> `https/org.example/index.GET_8198_C200C_0.htm`
893
+ - `https://example.org/index.html` -> `https/org.example/index.GET_f0dc_C200C_0.html`
894
+ - `https://example.org/media` -> `https/org.example/media/index.GET_086d_C200C_0.htm`
895
+ - `https://example.org/media/` -> `https/org.example/media/index.GET_3fbb_C200C_0.htm`
896
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `https/org.example/view/index?one=1&two=2&three=3.GET_5658_C200C_0.htm`
897
+ - `https://königsgäßchen.example.org/index.html` -> `https/org.example.königsgäßchen/index.GET_4f11_C200C_0.html`
898
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `https/org.example.ですの.ジャジェメント/испытание/is/index.GET_c4ae_C200C_0.htm`
899
+ - `url` : `%(netloc)s/%(mq_path)s%(oqm)s%(mq_query)s`
900
+ - `https://example.org`, `https://example.org/` -> `example.org/`
901
+ - `https://example.org/index.html` -> `example.org/index.html`
902
+ - `https://example.org/media`, `https://example.org/media/` -> `example.org/media`
903
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `example.org/view?one=1&two=2&three&three=3`
904
+ - `https://königsgäßchen.example.org/index.html` -> `königsgäßchen.example.org/index.html`
905
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `ジャジェメント.ですの.example.org/испытание/is`
906
+ - `url_msn` : `%(netloc)s/%(mq_path)s%(oqm)s%(mq_query)s__%(method)s_%(status)s_%(num)d`
907
+ - `https://example.org`, `https://example.org/` -> `example.org/__GET_C200C_0`
908
+ - `https://example.org/index.html` -> `example.org/index.html__GET_C200C_0`
909
+ - `https://example.org/media`, `https://example.org/media/` -> `example.org/media__GET_C200C_0`
910
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `example.org/view?one=1&two=2&three&three=3__GET_C200C_0`
911
+ - `https://königsgäßchen.example.org/index.html` -> `königsgäßchen.example.org/index.html__GET_C200C_0`
912
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `ジャジェメント.ですの.example.org/испытание/is__GET_C200C_0`
913
+ - `hupq` : `%(hostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_query|abbrev 120)s%(filepath_ext)s`
914
+ - `https://example.org`, `https://example.org/` -> `example.org/index.htm`
915
+ - `https://example.org/index.html` -> `example.org/index.html`
916
+ - `https://example.org/media`, `https://example.org/media/` -> `example.org/media/index.htm`
917
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `example.org/view/index?one=1&two=2&three&three=3.htm`
918
+ - `https://königsgäßchen.example.org/index.html` -> `königsgäßchen.example.org/index.html`
919
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `ジャジェメント.ですの.example.org/испытание/is/index.htm`
920
+ - `hupq_n` : `%(hostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_query|abbrev 120)s.%(num)d%(filepath_ext)s`
921
+ - `https://example.org`, `https://example.org/` -> `example.org/index.0.htm`
922
+ - `https://example.org/index.html` -> `example.org/index.0.html`
923
+ - `https://example.org/media`, `https://example.org/media/` -> `example.org/media/index.0.htm`
924
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `example.org/view/index?one=1&two=2&three&three=3.0.htm`
925
+ - `https://königsgäßchen.example.org/index.html` -> `königsgäßchen.example.org/index.0.html`
926
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `ジャジェメント.ですの.example.org/испытание/is/index.0.htm`
927
+ - `hupq_msn` : `%(hostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_query|abbrev 100)s.%(method)s_%(status)s_%(num)d%(filepath_ext)s`
928
+ - `https://example.org`, `https://example.org/` -> `example.org/index.GET_C200C_0.htm`
929
+ - `https://example.org/index.html` -> `example.org/index.GET_C200C_0.html`
930
+ - `https://example.org/media`, `https://example.org/media/` -> `example.org/media/index.GET_C200C_0.htm`
931
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `example.org/view/index?one=1&two=2&three&three=3.GET_C200C_0.htm`
932
+ - `https://königsgäßchen.example.org/index.html` -> `königsgäßchen.example.org/index.GET_C200C_0.html`
933
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `ジャジェメント.ですの.example.org/испытание/is/index.GET_C200C_0.htm`
934
+ - `hupnq` : `%(hostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_nquery|abbrev 120)s%(filepath_ext)s`
935
+ - `https://example.org`, `https://example.org/` -> `example.org/index.htm`
936
+ - `https://example.org/index.html` -> `example.org/index.html`
937
+ - `https://example.org/media`, `https://example.org/media/` -> `example.org/media/index.htm`
938
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `example.org/view/index?one=1&two=2&three=3.htm`
939
+ - `https://königsgäßchen.example.org/index.html` -> `königsgäßchen.example.org/index.html`
940
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `ジャジェメント.ですの.example.org/испытание/is/index.htm`
941
+ - `hupnq_n` : `%(hostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_nquery|abbrev 120)s.%(num)d%(filepath_ext)s`
942
+ - `https://example.org`, `https://example.org/` -> `example.org/index.0.htm`
943
+ - `https://example.org/index.html` -> `example.org/index.0.html`
944
+ - `https://example.org/media`, `https://example.org/media/` -> `example.org/media/index.0.htm`
945
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `example.org/view/index?one=1&two=2&three=3.0.htm`
946
+ - `https://königsgäßchen.example.org/index.html` -> `königsgäßchen.example.org/index.0.html`
947
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `ジャジェメント.ですの.example.org/испытание/is/index.0.htm`
948
+ - `hupnq_msn` : `%(hostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_nquery|abbrev 100)s.%(method)s_%(status)s_%(num)d%(filepath_ext)s`
949
+ - `https://example.org`, `https://example.org/` -> `example.org/index.GET_C200C_0.htm`
950
+ - `https://example.org/index.html` -> `example.org/index.GET_C200C_0.html`
951
+ - `https://example.org/media`, `https://example.org/media/` -> `example.org/media/index.GET_C200C_0.htm`
952
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `example.org/view/index?one=1&two=2&three=3.GET_C200C_0.htm`
953
+ - `https://königsgäßchen.example.org/index.html` -> `königsgäßchen.example.org/index.GET_C200C_0.html`
954
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `ジャジェメント.ですの.example.org/испытание/is/index.GET_C200C_0.htm`
955
+ - `hupnq_mhs` : `%(hostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_nquery|abbrev 120)s.%(method)s_%(net_url|to_ascii|sha256|take_prefix 4)s_%(status)s%(filepath_ext)s`
956
+ - `https://example.org` -> `example.org/index.GET_50d7_C200C.htm`
957
+ - `https://example.org/` -> `example.org/index.GET_8198_C200C.htm`
958
+ - `https://example.org/index.html` -> `example.org/index.GET_f0dc_C200C.html`
959
+ - `https://example.org/media` -> `example.org/media/index.GET_086d_C200C.htm`
960
+ - `https://example.org/media/` -> `example.org/media/index.GET_3fbb_C200C.htm`
961
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `example.org/view/index?one=1&two=2&three=3.GET_5658_C200C.htm`
962
+ - `https://königsgäßchen.example.org/index.html` -> `königsgäßchen.example.org/index.GET_4f11_C200C.html`
963
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `ジャジェメント.ですの.example.org/испытание/is/index.GET_c4ae_C200C.htm`
964
+ - `hupnq_mhsn` : `%(hostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_nquery|abbrev 100)s.%(method)s_%(net_url|to_ascii|sha256|take_prefix 4)s_%(status)s_%(num)d%(filepath_ext)s`
965
+ - `https://example.org` -> `example.org/index.GET_50d7_C200C_0.htm`
966
+ - `https://example.org/` -> `example.org/index.GET_8198_C200C_0.htm`
967
+ - `https://example.org/index.html` -> `example.org/index.GET_f0dc_C200C_0.html`
968
+ - `https://example.org/media` -> `example.org/media/index.GET_086d_C200C_0.htm`
969
+ - `https://example.org/media/` -> `example.org/media/index.GET_3fbb_C200C_0.htm`
970
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `example.org/view/index?one=1&two=2&three=3.GET_5658_C200C_0.htm`
971
+ - `https://königsgäßchen.example.org/index.html` -> `königsgäßchen.example.org/index.GET_4f11_C200C_0.html`
972
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `ジャジェメント.ですの.example.org/испытание/is/index.GET_c4ae_C200C_0.htm`
973
+ - `rhupq` : `%(rhostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_query|abbrev 120)s%(filepath_ext)s`
974
+ - `https://example.org`, `https://example.org/` -> `org.example/index.htm`
975
+ - `https://example.org/index.html` -> `org.example/index.html`
976
+ - `https://example.org/media`, `https://example.org/media/` -> `org.example/media/index.htm`
977
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `org.example/view/index?one=1&two=2&three&three=3.htm`
978
+ - `https://königsgäßchen.example.org/index.html` -> `org.example.königsgäßchen/index.html`
979
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `org.example.ですの.ジャジェメント/испытание/is/index.htm`
980
+ - `rhupq_n` : `%(rhostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_query|abbrev 120)s.%(num)d%(filepath_ext)s`
981
+ - `https://example.org`, `https://example.org/` -> `org.example/index.0.htm`
982
+ - `https://example.org/index.html` -> `org.example/index.0.html`
983
+ - `https://example.org/media`, `https://example.org/media/` -> `org.example/media/index.0.htm`
984
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `org.example/view/index?one=1&two=2&three&three=3.0.htm`
985
+ - `https://königsgäßchen.example.org/index.html` -> `org.example.königsgäßchen/index.0.html`
986
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `org.example.ですの.ジャジェメント/испытание/is/index.0.htm`
987
+ - `rhupq_msn` : `%(rhostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_query|abbrev 100)s.%(method)s_%(status)s_%(num)d%(filepath_ext)s`
988
+ - `https://example.org`, `https://example.org/` -> `org.example/index.GET_C200C_0.htm`
989
+ - `https://example.org/index.html` -> `org.example/index.GET_C200C_0.html`
990
+ - `https://example.org/media`, `https://example.org/media/` -> `org.example/media/index.GET_C200C_0.htm`
991
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `org.example/view/index?one=1&two=2&three&three=3.GET_C200C_0.htm`
992
+ - `https://königsgäßchen.example.org/index.html` -> `org.example.königsgäßchen/index.GET_C200C_0.html`
993
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `org.example.ですの.ジャジェメント/испытание/is/index.GET_C200C_0.htm`
994
+ - `rhupnq` : `%(rhostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_nquery|abbrev 120)s%(filepath_ext)s`
995
+ - `https://example.org`, `https://example.org/` -> `org.example/index.htm`
996
+ - `https://example.org/index.html` -> `org.example/index.html`
997
+ - `https://example.org/media`, `https://example.org/media/` -> `org.example/media/index.htm`
998
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `org.example/view/index?one=1&two=2&three=3.htm`
999
+ - `https://königsgäßchen.example.org/index.html` -> `org.example.königsgäßchen/index.html`
1000
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `org.example.ですの.ジャジェメント/испытание/is/index.htm`
1001
+ - `rhupnq_n` : `%(rhostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_nquery|abbrev 120)s.%(num)d%(filepath_ext)s`
1002
+ - `https://example.org`, `https://example.org/` -> `org.example/index.0.htm`
1003
+ - `https://example.org/index.html` -> `org.example/index.0.html`
1004
+ - `https://example.org/media`, `https://example.org/media/` -> `org.example/media/index.0.htm`
1005
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `org.example/view/index?one=1&two=2&three=3.0.htm`
1006
+ - `https://königsgäßchen.example.org/index.html` -> `org.example.königsgäßchen/index.0.html`
1007
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `org.example.ですの.ジャジェメント/испытание/is/index.0.htm`
1008
+ - `rhupnq_msn` : `%(rhostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_nquery|abbrev 100)s.%(method)s_%(status)s_%(num)d%(filepath_ext)s`
1009
+ - `https://example.org`, `https://example.org/` -> `org.example/index.GET_C200C_0.htm`
1010
+ - `https://example.org/index.html` -> `org.example/index.GET_C200C_0.html`
1011
+ - `https://example.org/media`, `https://example.org/media/` -> `org.example/media/index.GET_C200C_0.htm`
1012
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `org.example/view/index?one=1&two=2&three=3.GET_C200C_0.htm`
1013
+ - `https://königsgäßchen.example.org/index.html` -> `org.example.königsgäßchen/index.GET_C200C_0.html`
1014
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `org.example.ですの.ジャジェメント/испытание/is/index.GET_C200C_0.htm`
1015
+ - `rhupnq_mhs` : `%(rhostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_nquery|abbrev 120)s.%(method)s_%(net_url|to_ascii|sha256|take_prefix 4)s_%(status)s%(filepath_ext)s`
1016
+ - `https://example.org` -> `org.example/index.GET_50d7_C200C.htm`
1017
+ - `https://example.org/` -> `org.example/index.GET_8198_C200C.htm`
1018
+ - `https://example.org/index.html` -> `org.example/index.GET_f0dc_C200C.html`
1019
+ - `https://example.org/media` -> `org.example/media/index.GET_086d_C200C.htm`
1020
+ - `https://example.org/media/` -> `org.example/media/index.GET_3fbb_C200C.htm`
1021
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `org.example/view/index?one=1&two=2&three=3.GET_5658_C200C.htm`
1022
+ - `https://königsgäßchen.example.org/index.html` -> `org.example.königsgäßchen/index.GET_4f11_C200C.html`
1023
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `org.example.ですの.ジャジェメント/испытание/is/index.GET_c4ae_C200C.htm`
1024
+ - `rhupnq_mhsn` : `%(rhostname)s/%(filepath_parts|abbrev_each 120|pp_to_path)s%(oqm)s%(mq_nquery|abbrev 100)s.%(method)s_%(net_url|to_ascii|sha256|take_prefix 4)s_%(status)s_%(num)d%(filepath_ext)s`
1025
+ - `https://example.org` -> `org.example/index.GET_50d7_C200C_0.htm`
1026
+ - `https://example.org/` -> `org.example/index.GET_8198_C200C_0.htm`
1027
+ - `https://example.org/index.html` -> `org.example/index.GET_f0dc_C200C_0.html`
1028
+ - `https://example.org/media` -> `org.example/media/index.GET_086d_C200C_0.htm`
1029
+ - `https://example.org/media/` -> `org.example/media/index.GET_3fbb_C200C_0.htm`
1030
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `org.example/view/index?one=1&two=2&three=3.GET_5658_C200C_0.htm`
1031
+ - `https://königsgäßchen.example.org/index.html` -> `org.example.königsgäßchen/index.GET_4f11_C200C_0.html`
1032
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `org.example.ですの.ジャジェメント/испытание/is/index.GET_c4ae_C200C_0.htm`
1033
+ - `flat` : `%(hostname)s/%(filepath_parts|abbrev_each 120|pp_to_path|replace / __|abbrev 120)s%(oqm)s%(mq_nquery|abbrev 100)s%(filepath_ext)s`
1034
+ - `https://example.org`, `https://example.org/` -> `example.org/index.htm`
1035
+ - `https://example.org/index.html` -> `example.org/index.html`
1036
+ - `https://example.org/media`, `https://example.org/media/` -> `example.org/media__index.htm`
1037
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `example.org/view__index?one=1&two=2&three=3.htm`
1038
+ - `https://königsgäßchen.example.org/index.html` -> `königsgäßchen.example.org/index.html`
1039
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `ジャジェメント.ですの.example.org/испытание__is__index.htm`
1040
+ - `flat_n` : `%(hostname)s/%(filepath_parts|abbrev_each 120|pp_to_path|replace / __|abbrev 120)s%(oqm)s%(mq_nquery|abbrev 100)s.%(num)d%(filepath_ext)s`
1041
+ - `https://example.org`, `https://example.org/` -> `example.org/index.0.htm`
1042
+ - `https://example.org/index.html` -> `example.org/index.0.html`
1043
+ - `https://example.org/media`, `https://example.org/media/` -> `example.org/media__index.0.htm`
1044
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `example.org/view__index?one=1&two=2&three=3.0.htm`
1045
+ - `https://königsgäßchen.example.org/index.html` -> `königsgäßchen.example.org/index.0.html`
1046
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `ジャジェメント.ですの.example.org/испытание__is__index.0.htm`
1047
+ - `flat_ms` : `%(hostname)s/%(filepath_parts|abbrev_each 120|pp_to_path|replace / __|abbrev 120)s%(oqm)s%(mq_nquery|abbrev 100)s.%(method)s_%(status)s%(filepath_ext)s`
1048
+ - `https://example.org`, `https://example.org/` -> `example.org/index.GET_C200C.htm`
1049
+ - `https://example.org/index.html` -> `example.org/index.GET_C200C.html`
1050
+ - `https://example.org/media`, `https://example.org/media/` -> `example.org/media__index.GET_C200C.htm`
1051
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `example.org/view__index?one=1&two=2&three=3.GET_C200C.htm`
1052
+ - `https://königsgäßchen.example.org/index.html` -> `königsgäßchen.example.org/index.GET_C200C.html`
1053
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `ジャジェメント.ですの.example.org/испытание__is__index.GET_C200C.htm`
1054
+ - `flat_msn` : `%(hostname)s/%(filepath_parts|abbrev_each 120|pp_to_path|replace / __|abbrev 120)s%(oqm)s%(mq_nquery|abbrev 100)s.%(method)s_%(status)s_%(num)d%(filepath_ext)s`
1055
+ - `https://example.org`, `https://example.org/` -> `example.org/index.GET_C200C_0.htm`
1056
+ - `https://example.org/index.html` -> `example.org/index.GET_C200C_0.html`
1057
+ - `https://example.org/media`, `https://example.org/media/` -> `example.org/media__index.GET_C200C_0.htm`
1058
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `example.org/view__index?one=1&two=2&three=3.GET_C200C_0.htm`
1059
+ - `https://königsgäßchen.example.org/index.html` -> `königsgäßchen.example.org/index.GET_C200C_0.html`
1060
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `ジャジェメント.ですの.example.org/испытание__is__index.GET_C200C_0.htm`
1061
+ - `flat_mhs` : `%(hostname)s/%(filepath_parts|abbrev_each 120|pp_to_path|replace / __|abbrev 120)s%(oqm)s%(mq_nquery|abbrev 100)s.%(method)s_%(net_url|to_ascii|sha256|take_prefix 4)s_%(status)s%(filepath_ext)s`
1062
+ - `https://example.org` -> `example.org/index.GET_50d7_C200C.htm`
1063
+ - `https://example.org/` -> `example.org/index.GET_8198_C200C.htm`
1064
+ - `https://example.org/index.html` -> `example.org/index.GET_f0dc_C200C.html`
1065
+ - `https://example.org/media` -> `example.org/media__index.GET_086d_C200C.htm`
1066
+ - `https://example.org/media/` -> `example.org/media__index.GET_3fbb_C200C.htm`
1067
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `example.org/view__index?one=1&two=2&three=3.GET_5658_C200C.htm`
1068
+ - `https://königsgäßchen.example.org/index.html` -> `königsgäßchen.example.org/index.GET_4f11_C200C.html`
1069
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `ジャジェメント.ですの.example.org/испытание__is__index.GET_c4ae_C200C.htm`
1070
+ - `flat_mhsn` : `%(hostname)s/%(filepath_parts|abbrev_each 120|pp_to_path|replace / __|abbrev 120)s%(oqm)s%(mq_nquery|abbrev 100)s.%(method)s_%(net_url|to_ascii|sha256|take_prefix 4)s_%(status)s_%(num)d%(filepath_ext)s`
1071
+ - `https://example.org` -> `example.org/index.GET_50d7_C200C_0.htm`
1072
+ - `https://example.org/` -> `example.org/index.GET_8198_C200C_0.htm`
1073
+ - `https://example.org/index.html` -> `example.org/index.GET_f0dc_C200C_0.html`
1074
+ - `https://example.org/media` -> `example.org/media__index.GET_086d_C200C_0.htm`
1075
+ - `https://example.org/media/` -> `example.org/media__index.GET_3fbb_C200C_0.htm`
1076
+ - `https://example.org/view?one=1&two=2&three=&three=3#fragment` -> `example.org/view__index?one=1&two=2&three=3.GET_5658_C200C_0.htm`
1077
+ - `https://königsgäßchen.example.org/index.html` -> `königsgäßchen.example.org/index.GET_4f11_C200C_0.html`
1078
+ - `https://ジャジェメント.ですの.example.org/испытание/is/`, `https://xn--hck7aa9d8fj9i.xn--88j1aw.example.org/%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5/is/` -> `ジャジェメント.ですの.example.org/испытание__is__index.GET_c4ae_C200C_0.htm`
1079
+ - available substitutions:
1080
+ - all expressions of `hoardy-web get --expr` (which see);
1081
+ - `num`: number of times the resulting output path was encountered before; adding this parameter to your `--output` format will ensure all generated file names will be unique
1082
+
1083
+ - new `--output`s printing:
1084
+ - `--no-print`
1085
+ : don't print anything; default
1086
+ - `-l, --lf-terminated`
1087
+ : print absolute paths of newly produced or replaced files terminated with `\n` (LF) newline characters
1088
+ - `-z, --zero-terminated`
1089
+ : print absolute paths of newly produced or replaced files terminated with `\0` (NUL) bytes
1090
+
1091
+ - updates to `--output`s:
1092
+ - `--no-overwrites`
1093
+ : disallow overwrites and replacements of any existing `--output` files under `DESTINATION`, i.e. only ever create new files under `DESTINATION`, producing errors instead of attempting any other updates; default;
1094
+ `--output` targets that are broken symlinks will be considered to be non-existent and will be replaced;
1095
+ when the operation's source is binary-eqivalent to the `--output` target, the operation will be permitted, but the disk write will be reduced to a noop, i.e. the results will be deduplicated;
1096
+ the `dirname` of a source file and the `--to` target directories can be the same, in that case the source file will be renamed to use new `--output` name, though renames that attempt to swap source file names will still fail
1097
+ - `--latest`
1098
+ : replace files under `DESTINATION` with their latest version;
1099
+ this is only allowed in combination with `--symlink` at the moment;
1100
+ for each source `PATH` file, the destination `--output` file will be replaced with a symlink to the source if and only if `stime_ms` of the source reqres is newer than `stime_ms` of the reqres stored at the destination file
1101
+
1102
+ - caching, deferring, and batching:
1103
+ - `--seen-number INT`
1104
+ : track at most this many distinct generated `--output` values; default: `16384`;
1105
+ making this larger improves disk performance at the cost of increased memory consumption;
1106
+ setting it to zero will force force `hoardy-web` to constantly re-check existence of `--output` files and force `hoardy-web` to execute all IO actions immediately, disregarding `--defer-number` setting
1107
+ - `--cache-number INT`
1108
+ : cache `stat(2)` information about this many files in memory; default: `8192`;
1109
+ making this larger improves performance at the cost of increased memory consumption;
1110
+ setting this to a too small number will likely force `hoardy-web` into repeatedly performing lots of `stat(2)` system calls on the same files;
1111
+ setting this to a value smaller than `--defer-number` will not improve memory consumption very much since deferred IO actions also cache information about their own files
1112
+ - `--defer-number INT`
1113
+ : defer at most this many IO actions; default: `1024`;
1114
+ making this larger improves performance at the cost of increased memory consumption;
1115
+ setting it to zero will force all IO actions to be applied immediately
1116
+ - `--batch-number INT`
1117
+ : queue at most this many deferred IO actions to be applied together in a batch; this queue will only be used if all other resource constraints are met; default: 128
1118
+ - `--max-memory INT`
1119
+ : the caches, the deferred actions queue, and the batch queue, all taken together, must not take more than this much memory in MiB; default: `1024`;
1120
+ making this larger improves performance;
1121
+ the actual maximum whole-program memory consumption is `O(<size of the largest reqres> + <--seen-number> + <sum of lengths of the last --seen-number generated --output paths> + <--cache-number> + <--defer-number> + <--batch-number> + <--max-memory>)`
1122
+ - `--lazy`
1123
+ : sets all of the above options to positive infinity;
1124
+ most useful when doing `hoardy-web organize --symlink --latest --output flat` or similar, where the number of distinct generated `--output` values and the amount of other data `hoardy-web` needs to keep in memory is small, in which case it will force `hoardy-web` to compute the desired file system state first and then perform all disk writes in a single batch
1125
+
1126
+ - file system path ordering:
1127
+ - `--paths-given-order`
1128
+ : `argv` and `--stdin0` `PATH`s are processed in the order they are given; default when `--keep`
1129
+ - `--paths-sorted`
1130
+ : `argv` and `--stdin0` `PATH`s are processed in lexicographic order
1131
+ - `--paths-reversed`
1132
+ : `argv` and `--stdin0` `PATH`s are processed in reverse lexicographic order; default when `--latest`
1133
+ - `--walk-fs-order`
1134
+ : recursive file system walk is done in the order `readdir(2)` gives results
1135
+ - `--walk-sorted`
1136
+ : recursive file system walk is done in lexicographic order; default when `--keep`
1137
+ - `--walk-reversed`
1138
+ : recursive file system walk is done in reverse lexicographic order; default when `--latest`
1139
+
1140
+ ### hoardy-web import
1141
+
1142
+ Use specified parser to parse data in each `INPUT` `PATH` into (a sequence of) reqres and then generate and place their WRR-dumps into separate WRR files under `DESTINATION` with paths derived from their metadata.
1143
+ In short, this is `hoardy-web organize --copy` for `INPUT` files that use different files formats.
1144
+
1145
+ - file formats:
1146
+ - `{bundle,mitmproxy}`
1147
+ - `bundle`
1148
+ : convert WRR-bundles into separate WRR files
1149
+ - `mitmproxy`
1150
+ : convert `mitmproxy` stream dumps into WRR files
1151
+
1152
+ ### hoardy-web import bundle
1153
+
1154
+ Parse each `INPUT` `PATH` as a WRR-bundle (an optionally compressed sequence of WRR-dumps) and then generate and place their WRR-dumps into separate WRR files under `DESTINATION` with paths derived from their metadata.
1155
+
1156
+ - positional arguments:
1157
+ - `PATH`
1158
+ : inputs, can be a mix of files and directories (which will be traversed recursively)
1159
+
1160
+ - options:
1161
+ - `--dry-run`
1162
+ : perform a trial run without actually performing any changes
1163
+ - `-q, --quiet`
1164
+ : don't log computed updates to stderr
1165
+ - `--stdin0`
1166
+ : read zero-terminated `PATH`s from stdin, these will be processed after `PATH`s specified as command-line arguments
1167
+
1168
+ - error handling:
1169
+ - `--errors {fail,skip,ignore}`
1170
+ : when an error occurs:
1171
+ - `fail`: report failure and stop the execution; default
1172
+ - `skip`: report failure but skip the reqres that produced it from the output and continue
1173
+ - `ignore`: `skip`, but don't report the failure
1174
+
1175
+ - filters; both can be specified at the same time, both can be specified multiple times, both use the same expression format as `hoardy-web get --expr` (which see), the resulting logical expression that will checked is `(O1 or O2 or ... or (A1 and A2 and ...))`, where `O1`, `O2`, ... are the arguments to `--or`s and `A1`, `A2`, ... are the arguments to `--and`s:
1176
+ - `--or EXPR`
1177
+ : only import reqres which match any of these expressions
1178
+ - `--and EXPR`
1179
+ : only import reqres which match all of these expressions
1180
+
1181
+ - file outputs:
1182
+ - `-t DESTINATION, --to DESTINATION`
1183
+ : destination directory
1184
+ - `-o FORMAT, --output FORMAT`
1185
+ : format describing generated output paths, an alias name or "format:" followed by a custom pythonic %-substitution string; same expression format as `hoardy-web organize --output` (which see); default: default
1186
+
1187
+ - new `--output`s printing:
1188
+ - `--no-print`
1189
+ : don't print anything; default
1190
+ - `-l, --lf-terminated`
1191
+ : print absolute paths of newly produced or replaced files terminated with `\n` (LF) newline characters
1192
+ - `-z, --zero-terminated`
1193
+ : print absolute paths of newly produced or replaced files terminated with `\0` (NUL) bytes
1194
+
1195
+ - updates to `--output`s:
1196
+ - `--no-overwrites`
1197
+ : disallow overwrites and replacements of any existing `--output` files under `DESTINATION`, i.e. only ever create new files under `DESTINATION`, producing errors instead of attempting any other updates; default
1198
+ - `--overwrite-dangerously`
1199
+ : permit overwriting of old `--output` files under `DESTINATION`;
1200
+ DANGEROUS! not recommended, importing to a new `DESTINATION` with the default `--no-overwrites` and then `rsync`ing some of the files over to the old `DESTINATION` is a safer way to do this
1201
+
1202
+ - caching, deferring, and batching:
1203
+ - `--seen-number INT`
1204
+ : track at most this many distinct generated `--output` values; default: `16384`;
1205
+ making this larger improves disk performance at the cost of increased memory consumption;
1206
+ setting it to zero will force force `hoardy-web` to constantly re-check existence of `--output` files and force `hoardy-web` to execute all IO actions immediately, disregarding `--defer-number` setting
1207
+ - `--cache-number INT`
1208
+ : cache `stat(2)` information about this many files in memory; default: `8192`;
1209
+ making this larger improves performance at the cost of increased memory consumption;
1210
+ setting this to a too small number will likely force `hoardy-web` into repeatedly performing lots of `stat(2)` system calls on the same files;
1211
+ setting this to a value smaller than `--defer-number` will not improve memory consumption very much since deferred IO actions also cache information about their own files
1212
+ - `--defer-number INT`
1213
+ : defer at most this many IO actions; default: `0`;
1214
+ making this larger improves performance at the cost of increased memory consumption;
1215
+ setting it to zero will force all IO actions to be applied immediately
1216
+ - `--batch-number INT`
1217
+ : queue at most this many deferred IO actions to be applied together in a batch; this queue will only be used if all other resource constraints are met; default: 1024
1218
+ - `--max-memory INT`
1219
+ : the caches, the deferred actions queue, and the batch queue, all taken together, must not take more than this much memory in MiB; default: `1024`;
1220
+ making this larger improves performance;
1221
+ the actual maximum whole-program memory consumption is `O(<size of the largest reqres> + <--seen-number> + <sum of lengths of the last --seen-number generated --output paths> + <--cache-number> + <--defer-number> + <--batch-number> + <--max-memory>)`
1222
+ - `--lazy`
1223
+ : sets all of the above options to positive infinity;
1224
+ most useful when doing `hoardy-web organize --symlink --latest --output flat` or similar, where the number of distinct generated `--output` values and the amount of other data `hoardy-web` needs to keep in memory is small, in which case it will force `hoardy-web` to compute the desired file system state first and then perform all disk writes in a single batch
1225
+
1226
+ - file system path ordering:
1227
+ - `--paths-given-order`
1228
+ : `argv` and `--stdin0` `PATH`s are processed in the order they are given; default
1229
+ - `--paths-sorted`
1230
+ : `argv` and `--stdin0` `PATH`s are processed in lexicographic order
1231
+ - `--paths-reversed`
1232
+ : `argv` and `--stdin0` `PATH`s are processed in reverse lexicographic order
1233
+ - `--walk-fs-order`
1234
+ : recursive file system walk is done in the order `readdir(2)` gives results
1235
+ - `--walk-sorted`
1236
+ : recursive file system walk is done in lexicographic order; default
1237
+ - `--walk-reversed`
1238
+ : recursive file system walk is done in reverse lexicographic order
1239
+
1240
+ ### hoardy-web import mitmproxy
1241
+
1242
+ Parse each `INPUT` `PATH` as `mitmproxy` stream dump (by using `mitmproxy`'s own parser) into a sequence of reqres and then generate and place their WRR-dumps into separate WRR files under `DESTINATION` with paths derived from their metadata.
1243
+
1244
+ - positional arguments:
1245
+ - `PATH`
1246
+ : inputs, can be a mix of files and directories (which will be traversed recursively)
1247
+
1248
+ - options:
1249
+ - `--dry-run`
1250
+ : perform a trial run without actually performing any changes
1251
+ - `-q, --quiet`
1252
+ : don't log computed updates to stderr
1253
+ - `--stdin0`
1254
+ : read zero-terminated `PATH`s from stdin, these will be processed after `PATH`s specified as command-line arguments
1255
+
1256
+ - error handling:
1257
+ - `--errors {fail,skip,ignore}`
1258
+ : when an error occurs:
1259
+ - `fail`: report failure and stop the execution; default
1260
+ - `skip`: report failure but skip the reqres that produced it from the output and continue
1261
+ - `ignore`: `skip`, but don't report the failure
1262
+
1263
+ - filters; both can be specified at the same time, both can be specified multiple times, both use the same expression format as `hoardy-web get --expr` (which see), the resulting logical expression that will checked is `(O1 or O2 or ... or (A1 and A2 and ...))`, where `O1`, `O2`, ... are the arguments to `--or`s and `A1`, `A2`, ... are the arguments to `--and`s:
1264
+ - `--or EXPR`
1265
+ : only import reqres which match any of these expressions
1266
+ - `--and EXPR`
1267
+ : only import reqres which match all of these expressions
1268
+
1269
+ - file outputs:
1270
+ - `-t DESTINATION, --to DESTINATION`
1271
+ : destination directory
1272
+ - `-o FORMAT, --output FORMAT`
1273
+ : format describing generated output paths, an alias name or "format:" followed by a custom pythonic %-substitution string; same expression format as `hoardy-web organize --output` (which see); default: default
1274
+
1275
+ - new `--output`s printing:
1276
+ - `--no-print`
1277
+ : don't print anything; default
1278
+ - `-l, --lf-terminated`
1279
+ : print absolute paths of newly produced or replaced files terminated with `\n` (LF) newline characters
1280
+ - `-z, --zero-terminated`
1281
+ : print absolute paths of newly produced or replaced files terminated with `\0` (NUL) bytes
1282
+
1283
+ - updates to `--output`s:
1284
+ - `--no-overwrites`
1285
+ : disallow overwrites and replacements of any existing `--output` files under `DESTINATION`, i.e. only ever create new files under `DESTINATION`, producing errors instead of attempting any other updates; default
1286
+ - `--overwrite-dangerously`
1287
+ : permit overwriting of old `--output` files under `DESTINATION`;
1288
+ DANGEROUS! not recommended, importing to a new `DESTINATION` with the default `--no-overwrites` and then `rsync`ing some of the files over to the old `DESTINATION` is a safer way to do this
1289
+
1290
+ - caching, deferring, and batching:
1291
+ - `--seen-number INT`
1292
+ : track at most this many distinct generated `--output` values; default: `16384`;
1293
+ making this larger improves disk performance at the cost of increased memory consumption;
1294
+ setting it to zero will force force `hoardy-web` to constantly re-check existence of `--output` files and force `hoardy-web` to execute all IO actions immediately, disregarding `--defer-number` setting
1295
+ - `--cache-number INT`
1296
+ : cache `stat(2)` information about this many files in memory; default: `8192`;
1297
+ making this larger improves performance at the cost of increased memory consumption;
1298
+ setting this to a too small number will likely force `hoardy-web` into repeatedly performing lots of `stat(2)` system calls on the same files;
1299
+ setting this to a value smaller than `--defer-number` will not improve memory consumption very much since deferred IO actions also cache information about their own files
1300
+ - `--defer-number INT`
1301
+ : defer at most this many IO actions; default: `0`;
1302
+ making this larger improves performance at the cost of increased memory consumption;
1303
+ setting it to zero will force all IO actions to be applied immediately
1304
+ - `--batch-number INT`
1305
+ : queue at most this many deferred IO actions to be applied together in a batch; this queue will only be used if all other resource constraints are met; default: 1024
1306
+ - `--max-memory INT`
1307
+ : the caches, the deferred actions queue, and the batch queue, all taken together, must not take more than this much memory in MiB; default: `1024`;
1308
+ making this larger improves performance;
1309
+ the actual maximum whole-program memory consumption is `O(<size of the largest reqres> + <--seen-number> + <sum of lengths of the last --seen-number generated --output paths> + <--cache-number> + <--defer-number> + <--batch-number> + <--max-memory>)`
1310
+ - `--lazy`
1311
+ : sets all of the above options to positive infinity;
1312
+ most useful when doing `hoardy-web organize --symlink --latest --output flat` or similar, where the number of distinct generated `--output` values and the amount of other data `hoardy-web` needs to keep in memory is small, in which case it will force `hoardy-web` to compute the desired file system state first and then perform all disk writes in a single batch
1313
+
1314
+ - file system path ordering:
1315
+ - `--paths-given-order`
1316
+ : `argv` and `--stdin0` `PATH`s are processed in the order they are given; default
1317
+ - `--paths-sorted`
1318
+ : `argv` and `--stdin0` `PATH`s are processed in lexicographic order
1319
+ - `--paths-reversed`
1320
+ : `argv` and `--stdin0` `PATH`s are processed in reverse lexicographic order
1321
+ - `--walk-fs-order`
1322
+ : recursive file system walk is done in the order `readdir(2)` gives results
1323
+ - `--walk-sorted`
1324
+ : recursive file system walk is done in lexicographic order; default
1325
+ - `--walk-reversed`
1326
+ : recursive file system walk is done in reverse lexicographic order
1327
+
1328
+ ### hoardy-web export
1329
+
1330
+ Parse given WRR files into their respective reqres, convert to another file format, and then dump the result under `DESTINATION` with the new path derived from each reqres' metadata.
1331
+
1332
+ - file formats:
1333
+ - `{mirror}`
1334
+ - `mirror`
1335
+ : convert given WRR files into a local website mirror stored in interlinked plain files
1336
+
1337
+ ### hoardy-web export mirror
1338
+
1339
+ Parse given WRR files, filter out those that have no responses, transform and then dump their response bodies into separate files under `DESTINATION` with the new path derived from each reqres' metadata.
1340
+ In short, this is a combination of `hoardy-web organize --copy` followed by in-place `hoardy-web get`.
1341
+ In other words, this generates static offline website mirrors, producing results similar to those of `wget -mpk`.
1342
+
1343
+ - positional arguments:
1344
+ - `PATH`
1345
+ : inputs, can be a mix of files and directories (which will be traversed recursively)
1346
+
1347
+ - options:
1348
+ - `--dry-run`
1349
+ : perform a trial run without actually performing any changes
1350
+ - `-q, --quiet`
1351
+ : don't log computed updates to stderr
1352
+ - `--stdin0`
1353
+ : read zero-terminated `PATH`s from stdin, these will be processed after `PATH`s specified as command-line arguments
1354
+
1355
+ - error handling:
1356
+ - `--errors {fail,skip,ignore}`
1357
+ : when an error occurs:
1358
+ - `fail`: report failure and stop the execution; default
1359
+ - `skip`: report failure but skip the reqres that produced it from the output and continue
1360
+ - `ignore`: `skip`, but don't report the failure
1361
+
1362
+ - filters; both can be specified at the same time, both can be specified multiple times, both use the same expression format as `hoardy-web get --expr` (which see), the resulting logical expression that will checked is `(O1 or O2 or ... or (A1 and A2 and ...))`, where `O1`, `O2`, ... are the arguments to `--or`s and `A1`, `A2`, ... are the arguments to `--and`s:
1363
+ - `--or EXPR`
1364
+ : only export reqres which match any of these expressions
1365
+ - `--and EXPR`
1366
+ : only export reqres which match all of these expressions
1367
+
1368
+ - expression evaluation:
1369
+ - `-e EXPR, --expr EXPR`
1370
+ : an expression to compute, same expression format and semantics as `hoardy-web get --expr` (which see); can be specified multiple times; default: `response.body|eb|scrub response +all_refs,-actions`, which will export safe scrubbed versions of all files
1371
+
1372
+ - URL remapping; used by `scrub` atom of `--expr`:
1373
+ - `--remap-id`
1374
+ : remap all URLs with an identity function; i.e. don't remap anything
1375
+ - `--remap-void`
1376
+ : remap all jump-link and action URLs to `javascript:void(0)` and all resource URLs into empty `data:` URLs; resulting web pages will be self-contained
1377
+ - `--remap-open, -k, --convert-links`
1378
+ : point all URLs present in input `PATH`s and reachable from `--root`s in no more that `--depth` steps to their corresponding output paths, remap all other URLs like `--remap-id` does; this is similar to `wget (-k|--convert-links)`
1379
+ - `--remap-closed`
1380
+ : remap all reachable URLs like `--remap-open` does, remap all other URLs like `--remap-void` does; `export`ed `mirror`s will be self-contained
1381
+ - `--remap-all`
1382
+ : remap all reachable URLs like `--remap-open` does, remap other URLs as if for each missing URL a trivial `GET <URL> -> 200 OK` reqres is present among input `PATH`s; this will produce broken links if the `--output` format depends on anything but the URL itself, but for a simple `--output` (like the default `hupq`) this will remap missing URLs to `--output` paths that they would occupy if they were present; this allows `hoardy-web export` to be used incrementally; `export`ed `mirror`s will be self-contained; default
1383
+
1384
+ - exporting:
1385
+ - `--not-separated`
1386
+ : export values without separating them with anything, just concatenate them
1387
+ - `--lf-separated`
1388
+ : export values separated with `\n` (LF) newline characters; default
1389
+ - `--zero-separated`
1390
+ : export values separated with `\0` (NUL) bytes
1391
+
1392
+ - file outputs:
1393
+ - `-t DESTINATION, --to DESTINATION`
1394
+ : destination directory
1395
+ - `-o FORMAT, --output FORMAT`
1396
+ : format describing generated output paths, an alias name or "format:" followed by a custom pythonic %-substitution string; same expression format as `hoardy-web organize --output` (which see); default: hupq
1397
+
1398
+ - new `--output`s printing:
1399
+ - `--no-print`
1400
+ : don't print anything; default
1401
+ - `-l, --lf-terminated`
1402
+ : print absolute paths of newly produced or replaced files terminated with `\n` (LF) newline characters
1403
+ - `-z, --zero-terminated`
1404
+ : print absolute paths of newly produced or replaced files terminated with `\0` (NUL) bytes
1405
+
1406
+ - updates to `--output`s:
1407
+ - `--no-overwrites`
1408
+ : disallow overwrites and replacements of any existing `--output` files under `DESTINATION`, i.e. only ever create new files under `DESTINATION`, producing errors instead of attempting any other updates; default;
1409
+ repeated exports of the same export targets with the same parameters (which, therefore, will produce the same `--output` data) are allowed and will be reduced to noops;
1410
+ however, trying to overwrite existing `--output` files under `DESTINATION` with any new data will produce errors;
1411
+ this allows reusing the `DESTINATION` between unrelated exports and between exports that produce the same data on disk in their common parts
1412
+ - `--skip-existing, --partial`
1413
+ : skip exporting of targets which have a corresponding `--output` file under `DESTINATION`;
1414
+ using this together with `--depth` is likely to produce a partially broken result, since skipping an export target will also skip all the documents it references;
1415
+ on the other hand, this is quite useful when growing a partial mirror generated with `--remap-all`
1416
+ - `--overwrite-dangerously`
1417
+ : export all targets while permitting overwriting of old `--output` files under `DESTINATION`;
1418
+ DANGEROUS! not recommended, exporting to a new `DESTINATION` with the default `--no-overwrites` and then `rsync`ing some of the files over to the old `DESTINATION` is a safer way to do this
1419
+
1420
+ - export targets:
1421
+ - `-r URL, --root URL`
1422
+ : recursion root; a URL which will be used as a root for recursive export; can be specified multiple times; if none are specified, then all (`net_url`) URLs available from input `PATH`s will be treated as roots
1423
+ - `-d DEPTH, --depth DEPTH`
1424
+ : maximum recursion depth level; the default is `0`, which means "`--root` documents and their resources only"; setting this to `1` will also export one level of documents referenced via jump and action links, if those are being remapped to local files with `--remap-*`; higher values will mean even more recursion
1425
+
1426
+ - file system path ordering:
1427
+ - `--paths-given-order`
1428
+ : `argv` and `--stdin0` `PATH`s are processed in the order they are given; default
1429
+ - `--paths-sorted`
1430
+ : `argv` and `--stdin0` `PATH`s are processed in lexicographic order
1431
+ - `--paths-reversed`
1432
+ : `argv` and `--stdin0` `PATH`s are processed in reverse lexicographic order
1433
+ - `--walk-fs-order`
1434
+ : recursive file system walk is done in the order `readdir(2)` gives results
1435
+ - `--walk-sorted`
1436
+ : recursive file system walk is done in lexicographic order; default
1437
+ - `--walk-reversed`
1438
+ : recursive file system walk is done in reverse lexicographic order
1439
+
1440
+ ## Examples
1441
+
1442
+ - Pretty-print all reqres in `../simple_server/pwebarc-dump` using an abridged (for ease of reading and rendering) verbose textual representation:
1443
+ ```
1444
+ hoardy-web pprint ../simple_server/pwebarc-dump
1445
+ ```
1446
+
1447
+ - Pipe raw response body from a given WRR file to stdout:
1448
+ ```
1449
+ hoardy-web get ../simple_server/pwebarc-dump/path/to/file.wrr
1450
+ ```
1451
+
1452
+ - Pipe response body scrubbed of dynamic content from a given WRR file to stdout:
1453
+ ```
1454
+ hoardy-web get -e "response.body|eb|scrub response defaults" ../simple_server/pwebarc-dump/path/to/file.wrr
1455
+ ```
1456
+
1457
+ - Get first 4 characters of a hex digest of sha256 hash computed on the URL without the fragment/hash part:
1458
+ ```
1459
+ hoardy-web get -e "net_url|to_ascii|sha256|take_prefix 4" ../simple_server/pwebarc-dump/path/to/file.wrr
1460
+ ```
1461
+
1462
+ - Pipe response body from a given WRR file to stdout, but less efficiently, by generating a temporary file and giving it to `cat`:
1463
+ ```
1464
+ hoardy-web run cat ../simple_server/pwebarc-dump/path/to/file.wrr
1465
+ ```
1466
+
1467
+ Thus `hoardy-web run` can be used to do almost anything you want, e.g.
1468
+
1469
+ ```
1470
+ hoardy-web run less ../simple_server/pwebarc-dump/path/to/file.wrr
1471
+ ```
1472
+
1473
+ ```
1474
+ hoardy-web run -- sort -R ../simple_server/pwebarc-dump/path/to/file.wrr
1475
+ ```
1476
+
1477
+ ```
1478
+ hoardy-web run -n 2 -- diff -u ../simple_server/pwebarc-dump/path/to/file-v1.wrr ../simple_server/pwebarc-dump/path/to/file-v2.wrr
1479
+ ```
1480
+
1481
+ - List paths of all WRR files from `../simple_server/pwebarc-dump` that contain only complete `200 OK` responses with bodies larger than 1K:
1482
+ ```
1483
+ hoardy-web find --and "status|~= .200C" --and "response.body|len|> 1024" ../simple_server/pwebarc-dump
1484
+ ```
1485
+
1486
+ - Rename all WRR files in `../simple_server/pwebarc-dump/default` according to their metadata using `--output default` (see the `hoardy-web organize` section for its definition, the `default` format is designed to be human-readable while causing almost no collisions, thus making `num` substitution parameter to almost always stay equal to `0`, making things nice and deterministic):
1487
+ ```
1488
+ hoardy-web organize ../simple_server/pwebarc-dump/default
1489
+ ```
1490
+
1491
+ alternatively, just show what would be done
1492
+
1493
+ ```
1494
+ hoardy-web organize --dry-run ../simple_server/pwebarc-dump/default
1495
+ ```
1496
+
1497
+ ## Advanced examples
1498
+
1499
+ - Pretty-print all reqres in `../simple_server/pwebarc-dump` by dumping their whole structure into an abridged Pythonic Object Representation (repr):
1500
+ ```
1501
+ hoardy-web stream --expr . ../simple_server/pwebarc-dump
1502
+ ```
1503
+
1504
+ ```
1505
+ hoardy-web stream -e . ../simple_server/pwebarc-dump
1506
+ ```
1507
+
1508
+ - Pretty-print all reqres in `../simple_server/pwebarc-dump` using the unabridged verbose textual representation:
1509
+ ```
1510
+ hoardy-web pprint --unabridged ../simple_server/pwebarc-dump
1511
+ ```
1512
+
1513
+ ```
1514
+ hoardy-web pprint -u ../simple_server/pwebarc-dump
1515
+ ```
1516
+
1517
+ - Pretty-print all reqres in `../simple_server/pwebarc-dump` by dumping their whole structure into the unabridged Pythonic Object Representation (repr) format:
1518
+ ```
1519
+ hoardy-web stream --unabridged --expr . ../simple_server/pwebarc-dump
1520
+ ```
1521
+
1522
+ ```
1523
+ hoardy-web stream -ue . ../simple_server/pwebarc-dump
1524
+ ```
1525
+
1526
+ - Produce a JSON list of `[<file path>, <time it finished loading in seconds since UNIX epoch>, <URL>]` tuples (one per reqres) and pipe it into `jq` for indented and colored output:
1527
+ ```
1528
+ hoardy-web stream --format=json -ue fs_path -e finished_at -e request.url ../simple_server/pwebarc-dump | jq .
1529
+ ```
1530
+
1531
+ - Similarly, but produce a CBOR output:
1532
+ ```
1533
+ hoardy-web stream --format=cbor -ue fs_path -e finished_at -e request.url ../simple_server/pwebarc-dump | less
1534
+ ```
1535
+
1536
+ - Concatenate all response bodies of all the requests in `../simple_server/pwebarc-dump`:
1537
+ ```
1538
+ hoardy-web stream --format=raw --not-terminated -ue "response.body|es" ../simple_server/pwebarc-dump | less
1539
+ ```
1540
+
1541
+ - Print all unique visited URLs, one per line:
1542
+ ```
1543
+ hoardy-web stream --format=raw --lf-terminated -ue request.url ../simple_server/pwebarc-dump | sort | uniq
1544
+ ```
1545
+
1546
+ - Same idea, but using NUL bytes while processing, and prints two URLs per line:
1547
+ ```
1548
+ hoardy-web stream --format=raw --zero-terminated -ue request.url ../simple_server/pwebarc-dump | sort -z | uniq -z | xargs -0 -n2 echo
1549
+ ```
1550
+
1551
+ ### How to handle binary data
1552
+
1553
+ Trying to use response bodies produced by `hoardy-web stream --format=json` is likely to result garbled data as JSON can't represent raw sequences of bytes, thus binary data will have to be encoded into UNICODE using replacement characters:
1554
+
1555
+ ```
1556
+ hoardy-web stream --format=json -ue . ../simple_server/pwebarc-dump/path/to/file.wrr | jq .
1557
+ ```
1558
+
1559
+ The most generic solution to this is to use `--format=cbor` instead, which would produce a verbose CBOR representation equivalent to the one used by `--format=json` but with binary data preserved as-is:
1560
+
1561
+ ```
1562
+ hoardy-web stream --format=cbor -ue . ../simple_server/pwebarc-dump/path/to/file.wrr | less
1563
+ ```
1564
+
1565
+ Or you could just dump raw response bodies separately:
1566
+
1567
+ ```
1568
+ hoardy-web stream --format=raw -ue response.body ../simple_server/pwebarc-dump/path/to/file.wrr | less
1569
+ ```
1570
+
1571
+ ```
1572
+ hoardy-web get ../simple_server/pwebarc-dump/path/to/file.wrr | less
1573
+ ```
1574
+