# HG changeset patch # User Brian Neal # Date 1258173152 0 # Node ID 9c18250972d57299c32e980ca944af97e75cbe54 # Parent 3ae999b0c53bb559bda773c1d9e89a0cc3378772 Refactored the markdown/smiley logic. Created classes for Markdown and Smilify. No longer call render_to_string() in models.py for various models. diff -r 3ae999b0c53b -r 9c18250972d5 gpp/bio/models.py --- a/gpp/bio/models.py Sun Nov 08 21:15:31 2009 +0000 +++ b/gpp/bio/models.py Sat Nov 14 04:32:32 2009 +0000 @@ -8,9 +8,11 @@ from django.db import models from django.contrib import auth from django.conf import settings -from django.template.loader import render_to_string from django.core.cache import cache +from core.markup import Markdown +from smiley import Smilify + def avatar_file_path_for_user(username, filename): return os.path.join(settings.AVATAR_DIR, 'users', username, filename) @@ -46,10 +48,9 @@ ordering = ('user__username', ) def save(self, *args, **kwargs): - html = render_to_string('bio/markdown.html', {'data': self.profile_text}) - self.profile_html = html.strip() - html = render_to_string('bio/markdown.html', {'data': self.signature}) - self.signature_html = html.strip() + md = Markdown() + sm = Smilify() + self.profile_html = sm.convert(md.convert(self.profile_text)) + self.signature_html = sm.convert(md.convert(self.signature)) super(UserProfile, self).save(*args, **kwargs) cache.delete('avatar_' + self.user.username) - diff -r 3ae999b0c53b -r 9c18250972d5 gpp/comments/models.py --- a/gpp/comments/models.py Sun Nov 08 21:15:31 2009 +0000 +++ b/gpp/comments/models.py Sat Nov 14 04:32:32 2009 +0000 @@ -6,9 +6,11 @@ from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes import generic from django.contrib.auth.models import User -from django.template.loader import render_to_string from django.core import urlresolvers +from core.markup import markdown +from smiley import smilify + COMMENT_MAX_LENGTH = getattr(settings, 'COMMENT_MAX_LENGTH', 3000) @@ -51,8 +53,7 @@ return u'%s: %s...' % (self.user.username, self.comment[:50]) def save(self, force_insert=False, force_update=False): - html = render_to_string('comments/markdown.html', {'data': self.comment}) - self.html = html.strip() + self.html = smilify(markdown(self.comment)) super(Comment, self).save(force_insert, force_update) def get_absolute_url(self): diff -r 3ae999b0c53b -r 9c18250972d5 gpp/core/markup.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gpp/core/markup.py Sat Nov 14 04:32:32 2009 +0000 @@ -0,0 +1,30 @@ +""" +This is a thin wrapper around the Markdown class which deals with the +differences in Markdown versions on the production and development server. +This code was inspired by the code in +django/contrib/markup/templatetags/markup.py. +Currently, we only have to worry about Markdown 1.6b and 2.0. +""" +import markdown as _markdown +from django.utils.encoding import force_unicode + +from smiley.utils import smilify + +class Markdown(object): + + def __init__(self, safe_mode='escape'): + # Unicode support only in markdown v1.7 or above. Version_info + # exists only in markdown v1.6.2rc-2 or above. + self.unicode_support = getattr(_markdown, "version_info", None) >= (1, 7) + self.md = _markdown.Markdown(safe_mode=safe_mode) + + def convert(self, s): + if self.unicode_support: + return self.md.convert(force_unicode(s)) + else: + return force_unicode(self.md.convert(s)) + + +def markdown(s): + md = Markdown() + return md.convert(s) diff -r 3ae999b0c53b -r 9c18250972d5 gpp/downloads/models.py --- a/gpp/downloads/models.py Sun Nov 08 21:15:31 2009 +0000 +++ b/gpp/downloads/models.py Sat Nov 14 04:32:32 2009 +0000 @@ -6,9 +6,11 @@ import datetime from django.db import models from django.contrib.auth.models import User -from django.template.loader import render_to_string from django.template.defaultfilters import filesizeformat +from core.markup import markdown +from smiley import smilify + class Category(models.Model): """Downloads belong to categories.""" @@ -72,8 +74,7 @@ return ('downloads-details', [str(self.id)]) def save(self, force_insert=False, force_update=False): - html = render_to_string('downloads/markdown.html', {'data': self.description}) - self.html = html.strip() + self.html = smilify(markdown(self.description)) super(Download, self).save(force_insert, force_update) def vote(self, vote_value): diff -r 3ae999b0c53b -r 9c18250972d5 gpp/forums/models.py --- a/gpp/forums/models.py Sun Nov 08 21:15:31 2009 +0000 +++ b/gpp/forums/models.py Sat Nov 14 04:32:32 2009 +0000 @@ -6,7 +6,8 @@ from django.db import models from django.db.models import Q from django.contrib.auth.models import User, Group -from django.template.loader import render_to_string +from core.markup import markdown +from smiley import smilify POST_EDIT_DELTA = datetime.timedelta(seconds=3) @@ -251,8 +252,7 @@ return self.summary() def save(self, *args, **kwargs): - html = render_to_string('forums/post.html', {'data': self.body}) - self.html = html.strip() + self.html = smilify(markdown(self.body)) super(Post, self).save(*args, **kwargs) def delete(self, *args, **kwargs): diff -r 3ae999b0c53b -r 9c18250972d5 gpp/gcalendar/calendar.py --- a/gpp/gcalendar/calendar.py Sun Nov 08 21:15:31 2009 +0000 +++ b/gpp/gcalendar/calendar.py Sat Nov 14 04:32:32 2009 +0000 @@ -86,8 +86,8 @@ error = True if error: - err_msgs.append('%s - (%d) %s' % \ - (qs[i].title, code, entry.batch_status.reason)) + err_msgs.append('%s - (%d) %s' % ( + qs[i].what, code, entry.batch_status.reason)) if len(err_msgs) > 0: raise CalendarError(', '.join(err_msgs)) diff -r 3ae999b0c53b -r 9c18250972d5 gpp/gcalendar/models.py --- a/gpp/gcalendar/models.py Sun Nov 08 21:15:31 2009 +0000 +++ b/gpp/gcalendar/models.py Sat Nov 14 04:32:32 2009 +0000 @@ -4,7 +4,9 @@ from django.db import models from django.db.models import Q from django.contrib.auth.models import User -from django.template.loader import render_to_string + +from core.markup import markdown +from smiley import smilify class PendingEventManager(models.Manager): @@ -90,12 +92,9 @@ ordering = ('-date_submitted', ) def save(self, *args, **kwargs): - html = render_to_string('gcalendar/markdown.html', {'data': self.description}) - self.html = html.strip() + self.html = smilify(markdown(self.description)) super(Event, self).save(*args, **kwargs) def needs_approval(self): return self.status in (self.NEW, self.EDIT_REQ, self.DEL_REQ) - -# vim: ts=4 sw=4 diff -r 3ae999b0c53b -r 9c18250972d5 gpp/messages/models.py --- a/gpp/messages/models.py Sun Nov 08 21:15:31 2009 +0000 +++ b/gpp/messages/models.py Sat Nov 14 04:32:32 2009 +0000 @@ -4,7 +4,8 @@ from django.db import models from django.db.models import Q from django.contrib.auth.models import User -from django.template.loader import render_to_string +from core.markup import markdown +from smiley import smilify class MessageManager(models.Manager): @@ -62,8 +63,7 @@ def save(self, force_insert = False, force_update = False): if not self.id: self.send_date = datetime.datetime.now() - html = render_to_string('messages/markdown.html', {'data': self.message}) - self.html = html.strip() + self.html = smilify(markdown(self.message)) super(Message, self).save(force_insert, force_update) @models.permalink diff -r 3ae999b0c53b -r 9c18250972d5 gpp/smiley/__init__.py --- a/gpp/smiley/__init__.py Sun Nov 08 21:15:31 2009 +0000 +++ b/gpp/smiley/__init__.py Sat Nov 14 04:32:32 2009 +0000 @@ -0,0 +1,41 @@ +""" +Smiley class and function. +""" +import re + +from django.utils.safestring import SafeData +from django.utils.html import conditional_escape + +from smiley.models import Smiley + + +class Smilify(object): + """ + A class to "smilify" text by replacing text with HTML img tags of smilies. + """ + def __init__(self): + self.map = Smiley.objects.get_smiley_map() + + def convert(self, value, autoescape=False): + if not autoescape or isinstance(value, SafeData): + esc = lambda x: x + else: + esc = conditional_escape + + words = value.split() + for i, word in enumerate(words): + if word in self.map: + words[i] = self.map[word] + else: + words[i] = esc(words[i]) + return u' '.join(words) + + +def smilify(value, autoescape=False): + """ + A convenience function to "smilify" text by replacing text with HTML + img tags of smilies. + """ + s = Smilify() + return s.convert(value, autoescape) + diff -r 3ae999b0c53b -r 9c18250972d5 gpp/smiley/templatetags/smiley_tags.py --- a/gpp/smiley/templatetags/smiley_tags.py Sun Nov 08 21:15:31 2009 +0000 +++ b/gpp/smiley/templatetags/smiley_tags.py Sat Nov 14 04:32:32 2009 +0000 @@ -1,37 +1,21 @@ """ Template tags for the smiley application. """ -import re from django import template from django.template.defaultfilters import stringfilter -from django.utils.html import conditional_escape from django.utils.safestring import mark_safe -from django.utils.safestring import SafeData from smiley.models import Smiley register = template.Library() -word_split_re = re.compile(r'(\s+)') @register.filter @stringfilter def smilify(value, autoescape=False): """A filter to "smilify" text by replacing text with HTML img tags of smilies.""" - if not autoescape or isinstance(value, SafeData): - esc = lambda x: x - else: - esc = conditional_escape - - smiley_map = Smiley.objects.get_smiley_map() - - words = word_split_re.split(value) - for i, word in enumerate(words): - if word in smiley_map: - words[i] = smiley_map[word] - else: - words[i] = esc(words[i]) - return mark_safe(u''.join(words)) + from smiley import smilify + return mark_safe(smilify(value, autoescape)) smilify.needs_autoescape = True