Skip to content

Commit

Permalink
Merge pull request #130 from crypotex/feature/129
Browse files Browse the repository at this point in the history
Add celery server setup and tasks (feature/129)
  • Loading branch information
crypotex committed Dec 3, 2015
2 parents 6592af2 + bc1c46c commit e9dfe32
Show file tree
Hide file tree
Showing 12 changed files with 188 additions and 77 deletions.
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
'django-widget-tweaks==1.4.1',
'pytz==2015.6',
'freezegun==0.3.5',
'django-tables2==1.0.4'
'django-tables2==1.0.4',
'celery==3.1.19'
]

setup(
Expand Down
22 changes: 22 additions & 0 deletions taas/reservation/tasks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import logging

from celery import shared_task
from django.utils import timezone

from taas.reservation import models


logger = logging.getLogger(__name__)


@shared_task
def remove_expired_reservations():
limit_date = timezone.now() - timezone.timedelta(minutes=10)
unpaid_reservations = models.Reservation.objects.filter(paid=False,
date_created__lt=limit_date)
if unpaid_reservations.exists():
unpaid_reservations.delete()
logger.info("Expired unpaid reservations has been removed.")
else:
logger.info("There are no expired unpaid reservations.")

1 change: 1 addition & 0 deletions taas/server/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from taas.server.celery import app as celery_app
10 changes: 10 additions & 0 deletions taas/server/base_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

import os

from datetime import timedelta

from django.conf import global_settings
from django.core.urlresolvers import reverse_lazy

Expand Down Expand Up @@ -96,6 +98,14 @@
}
}

# CELERY SETTINGS
BROKER_URL = 'redis://localhost:6379/0'
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'

CELERY_TIMEZONE = 'Europe/Tallinn'

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'Europe/Tallinn'
Expand Down
14 changes: 14 additions & 0 deletions taas/server/celery.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import os

from celery import Celery
from django.conf import settings

# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'taas.server.settings')

app = Celery('taas')

# Using a string here means the worker will not have to
# pickle the object when using Windows.
app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
7 changes: 7 additions & 0 deletions taas/server/settings.py.example
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ EMAIL_HOST_PASSWORD = 'blablabla'

ADMIN_EMAILS = ['example@gmail.com']

CELERYBEAT_SCHEDULE = {
'remove-expired-reservations': {
'task': 'taas.reservation.tasks.remove_expired_reservations',
'schedule': timedelta(minutes=5),
},
}

if DEBUG:
EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
EMAIL_FILE_PATH = os.path.join(PROJECT_ROOT, 'inbox')
27 changes: 25 additions & 2 deletions taas/server/test_settings.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from .base_settings import *
from .email_settings import *
from taas.server.base_settings import *
from taas.server.email_settings import *

SECRET_KEY = 'test-key'

Expand All @@ -14,3 +14,26 @@
'NAME': ':memory:',
}
}

CELERY_EAGER_PROPAGATES_EXCEPTIONS = True
CELERY_ALWAYS_EAGER = True
BROKER_BACKEND = 'memory'

CELERYBEAT_SCHEDULE = {
'remove-expired-reservations': {
'task': 'taas.reservation.tasks.remove_expired_reservations',
'schedule': timedelta(minutes=5),
},
}

EMAIL_HOST = 'smtp.example.com'

EMAIL_HOST_USER = 'test.user@example.com'

EMAIL_HOST_PASSWORD = 'test'

ADMIN_EMAILS = ['test.admin@example.com']

if DEBUG:
EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
EMAIL_FILE_PATH = os.path.join(PROJECT_ROOT, 'inbox')
12 changes: 8 additions & 4 deletions taas/user/handlers.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
import logging

from taas.user import tasks

logger = logging.getLogger(__name__)


def send_emails_to_users(sender, instance=None, created=False, **kwargs):
if created:
instance.email_user_on_registration()
tasks.email_user_on_registration.delay(instance.id)

if instance.is_active:
instance.email_user_on_activation()
tasks.email_user_on_activation.delay(instance.id)

return

old_active = instance.tracker.previous('is_active')
new_active = instance.is_active

