6 Commits

Author SHA1 Message Date
  Alois Mahdal c3137b8a70 Bump version 4 years ago
  Alois Mahdal b4ae749515 Revamp packaging to achieve more correct Lua style 4 years ago
  Alois Mahdal b58b69cc9e Remove unnecessary import 4 years ago
  Alois Mahdal c4dd99c13d Add support for hooks 5 years ago
  Alois Mahdal 7b272940d8 Remove unnecessary argument 5 years ago
  Alois Mahdal 7b0ad1ca2b Enable lock-related debugging 5 years ago
6 changed files with 96 additions and 38 deletions
  1. 2
    2
      mkit.ini
  2. 1
    1
      packaging/debian/install
  3. 1
    1
      packaging/template.spec
  4. 78
    29
      src/imapdomo.lua
  5. 12
    3
      src/imapdomo.skel
  6. 2
    2
      src/main.lua.skel

+ 2
- 2
mkit.ini View File

@@ -1,5 +1,5 @@
1 1
 [project]
2
-    version     = 0.0.9
2
+    version     = 0.0.10
3 3
     name        = imapdomo
4 4
     pkgname     = imapdomo
5 5
     maintainer  = Alois Mahdal <netvor+imapdomo@vornet.cz>
@@ -38,7 +38,7 @@
38 38
 
39 39
 [files]
40 40
     bin     = src/imapdomo
41
+    share   = src/imapdomo.lua
41 42
     share   = src/main.lua
42
-    share   = src/common.lua
43 43
 
44 44
 #mkit version=0.0.34

+ 1
- 1
packaging/debian/install View File

@@ -1,3 +1,3 @@
1 1
 /usr/bin/imapdomo
2
-/usr/share/imapdomo/common.lua
2
+/usr/share/imapdomo/imapdomo.lua
3 3
 /usr/share/imapdomo/main.lua

+ 1
- 1
packaging/template.spec View File

@@ -29,7 +29,7 @@ make %{?_smp_mflags}
29 29
 %files
30 30
 %dir %{_datadir}/%{name}
31 31
 %{_bindir}/%{name}
32
-%{_datadir}/%{name}/common.lua
32
+%{_datadir}/%{name}/imapdomo.lua
33 33
 %{_datadir}/%{name}/main.lua
34 34
 
35 35
 %changelog

src/common.lua → src/imapdomo.lua View File

@@ -1,11 +1,19 @@
1
-os = require "os"
2
-
1
+local pkg = {}
3 2
 
4 3
 ------------------------------------------------------------------------------
5 4
 -- config and handling                                                      --
6 5
 ------------------------------------------------------------------------------
7 6
 
8
-function file_exists(name)
7
+pkg.load_mailboxes = function()
8
+    --
9
+    -- Load mailboxes from $IMAPDOMO_CFGDIR/mailboxes.lua
10
+    --
11
+    local fname = os.getenv("IMAPDOMO_CFGDIR") .. '/mailboxes.lua'
12
+    assert(pkg.file_exists(fname))
13
+    return dofile(fname)
14
+end
15
+
16
+pkg.file_exists = function(name)
9 17
     --
10 18
     -- True if file *name* exists
11 19
     --
@@ -18,25 +26,25 @@ function file_exists(name)
18 26
     end
19 27
 end
20 28
 
21
-function do_if_exists(filename)
29
+pkg.do_if_exists = function (filename)
22 30
     --
23 31
     -- Do file from home, if exists
24 32
     --
25 33
     local file = os.getenv("IMAPFILTER_HOME") .. "/" .. filename
26
-    if file_exists(file) then
34
+    if pkg.file_exists(file) then
27 35
         dofile(file)
28 36
         return
29 37
     end
30 38
 end
31 39
 
32
-function handle()
40
+pkg.handle = function()
33 41
     --
34 42
     -- Handle action if it's valid
35 43
     --
36 44
     local action = os.getenv("IMAPDOMO_ACTION")
37 45
     local file = os.getenv("IMAPFILTER_HOME") .. "/handlers/" .. action .. ".lua"
38
-    if file_exists(file) then
39
-        do_if_exists("init.lua")
46
+    if pkg.file_exists(file) then
47
+        pkg.do_if_exists("init.lua")
40 48
         dofile(file)
41 49
     else
42 50
         error("no handler for action: " .. action)
@@ -49,21 +57,21 @@ end
49 57
 -- mail getters                                                             --
50 58
 ------------------------------------------------------------------------------
51 59
 
52
-function get_queue(acct, mbox)
60
+pkg.get_queue = function(acct, mbox)
53 61
     --
54 62
     -- Get queue from *mbox* from *acct* or nil (no messages)
55 63
     --
56 64
     -- If mbox is not specified, "FILTER_QUEUE" is used
57 65
     --
58 66
     mbox = mbox or "FILTER_QUEUE"
59
-    local exist, unread, unseen, uidnext = acct[mbox]:check_status()
67
+    local exist = acct[mbox]:check_status()
60 68
     if exist > 0 then
