Pārlūkot izejas kodu

Moved imapdomo code to separate repo

Alois Mahdal 7 gadus atpakaļ
vecāks
revīzija
505a533746

+ 1
- 0
dotfiles.config/imapdomo/host Parādīt failu

@@ -0,0 +1 @@
1
+../../external/dotfiles.config/imapdomo/host

dotfiles/imapdomo/private/README → dotfiles.config/imapdomo/private/README Parādīt failu


+ 0
- 188
dotfiles/imapdomo/common.lua Parādīt failu

@@ -1,190 +0,0 @@
1
-os = require "os"
2
-socket = require "socket"
3
-
4
-
5
-------------------------------------------------------------------------------
6
-------------------------------------------------------------------------------
7
-
8
-function shortname()
9
-    --
10
-    -- Short hostname
11
-    --
12
-    local long = socket.dns.gethostname()
13
-    return string.gmatch(long, '[^.]+')()
14
-end
15
-
16
-function file_exists(name)
17
-    --
18
-    -- True if file *name* exists
19
-    --
20
-    local f = io.open(name,"r")
21
-    if f ~= nil then
22
-        io.close(f)
23
-        return true
24
-    else
25
-        return false
26
-    end
27
-end
28
-
29
-function init_host(session)
30
-    --
31
-    -- Do host-specific init, if exists
32
-    --
33
-    local init = session.dirs.host .. "/init.lua"
34
-    if file_exists(init) then
35
-        dofile(init)
36
-        return
37
-    end
38
-end
39
-
40
-function handle(session)
41
-    --
42
-    -- Look for action handler in session dirs; do first one that exists
43
-    --
44
-    local valid = {
45
-        newmail = true,
46
-        rewind = true,
47
-        cleanup = true,
48
-        migrate = true
49
-    }
50
-    if not valid[session.action] then
51
-        error("invalid action: " .. session.action)
52
-        return nil
53
-    end
54
-    init_host(session)
55
-    for k,v in ipairs({session.dirs.host, session.dirs.default}) do
56
-        attempt = v .. "/handlers/" .. session.action .. ".lua"
57
-        if file_exists(attempt) then
58
-            dofile(attempt)
59
-            return
60
-        end
61
-    end
62
-end
63
-
64
-
65
-------------------------------------------------------------------------------
66
-------------------------------------------------------------------------------
67
-
68
-function get_queue(acct, mbox)
69
-    --
70
-    -- Get queue from *mbox* from *acct* or nil (no messages)
71
-    --
72
-    -- If mbox is not specified, "FILTER_QUEUE" is used
73
-    --
74
-    mbox = mbox or "FILTER_QUEUE"
75
-    local exist, unread, unseen, uidnext = acct[mbox]:check_status()
76
-    if exist > 0 then
77
-        return acct[mbox]:select_all()
78
-    end
79
-    return nil
80
-end
81
-
82
-function _notifirc1(subj, from, body)
83
-    --
84
-    -- notify about message using (pre-configured) notifirc
85
-    --
86
-    local fd = assert(io.popen('notifirc -c mail -f - "message preview:"', "w"))
87
-    local fmt = "> %s\n> %s\n> BODY: %s"
88
-    fd:write(fmt:format(subj, from, body))
89
-    fd:close()
90
-end
91
-
92
-function notifirc_all(seq)
93
-    --
94
-    -- Send notifications about all messages in *seq*
95
-    --
96
-    for _, mesg in ipairs(seq) do
97
-        mbox, uid = table.unpack(mesg)
98
-        subj = mbox[uid]:fetch_field('Subject')
99
-        from = mbox[uid]:fetch_field('From')
100
-        body = mbox[uid]:fetch_body()
101
-        _notifirc1(subj, from, body)
102
-    end
103
-end
104
-
105
-function _partinf_compare(a, b)
106
-    if not type(a) == type(b) then
107
-        return false
108
-    end
109
-    if type(a) == 'number' then
110
-        return a == b
111
-    elseif type(a) == 'string' then
112
-        return a:lower() == b:lower()
113
-    end
114
-end
115
-
116
-function has_part_like(query, structure)
117
-    --
118
-    -- True if structure has MIME part matching *query*
119
-    --
120
-    if structure == nil then
121
-        return false
122
-    end
123
-    for partid, partinf in pairs(structure) do
124
-        local part_answer = true
125
-        -- check all query parts
126
-        for qkey, qvalue in pairs(query) do
127
-            value = partinf[qkey]
128
-            if not _partinf_compare(value, qvalue) then
129
-                part_answer = false
130
-                break
131
-            end
132
-        end
133
-        if part_answer then
134
-            return true
135
-        end
136
-    end
137
-    return false
138
-end
139
-
140
-function save_header(mesg, name)
141
-    --
142
-    -- Append header from *mesg* to file named *name*
143
-    --
144
-    -- File will be placed under directory specified by IMAPDOMO_HEADERS
145
-    -- environment variable.
146
-    --
147
-    local dest = os.getenv("IMAPDOMO_HEADERS") .. '/' .. name
148
-    local cmd = ('cat >>"%q"'):format(dest)
149
-    mbox, uid = table.unpack(mesg)
150
-    header = mbox[uid]:fetch_header()
151
-    if pipe_to(cmd, header) == 0 then
152
-        return true
153
-    else
154
-        return false
155
-    end
156
-end
157
-
158
-function filter_header_saved(seq, name)
159
-    --
160
-    -- Save headers from sequence
161
-    --
162
-    -- Append header of each message in sequence *seq* to file names
163
-    -- *name* and return new sequence with those messages where save was
164
-    -- successful.
165
-    --
166
-    result = Set {}
167
-    for _, mesg in ipairs(seq) do
168
-        if save_header(mesg, name) then
169
-            table.insert(result, mesg)
170
-        end
171
-    end
172
-    return result
173
-end
174
-
175
-function filter_part_like(query, seq)
176
-    --
177
-    -- Run MIME part query on *seq* sequence of messages
178
-    --
179
-    result = Set {}
180
-    for _, mesg in ipairs(seq) do
181
-        mbox, uid = table.unpack(mesg)
182
-        structure = mbox[uid]:fetch_structure()
183
-        if has_part_like(query, structure) then
184
-            table.insert(result, mesg)
185
-        end
186
-    end
187
-    return result
188
-end

