Skip to content

Commit

Permalink
pluggable-backends: Moved message related functions into its own modu…
Browse files Browse the repository at this point in the history
…le to

prevent circular imports between models.py and backends.


git-svn-id: https://django-notification.googlecode.com/svn/branches/pluggable-backends@61 590c3fc9-4838-0410-bb95-17a0c9b37ca9
  • Loading branch information
brosner committed May 31, 2008
1 parent 25bd4ac commit c1989a4
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 99 deletions.
1 change: 1 addition & 0 deletions notification/backends/email.py
Expand Up @@ -5,6 +5,7 @@
from django.utils.translation import ugettext from django.utils.translation import ugettext


from notification import backends from notification import backends
from notification.message import message_to_text


# favour django-mailer but fall back to django.core.mail # favour django-mailer but fall back to django.core.mail
try: try:
Expand Down
109 changes: 109 additions & 0 deletions notification/message.py
@@ -0,0 +1,109 @@

from django.db.models import get_model
from django.utils.translation import ugettext


# a notice like "foo and bar are now friends" is stored in the database
# as "{auth.User.5} and {auth.User.7} are now friends".
#
# encode_object takes an object and turns it into "{app.Model.pk}" or
# "{app.Model.pk.msgid}" if named arguments are used in send()
# decode_object takes "{app.Model.pk}" and turns it into the object
#
# encode_message takes either ("%s and %s are now friends", [foo, bar]) or
# ("%(foo)s and %(bar)s are now friends", {'foo':foo, 'bar':bar}) and turns
# it into "{auth.User.5} and {auth.User.7} are now friends".
#
# decode_message takes "{auth.User.5} and {auth.User.7}" and converts it
# into a string using the given decode function to convert the object to
# string representation
#
# message_to_text and message_to_html use decode_message to produce a
# text and html version of the message respectively.

def encode_object(obj, name=None):
encoded = "%s.%s.%s" % (obj._meta.app_label, obj._meta.object_name, obj.pk)
if name:
encoded = "%s.%s" % (encoded, name)
return "{%s}" % encoded


def encode_message(message_template, objects):
if objects is None:
return message_template
if isinstance(objects, list) or isinstance(objects, tuple):
return message_template % tuple(encode_object(obj) for obj in objects)
if type(objects) is dict:
return message_template % dict((name, encode_object(obj, name)) for name, obj in objects.iteritems())
return ''


def decode_object(ref):
decoded = ref.split(".")
if len(decoded) == 4:
app, name, pk, msgid = decoded
return get_model(app, name).objects.get(pk=pk), msgid
app, name, pk = decoded
return get_model(app, name).objects.get(pk=pk), None


class FormatException(Exception):
pass


def decode_message(message, decoder):
out = []
objects = []
mapping = {}
in_field = False
prev = 0
for index, ch in enumerate(message):
if not in_field:
if ch == '{':
in_field = True
if prev != index:
out.append(message[prev:index])
prev = index
elif ch == '}':
raise FormatException("unmatched }")
elif in_field:
if ch == '{':
raise FormatException("{ inside {}")
elif ch == '}':
in_field = False
obj, msgid = decoder(message[prev+1:index])
if msgid is None:
objects.append(obj)
out.append("%s")
else:
mapping[msgid] = obj
out.append("%("+msgid+")s")
prev = index + 1
if in_field:
raise FormatException("unmatched {")
if prev <= index:
out.append(message[prev:index+1])
result = "".join(out)
if mapping:
args = mapping
else:
args = tuple(objects)
return ugettext(result) % args


def message_to_text(message):
def decoder(ref):
obj, msgid = decode_object(ref)
return unicode(obj), msgid
return decode_message(message, decoder)


def message_to_html(message):
def decoder(ref):
obj, msgid = decode_object(ref)
if hasattr(obj, "get_absolute_url"): # don't fail silenty if get_absolute_url hasn't been defined
return u"""<a href="%s">%s</a>""" % (obj.get_absolute_url(), unicode(obj)), msgid
else:
return unicode(obj), msgid
return decode_message(message, decoder)

102 changes: 3 additions & 99 deletions notification/models.py
Expand Up @@ -3,7 +3,6 @@
from django.db import models from django.db import models
from django.conf import settings from django.conf import settings
from django.db.models import Q from django.db.models import Q
from django.db.models import get_model


from django.contrib.sites.models import Site from django.contrib.sites.models import Site
from django.contrib.auth.models import User from django.contrib.auth.models import User
Expand All @@ -12,6 +11,7 @@
from django.utils.translation import ugettext from django.utils.translation import ugettext


from notification import backends from notification import backends
from notification.message import encode_message