61 69
         return acct[mbox]:select_all()
62 70
     end
63 71
     return nil
64 72
 end
65 73
 
66
-function _notifirc1(subj, from, body)
74
+pkg._notifirc1 = function(subj, from, body)
67 75
     --
68 76
     -- notify about message using (pre-configured) notifirc
69 77
     --
@@ -73,20 +81,59 @@ function _notifirc1(subj, from, body)
73 81
     fd:close()
74 82
 end
75 83
 
76
-function notifirc_all(seq)
84
+pkg.notifirc_all = function(seq)
77 85
     --
78 86
     -- Send notifications about all messages in *seq*
79 87
     --
80 88
     for _, mesg in ipairs(seq) do
89
+        local mbox, uid, subj, from, body
81 90
         mbox, uid = table.unpack(mesg)
82 91
         subj = mbox[uid]:fetch_field('Subject')
83 92
         from = mbox[uid]:fetch_field('From')
84 93
         body = mbox[uid]:fetch_body()
85
-        _notifirc1(subj, from, body)
94
+        pkg._notifirc1(subj, from, body)
86 95
     end
87 96
 end
88 97
 
89
-function _partinf_compare(a, b)
98
+pkg.hook_all = function(seq, hname, ...)
99
+    --
100
+    -- Call hook hname for all messages in seq
101
+    --
102
+    local hfile = os.getenv("IMAPFILTER_HOME") .. "/hooks/" .. hname
103
+    local hargs = {...}
104
+    local hcmd = hfile
105
+    local fmt = ' %q'
106
+    if pkg.file_exists(hfile) then
107
+        for _, harg in pairs(hargs) do
108
+            hcmd = hcmd .. fmt:format(harg)
109
+        end
110
+        for _, mesg in ipairs(seq) do
111
+            local mbox, uid, subj, body, from, to, date
112
+            mbox, uid = table.unpack(mesg)
113
+            subj = mbox[uid]:fetch_field('Subject')
114
+            from = mbox[uid]:fetch_field('From')
115
+            to = mbox[uid]:fetch_field('To')
116
+            date = mbox[uid]:fetch_field('Date')
117
+            body = mbox[uid]:fetch_body()
118
+            pkg._hook1(hcmd, subj, from, to, date, body)
119
+        end
120
+    else
121
+        error("no such hook: " .. hname)
122
+        return nil
123
+    end
124
+end
125
+
126
+pkg._hook1 = function(hcmd, subj, from, to, date, body)
127
+    --
128
+    -- push message through hook script
129
+    --
130
+    local fd = assert(io.popen(hcmd, "w"))
131
+    local fmt = "subj=%s\nfrom=%s\nto=%s\ndate=%s\n%s"
132
+    fd:write(fmt:format(subj, from, to, date, body))
133
+    fd:close()
134
+end
135
+
136
+pkg._partinf_compare = function(a, b)
90 137
     if not type(a) == type(b) then
91 138
         return false
92 139
     end
@@ -97,7 +144,7 @@ function _partinf_compare(a, b)
97 144
     end
98 145
 end
99 146
 
100
-function has_part_like(query, structure)
147
+pkg.has_part_like = function(query, structure)
101 148
     --
102 149
     -- True if structure has MIME part matching *query*
103 150
     --
@@ -108,8 +155,8 @@ function has_part_like(query, structure)
108 155
         local part_answer = true
109 156
         -- check all query parts
110 157
         for qkey, qvalue in pairs(query) do
111
-            value = partinf[qkey]
112
-            if not _partinf_compare(value, qvalue) then
158
+            local value = partinf[qkey]
159
+            if not pkg._partinf_compare(value, qvalue) then
113 160
                 part_answer = false
114 161
                 break
115 162
             end
@@ -121,7 +168,7 @@ function has_part_like(query, structure)
121 168
     return false
122 169
 end
123 170
 
124
-function save_header(mesg, name)
171
+pkg.save_header = function(mesg, name)
125 172
     --
126 173
     -- Append header from *mesg* to file named *name*
127 174
     --
@@ -130,16 +177,16 @@ function save_header(mesg, name)
130 177
     --
131 178
     local dest = os.getenv("IMAPDOMO_HEADERS") .. '/' .. name
132 179
     local cmd = ('cat >>"%q"'):format(dest)
133
-    mbox, uid = table.unpack(mesg)
134
-    header = mbox[uid]:fetch_header()
135
-    if pipe_to(cmd, header) == 0 then
180
+    local mbox, uid = table.unpack(mesg)
181
+    local header = mbox[uid]:fetch_header()
182
+    if pkg.pipe_to(cmd, header) == 0 then
136 183
         return true
137 184
     else
138 185
         return false
139 186
     end
140 187
 end
141 188
 
142
-function filter_header_saved(seq, name)
189
+pkg.filter_header_saved = function(seq, name)
143 190
     --
144 191
     -- Save headers from sequence
145 192
     --
