mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-17 05:41:25 +02:00
We can now release messages properly. New class AMrelease supports both unix and inet connection modes.
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
import socket
|
||||
import re
|
||||
import struct
|
||||
import string
|
||||
from django.conf import settings
|
||||
|
||||
def getParam(param, default=None):
|
||||
try:
|
||||
res = getattr(settings, param)
|
||||
except AttributeError:
|
||||
res = default
|
||||
return res
|
||||
|
||||
class AMrelease(object):
|
||||
def __init__(self):
|
||||
mode = getParam('AM_PDP_MODE', "unix")
|
||||
if mode == "inet":
|
||||
host = getParam('AM_PDP_HOST', 'localhost')
|
||||
port = getParam('AM_PDP_PORT', '9998')
|
||||
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.sock.connect((host, int(port)))
|
||||
else:
|
||||
path = getParam('AM_PDP_SOCKET', '/var/amavis/amavisd.sock')
|
||||
self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
self.sock.connect(path)
|
||||
|
||||
def decode(self, answer):
|
||||
def repl(match):
|
||||
return struct.pack("B", string.atoi(match.group(0)[1:], 16))
|
||||
|
||||
return re.sub(r"%([0-9a-fA-F]{2})", repl, answer)
|
||||
|
||||
def __del__(self):
|
||||
self.sock.close()
|
||||
|
||||
def sendreq(self, mailid, secretid, recipient, *others):
|
||||
self.sock.send("""request=release
|
||||
mail_id=%s
|
||||
secret_id=%s
|
||||
quar_type=Q
|
||||
recipient=%s
|
||||
|
||||
""" % (mailid, secretid, recipient))
|
||||
answer = self.sock.recv(1024)
|
||||
answer = self.decode(answer)
|
||||
if re.search("250 [\d\.]+ Ok", answer):
|
||||
return True
|
||||
return False
|
||||
@@ -17,6 +17,7 @@ from mailng.lib import events
|
||||
from mailng.lib import _render, _ctx_ok, _ctx_ko, decode
|
||||
from mailng.lib import db
|
||||
from mailng.admin.models import Mailbox
|
||||
from lib import AMrelease
|
||||
from datetime import datetime
|
||||
import email
|
||||
import re
|
||||
@@ -219,8 +220,6 @@ def _redirect_to_index(request, message, count):
|
||||
@login_required
|
||||
def delete(request, mail_id, count=1):
|
||||
conn = db.getconnection("amavis_quarantine")
|
||||
if count == 1:
|
||||
mail_id = "'%s'" % mail_id
|
||||
status, error = db.execute(conn,
|
||||
"DELETE FROM msgs WHERE mail_id IN (%s)" % mail_id)
|
||||
if status:
|
||||
@@ -233,13 +232,12 @@ def delete(request, mail_id, count=1):
|
||||
@login_required
|
||||
def release(request, mail_id, count=1):
|
||||
conn = db.getconnection("amavis_quarantine")
|
||||
if count == 1:
|
||||
mail_id = "'%s'" % mail_id
|
||||
status, cursor = db.execute(conn, """
|
||||
SELECT msgs.mail_id,secret_id,quar_type,maddr.email FROM msgs, maddr, msgrcpt
|
||||
WHERE msgrcpt.mail_id=msgs.mail_id AND msgrcpt.rid=maddr.id AND msgs.mail_id IN (%s)
|
||||
""" % (mail_id))
|
||||
emails = {}
|
||||
amr = AMrelease()
|
||||
for row in cursor.fetchall():
|
||||
if not emails.has_key(row[0]):
|
||||
emails[row[0]] = {}
|
||||
@@ -249,14 +247,15 @@ WHERE msgrcpt.mail_id=msgs.mail_id AND msgrcpt.rid=maddr.id AND msgs.mail_id IN
|
||||
count = 0
|
||||
error = None
|
||||
for k, values in emails.iteritems():
|
||||
cmd = "/tmp/amavisd-release "
|
||||
cmd += "%s %s" % (k, values["secret"])
|
||||
for rcpt in values["rcpts"]:
|
||||
cmd += " %s" % rcpt
|
||||
cmd += "\n"
|
||||
result = os.system(cmd)
|
||||
result = amr.sendreq(k, values["secret"], *values["rcpts"])
|
||||
# cmd = "/tmp/amavisd-release "
|
||||
# cmd += "%s %s" % (k, values["secret"])
|
||||
# for rcpt in values["rcpts"]:
|
||||
# cmd += " %s" % rcpt
|
||||
# cmd += "\n"
|
||||
# result = os.system(cmd)
|
||||
# if re.search("250 [^\s]+ Ok", result):
|
||||
if not result:
|
||||
if result:
|
||||
count += 1
|
||||
else:
|
||||
error = result
|
||||
@@ -278,10 +277,10 @@ def process(request):
|
||||
ids += "'%s'" % id
|
||||
if ids == "":
|
||||
return HttpResponseRedirect(reverse(index))
|
||||
if request.POST.has_key("release"):
|
||||
if request.POST["action"] == "release":
|
||||
release(request, ids, count)
|
||||
|
||||
if request.POST.has_key("delete"):
|
||||
if request.POST["action"] == "delete":
|
||||
delete(request, ids, count)
|
||||
|
||||
try:
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
import socket
|
||||
import sys
|
||||
import re
|
||||
import struct
|
||||
from optparse import OptionParser
|
||||
|
||||
def getsocket(options):
|
||||
if options.mode == "net":
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.connect((options.host, options.port))
|
||||
|
||||
return s
|
||||
|
||||
def from_stdin():
|
||||
res = []
|
||||
for line in sys.stdin:
|
||||
res += [line]
|
||||
return res
|
||||
|
||||
def decodevalue(val):
|
||||
def pack(match):
|
||||
return struct.pack('B', match.group(0))
|
||||
res = re.sub("%([0-9a-fA-F]{2})", pack, val)
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = OptionParser()
|
||||
parser.add_option("-o", "--host", default="127.0.0.1",
|
||||
help="")
|
||||
parser.add_option("-p", "--port", default=9998,
|
||||
help="")
|
||||
parser.add_option("-s", "--socket", default="",
|
||||
help="")
|
||||
parser.add_option("-m", "--mode", default="unix",
|
||||
help="")
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
if not len(args):
|
||||
print "Nothing to do, exiting."
|
||||
sys.exit(1)
|
||||
|
||||
s = getsocket(options)
|
||||
# if args[0] == '-':
|
||||
# worklist = from_stdin()
|
||||
# else:
|
||||
# worklist = [args[0]]
|
||||
|
||||
# for message in worklist:
|
||||
# params = message.split()
|
||||
params = ["k1URJIk76bKa", "k1URJIk76bKa", "antoine.nguyen@streamcore.com"]
|
||||
cmd = """request=release
|
||||
mail_id=%s
|
||||
secret_id=%s
|
||||
quar_type=Q
|
||||
recipient=%s
|
||||
|
||||
""" % (params[0], params[1], params[2])
|
||||
s.send(cmd)
|
||||
answer = s.recv(1024)
|
||||
print answer
|
||||
|
||||
s.close()
|
||||
@@ -64,8 +64,8 @@ window.addEvent("domready", function() {
|
||||
mysubmit = function(event, name) {
|
||||
event.stop();
|
||||
new Element('input', {
|
||||
'type' : 'submit', 'name' : name, style: "display:none"
|
||||
}).inject($("quarlistingform"));
|
||||
'type' : 'hidden', 'name' : "action", style: "display:none", 'value' : name
|
||||
}).inject($("quarlistingform"), "top");
|
||||
$("quarlistingform").set("send", {
|
||||
onSuccess : function(res) {
|
||||
response = JSON.decode(res);
|
||||
|
||||
@@ -108,3 +108,13 @@ VIRTUAL_GID = "vmail"
|
||||
|
||||
# Quarantine messages maximum age (in days) before deletion
|
||||
# MAX_MESSAGES_AGE = 14
|
||||
|
||||
# AM.PDP daemon
|
||||
# Modify above parameters if you want MailNG to be able
|
||||
# to release messages from the quarantine. Mode can be
|
||||
# either "inet" or "unix".
|
||||
|
||||
# AM_PDP_MODE = "inet"
|
||||
# AM_PDP_HOST = "localhost"
|
||||
# AM_PDP_PORT = 9998
|
||||
# AM_PDP_SOCKET = "/var/amavis/amavisd.sock"
|
||||
|
||||
@@ -309,12 +309,15 @@ body {
|
||||
}
|
||||
|
||||
.header {
|
||||
margin-left: 20px;
|
||||
margin-bottom: 20px;
|
||||
margin: 10px 0px 20px 20px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
font-size: medium;
|
||||
width: 50%;
|
||||
float: left;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#setcontent h4 {
|
||||
@@ -323,9 +326,11 @@ body {
|
||||
|
||||
#infos {
|
||||
float: right;
|
||||
width: 40%;
|
||||
color: green;
|
||||
font-weight: bold;
|
||||
margin-right: 10px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.info {
|
||||
|
||||
@@ -95,12 +95,13 @@
|
||||
{% endif %}
|
||||
<div class="header">
|
||||
<h1>{% block middletitle %}{% endblock %}</h1>
|
||||
{% if messages %}
|
||||
<div id="infos">
|
||||
{% if messages %}
|
||||
{% for m in messages %}{{ m }}{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="spacer"></div>
|
||||
<div id="menubar" class="menu2">
|
||||
{% block menu %}{% endblock %}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user