mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-18 05:51:26 +02:00
wip: sort spam messages by score.
Better navigation parameters storing. We don't use the same places to store webmail and quarantine parameters anymore. see #375
This commit is contained in:
@@ -19,17 +19,17 @@ class Qtable(tables.Table):
|
||||
idkey = "mailid"
|
||||
|
||||
type = tables.Column(
|
||||
"type", align="center", width="30px",
|
||||
"type", align="center", width="30px", sort_order="type"
|
||||
)
|
||||
score = tables.Column("score", label=ugettext_lazy("Score"), limit=6,
|
||||
sort_order="score")
|
||||
rstatus = tables.ImgColumn("rstatus", width='25px', sortable=False)
|
||||
from_ = tables.Column("from", label=ugettext_lazy("From"), limit=30,
|
||||
sortable=False)
|
||||
sort_order="from")
|
||||
subject = tables.Column("subject", label=ugettext_lazy("Subject"), limit=40,
|
||||
sortable=False)
|
||||
sort_order="subject")
|
||||
time = tables.Column("date", label=ugettext_lazy("Date"), sort_order="date")
|
||||
to = tables.Column("to", label=ugettext_lazy("To"), sortable=False)
|
||||
to = tables.Column("to", label=ugettext_lazy("To"), sort_order="to")
|
||||
|
||||
cols_order = []
|
||||
|
||||
@@ -39,8 +39,12 @@ class Qtable(tables.Table):
|
||||
|
||||
class SQLconnector(MBconnector):
|
||||
order_translation_table = {
|
||||
"type": "mail__msgrcpt__content",
|
||||
"score": "mail__msgrcpt__bspam_level",
|
||||
"date": "mail__time_num"
|
||||
"date": "mail__time_num",
|
||||
"subject": "mail__subject",
|
||||
"from": "mail__from_addr",
|
||||
"to": "mail__msgrcpt__rid__email"
|
||||
}
|
||||
|
||||
def __init__(self, mail_ids=None, filter=None):
|
||||
@@ -56,14 +60,16 @@ class SQLconnector(MBconnector):
|
||||
filter &= Q(mail__in=self.mail_ids)
|
||||
if self.filter:
|
||||
filter &= self.filter
|
||||
self.messages = Quarantine.objects.filter(filter).values("mail__from_addr",
|
||||
"mail__msgrcpt__rid__email",
|
||||
"mail__subject",
|
||||
"mail__mail_id",
|
||||
"mail__time_num",
|
||||
"mail__msgrcpt__content",
|
||||
"mail__msgrcpt__bspam_level",
|
||||
"mail__msgrcpt__rs")
|
||||
self.messages = Quarantine.objects.filter(filter).values(
|
||||
"mail__from_addr",
|
||||
"mail__msgrcpt__rid__email",
|
||||
"mail__subject",
|
||||
"mail__mail_id",
|
||||
"mail__time_num",
|
||||
"mail__msgrcpt__content",
|
||||
"mail__msgrcpt__bspam_level",
|
||||
"mail__msgrcpt__rs"
|
||||
)
|
||||
if "order" in kwargs:
|
||||
order = kwargs["order"]
|
||||
sign = ""
|
||||
|
||||
@@ -14,9 +14,11 @@ from modoboa.lib.exceptions import ModoboaException
|
||||
from modoboa.lib.webutils import (
|
||||
getctx, ajax_response, ajax_simple_response
|
||||
)
|
||||
from modoboa.lib.email_listing import parse_search_parameters
|
||||
from modoboa.lib.templatetags.lib_tags import pagination_bar
|
||||
from modoboa.extensions.admin.models import Mailbox, Domain
|
||||
from templatetags.amavis_tags import quar_menu, viewm_menu
|
||||
from modoboa.extensions.amavis.templatetags.amavis_tags import (
|
||||
quar_menu, viewm_menu
|
||||
)
|
||||
from .lib import selfservice, AMrelease
|
||||
from .sql_listing import SQLlisting, SQLemail, get_wrapper
|
||||
from .models import Msgrcpt
|
||||
@@ -50,6 +52,37 @@ def empty_quarantine(request):
|
||||
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
|
||||
|
||||
|
||||
def store_navparams(request):
|
||||
"""Store navigation paramters into session.
|
||||
|
||||
:param request: current request
|
||||
"""
|
||||
import re
|
||||
|
||||
sessionkey = 'quarantine_navparams'
|
||||
if not sessionkey in request.session:
|
||||
request.session[sessionkey] = {}
|
||||
navparams = request.session[sessionkey]
|
||||
navparams["order"] = request.GET.get("sort_order", "-date")
|
||||
navparams["page"] = int(request.GET.get("page", 1))
|
||||
for param, defvalue in [('pattern', ''), ('criteria', 'from_addr')]:
|
||||
navparams[param] = re.escape(request.GET.get(param, defvalue))
|
||||
|
||||
|
||||
def get_navparam(request, param, defaultvalue=None):
|
||||
"""Retrieve a navigation parameter.
|
||||
|
||||
Just a simple getter to avoid using the full key name to access a
|
||||
parameter.
|
||||
|
||||
:param request: current request object
|
||||
:param str param: parameter name
|
||||
:param defaultvalue: default value if none is found
|
||||
:return: parameter's value
|
||||
"""
|
||||
return request.session['quarantine_navparams'].get(param, defaultvalue)
|
||||
|
||||
|
||||
@login_required
|
||||
def _listing(request):
|
||||
flt = None
|
||||
@@ -60,14 +93,10 @@ def _listing(request):
|
||||
if not Domain.objects.get_for_admin(request.user).count():
|
||||
return empty_quarantine(request)
|
||||
|
||||
order = request.GET.get("sort_order", "-date")
|
||||
if not "navparams" in request.session:
|
||||
request.session["navparams"] = {}
|
||||
request.session["navparams"]["order"] = order
|
||||
|
||||
parse_search_parameters(request)
|
||||
if "pattern" in request.session:
|
||||
criteria = request.session["criteria"]
|
||||
store_navparams(request)
|
||||
pattern = get_navparam(request, 'pattern', '')
|
||||
if pattern:
|
||||
criteria = get_navparam(request, 'criteria')
|
||||
if criteria == "both":
|
||||
criteria = "from_addr,subject,to"
|
||||
for c in criteria.split(","):
|
||||
@@ -83,21 +112,13 @@ def _listing(request):
|
||||
flt = nfilter if flt is None else flt | nfilter
|
||||
|
||||
msgs = get_wrapper().get_mails(request, rcptfilter)
|
||||
|
||||
if "page" in request.GET:
|
||||
request.session["page"] = request.GET["page"]
|
||||
pageid = int(request.session["page"])
|
||||
else:
|
||||
if "page" in request.session:
|
||||
del request.session["page"]
|
||||
pageid = 1
|
||||
|
||||
page = get_navparam(request, 'page')
|
||||
lst = SQLlisting(
|
||||
request.user, msgs, flt,
|
||||
navparams=request.session["navparams"],
|
||||
navparams=request.session["quarantine_navparams"],
|
||||
elems_per_page=int(parameters.get_user(request.user, "MESSAGES_PER_PAGE"))
|
||||
)
|
||||
page = lst.paginator.getpage(pageid)
|
||||
page = lst.paginator.getpage(page)
|
||||
if not page:
|
||||
return empty_quarantine(request)
|
||||
|
||||
@@ -110,16 +131,10 @@ def _listing(request):
|
||||
|
||||
@login_required
|
||||
def index(request):
|
||||
<<<<<<< HEAD
|
||||
return _render(request, "amavis/index.html", dict(
|
||||
deflocation="listing/?sort_order=-date",
|
||||
defcallback="listing_cb", selection="quarantine"
|
||||
))
|
||||
=======
|
||||
return render(request, "amavis/index.html", dict(
|
||||
deflocation="listing/", defcallback="listing_cb", selection="quarantine"
|
||||
deflocation="listing/?sort_order=-date", defcallback="listing_cb",
|
||||
selection="quarantine"
|
||||
))
|
||||
>>>>>>> master
|
||||
|
||||
|
||||
def getmailcontent_selfservice(request, mail_id):
|
||||
|
||||
@@ -142,9 +142,10 @@ class ImapListing(EmailListing):
|
||||
def __init__(self, user, password, **kwargs):
|
||||
self.user = user
|
||||
self.mbc = IMAPconnector(user=user.username, password=password)
|
||||
if "pattern" in kwargs:
|
||||
self.parse_search_parameters(kwargs["criteria"],
|
||||
kwargs["pattern"])
|
||||
if "pattern" in kwargs and kwargs["pattern"]:
|
||||
self.parse_search_parameters(
|
||||
kwargs["criteria"], kwargs["pattern"]
|
||||
)
|
||||
else:
|
||||
self.mbc.criterions = []
|
||||
|
||||
@@ -604,17 +605,6 @@ def html2plaintext(content):
|
||||
return plaintext
|
||||
|
||||
|
||||
def get_current_url(request):
|
||||
if not "folder" in request.session:
|
||||
return ""
|
||||
|
||||
res = "%s?page=%s" % (request.session["folder"], request.session["page"])
|
||||
for p in ["criteria", "pattern", "order"]:
|
||||
if p in request.session.keys():
|
||||
res += "&%s=%s" % (p, request.session[p])
|
||||
return res
|
||||
|
||||
|
||||
def create_mail_attachment(attdef):
|
||||
"""Create the MIME part corresponding to the given attachment.
|
||||
|
||||
@@ -725,7 +715,7 @@ def send_mail(request, posturl=None):
|
||||
password=request.session["password"]).push_mail(sentfolder, msg)
|
||||
clean_attachments(request.session["compose_mail"]["attachments"])
|
||||
del request.session["compose_mail"]
|
||||
return True, dict(url=get_current_url(request))
|
||||
return True, {}
|
||||
|
||||
listing = _render_to_string(request, "webmail/compose.html",
|
||||
{"form": form, "noerrors": True,
|
||||
|
||||
@@ -63,8 +63,8 @@ def move(request):
|
||||
if not arg in request.GET:
|
||||
raise WebmailError(_("Invalid request"))
|
||||
mbc = get_imapconnector(request)
|
||||
mbc.move(request.GET["msgset"], request.session["mbox"], request.GET["to"])
|
||||
resp = listmailbox(request, request.session["mbox"], update_session=False)
|
||||
mbc.move(request.GET["msgset"], get_navparam(request, 'mbox'), request.GET["to"])
|
||||
resp = listmailbox(request, get_navparam(request, 'mbox'), update_session=False)
|
||||
resp.update(status="ok")
|
||||
return ajax_simple_response(resp)
|
||||
|
||||
@@ -191,8 +191,7 @@ def editfolder(request, tplname="webmail/folder.html"):
|
||||
res["newmb"] = form.cleaned_data["name"]
|
||||
res["oldparent"] = oldparent
|
||||
res["newparent"] = pf
|
||||
if "mbox" in request.session:
|
||||
del request.session["mbox"]
|
||||
remove_navparam(request, 'mbox')
|
||||
return ajax_simple_response(res)
|
||||
|
||||
ctx["mboxes"] = mbc.getmboxes(request.user)
|
||||
@@ -220,8 +219,7 @@ def delfolder(request):
|
||||
mbc = IMAPconnector(user=request.user.username,
|
||||
password=request.session["password"])
|
||||
mbc.delete_folder(name)
|
||||
if "mbox" in request.session:
|
||||
del request.session["mbox"]
|
||||
remove_navparam(request, 'mbox')
|
||||
return ajax_response(request)
|
||||
|
||||
|
||||
@@ -303,7 +301,7 @@ def render_mboxes_list(request, imapc):
|
||||
:param imapc: an ``IMAPconnector` object
|
||||
:return: a string
|
||||
"""
|
||||
curmbox = request.session.get("mbox", "INBOX")
|
||||
curmbox = get_navparam(request, "mbox", "INBOX")
|
||||
return _render_to_string(request, "webmail/folders.html", {
|
||||
"selected": curmbox,
|
||||
"mboxes": imapc.getmboxes(request.user),
|
||||
@@ -311,23 +309,50 @@ def render_mboxes_list(request, imapc):
|
||||
})
|
||||
|
||||
|
||||
def set_nav_params(request):
|
||||
if not "navparams" in request.session:
|
||||
request.session["navparams"] = {}
|
||||
def store_navparams(request, extra_parameters=None):
|
||||
"""Store navigation parameters into session
|
||||
|
||||
request.session["pageid"] = \
|
||||
int(request.GET.get("page", 1))
|
||||
if not request.GET.get("order", False):
|
||||
if not "order" in request.session["navparams"]:
|
||||
request.session["navparams"]["order"] = "-date"
|
||||
else:
|
||||
request.session["navparams"]["order"] = request.GET.get("order")
|
||||
:param request: current request object
|
||||
"""
|
||||
import re
|
||||
|
||||
for p in ["pattern", "criteria"]:
|
||||
if request.GET.get(p, False):
|
||||
request.session["navparams"][p] = request.GET[p]
|
||||
elif p in request.session["navparams"]:
|
||||
del request.session["navparams"][p]
|
||||
sessionkey = 'webmail_navparams'
|
||||
if not sessionkey in request.session:
|
||||
request.session[sessionkey] = {}
|
||||
navparams = request.session[sessionkey]
|
||||
navparams["page"] = int(request.GET.get("page", 1))
|
||||
navparams["order"] = request.GET.get("sort_order", "-date")
|
||||
for param, defvalue in [("pattern", ""), ("criteria", "from_addr")]:
|
||||
navparams[param] = re.escape(request.GET.get(param, defvalue))
|
||||
if extra_parameters is None:
|
||||
return
|
||||
for param, defvalue in extra_parameters:
|
||||
navparams[param] = re.escape(request.GET.get(param, defvalue))
|
||||
|
||||
|
||||
def get_navparam(request, param, defaultvalue=None):
|
||||
"""Retrieve a navigation parameter.
|
||||
|
||||
Just a simple getter to avoid using the full key name to access a
|
||||
parameter.
|
||||
|
||||
:param request: current request object
|
||||
:param str param: parameter name
|
||||
:param defaultvalue: default value if none is found
|
||||
:return: parameter's value
|
||||
"""
|
||||
return request.session['webmail_navparams'].get(param, defaultvalue)
|
||||
|
||||
|
||||
def remove_navparam(request, param):
|
||||
"""Remove a navigation parameter from session.
|
||||
|
||||
:param request: current request object
|
||||
:param str param: parameter name
|
||||
"""
|
||||
navparams = request.session["webmail_navparams"]
|
||||
if param in navparams:
|
||||
del navparams[param]
|
||||
|
||||
|
||||
def listmailbox(request, defmailbox="INBOX", update_session=True):
|
||||
@@ -341,19 +366,17 @@ def listmailbox(request, defmailbox="INBOX", update_session=True):
|
||||
:param defmailbox: the default mailbox (when not present inside request arguments)
|
||||
:return: a dictionnary
|
||||
"""
|
||||
mbox = request.GET.get("mbox", defmailbox)
|
||||
if update_session:
|
||||
set_nav_params(request)
|
||||
request.session["mbox"] = mbox
|
||||
|
||||
store_navparams(request, [('mbox', defmailbox)])
|
||||
mbox = get_navparam(request, 'mbox')
|
||||
lst = ImapListing(
|
||||
request.user, request.session["password"],
|
||||
baseurl="?action=listmailbox&mbox=%s&" % mbox,
|
||||
folder=mbox,
|
||||
elems_per_page=int(parameters.get_user(request.user, "MESSAGES_PER_PAGE")),
|
||||
**request.session["navparams"]
|
||||
**request.session["webmail_navparams"]
|
||||
)
|
||||
return lst.render(request, request.session["pageid"])
|
||||
return lst.render(request, get_navparam(request, 'page'))
|
||||
|
||||
|
||||
def render_compose(request, form, posturl, email=None, insert_signature=False):
|
||||
@@ -530,7 +553,7 @@ def index(request):
|
||||
raise WebmailError(_("Bad request"))
|
||||
response = dict(selection="webmail")
|
||||
|
||||
curmbox = request.session.get("mbox", "INBOX")
|
||||
curmbox = get_navparam(request, "mbox", "INBOX")
|
||||
if not request.is_ajax():
|
||||
request.session["lastaction"] = None
|
||||
imapc = get_imapconnector(request)
|
||||
|
||||
@@ -139,16 +139,3 @@ class EmailListing(object):
|
||||
else:
|
||||
listing = self.fetch(request, page.id_start, page.id_stop)
|
||||
return dict(listing=listing, navbar=self.render_navbar(page, self.baseurl))
|
||||
|
||||
|
||||
def parse_search_parameters(request):
|
||||
if 'pattern' in request.GET:
|
||||
request.session["pattern"] = re.escape(request.GET["pattern"])
|
||||
if 'criteria' in request.GET:
|
||||
request.session["criteria"] = request.GET["criteria"]
|
||||
else:
|
||||
request.session["criteria"] = ["from_addr"]
|
||||
else:
|
||||
for p in ["pattern", "criteria"]:
|
||||
if p in request.session.keys():
|
||||
del request.session[p]
|
||||
|
||||
@@ -43,7 +43,7 @@ class Column(object):
|
||||
limit = getattr(self, "limit")
|
||||
if limit:
|
||||
# The value is not necessarily a string, so...
|
||||
col["value"] = str(col["value"])
|
||||
col["value"] = unicode(col["value"])
|
||||
if len(col["value"]) > limit:
|
||||
col["value"] = col["value"][0:limit] + "..."
|
||||
except AttributeError:
|
||||
|
||||
Reference in New Issue
Block a user