+ 0
- 1
dotfiles/imapdomo/host Parādīt failu

@@ -1 +0,0 @@
1
-../../external/dotfiles/imapdomo/host

+ 0
- 11
dotfiles/imapdomo/main.lua Parādīt failu

@@ -1,11 +0,0 @@
1
-
2
-dofile ".imapdomo/common.lua"
3
-
4
-handle({
5
-    action = os.getenv("IMAPDOMO_ACTION"),
6
-    dirs = {
7
-        main = os.getenv("HOME") .. "/.imapdomo",
8
-        host = os.getenv("HOME") .. "/.imapdomo/host/" .. shortname(),
9
-        defhost = os.getenv("HOME") .. "/.imapdomo/default",
10
-    }
11
-})

+ 0
- 78
dotfiles/imapdomo/utils/imapdomo Parādīt failu

@@ -1,78 +0,0 @@
1
-#!/bin/bash
2
-
3
-. "$(shellfu-get path)" || exit 3
4
-
5
-shellfu import pretty
6
-
7
-usage() {
8
-    mkusage "[options] ACTION" \
9
-        -o                                                                    \
10
-            "-c DIR      change to DIR before doing anything"                 \
11
-            "-d          turn on debugging mode"                              \
12
-       --                                                                     \
13
-       "imapdomo will try to read .imapdomo/host/HOSTNAME/init.lua and"       \
14
-       ".imapdomo/host/HOSTNAME/handlers/ACTION.lua, where HOSTNAME is your"  \
15
-       "short hostname (eg. 'foo' in 'foo.example.com')."                     \
16
-       ""                                                                     \
17
-       "four valid actions are understood; since you must write handler for"  \
18
-       "each action you want to use, the meanings below are purely a guide:"  \
19
-       ""                                                                     \
20
-       "    newmail - check for and file new mail"                            \
21
-       "    rewind  - re-add messages from FILTER_FAIL back to FILTER_QUEUE"  \
22
-       "    cleanup - delete or archive old messages"                         \
23
-       "    migrate - move mail between mailboxes"                            \
24
-       ""                                                                     \
25
-       "See imapfilter_config(5)) for guide and API reference.  Few functions"\
26
-       "are also available in .imapdomo/common.lua"
27
-}
28
-
29
-mkcmd() {
30
-    #
31
-    # Compose imapfilter command
32
-    #
33
-    echo -n "IMAPDOMO_ACTION=$Action"
34
-    echo -n "  IMAPDOMO_HEADERS=$HeaderDir"
35
-    echo -n "  IMAPFILTER_HOME=$CfgDir"
36
-    echo -n "  imapfilter"
37
-    if $Debug
38
-    then
39
-        mkdir -p "$LogDir"
40
-        echo -n "  -d $LogDir/debug.log"
41
-        echo -n "  -v"
42
-    fi
43
-    echo -n "  -c $CfgDir/main.lua"
44
-}
45
-
46
-main() {
47
-    local Action    # what to do
48
-    local Debug     # true if debugging
49
-    local cmd       # imapfilter command
50
-    local CfgDir    # config directory
51
-    local LogDir    # directory to store logs
52
-    local HeaderDir # directory to store headers by save_header()
53
-    local CdTo      # change dir to this before running imapfilter
54
-    CfgDir="$HOME/.imapdomo"
55
-    LogDir="$HOME/.local/share/imapdomo/logs"
56
-    HeaderDir="$HOME/.local/share/imapdomo/headers"
57
-    Debug=false
58
-    #shellcheck disable=SC2034
59
-    while true; do case $1 in
60
-        -c) CdTo="$2"; shift 2 || usage ;;
61
-        -d) Debug=true; PRETTY_DEBUG=true; shift ;;
62
-        -*) usage ;;
63
-        *)  break ;;
64
-    esac done
65
-    Action="$1"; shift
66
-    grep -qw "$Action" <<< "newmail|rewind|cleanup|migrate" || usage
67
-    cmd=$(mkcmd)
68
-    debug -v cmd
69
-    bash -n <<<"$cmd" || die
70
-    if test -n "$CdTo";
71
-    then
72
-        cd "$CdTo" || die
73
-    fi
74
-    mkdir -p "$HeaderDir" || die
75
-    eval "$cmd"
76
-}
77
-
78
-main "$@"

