Browse files

Updated the pluggable-backend branch to include all the changes made …

…from trunk.

The big change here is that backends are now in charge of rendering their
own templates. get_formatted_messages was moved to the backend and each
backend has access to it from BaseBackend.
  • Loading branch information...
1 parent 81de973 commit 62e90a47823b3932cb23a5487af365411f52cafd @brosner brosner committed Jan 6, 2009
Showing with 56 additions and 88 deletions.
  1. +19 −4 notification/backends/base.py
  2. +25 −9 notification/backends/email.py
  3. +12 −75 notification/models.py
View
23 notification/backends/base.py
@@ -1,4 +1,6 @@
+from django.template.loader import render_to_string
+
class BaseBackend(object):
"""
The base backend.
@@ -10,10 +12,23 @@ def can_send(self, user, notice_type):
"""
return False
- def deliver(self, recipients, notice_type):
+ def deliver(self, recipient, notice_type, extra_context):
"""
- Called once each recipient has been verified with ``can_send``. This
- will determine the best way to deliver the notification to all
- recipients.
+ Deliver a notification to the given recipient.
"""
raise NotImplemented()
+
+ def get_formatted_messages(self, formats, label, context):
+ """
+ Returns a dictionary with the format identifier as the key. The values are
+ are fully rendered templates with the given context.
+ """
+ format_templates = {}
+ for format in formats:
+ # conditionally turn off autoescaping for .txt extensions in format
+ if format.endswith(".txt"):
+ context.autoescape = False
+ format_templates[format] = render_to_string((
+ "notification/%s/%s" % (label, format),
+ "notification/%s" % format), context_instance=context)
+ return format_templates
View
34 notification/backends/email.py
@@ -24,18 +24,34 @@ def can_send(self, user, notice_type):
return True
return False
- def deliver(self, recipients, notice_type, message):
+ def deliver(self, recipient, notice_type, extra_context):
+ # TODO: require this to be passed in extra_context
+ current_site = Site.objects.get_current()
notices_url = u"http://%s%s" % (
unicode(Site.objects.get_current()),
reverse("notification_notices"),
)
- subject = render_to_string("notification/notification_subject.txt", {
- "display": ugettext(notice_type.display),
- })
- message_body = render_to_string("notification/notification_body.txt", {
- "message": message_to_text(message),
+
+ # update context with user specific translations
+ context = Context({
+ "user": recipient,
+ "notice": ugettext(notice_type.display),
"notices_url": notices_url,
- "contact_email": settings.CONTACT_EMAIL,
+ "current_site": current_site,
})
- send_mail(subject, message_body,
- settings.DEFAULT_FROM_EMAIL, recipients)
+ context.update(extra_context)
+
+ messages = self.get_formatted_messages((
+ "short.txt",
+ "full.txt"
+ ), notice_type.label, context)
+
+ subject = "".join(render_to_string("notification/email_subject.txt", {
+ "message": messages["short.txt"],
+ }, context).splitlines())
+
+ body = render_to_string("notification/email_body.txt", {
+ "message": messages["full.txt"],
+ }, context)
+
+ send_mail(subject, body, settings.DEFAULT_FROM_EMAIL, [recipient])
View
87 notification/models.py
@@ -218,62 +218,24 @@ def get_notification_language(user):
raise LanguageStoreNotAvailable
raise LanguageStoreNotAvailable
-def get_formatted_messages(formats, label, context):
- """
- Returns a dictionary with the format identifier as the key. The values are
- are fully rendered templates with the given context.
- """
- format_templates = {}
- for format in formats:
- # conditionally turn off autoescaping for .txt extensions in format
- if format.endswith(".txt"):
- context.autoescape = False
- format_templates[format] = render_to_string((
- 'notification/%s/%s' % (label, format),
- 'notification/%s' % format), context_instance=context)
- return format_templates
-
def send_now(users, label, extra_context=None, on_site=True):
"""
- Creates a new notice.
-
- This is intended to be how other apps create new notices.
-
- notification.send(user, 'friends_invite_sent', {
- 'spam': 'eggs',
- 'foo': 'bar',
- )
-
- You can pass in on_site=False to prevent the notice emitted from being
- displayed on the site.
+ Sends a notifications to the given users and configured based on the
+ arguments passed in. Example usage::
- FIXME: this function needs some serious reworking.
+ notification.send([user], "friends_invite_sent", {
+ "spam": "eggs",
+ "foo": "bar",
+ })
"""
if extra_context is None:
extra_context = {}
notice_type = NoticeType.objects.get(label=label)
-
- notice_type = NoticeType.objects.get(label=label)
- backend_recipients = {}
- current_site = Site.objects.get_current()
- notices_url = u"http://%s%s" % (
- unicode(current_site),
- reverse("notification_notices"),
- )
-
current_language = get_language()
-
- formats = (
- 'short.txt',
- 'full.txt',
- 'notice.html',
- 'full.html',
- ) # TODO make formats configurable
-
+
for user in users:
- recipients = []
# get user language for user from language store defined in
# NOTIFICATION_LANGUAGE_MODULE setting
try:
@@ -284,42 +246,15 @@ def send_now(users, label, extra_context=None, on_site=True):
if language is not None:
# activate the user's language
activate(language)
-
- # update context with user specific translations
- context = Context({
- "user": user,
- "notice": ugettext(notice_type.display),
- "notices_url": notices_url,
- "current_site": current_site,
- })
- context.update(extra_context)
-
- # get prerendered format messages
- # TODO: figure out how to handle this in the branch.
- messages = get_formatted_messages(formats, label, context)
-
- # Strip newlines from subject
- # TODO: this should move to the email backend
- subject = ''.join(render_to_string('notification/email_subject.txt', {
- 'message': messages['short.txt'],
- }, context).splitlines())
-
- body = render_to_string('notification/email_body.txt', {
- 'message': messages['full.txt'],
- }, context)
- notice = Notice.objects.create(user=user, message=messages['notice.html'],
- notice_type=notice_type, on_site=on_site)
for key, backend in NOTIFICATION_BACKENDS:
- recipients = backend_recipients.setdefault(key, [])
if backend.can_send(user, notice_type):
- recipients.append(user)
- for key, backend in NOTIFICATION_BACKENDS:
- backend.deliver(backend_recipients[key], notice_type, message)
-
+ backend.deliver(user, notice_type, extra_context)
+
# reset environment to original language
activate(current_language)
+
def send(*args, **kwargs):
"""
A basic interface around both queue and send_now. This honors a global
@@ -340,6 +275,7 @@ def send(*args, **kwargs):
else:
return send_now(*args, **kwargs)
+
def queue(users, label, extra_context=None, on_site=True):
"""
Queue the notification in NoticeQueueBatch. This allows for large amounts
@@ -357,6 +293,7 @@ def queue(users, label, extra_context=None, on_site=True):
notices.append((user, label, extra_context, on_site))
NoticeQueueBatch(pickled_data=pickle.dumps(notices).encode("base64")).save()
+
class ObservedItemManager(models.Manager):
def all_for(self, observed, signal):

0 comments on commit 62e90a4

Please sign in to comment.