if (old_active, new_active) == (False, True):
instance.email_user_on_activation()
tasks.email_user_on_activation.delay(instance.id)
elif (old_active, new_active) == (True, False):
instance.email_user_on_deactivation()
tasks.email_user_on_deactivation.delay(instance.id)


def check_user_activation(sender, instance=None, created=False, **kwargs):

Expand Down
68 changes: 1 addition & 67 deletions taas/user/models.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import logging

from django.conf import settings
from django.contrib.auth.models import AbstractBaseUser, UserManager, PermissionsMixin
from django.core.mail import send_mail
from django.core.validators import RegexValidator, MinValueValidator
from django.db import models
from django.utils import timezone
Expand Down Expand Up @@ -36,6 +34,7 @@ def create_user(self, email=None, password=None, **extra_fields):
def create_superuser(self, email, password, **extra_fields):
return self._create_user(email, password, True, True, **extra_fields)


class User(AbstractBaseUser, PermissionsMixin):
first_name = models.CharField(_('first name'), max_length=30)
last_name = models.CharField(_('last name'), max_length=30)
Expand Down Expand Up @@ -81,7 +80,6 @@ def display_budget_money(self):
"""
return '%d€' % self.budget


def create_pin(self):
"""
Generates a pin for user
Expand All @@ -91,67 +89,3 @@ def create_pin(self):
used_pins = set(User.objects.values_list('pin', flat=True))
all_pins.difference(used_pins)
self.pin = sample(all_pins, 1)[0]

def email_user_on_registration(self):
"""
Sends an email to this user, when he is created.
"""
message = settings.USER_REGISTRATION_MESSAGE
message = message % {'first_name': self.first_name}
subject = settings.REGISTRATION_SUBJECT
from_email = settings.EMAIL_HOST_USER

send_mail(subject, message, from_email, [self.email])
logger.info('Registration message for user with email %s has been sent.' % self.email)

def email_user_on_activation(self):
"""
Sends an email to this user, when he is verified.
"""
message = settings.USER_VERIFICATION_MESSAGE
message = message % {'first_name': self.first_name}
subject = settings.USER_STATUS_SUBJECT
from_email = settings.EMAIL_HOST_USER

send_mail(subject, message, from_email, [self.email])
logger.info('Activation message for user with email %s has been sent.' % self.email)

def email_user_on_deactivation(self):
"""
Sends an email to this user, when he is disabled.
"""
message = settings.USER_DISABLE_MESSAGE
message = message % {'first_name': self.first_name}
subject = settings.USER_STATUS_SUBJECT
from_email = settings.EMAIL_HOST_USER

send_mail(subject, message, from_email, [self.email])
logger.info('Deactivation message for user with email %s has been sent.' % self.email)

def email_admin_on_user_registration(self):
"""
Sends an email to the admin users, when new user was created.
"""
message = settings.ADMIN_REGISTRATION_MESSAGE
message = message % {'email': self.email}
subject = settings.REGISTRATION_SUBJECT
from_email = settings.EMAIL_HOST_USER
to_emails = settings.ADMIN_EMAILS

send_mail(subject, message, from_email, to_emails)
logger.info('User with email %s registration message has been sent to admin emails: %s.'
% (self.email, ', '.join(to_emails)))

def email_admin_on_user_deactivation(self):
"""
Sends an email to the admin users, when new user was deactivated.
"""
message = settings.ADMIN_USER_DISABLE_MESSAGE
message = message % {'email': self.email}
subject = settings.USER_STATUS_SUBJECT
from_email = settings.EMAIL_HOST_USER
to_emails = settings.ADMIN_EMAILS

send_mail(subject, message, from_email, to_emails)
logger.info('User with email %s deactivation message has been sent to admin emails: %s.'
% (self.email, ', '.join(to_emails)))
95 changes: 95 additions & 0 deletions taas/user/tasks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import logging

from celery import shared_task
from django.conf import settings
from django.core.mail import send_mail

from taas.user import models


logger = logging.getLogger(__name__)


