Skip to content
This repository has been archived by the owner on May 13, 2019. It is now read-only.

Commit

Permalink
email notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
drinks committed Feb 15, 2012
1 parent 45b4105 commit ec55328
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 3 deletions.
76 changes: 76 additions & 0 deletions one80/photos/management/commands/newtagnotifications.py
@@ -0,0 +1,76 @@
import datetime
import logging

from django.conf import settings
from django.core.mail import send_mail
from django.core.management.base import BaseCommand, CommandError
from django.template import loader, Context
from optparse import make_option

from postmark.models import EmailMessage
from one80.photos.models import Annotation

THRESHOLD = getattr(settings, 'ANNOTATION_MAX_QUEUE_SIZE', 5)

class Command(BaseCommand):
args = None
option_list = BaseCommand.option_list + (
make_option('--sender',
dest='sender',
default='cron',
help='The sender of the call; could be "cron" or "hook"'),
)
help = '''
Sends notifications of new annotations.
This is run 2 ways: crontab and post-save hook.
If called from cron, it will only email every hour at most.
If called from a hook, it will send if n or more new annotations are queued,
and 5 minutes have passed since the last annotation was submitted, not more than every 30 minutes.
'''

def handle(self, *args, **options):
verbosity = int(options.get('verbosity', 0))
if verbosity == 0:
level = logging.WARNING
elif verbosity == 1:
level = logging.INFO
else:
level = logging.DEBUG

logging.basicConfig(level=level, format="%(message)s")
annot_qset = Annotation.objects.unpublished().order_by('-created_date')
try:
last_email = EmailMessage.objects.filter(subject__startswith='[180] New annotations').order_by('-created_at')[0]
except IndexError:
last_email = lambda: None
last_email.created_at=datetime.datetime(1970,1,1)
waiting = annot_qset.filter(created_date__gt=last_email.created_at)
send_email = False
now = datetime.datetime.now()
if not waiting.count():
logging.info('No annotations queued.')
return

if options.get('sender') == 'hook':
if ((waiting.count() >= THRESHOLD) and
((now - datetime.timedelta(minutes=20) >= last_email.created_at) or
(now - datetime.timedelta(minutes=5) >= waiting[1].created_date))):
send_email = True
else:
if (((waiting.count() >= THRESHOLD) and now - datetime.timedelta(minutes=20) >= last_email.created_at) or
(waiting.count() and (now - datetime.timedelta(hours=1) >= last_email.created_at))):
send_email = True

if not send_email:
logging.info('Found %d queued annotations, but it\'s not time to send mail yet, skipping.' % waiting.count())
else:
ctx = {
'annotations': waiting,
}
subject = '[180] New annotations are waiting for approval'
message = loader.get_template('emails/new_annotations.txt').render(Context(ctx))
if send_mail(subject,
message,
'%s <%s>' % ('180-mailer', settings.EMAIL_FROM),
[admin[1] for admin in settings.ADMINS]):
logging.info('Email sent.')
12 changes: 9 additions & 3 deletions one80/photos/models.py
Expand Up @@ -6,7 +6,7 @@
from django.contrib.auth.models import User
from django.core.files.base import ContentFile
from django.db import models
from django.db.models.signals import pre_save
from django.db.models.signals import pre_save, post_save
from django.template import Context
from django.template.loader import get_template
from PIL import Image
Expand Down Expand Up @@ -308,11 +308,17 @@ def _get_thumbnail(self, **kwargs):
self.thumbnail.save(self.get_filename(), ContentFile(bffr.getvalue()), save=False)
bffr.close()

def save_annotation_handler(sender, instance, *args, **kwargs):
def pre_save_annotation_handler(sender, instance, *args, **kwargs):
if instance.is_public and not instance.person:
instance.person = Person.objects.get_or_create(first_name=instance.first_name,
last_name=instance.last_name,
title=instance.title,
organization=instance.organization,)[0]

pre_save.connect(save_annotation_handler, sender=Annotation)
def post_save_annotation_handler(sender, instance, *args, **kwargs):
if not instance.is_public:
from django.core.management import call_command
call_command('newtagnotifications', sender='hook')

pre_save.connect(pre_save_annotation_handler, sender=Annotation)
post_save.connect(post_save_annotation_handler, sender=Annotation)
15 changes: 15 additions & 0 deletions one80/photos/templates/emails/new_annotations.txt
@@ -0,0 +1,15 @@
Hello there,

This is just a friendly email to let you know there are some new annotations awaiting your approval:

{% for annot in annotations %}
- {{ annot.name }}, {{ annot.position }} in {{ annot.hearing.title }}
http://180.sunlightfoundation.com/admin/photos/annotation/{{ annot.pk }}/

{% endfor %}

As a reminder, you can always see the unapproved queue at http://180.sunlightfoundation.com/admin/photos/annotation/?is_public__exact=0

Thanks and have a great day!

- The 180° Project
1 change: 1 addition & 0 deletions requirements.txt
Expand Up @@ -19,4 +19,5 @@ yql
-e git+https://github.com/dandrinkard/python-inboxinfluence.git#egg=python_inboxinfluence-dev
-e git+https://github.com/dandrinkard/python-crunchbase.git#egg=python_crunchbase-dev
-e git+https://github.com/liberation/django-jsonfield.git#egg=django_jsonfield-dev
# important to stick with this fork; relies on a new model field
-e git+https://github.com/dandrinkard/django-postmark.git#egg=django_postmark-dev

0 comments on commit ec55328

Please sign in to comment.