class NoticeType(models.Model): class NoticeType(models.Model):
Expand All @@ -32,6 +32,7 @@ class Admin:
class Meta: class Meta:
verbose_name = _("notice type") verbose_name = _("notice type")
verbose_name_plural = _("notice types") verbose_name_plural = _("notice types")



NOTIFICATION_BACKENDS = backends.load_backends() NOTIFICATION_BACKENDS = backends.load_backends()
NOTICE_MEDIA = tuple( NOTICE_MEDIA = tuple(
Expand Down Expand Up @@ -62,6 +63,7 @@ class Meta:
verbose_name = _("notice setting") verbose_name = _("notice setting")
verbose_name_plural = _("notice settings") verbose_name_plural = _("notice settings")



def get_notification_setting(user, notice_type, medium): def get_notification_setting(user, notice_type, medium):
try: try:
return NoticeSetting.objects.get(user=user, notice_type=notice_type, medium=medium) return NoticeSetting.objects.get(user=user, notice_type=notice_type, medium=medium)
Expand Down Expand Up @@ -142,104 +144,6 @@ def create_notice_type(label, display, description, default=2):
NoticeType(label=label, display=display, description=description, default=default).save() NoticeType(label=label, display=display, description=description, default=default).save()
print "Created %s NoticeType" % label print "Created %s NoticeType" % label


# a notice like "foo and bar are now friends" is stored in the database
# as "{auth.User.5} and {auth.User.7} are now friends".
#
# encode_object takes an object and turns it into "{app.Model.pk}" or
# "{app.Model.pk.msgid}" if named arguments are used in send()
# decode_object takes "{app.Model.pk}" and turns it into the object
#
# encode_message takes either ("%s and %s are now friends", [foo, bar]) or
# ("%(foo)s and %(bar)s are now friends", {'foo':foo, 'bar':bar}) and turns
# it into "{auth.User.5} and {auth.User.7} are now friends".
#
# decode_message takes "{auth.User.5} and {auth.User.7}" and converts it
# into a string using the given decode function to convert the object to
# string representation
#
# message_to_text and message_to_html use decode_message to produce a
# text and html version of the message respectively.

def encode_object(obj, name=None):
encoded = "%s.%s.%s" % (obj._meta.app_label, obj._meta.object_name, obj.pk)
if name:
encoded = "%s.%s" % (encoded, name)
return "{%s}" % encoded

def encode_message(message_template, objects):
if objects is None:
return message_template
if isinstance(objects, list) or isinstance(objects, tuple):
return message_template % tuple(encode_object(obj) for obj in objects)
if type(objects) is dict:
return message_template % dict((name, encode_object(obj, name)) for name, obj in objects.iteritems())
return ''

def decode_object(ref):
decoded = ref.split(".")
if len(decoded) == 4:
app, name, pk, msgid = decoded
return get_model(app, name).objects.get(pk=pk), msgid
app, name, pk = decoded
return get_model(app, name).objects.get(pk=pk), None

class FormatException(Exception):
pass

def decode_message(message, decoder):
out = []
objects = []
mapping = {}
in_field = False
prev = 0
for index, ch in enumerate(message):
if not in_field:
if ch == '{':
in_field = True
if prev != index:
out.append(message[prev:index])
prev = index
elif ch == '}':
raise FormatException("unmatched }")
elif in_field:
if ch == '{':
raise FormatException("{ inside {}")
elif ch == '}':
in_field = False
obj, msgid = decoder(message[prev+1:index])
if msgid is None:
objects.append(obj)
out.append("%s")
else:
mapping[msgid] = obj
out.append("%("+msgid+")s")
prev = index + 1
if in_field:
raise FormatException("unmatched {")
if prev <= index:
out.append(message[prev:index+1])
result = "".join(out)
if mapping:
args = mapping
else:
args = tuple(objects)
return ugettext(result) % args

def message_to_text(message):
def decoder(ref):
obj, msgid = decode_object(ref)
return unicode(obj), msgid
return decode_message(message, decoder)

def message_to_html(message):
def decoder(ref):
obj, msgid = decode_object(ref)
if hasattr(obj, "get_absolute_url"): # don't fail silenty if get_absolute_url hasn't been defined
return u"""<a href="%s">%s</a>""" % (obj.get_absolute_url(), unicode(obj)), msgid
else:
return unicode(obj), msgid
return decode_message(message, decoder)



def send(users, notice_type_label, message_template, object_list=None, issue_notice=True): def send(users, notice_type_label, message_template, object_list=None, issue_notice=True):
""" """
Expand Down

0 comments on commit c1989a4

Please sign in to comment.