forked from bkram/inotify-spamlearn
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinotify-spamlearn.py
executable file
·108 lines (91 loc) · 4.08 KB
/
inotify-spamlearn.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# vim: ai ts=4 sts=4 et sw=4
import configparser
import logging
import os
import subprocess
import threading
import inotify.adapters
def getconfig():
config = configparser.ConfigParser()
try:
config.read('/etc/kopano/inotify-spamlearn.cfg')
spam_dir = config.get('paths', 'spam_dir')
ham_dir = config.get('paths', 'ham_dir')
spamcmd = config.get('spam', 'spamcmd')
hamcmd = config.get('spam', 'hamcmd')
delete = config.getboolean('mode', 'delete')
scan = config.getboolean('mode', 'scan')
oneshot = config.getboolean('mode', 'oneshot')
loglevel = config.get('logging', 'loglevel')
logfile = config.get('logging', 'logfile')
return spam_dir, ham_dir, spamcmd, hamcmd, logfile, loglevel, delete, scan, oneshot
except Exception as e:
exit('Configuration {}\n please check inotify-spamlearn.cfg'.format(e))
def process(filename, spamcmd, delete, initiator):
if os.path.exists(filename):
try:
p1 = subprocess.Popen(["cat", filename], stdout=subprocess.PIPE)
p2 = subprocess.Popen(spamcmd.split(' '), stdin=p1.stdout, stdout=subprocess.PIPE)
p1.stdout.close()
learning, output_err = p2.communicate()
logging.info('Processing [%s] %s: %s' % (initiator, filename, str(learning.decode('utf-8')).strip('\n')))
except Exception as e:
logging.warning('Processing failed [{}]: '.format(e))
else:
if delete:
logging.info('Removing file: {}'.format(filename))
os.remove(filename)
else:
logging.warning('File %s does not exist (anymore)' % filename)
def scandirs(spam_dir, ham_dir, spamcmd, hamcmd, delete):
initiator = 'Dirscan'
for checkdir in [spam_dir, ham_dir]:
logging.info('Looking for existing files in {}'.format(checkdir))
for spam in os.listdir(checkdir):
try:
if checkdir == spam_dir:
process('/'.join([checkdir, spam]), spamcmd, delete, initiator)
elif checkdir == ham_dir:
process('/'.join([checkdir, spam]), hamcmd, delete, initiator)
except Exception as e:
logging.error('Cannot open path {} {}'.format(checkdir, e))
logging.info('Finished looking for existing files in {}'.format(checkdir))
def inotified(spam_dir, ham_dir, spamcmd, hamcmd, delete):
initiator = 'Inotify'
i = inotify.adapters.Inotify()
try:
i.add_watch(spam_dir)
i.add_watch(ham_dir)
except Exception as e:
logging.error('Cannot start inotify watch: {}'.format(e))
else:
logging.info('Inotify learning started')
try:
for event in i.event_gen():
if event is not None:
(header, type_names, watch_path, filename) = event
if type_names[0] == 'IN_CLOSE_WRITE' and filename.endswith('.eml'):
if watch_path == spam_dir:
process('/'.join([watch_path, filename]), spamcmd, delete, initiator)
elif watch_path == ham_dir:
process('/'.join([watch_path, filename]), hamcmd, delete, initiator)
finally:
i.remove_watch([spam_dir, ham_dir])
def main():
(spam_dir, ham_dir, spamcmd, hamcmd, logfile, loglevel, delete, scan, oneshot) = getconfig()
loglevel = getattr(logging, loglevel.upper(), 'INFO')
logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s',
filename=logfile, level=loglevel)
logging.info('Starting inotify-spamlearn.py')
scanthread = threading.Thread(name='Scan Directories', target=scandirs,
args=(spam_dir, ham_dir, spamcmd, hamcmd, delete))
inotifythread = threading.Thread(name='Inotify Handling', target=inotified,
args=(spam_dir, ham_dir, spamcmd, hamcmd, delete))
if scan:
scanthread.start()
if not oneshot:
inotifythread.start()
if __name__ == '__main__':
main()