@shared_task
def email_user_on_registration(user_id):
"""
Sends an email to this user, when he is created.
:param user_id: id of the User
"""
user = models.User.objects.get(id=user_id)
message = settings.USER_REGISTRATION_MESSAGE
message = message % {'first_name': user.first_name}
subject = settings.REGISTRATION_SUBJECT
from_email = settings.EMAIL_HOST_USER

send_mail(subject, message, from_email, [user.email])
logger.info('Registration message for user with email %s has been sent.' % user.email)


@shared_task
def email_user_on_activation(user_id):
"""
Sends an email to this user, when he is verified.
:param user_id: id of the User
"""
user = models.User.objects.get(id=user_id)
message = settings.USER_VERIFICATION_MESSAGE
message = message % {'first_name': user.first_name}
subject = settings.USER_STATUS_SUBJECT
from_email = settings.EMAIL_HOST_USER

send_mail(subject, message, from_email, [user.email])
logger.info('Activation message for user with email %s has been sent.' % user.email)


@shared_task
def email_user_on_deactivation(user_id):
"""
Sends an email to this user, when he is disabled.
:param user_id: id of the User
"""
user = models.User.objects.get(id=user_id)
message = settings.USER_DISABLE_MESSAGE
message = message % {'first_name': user.first_name}
subject = settings.USER_STATUS_SUBJECT
from_email = settings.EMAIL_HOST_USER

send_mail(subject, message, from_email, [user.email])
logger.info('Deactivation message for user with email %s has been sent.' % user.email)


@shared_task
def email_admin_on_user_registration(user_id):
"""
Sends an email to the admin users, when new user was created.
:param user_id: id of the User
"""
user = models.User.objects.get(id=user_id)
message = settings.ADMIN_REGISTRATION_MESSAGE
message = message % {'email': user.email}
subject = settings.REGISTRATION_SUBJECT
from_email = settings.EMAIL_HOST_USER
to_emails = settings.ADMIN_EMAILS

send_mail(subject, message, from_email, to_emails)
logger.info('User with email %s registration message has been sent to admin emails: %s.'
% (user.email, ', '.join(to_emails)))


@shared_task
def email_admin_on_user_deactivation(user_id):
"""
Sends an email to the admin users, when new user was deactivated.
:param user_id: id of the User
"""

user = models.User.objects.get(id=user_id)
message = settings.ADMIN_USER_DISABLE_MESSAGE
message = message % {'email': user.email}
subject = settings.USER_STATUS_SUBJECT
from_email = settings.EMAIL_HOST_USER
to_emails = settings.ADMIN_EMAILS

send_mail(subject, message, from_email, to_emails)
logger.info('User with email %s deactivation message has been sent to admin emails: %s.'
% (user.email, ', '.join(to_emails)))
1 change: 0 additions & 1 deletion taas/user/tests/test_user_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ def test_deactivated_user_has_None_pin(self):
user.save()
self.assertEqual(user.pin, None)


def test_logged_in_user_can_update_his_last_name(self):
self.client.login(username=self.user.email, password='isherenow', follow=True)

Expand Down
5 changes: 3 additions & 2 deletions taas/user/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from taas.user import forms
from taas.user import mixins
from taas.user import models
from taas.user import tasks

logger = logging.getLogger(__name__)

Expand All @@ -31,7 +32,7 @@ class UserCreateView(CreateView):

def form_valid(self, form):
self.object = form.save()
self.object.email_admin_on_user_registration()
tasks.email_admin_on_user_registration.delay(self.object.id)

messages.success(self.request, self.success_message)
logger.info('Unverified user with email %s has been successfully registered.'
Expand Down Expand Up @@ -78,7 +79,7 @@ def get_form_kwargs(self):
def form_valid(self, form):
self.request.user.is_active = False
self.request.user.save()
self.request.user.email_admin_on_user_deactivation()
tasks.email_admin_on_user_deactivation.delay(self.request.user.id)
logger.info('User with email %s has been been deactivated.' % form.cleaned_data.get('email'))

logout(self.request)
Expand Down

0 comments on commit e9dfe32

Please sign in to comment.