Permalink
Browse files

Remove dependency on Celery and django-celery. Relates to #5

- refactored the email backend to use threading instead of Celery
- dropped Celery based Bugzilla integration. Fixes #1
- dropped the following configuration settings:
  EMAILS_FOR_DEBUG (replaced by ADMINS), ENABLE_ASYNC_EMAIL,
  BROKER_URL, CELERY_TASK_RESULT_EXPIRES, CELERY_RESULT_BACKEND,
  CELERYD_TIMER_PRECISION, CELERY_IGNORE_RESULT,
  CELERY_MAX_CACHED_RESULTS, CELERY_DEFAULT_RATE_LIMIT
  • Loading branch information...
atodorov committed Jun 6, 2017
1 parent 4a67c34 commit b323b4281b01e61884ad9495c4c108e68dc3bed4
View
@@ -2,8 +2,6 @@ Django==1.8.14
kerberos==1.1.1
qpid-python==0.20
django-uuslug==1.1.8
django-celery>=3.1.10
celery>=3.1.15,<4.0
odfpy>=0.9.6
python-bugzilla
django-pagination==1.0.7
@@ -49,7 +49,7 @@ def send_confirm_mail(self, request, active_key,
args=[active_key.activation_key, ])
)
mailto(
template_name=template_name, to_mail=self.cleaned_data['email'],
template_name=template_name, recipients=self.cleaned_data['email'],
subject='Your new %s account confirmation' % s.domain,
context={
'user': self.instance,
@@ -119,7 +119,6 @@ def test_open_registration_page(self):
'<input value="Register" class="loginbutton sprites" type="submit">',
html=True)
@patch('tcms.core.contrib.auth.views.settings.ENABLE_ASYNC_EMAIL', new=False)
@patch('tcms.core.utils.mailto.threading.Thread', new=MockThread)
@patch('tcms.core.contrib.auth.models.sha1')
def assert_user_registration(self, username, sha1):
View
@@ -1,61 +1,36 @@
# -*- coding: utf-8 -*-
import threading
from celery import task
from django.conf import settings
from django.core.mail import get_connection
from django.core.mail import EmailMessage
from django.core.mail import send_mail
from django.template.loader import render_to_string
@task()
def blocking_mailto(template_name, subject, to_mail, context=None,
request=None, from_mail=None, cc=None):
"""
Based on Django's send_mail, to send notify email
Arguments:
template = the template of mail
to_mail = to someone's email address
subject = define the subject of the mail
context = Context to render the mail content
"""
try:
mail_content = render_to_string(template_name, context, request=request)
connection = get_connection(username=None,
password=None,
fail_silently=False)
def mailto(template_name, subject, recipients=None,
context=None, sender=settings.EMAIL_FROM,
cc=None):
# make a list with recipients and filter out duplicates
if isinstance(recipients, list):
recipients = list(set(recipients))
else:
recipients = [recipients]
subject = settings.EMAIL_SUBJECT_PREFIX + subject
from_email = from_mail or settings.EMAIL_FROM
recipient_list = isinstance(to_mail, list) \
and list(set(to_mail)) or [to_mail, ]
EmailMessage(subject, mail_content, from_email, recipient_list,
connection=connection, bcc=cc).send()
except:
if settings.DEBUG:
raise
# extend with the CC list
if cc:
recipients.extend(cc)
def non_blocking_mailto(template_name, subject, recipients=None,
context=None, sender=settings.EMAIL_FROM,
cc=None):
body = render_to_string(template_name, context)
# if debugging then send to ADMINS as well
if settings.DEBUG:
recipients = settings.EMAILS_FOR_DEBUG
for (admin_name, admin_email) in settings.ADMINS:
recipients.append(admin_email)
email_msg = EmailMessage(subject=subject, body=body,
from_email=sender, to=recipients, bcc=cc)
body = render_to_string(template_name, context)
email_thread = threading.Thread(target=email_msg.send, args=[True, ])
email_thread = threading.Thread(
target=send_mail,
args=(subject, body, sender, recipients),
kwargs={'fail_silently': False}
)
# This is to tell Python not to wait for the thread to return
email_thread.setDaemon(True)
email_thread.start()
if settings.ENABLE_ASYNC_EMAIL:
send_email_using_threading = mailto = blocking_mailto.delay
else:
send_email_using_threading = non_blocking_mailto
mailto = blocking_mailto
@@ -9,7 +9,7 @@
from django.conf import settings
from django.core.urlresolvers import reverse
__all__ = ['add_bug_to_bugzilla']
__all__ = ['BugzillaThread']
def _rpc_add_bug_to_bugzilla(rpc, testcase, bug):
@@ -36,8 +36,9 @@ def _rpc_add_bug_to_bugzilla(rpc, testcase, bug):
class BugzillaThread(threading.Thread):
"""
Execute Bugzilla RPC code in a thread if celery
is not enabled.
Execute Bugzilla RPC code in a thread!
Executed from the IssueTracker interface methods.
"""
def __init__(self, rpc, testcase, bug):
@@ -48,35 +49,3 @@ def __init__(self, rpc, testcase, bug):
def run(self):
_rpc_add_bug_to_bugzilla(self.rpc, self.testcase, self.bug)
try:
# todo: fix this or completely remove it
# Adding test cases to Bugzilla currently breaks
# when executed as Celery task, but not when executed
# as a thread!!!
_celery_add_bug_to_bugzilla = None
# from celery import task
# @task
# def _celery_add_bug_to_bugzilla(rpc, testcase, bug):
# _rpc_add_bug_to_bugzilla(rpc, testcase, bug)
except ImportError:
_celery_add_bug_to_bugzilla = None
def add_bug_to_bugzilla(rpc, testcase, bug):
"""
Executed from the IssueTracker interface methods.
This function takes care to run either in a thread or
as a Celery task depending on how the settings are defined.
NOTE: this is the only public function from this module!
"""
# todo: fix problem with celery, doesn't seem to work properly
# or maybe self.rpc doesn't get serialized very well ???
if _celery_add_bug_to_bugzilla:
_celery_add_bug_to_bugzilla.delay(rpc, testcase, bug)
else:
BugzillaThread(rpc, testcase, bug).start()
@@ -89,7 +89,7 @@ def __init__(self, tracker):
def add_testcase_to_issue(self, testcases, issue):
for case in testcases:
bugzilla_integration.add_bug_to_bugzilla(self.rpc, case, issue)
bugzilla_integration.BugzillaThread(self.rpc, case, issue).start()
def all_issues_link(self, ids):
if not self.tracker.report_url:
View
@@ -42,9 +42,6 @@
EMAIL_PORT = 25
EMAIL_FROM = 'kiwi@example.com'
EMAIL_SUBJECT_PREFIX = '[Kiwi-TCMS] '
EMAILS_FOR_DEBUG = []
ENABLE_ASYNC_EMAIL = True
###########################################################
@@ -213,8 +210,6 @@
'django_comments',
'kobo.django.xmlrpc',
'djcelery',
'kombu.transport.django',
'pagination',
'tinymce',
@@ -272,20 +267,6 @@
)
# Celery worker settings
BROKER_URL = 'django://'
CELERY_TASK_RESULT_EXPIRES = 60 * 2
CELERY_RESULT_BACKEND = 'djcelery.backends.database:DatabaseBackend'
CELERYD_TIMER_PRECISION = 120
CELERY_IGNORE_RESULT = True
CELERY_MAX_CACHED_RESULTS = -1
CELERY_DEFAULT_RATE_LIMIT = '250/m'
# Celery async queue
import djcelery
djcelery.setup_loader()
# user guide URL
USER_GUIDE_URL = "http://kiwitestpad.readthedocs.io/en/latest/tutorial.html"
View
@@ -26,9 +26,6 @@
'debug_toolbar',
)
# For local development
ENABLE_ASYNC_EMAIL = False
FILE_UPLOAD_DIR = os.path.join(TCMS_ROOT_PATH, '..', 'uploads')
# Needed by django.template.context_processors.debug:
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from django.conf import settings
from tcms.core.utils.mailto import send_email_using_threading
from tcms.core.utils.mailto import mailto
def email_case_update(case):
@@ -16,7 +16,7 @@ def email_case_update(case):
'test_case_plain_text': txt.get_plain_text(),
}
template = settings.CASE_EMAIL_TEMPLATE
send_email_using_threading(template, subject, recipients, context, cc=cc)
mailto(template, subject, recipients, context, cc=cc)
def email_case_deletion(case):
@@ -29,7 +29,7 @@ def email_case_deletion(case):
'case': case,
}
template = settings.CASE_EMAIL_TEMPLATE
send_email_using_threading(template, subject, recipients, context, cc=cc)
mailto(template, subject, recipients, context, cc=cc)
def get_case_notification_recipients(case):
View
@@ -310,7 +310,7 @@ def mail_scene(cls, objects, field=None, value=None, ctype=None, object_pk=None)
'reviewer': {
'template_name': 'mail/change_case_reviewer.txt',
'subject': 'You have been speicific to be the reviewer of cases',
'to_mail': list(set(tcs.values_list('reviewer__email', flat=True))),
'recipients': list(set(tcs.values_list('reviewer__email', flat=True))),
'context': {'test_cases': tcs},
}
}
@@ -1,25 +1,25 @@
# -*- coding: utf-8 -*-
from django.conf import settings
from tcms.core.utils.mailto import send_email_using_threading
from tcms.core.utils.mailto import mailto
def email_plan_update(plan):
recipients = get_plan_notification_recipients(plan)
if len(recipients) == 0:
return
subject = u'TestPlan %s has been updated.' % plan.pk
send_email_using_threading(settings.PLAN_EMAIL_TEMPLATE, subject,
recipients, {'plan': plan})
mailto(settings.PLAN_EMAIL_TEMPLATE, subject,
recipients, {'plan': plan})
def email_plan_deletion(plan):
recipients = get_plan_notification_recipients(plan)
if len(recipients) == 0:
return
subject = u'TestPlan %s has been deleted.' % plan.pk
send_email_using_threading(settings.PLAN_DELELE_EMAIL_TEMPLATE, subject,
recipients, {'plan': plan})
mailto(settings.PLAN_DELELE_EMAIL_TEMPLATE, subject,
recipients, {'plan': plan})
def get_plan_notification_recipients(plan):
View
@@ -562,7 +562,7 @@ def mail_scene(cls, objects, field=None, value=None, ctype=None,
'assignee': {
'template_name': 'mail/change_case_run_assignee.txt',
'subject': 'Assignee of run %s has been changed' % tr.run_id,
'to_mail': tr.get_notify_addrs(),
'recipients': tr.get_notify_addrs(),
'context': {'test_run': tr, 'test_case_runs': tcrs},
}
}
View
@@ -35,10 +35,6 @@
from django.core.wsgi import get_wsgi_application
_application = get_wsgi_application()
# Celery async queue for apache mod_wsgi
import djcelery
djcelery.setup_loader()
def application(environ, start_response):
environ['PATH_INFO'] = environ['SCRIPT_NAME'] + environ['PATH_INFO']

0 comments on commit b323b42

Please sign in to comment.