@@ -147,26 +194,28 @@ function filter_header_saved(seq, name)
147 194
     -- *name* and return new sequence with those messages where save was
148 195
     -- successful.
149 196
     --
150
-    result = Set {}
197
+    local result = {}
151 198
     for _, mesg in ipairs(seq) do
152
-        if save_header(mesg, name) then
199
+        if pkg.save_header(mesg, name) then
153 200
             table.insert(result, mesg)
154 201
         end
155 202
     end
156 203
     return result
157 204
 end
158 205
 
159
-function filter_part_like(query, seq)
206
+pkg.filter_part_like = function(query, seq)
160 207
     --
161 208
     -- Run MIME part query on *seq* sequence of messages
162 209
     --
163
-    result = Set {}
210
+    local result = {}
164 211
     for _, mesg in ipairs(seq) do
165
-        mbox, uid = table.unpack(mesg)
166
-        structure = mbox[uid]:fetch_structure()
167
-        if has_part_like(query, structure) then
212
+        local mbox, uid = table.unpack(mesg)
213
+        local structure = mbox[uid]:fetch_structure()
214
+        if pkg.has_part_like(query, structure) then
168 215
             table.insert(result, mesg)
169 216
         end
170 217
     end
171 218
     return result
172 219
 end
220
+
221
+return pkg

+ 12
- 3
src/imapdomo.skel View File

@@ -24,7 +24,7 @@ usage() {
24 24
        "configuration directory."                                             \
25 25
        ""                                                                     \
26 26
        "See imapfilter_config(5)) for guide and API reference.  Few functions"\
27
-       "are also available in .imapdomo/common.lua"                           \
27
+       "are also available in .imapdomo/imapdomo.lua"                         \
28 28
        ""                                                                     \
29 29
        "NOTE: Be aware that it's your responsibility to ensure that filters"  \
30 30
        "don't cause performance problems. (Trust me, it's not so hard to"     \
@@ -46,6 +46,8 @@ mkcmd() {
46 46
     # Compose imapfilter command
47 47
     #
48 48
     echo -n "IMAPDOMO_ACTION=$Action"
49
+    echo -n "  LUA_PATH=$IMAPDOMO_HOME/?.lua"
50
+    echo -n "  IMAPDOMO_CFGDIR=$CfgDir"
49 51
     echo -n "  IMAPDOMO_HEADERS=$HeaderDir"
50 52
     echo -n "  IMAPFILTER_HOME=$CfgDir"
51 53
     echo -n "  imapfilter"
@@ -76,7 +78,7 @@ lshandlers() {
76 78
     #
77 79
     # List recognized handlers
78 80
     #
79
-    find "$CfgDir/handlers" -name "*.lua" -printf "%f\n" \
81
+    find "$CfgDir/handlers" -name "*.lua" -printf '%f\n' \
80 82
       | sed 's/.lua$//'
81 83
 }
82 84
 
@@ -84,8 +86,10 @@ lock() {
84 86
     #
85 87
     # Put the lockfile
86 88
     #
89
+    debug -v NoLock
87 90
     $NoLock && return 0
88 91
     date +"$$@%s" > "$IMAPDOMO_USER_CACHE/lock"
92
+    debug -f "$IMAPDOMO_USER_CACHE/lock"
89 93
 }
90 94
 
91 95
 is_locked() {
@@ -95,7 +99,9 @@ is_locked() {
95 99
     # True if lockfile exists. False if lockfile does not exist or locking
96 100
     # is turned off.
97 101
     #
102
+    debug -v NoLock
98 103
     $NoLock && return 1
104
+    debug -f "$IMAPDOMO_USER_CACHE/lock"
99 105
     test -e "$IMAPDOMO_USER_CACHE/lock"
100 106
 }
101 107
 
@@ -103,7 +109,9 @@ unlock() {
103 109
     #
104 110
     # Remove the lockfile
105 111
     #
112
+    debug -v NoLock
106 113
     $NoLock && return 0
114
+    debug -f "$IMAPDOMO_USER_CACHE/lock"
107 115
     rm "$IMAPDOMO_USER_CACHE/lock"
108 116
 }
109 117
 
@@ -166,10 +174,11 @@ main() {
166 174
     esac done
167 175
     Action="$1"; shift
168 176
     test -n "$Action" || usage -w "no action specified"
177
+    test -f "$CfgDir/mailboxes.lua" || die "no mailboxes defined"
169 178
     debug -v Action CfgDir LogDir HeaderDir Debug CdTo NoLock
170 179
     is_locked && return 1
171 180
     lock
172
-    handle "$Action"; es=$?
181
+    handle; es=$?
173 182
     unlock
174 183
     return $es
175 184
 }

+ 2
- 2
src/main.lua.skel View File

@@ -1,5 +1,5 @@
1 1
 #!/bin/lua
2 2
 
3
-dofile "__IMAPDOMO_SHARE__/common.lua"
3
+local imapdomo = require "imapdomo"
4 4
 
5
-handle()
5
+imapdomo.handle()