+ 0
- 734
dotfiles/imapdomo/utils/imapdomo-cron Parādīt failu

@@ -1,734 +0,0 @@
1
-#!/bin/bash
2
-#
3
-# shellfu embedded: /home/amahdal/local/mydots/dotfiles/imapdomo/utils/imapdomo
4
-# shellfu version: 0.9.0
5
-#
6
-
7
-# neuter any shellfu and shellfu-get calls
8
-shellfu() { :; }
9
-shellfu-get() { echo /dev/null; }
10
-
11
-#
12
-# begin module: d85843c5561356764375c3915e2b411b  /usr/local/share/shellfu/include-bash/exit.sh
13
-#
14
-
15
-#!/bin/bash
16
-
17
-
18
-EXIT_OK=0
19
-EXIT_NO=1
20
-EXIT_USAGE=2
21
-EXIT_ERROR=3
22
-EXIT_PANIC=4
23
-
24
-
25
-exit_ok() {
26
-    #
27
-    # Exit script with success
28
-    #
29
-    exit $EXIT_OK
30
-}
31
-
32
-
33
-exit_no() {
34
-    #
35
-    # Exit script with answer "no"
36
-    #
37
-    exit $EXIT_NO
38
-}
39
-
40
-
41
-exit_usage() {
42
-    #
43
-    # Exit script with usage error
44
-    #
45
-    exit $EXIT_USAGE
46
-}
47
-
48
-
49
-exit_error() {
50
-    #
51
-    # Exit script with generic unexpected error
52
-    #
53
-    exit $EXIT_ERROR
54
-}
55
-
56
-
57
-exit_panic() {
58
-    #
59
-    # Exit script in panic (e.g. assert failure, sure bug)
60
-    #
61
-    exit $EXIT_PANIC
62
-}
63
-
64
-#
65
-# end module: d85843c5561356764375c3915e2b411b  /usr/local/share/shellfu/include-bash/exit.sh
66
-#
67
-
68
-#
69
-# begin module: 8ee17c6681d102da92d36f71ef523a55  /usr/local/share/shellfu/include-bash/pretty.sh
70
-#
71
-
72
-#!/bin/bash
73
-
74
-shellfu import exit
75
-
76
-#
77
-# Application debug mode
78
-#
79
-PRETTY_DEBUG=${PRETTY_DEBUG:-false}
80
-
81
-#
82
-# List of module/function names to exclude from debuging
83
-#
84
-# For the sake of readability of your debug dumps, you can set this
85
-# variable to comma-separated list of module or function names that
86
-# you don't expect to get useful info from.
87
-#
88
-# If the caller has a qualified name (`modname__funcname()`, according
89
-# to Shellfu naming scheme it's possible to use just module name here
90
-# to mute all debug from that module (including internal functions).
91
-# Otherwise, full function name should be listed.
92
-#
93
-PRETTY_DEBUG_EXCLUDE=${PRETTY_DEBUG_EXCLUDE:-}
94
-
95
-#
96
-# Application verbosity mode
97
-#
98
-PRETTY_VERBOSE=${PRETTY_VERBOSE:-false}
99
-
100
-#
101
-# Name of pretty-printer module
102
-#
103
-# Friendly name of module used for decorating output.  For
104
-# example, if the value is NAME, a _pretty_NAME module must
105
-# exist and be importable.  Otherwise pretty will fall back
106
-# to plain, which is also the default value.
107
-#
108
-PRETTY=${PRETTY:-plain}
109
-
110
-#
111
-# Usage mode -- set to 'subcommand' to remove first dash
112
-#
113
-PRETTY_USAGE=${PRETTY_USAGE:-}
114
-
115
-
116
-__shellfu_pretty__init() {
117
-    #
118
-    # Import proper submodule
119
-    #
120
-    if shellfu try_import "_pretty_${PRETTY}";
121
-    then
122
-        shellfu import "_pretty_${PRETTY}"
123
-        return 0
124
-    else
125
-        warn "falling back to _pretty_plain"
126
-        PRETTY=plain
127
-        shellfu import "_pretty_${PRETTY}"
128
-    fi
129
-}
130
-
131
-
132
-##--------------------##
133
-## PRINTING FRONT-END ##
134
-##--------------------##
135
-
136
-debug() {
137
-    #
138
-    # You already know what it does
139
-    #
140
-    # BTW, following are equivalent:
141
-    #
142
-    #     debug "var1=$var1" "var2=$var2" "result=$result"
143
-    #     debug -v var1 var2 result
144
-    #
145
-    $PRETTY_DEBUG || return 0
146
-    _pretty__echo "$@"
147
-}
148
-
149
-
150
-debug_pipe() {
151
-    #
152
-    # Debug the whole pipe.
153
-    #
154
-    while IFS= read -r line;
155
-    do
156
-        debug "|$1: '$line'"
157
-        echos "$line"
158
-    done
159
-}
160
-
161
-
162
-die() {
163
-    #
164
-    # A fatal error
165
-    #
166
-    _pretty__echo -t
167
-    _pretty__echo "$@"
168
-    exit_error
169
-}
170
-
171
-
172
-echos() {
173
-    #
174
-    # Safer version of echo able to echo "-n"
175
-    #
176
-    # Traditional echo is broken in that it does not
177
-    # distinguish between string to print and its own switches
178
-    # (-e, -E or -n), leading to unexpected behavior.
179
-    #
180
-    # This echo version circumvents this by using printf.
181
-    #
182
-    printf -- '%s\n' "$@"
183
-}
184
-
185
-
186
-mkusage() {
187
-    #
188
-    # Echo out usage patterns and (by default) `exit 2`
189
-    #
190
-    #     mkusage [-e STATUS] [-E] pattern [patern...]
191
-    #
192
-    # Each pattern is prefixed by "usage: " and a resolved
193
-    # script/function name to produce traditional usage hint.
194
-    # By default, will exit with status *EXIT_USAGE*, you
195
-    # can use `-e STATUS` to specify other number. `-k` can be
196
-    # used as shorthand for `-e 0` (e.g. if user asked for
197
-    # the patterns)
198
-    #
199
-    # Use `-E` to prevent exiting; in that case, the status
200
-    # that would be fed to `exit` will be used as exit status
201
-    # of this function.
202
-    #
203
-    # Use "--" to delimit end of arguments processed by mkusage.
204
-    #
205
-    # Setting PRETTY_USAGE to 'subcommand' has effect that
206
-    # in each call, first hyphen in the script's "own" name is
207
-    # replaced by space; this is used for git-like sub-commands,
208
-    # where the actual binary name is e.g. "git-add" for
209
-    # "git add".
210
-    #
211
-    # Recommended usage is to define usage() in your script and
212
-    # use this in its body.  That way you only need to define
213
-    # usage patterns once and skip to them from any place where
214
-    # you detect incorrect usage.
215
-    #
216
-    local es=$EXIT_USAGE
217
-    local doexit=true
218
-    while true; do case "$1" in
219
-        -e) es="$2";            shift 2 || return 2 ;;
220
-        -E) doexit=false;       shift        ;;
221
-        -k) es=$EXIT_OK; shift       ;;
222
-        --)                     shift; break ;;
223
-        *)                      break        ;;
224
-    esac done
225
-    _pretty__echo -u "$@";
226
-    $doexit && exit "$es"
227
-    return "$es"
228
-}
229
-
230
-
231
-mkhelp() {
232
-    #
233
-    # Echo out help text
234
-    #
235
-    #     mkhelp [-e STATUS] [-E] arg...
236
-    #
237
-    # By default, will exit with status *EXIT_OK*, you
238
-    # can use `-e STATUS` to specify other number.
239
-    #
240
-    # Use `-E` to prevent exiting; in that case, the status
241
-    # that would be fed to `exit` will be used as exit status
242
-    # of this function.
243
-    #
244
-    # Use "--" to delimit end of arguments processed by mkhelp
245
-    #
246
-    local es=$EXIT_OK
247
-    local doexit=true
248
-    while true; do case "$1" in
249
-        -e) es="$2";            shift 2 || return 2 ;;
250
-        -E) doexit=false;       shift               ;;
251
-        --)                     shift; break        ;;
252
-        *)                      break               ;;
253
-    esac done
254
-    _pretty__echo "$@"
255
-    $doexit && exit "$es"
256
-    return "$es"
257
-}
258
-
259
-
260
-think() {
261
-    #
262
-    # If verbose is on, think loud
263
-    #
264
-    # Use "-l" to split every parameter to separate line, (useful
265
-    # or longer warnings)
266
-    #
267
-    $PRETTY_VERBOSE || return 0
268
-    _pretty__echo "$@"
269
-}
270
-
271
-
272
-warn() {
273
-    #
274
-    # Warn them
275
-    #
276
-    # Use "-l" to split every parameter to separate line, (useful
277
-    # or longer warnings)
278
-    #
279
-    _pretty__echo "$@"
280
-}
281
-
282
-
283
-##----------##
284
-## BACK-END ##
285
-##----------##
286
-
287
-
288
-_pretty__cat() {
289
-    #
290
-    # `cat` but without starting a process
291
-    #
292
-    # Used to avoid spanning new process where stream handler is chosen
293
-    # based on some logic
294
-    #
295
-    while IFS= read -r line;
296
-    do echos "$line"; done
297
-}
298
-
299
-
300
-_pretty__get_caller() {
301
-    #
302
-    # Get first user function and negative index from stack
303
-    #
304
-    local fname
305
-    local nidx="${#FUNCNAME[@]}"
306
-    for fname in "${FUNCNAME[@]}";
307
-    do
308
-        (( nidx-- ))
309
-        _pretty__is_internal && continue
310
-        _pretty__is_frontend && continue
311
-        test "$fname" = "usage" && continue
312
-        echos "$nidx" "$fname"
313
-        return
314
-    done
315
-}
316
-
317
-_pretty__get_frontend() {
318
-    #
319
-    # Get entry point function name from stack
320
-    #
321
-    local fname
322
-    for fname in "${FUNCNAME[@]}";
323
-    do
324
-        _pretty__is_internal && continue
325
-        _pretty__is_frontend && echos "$fname" && return 0
326
-        echo "do not call _pretty_* directly: $fname" >&2
327
-        return "$EXIT_USAGE"
328
-    done
329
-}
330
-
331
-_pretty__is_excluded() {
332
-    #
333
-    # True if $caller is excluded based on PRETTY_DEBUG_EXCLUDE
334
-    #
335
-    # Check PRETTY_DEBUG_EXCLUDE to see if $caller (using only module name
336
-    # part, if possible) should be muted from debugging.
337
-    #
338
-    local listed        # item listed in PRETTY_DEBUG_EXCLUDE
339
-    local name          # module part of caller's name
340
-    local qualified     # is caller "qualified" (ac. to shellfu scheme)?
341
-    name="$caller"
342
-    case "$name" in
343
-        __*__*) qualified=true  ;;
344
-        __*)    qualified=false ;;
345
-        *__*)   qualified=true  ;;
346
-        *)      qualified=false ;;
347
-    esac
348
-    if $qualified;
349
-    then
350
-        # we'll use only the module part of the name
351
-        name=${name#_}      # drop one "internal" prefix
352
-        name=${name#_}      # drop yet another one
353
-        name=${name%__*}    # drop funcname
354
-    fi
355
-    for listed in ${PRETTY_DEBUG_EXCLUDE//,/ };
356
-    do
357
-        test "$name" = "$listed" && return 0
358
-    done
359
-    return 1
360
-}
361
-
362
-_pretty__is_frontend() {
363
-    #
364
-    # True if $fname is one of our "frontends"
365
-    #
366
-    case "$fname" in
367
-        debug)      return 0 ;;
368
-        debug_pipe) return 0 ;;
369
-        die)        return 0 ;;
370
-        mkhelp)     return 0 ;;
371
-        think)      return 0 ;;
372
-        mkusage)    return 0 ;;
373
-        warn)       return 0 ;;
374
-    esac
375
-    return 1
376
-}
377
-
378
-_pretty__is_internal() {
379
-    #
380
-    # True if $fname is our internal function
381
-    #
382
-    case "$fname" in
383
-        _pretty__*) return 0 ;;
384
-        *)          return 1 ;;
385
-    esac
386
-}
387
-
388
-_pretty__echo() {
389
-    #
390
-    # A smarter echo backend
391
-    #
392
-    # A smarter backend for debug, warn, think, die and
393
-    # mkusage.
394
-    #
395
-    #   -c cmd      echo output of a command
396
-    #   -f file     echo output of a file (- for stdin)
397
-    #   -l line [line...] echo each line separately
398
-    #   -t          add stack trace to output
399
-    #   -u patt [patt...] convert each patt to usage pattern
400
-    #   -v var [var...] show contents of each var
401
-    #
402
-    local frontend  # who (of pretty.sh) was called (=> prettyprinter choice)
403
-    local caller    # which user's function (or script) called it
404
-    #     ^      ^    eg. if user calls 'debug hello' from function 'foo', then
405
-    #     :      :..   *  frontend is 'debug'
406
-    #     :.........   *  and caller is 'foo'.
407
-    local caller_nidx       # negative stack index of caller
408
-    local caller_is_main    # true if caller was main script or main() in it
409
-    local provider          # which provider (_pretty__echo_*()) to use
410
-    frontend="$(_pretty__get_frontend)" || exit_usage
411
-    read caller_nidx caller <<<$(_pretty__get_caller)
412
-    test "$frontend" = debug && _pretty__is_excluded "$caller" && return 0
413
-    case $caller_nidx:$caller in
414
-        0:*)        caller_is_main=true; caller="${0##*/}" ;;
415
-        1:main)     caller_is_main=true; caller="${0##*/}" ;;
416
-        *:usage)    frontend=mkusage                       ;;
417
-        *)          caller_is_main=false                   ;;
418
-    esac
419
-    while true; do case $1 in
420
-        -c|--cmd)   provider=cmd;   shift; break ;;
421
-        -f|--files) provider=files; shift; break ;;
422
-        -l|--lines) provider=lines; shift; break ;;
423
-        -t|--trace) provider=trace; shift; break ;;
424
-        -u|--usage) provider=usage; shift; break ;;
425
-        -v|--vars)  provider=vars;  shift; break ;;
426
-        *)          provider=args;         break ;;
427
-    esac done
428
-    _pretty__echo_$provider "$@" \
429
-      | _pretty__$frontend >&2
430
-}
431
-
432
-
433
-_pretty__echo_args() {
434
-    #
435
-    # The simplest (but safe) printing of args
436
-    #
437
-    echos "$*"
438
-}
439
-
440
-
441
-_pretty__echo_cmd() {
442
-    #
443
-    # Print command line, launch it and report exit status
444
-    #
445
-    local c=\$
446
-    test "$(id -u)" -eq 0 && c="#"
447
-    echo "$c $*"
448
-    "$@"
449
-    echo "^ exit status: $?"
450
-}
451
-
452
-
453
-_pretty__echo_files() {
454
-    #
455
-    # Print names and contents of existing files
456
-    #
457
-    local fp
458
-    for fp in "$@";
459
-    do
460
-        if test "$fp" = "-";
461
-        then
462
-            cat
463
-        elif test -s "$fp" || test "$fp" = "/dev/stdin";
464
-        then
465
-            echo "-- $fp --"
466
-            cat "$fp"
467
-        fi
468
-    done
469
-}
470
-
471
-
472
-_pretty__echo_lines() {
473
-    #
474
-    # Echo each argument as a separate line
475
-    #
476
-    local l;
477
-    for l in "$@"; do _pretty__echo_args "$l"; done
478
-}
479
-
480
-
481
-_pretty__echo_trace() {
482
-    #
483
-    # Print "decorated" call trace (only in debug mode)
484
-    #
485
-    $PRETTY_DEBUG || return 0
486
-    local depth
487
-    echo "== trace =="
488
-    for depth in $(seq 0 ${#FUNCNAME});
489
-    do
490
-        caller "$depth" || break
491
-    done \
492
-      | tail -n +3 \
493
-      | sed -e '
494
-            s/^\([^ ]\+\) \([^ ]\+\) \(.*\)/\3:\1:\2()/
495
-            #  ^line^,    ^func^,    ^file^
496
-            1   s/^/ -> /g
497
-            2,$ s/^/    /
498
-        ' \
499
-      | tac
500
-}
501
-
502
-
503
-_pretty__echo_help() {
504
-    local oldverbose="$PRETTY_VERBOSE"
505
-    think -l "$@"
506
-    PRETTY_VERBOSE=$oldverbose
507
-}
508
-
509
-_pretty__echo_usage() {
510
-    #
511
-    # Compose conventional usage guide
512
-    #
513
-    # The default mode treats each argument as usage pattern
514
-    # (see below for details).  Additional formatting can be
515
-    # conveniently achieved by switching to other modes, which
516
-    # automatically brings necessary headers and indentations
517
-    # where needed.
518
-    #
519
-    #  *  option mode (`-o`) prints "options:" header and 
520
-    #     indents next arguments,
521
-    #
522
-    #  *  command mode (`-c`) prints "commands:" header and
523
-    #     indents next arguments,
524
-    #
525
-    #  *  plain mode (`--`) prints empty line (new paragraph)
526
-    #     and turns indentations off.
527
-    #
528
-    #  *  usage mode (`-u`, active by default), prints
529
-    #     "usage:" header, indents next arguments and prefixes
530
-    #     them with name of the script.
531
-    #
532
-    #     A special case of usage mode is when only single
533
-    #     argument is passed to this function; then instead
534
-    #     of "usage:" header, this usage pattern is prefixed
535
-    #     with the same string.
536
-    #
537
-    # In order to help avoid (rare) conflict between mkusage()
538
-    # switches and your usage patterns, the very first argument,
539
-    # and each argument that comes right after one of these
540
-    # switches are guarranteed not to be interpreted as switch.
541
-    #
542
-    local self          # the script name
543
-    local mode=usage    # mode
544
-    local esc=1         # escape (take next argument as literal)
545
-    local arg           # argument to iterate
546
-    case "$PRETTY_USAGE" in
547
-        subcommand) self="${0##*/}"; self="${self/-/ }" ;;
548
-        *)          self="$caller" ;;
549
-    esac
550
-    case $# in
551
-        0)  return 0 ;;
552
-        1)  echo "usage: $self $1"; return 0 ;;
553
-    esac
554
-    echo usage:
555
-    for arg in "$@";
556
-    do
557
-        case $esc:$arg in
558
-            0:--) shift; mode=plain;  esc=1; echo                ;;
559
-            0:-c) shift; mode=indent; esc=1; echo; echo commands: ;;
560
-            0:-i) shift; mode=indent; esc=1; echo                ;;
561
-            0:-o) shift; mode=indent; esc=1; echo; echo options: ;;
562
-            0:-u) shift; mode=usage;  esc=1                      ;;
563
-            *)  esc=0
564
-                case $mode in
565
-                    usage)  echo  "  $self $arg" ;;
566
-                    indent) echo  "  $arg" ;;
567
-                    plain)  echos "$arg" ;;
568
-                esac
569
-                ;;
570
-        esac
571
-    done
572
-}
573
-
574
-
575
-_pretty__echo_vars() {
576
-    #
577
-    # Report value of each named variable
578
-    #
579
-    local varname
580
-    local declare_str
581
-    for varname in "$@";
582
-    do
583
-        if ! _pretty__is_word "$varname";
584
-        then
585
-            warn "unsafe value skipped: $varname";
586
-            continue
587
-        fi
588
-        if declare_str=$(declare -p "$varname" 2>/dev/null);
589
-        then
590
-            _pretty__echo "${declare_str#declare ?? }"
591
-        else
592
-            _pretty__echo "$varname #Unset"
593
-        fi
594
-    done
595
-}
596
-
597
-
598
-_pretty__is_word() {
599
-    #
600
-    # Check if $1 contains only alphanumeric chars or _
601
-    #
602
-    local tainted="$1"
603
-    local clean=$(tr -c -d '_[:alnum:]' <<< "$tainted")
604
-    test "$tainted" = "$clean"
605
-}
606
-
607
-#
608
-# end module: 8ee17c6681d102da92d36f71ef523a55  /usr/local/share/shellfu/include-bash/pretty.sh
609
-#
610
-
611
-#
612
-# begin module: 392f50abe388bd54c01d84ee7b2a0cdd  /usr/local/share/shellfu/include-bash/_pretty_plain.sh
613
-#
614
-
615
-#!/bin/bash
616
-
617
-
618
-_pretty__debug() {
619
-    local decor="()"
620
-    $caller_is_main && decor=
621
-    while IFS= read -r line;
622
-    do echo "debug:$caller$decor: $line"; done
623
-}
624
-
625
-_pretty__die() {
626
-    while IFS= read -r line;
627
-    do echo "$line"; done
628
-}
629
-
630
-_pretty__mkhelp() {
631
-    while IFS= read -r line;
632
-    do echo "$line"; done
633
-}
634
-
635
-_pretty__mkusage() {
636
-    while IFS= read -r line;
637
-    do echo "$line"; done
638
-}
639
-
640
-_pretty__think() {
641
-    while IFS= read -r line;
642
-    do echo "$line"; done
643
-}
644
-
645
-_pretty__warn() {
646
-    while IFS= read -r line;
647
-    do echo "$line"; done
648
-}
649
-
650
-#
651
-# end module: 392f50abe388bd54c01d84ee7b2a0cdd  /usr/local/share/shellfu/include-bash/_pretty_plain.sh
652
-#
653
-
654
-#!/bin/bash
655
-
656
-. "$(shellfu-get path)" || exit 3
657
-
658
-shellfu import pretty
659
-
660
-usage() {
661
-    mkusage "[options] ACTION" \
662
-        -o                                                                    \
663
-            "-c DIR      change to DIR before doing anything"                 \
664
-            "-d          turn on debugging mode"                              \
665
-       --                                                                     \
666
-       "imapdomo will try to read .imapdomo/host/HOSTNAME/init.lua and"       \
667
-       ".imapdomo/host/HOSTNAME/handlers/ACTION.lua, where HOSTNAME is your"  \
668
-       "short hostname (eg. 'foo' in 'foo.example.com')."                     \
669
-       ""                                                                     \
670
-       "four valid actions are understood; since you must write handler for"  \
671
-       "each action you want to use, the meanings below are purely a guide:"  \
672
-       ""                                                                     \
673
-       "    newmail - check for and file new mail"                            \
674
-       "    rewind  - re-add messages from FILTER_FAIL back to FILTER_QUEUE"  \
675
-       "    cleanup - delete or archive old messages"                         \
676
-       "    migrate - move mail between mailboxes"                            \
677
-       ""                                                                     \
678
-       "See imapfilter_config(5)) for guide and API reference.  Few functions"\
679
-       "are also available in .imapdomo/common.lua"
680
-}
681
-
682
-mkcmd() {
683
-    #
684
-    # Compose imapfilter command
685
-    #
686
-    echo -n "IMAPDOMO_ACTION=$Action"
687
-    echo -n "  IMAPDOMO_HEADERS=$HeaderDir"
688
-    echo -n "  IMAPFILTER_HOME=$CfgDir"
689
-    echo -n "  imapfilter"
690
-    if $Debug
691
-    then
692
-        mkdir -p "$LogDir"
693
-        echo -n "  -d $LogDir/debug.log"
694
-        echo -n "  -v"
695
-    fi
696
-    echo -n "  -c $CfgDir/main.lua"
697
-}
698
-
699
-main() {
700
-    local Action    # what to do
701
-    local Debug     # true if debugging
702
-    local cmd       # imapfilter command
703
-    local CfgDir    # config directory
704
-    local LogDir    # directory to store logs
705
-    local HeaderDir # directory to store headers by save_header()
706
-    local CdTo      # change dir to this before running imapfilter
707
-    CfgDir="$HOME/.imapdomo"
708
-    LogDir="$HOME/.local/share/imapdomo/logs"
709
-    HeaderDir="$HOME/.local/share/imapdomo/headers"
710
-    Debug=false
711
-    #shellcheck disable=SC2034
712
-    while true; do case $1 in
713
-        -c) CdTo="$2"; shift 2 || usage ;;
714
-        -d) Debug=true; PRETTY_DEBUG=true; shift ;;
715
-        -*) usage ;;
716
-        *)  break ;;
717
-    esac done
718
-    Action="$1"; shift
719
-    grep -qw "$Action" <<< "newmail|rewind|cleanup|migrate" || usage
720
-    cmd=$(mkcmd)
721
-    debug -v cmd
722
-    bash -n <<<"$cmd" || die
723
-    if test -n "$CdTo";
724
-    then
725
-        cd "$CdTo" || die
726
-    fi
727
-    mkdir -p "$HeaderDir" || die
728
-    eval "$cmd"
729
-}
730
-
731
-main "$@"
732
-#
733
-# end of shellfu-embedded shell script
734
-#