Hier nun das komplette Script mit funktionierender Verschiebung nach dem Lernen, falls jemand von euch dies so einsetzen möchte:
kopano-spamd.py:
#!/usr/bin/env python
# coding=utf-8
"""
ICS driven spam learning daemon for Kopano / SpamAssasin
See included readme.md for more information.
"""
import shlex
import subprocess
import time
import kopano
from MAPI.Tags import *
from kopano import Config, log_exc
CONFIG = {
'run_as_user': Config.string(default="kopano"),
'run_as_group': Config.string(default="kopano"),
'learncmdspam': Config.string(default="/usr/bin/sudo -u amavis /usr/bin/sa-learn --spam"),
'learncmdham': Config.string(default="/usr/bin/sudo -u amavis /usr/bin/sa-learn --ham"),
'spamfolder': Config.string(default="LearnSpam"),
'hamfolder': Config.string(default="LearnHam")
}
class Service(kopano.Service):
def main(self):
server = self.server
state = server.state
catcher = Checker(self)
with log_exc(self.log):
while True:
try:
state = server.sync(catcher, state)
except Exception as e:
if e.hr == MAPI_E_NETWORK_ERROR:
self.log.info('Trying to reconnect to Server in %s seconds' % 5)
else:
self.log.info('Error: [%s]' % e)
time.sleep(5)
time.sleep(1)
class Checker(object):
def __init__(self, service):
self.log = service.log
self.learncmdspam = service.config['learncmdspam']
self.learncmdham = service.config['learncmdham']
self.spamfolder = service.config['spamfolder']
self.hamfolder = service.config['hamfolder']
def update(self, item, flags):
if item.message_class == 'IPM.Note':
if item.folder == item.store.user.folder(self.spamfolder):
self.learn(item, 'spam')
elif item.folder == item.store.user.folder(self.hamfolder):
self.learn(item, 'ham')
def learn(self, item, learntype):
with log_exc(self.log):
try:
spameml = item.eml()
if learntype == 'spam':
learncmd = self.learncmdspam
targetfolder = item.store.user.junk
elif learntype == 'ham':
learncmd = self.learncmdspam
targetfolder = item.store.user.inbox
havespam = True
except Exception as e:
self.log.info('Failed to extract eml of email: [%s] [%s]' % (e, item.entryid))
if havespam and learncmd and targetfolder:
try:
p = subprocess.Popen(shlex.split(learncmd), stdin=subprocess.PIPE, stdout=subprocess.PIPE)
learning, output_err = p.communicate(spameml)
self.log.info('[%s] sa-learn %s: %s' % (item.store.user.name, learntype, learning.strip('\n')))
item.folder.move(item, targetfolder)
except Exception as e:
self.log.info('sa-learn failed: [%s] [%s]' % (e, item.entryid))
def main():
parser = kopano.parser('ckpsF') # select common cmd-line options
options, args = parser.parse_args()
service = Service('spamd', config=CONFIG, options=options)
service.start()
if __name__ == '__main__':
main()
spamd.cfg:
##############################################################
# SPAMD SERVICE SETTINGS
# run as specific user
#run_as_user = kopano
# run as specific group
#run_as_group = kopano
# control pid file
pid_file = /var/run/kopano/spamd.pid
# run server in this path (when not using the -F switch)
#running_path = /var/lib/kopano
##############################################################
# LOG SETTINGS
# Logging method (syslog, file)
log_method = file
# Loglevel (0(none), 1(crit), 2(err), 3(warn), 4(notice), 5(info), 6(debug))
#log_level = 3
# Logfile for log_method = file, use '-' for stderr
log_file = /var/log/kopano/spamd.log
# Log timestamp - prefix each log line with timestamp in 'file' logging mode
log_timestamp = 1
###############################################################
# SPAMD Specific settings
learncmdspam = /usr/bin/sudo -u amavis /usr/bin/sa-learn --spam
learncmdham = /usr/bin/sudo -u amavis /usr/bin/sa-learn --ham
spamfolder = LearnSpam
hamfolder = LearnHam
Installationsanleitung immer noch gemäss der Original-Lösung: https://kb.kopano.io/display/WIKI/Kopano-spamd
Vielen Dank nochmal @fbartels!