Skip to content

Commit

Permalink
Enabled asynchronous learning from user using RQ
Browse files Browse the repository at this point in the history
see #160
  • Loading branch information
tonioo committed Oct 20, 2023
1 parent de13b12 commit efd6721
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 24 deletions.
37 changes: 37 additions & 0 deletions modoboa_amavis/tasks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"""Async tasks."""

from typing import List

from django.utils.translation import ngettext

from modoboa.core import models as core_models

from .lib import SpamassassinClient
from .sql_connector import SQLconnector


def manual_learning(user_pk: int,
mtype: str,
selection: List[str],
recipient_db: str):
"""Task to trigger manual learning for given selection."""
user = core_models.User.objects.get(pk=user_pk)
connector = SQLconnector()
saclient = SpamassassinClient(user, recipient_db)
for item in selection:
rcpt, mail_id = item.split()
content = connector.get_mail_content(mail_id.encode("ascii"))
result = saclient.learn_spam(rcpt, content) if mtype == "spam" \
else saclient.learn_ham(rcpt, content)
if not result:
break
connector.set_msgrcpt_status(
rcpt, mail_id, mtype[0].upper()
)
if saclient.error is None:
saclient.done()
message = ngettext("%(count)d message processed successfully",
"%(count)d messages processed successfully",
len(selection)) % {"count": len(selection)}
else:
message = saclient.error
39 changes: 15 additions & 24 deletions modoboa_amavis/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,18 @@
from django.utils.translation import gettext as _, ngettext
from django.views.decorators.csrf import csrf_exempt

import django_rq

from modoboa.admin.models import Domain, Mailbox
from modoboa_amavis import tasks
from modoboa.lib.exceptions import BadRequest
from modoboa.lib.paginator import Paginator
from modoboa.lib.web_utils import getctx, render_to_json_response
from modoboa.parameters import tools as param_tools
from . import constants
from .forms import LearningRecipientForm
from .lib import (
AMrelease, QuarantineNavigationParameters, SpamassassinClient,
AMrelease, QuarantineNavigationParameters,
manual_learning_enabled, selfservice
)
from .models import Msgrcpt, Msgs
Expand Down Expand Up @@ -192,7 +195,7 @@ def viewheaders(request, mail_id):
return render(request, "modoboa_amavis/viewheader.html", context)


def check_mail_id(request, mail_id):
def check_mail_id(request, mail_id) -> list:
if isinstance(mail_id, six.string_types):
if "rcpt" in request.POST:
mail_id = ["%s %s" % (request.POST["rcpt"], mail_id)]
Expand Down Expand Up @@ -345,29 +348,17 @@ def mark_messages(request, selection, mtype, recipient_db=None):
"user" if request.user.role == "SimpleUsers" else "global"
)
selection = check_mail_id(request, selection)
connector = SQLconnector()
saclient = SpamassassinClient(request.user, recipient_db)
for item in selection:
rcpt, mail_id = item.split()
content = connector.get_mail_content(mail_id.encode("ascii"))
result = saclient.learn_spam(rcpt, content) if mtype == "spam" \
else saclient.learn_ham(rcpt, content)
if not result:
break
connector.set_msgrcpt_status(
rcpt, mail_id, mtype[0].upper()
)
if saclient.error is None:
saclient.done()
message = ngettext("%(count)d message processed successfully",
"%(count)d messages processed successfully",
len(selection)) % {"count": len(selection)}
else:
message = saclient.error
status = 400 if saclient.error else 200

queue = django_rq.get_queue("default")
queue.enqueue(tasks.manual_learning,
request.user.pk,
mtype,
selection,
recipient_db)

return render_to_json_response({
"message": message, "reload": True
}, status=status)
"message": _("Your request is being processed..."), "reload": True
})


@login_required
Expand Down

0 comments on commit efd6721

Please sign in to comment.