From a0d8de9db45ebc5f3c13779df19ffac842b9d96b Mon Sep 17 00:00:00 2001 From: hernani Date: Fri, 11 Jun 2010 01:31:18 +0000 Subject: [PATCH] Tries to eliminate a possible race condition when a user who is trying to ask a question registers for the first time. git-svn-id: http://svn.osqa.net/svnroot/osqa/trunk@405 0cfe37f9-358a-4d5e-be75-b63607b5c754 --- forum/models/action.py | 17 ++- forum/templatetags/extra_tags.py | 226 +++++++------------------------ forum/utils/mail.py | 3 + 3 files changed, 65 insertions(+), 181 deletions(-) diff --git a/forum/models/action.py b/forum/models/action.py index ca6b96e..d6d0c64 100644 --- a/forum/models/action.py +++ b/forum/models/action.py @@ -111,7 +111,7 @@ class Action(BaseModel): def get_type(cls): return re.sub(r'action$', '', cls.__name__.lower()) - def save(self, data=None, *args, **kwargs): + def save(self, data=None, threaded=True, *args, **kwargs): isnew = False if not self.id: @@ -127,7 +127,7 @@ class Action(BaseModel): if (self.node is None) or (not self.node.nis.wiki): self.repute_users() self.process_action() - self.trigger_hooks(True) + self.trigger_hooks(threaded, True) return self @@ -167,15 +167,18 @@ class Action(BaseModel): Action.hooks[cls].append(fn) - def trigger_hooks(self, new=True): - thread = Thread(target=trigger_hooks_threaded, args=[self, Action.hooks, new]) - thread.setDaemon(True) - thread.start() + def trigger_hooks(self, threaded, new=True): + if threaded: + thread = Thread(target=trigger_hooks, args=[self, Action.hooks, new]) + thread.setDaemon(True) + thread.start() + else: + trigger_hooks(self, Action.hooks, new) class Meta: app_label = 'forum' -def trigger_hooks_threaded(action, hooks, new): +def trigger_hooks(action, hooks, new): for cls, hooklist in hooks.items(): if isinstance(action, cls): for hook in hooklist: diff --git a/forum/templatetags/extra_tags.py b/forum/templatetags/extra_tags.py index db30278..6c3da35 100644 --- a/forum/templatetags/extra_tags.py +++ b/forum/templatetags/extra_tags.py @@ -21,18 +21,12 @@ from django.core.urlresolvers import reverse register = template.Library() GRAVATAR_TEMPLATE = ('') +'src="http://www.gravatar.com/avatar/%(gravatar_hash)s' +'?s=%(size)s&d=identicon&r=PG" ' +'alt="%(username)s\'s gravatar image" />') @register.simple_tag def gravatar(user, size): - """ - Creates an ```` for a user's Gravatar with a given size. - - This tag can accept a User object, or a dict containing the - appropriate values. - """ try: gravatar = user['gravatar'] username = user['username'] @@ -40,28 +34,11 @@ def gravatar(user, size): gravatar = user.gravatar username = user.username return mark_safe(GRAVATAR_TEMPLATE % { - 'size': size, - 'gravatar_hash': gravatar, - 'username': template.defaultfilters.urlencode(username), + 'size': size, + 'gravatar_hash': gravatar, + 'username': template.defaultfilters.urlencode(username), }) -#MAX_FONTSIZE = 18 -#MIN_FONTSIZE = 12 -#@register.simple_tag -#def tag_font_size(max_size, min_size, current_size): -# """ -# do a logarithmic mapping calcuation for a proper size for tagging cloud -# Algorithm from http://blogs.dekoh.com/dev/2007/10/29/choosing-a-good-font-size-variation-algorithm-for-your-tag-cloud/ -# """ -# #avoid invalid calculation -# if current_size == 0: -# current_size = 1 -# try: -# weight = (math.log10(current_size) - math.log10(min_size)) / (math.log10(max_size) - math.log10(min_size)) -# except: -# weight = 0 -# return MIN_FONTSIZE + round((MAX_FONTSIZE - MIN_FONTSIZE) * weight) - LEADING_PAGE_RANGE_DISPLAYED = TRAILING_PAGE_RANGE_DISPLAYED = 5 LEADING_PAGE_RANGE = TRAILING_PAGE_RANGE = 4 @@ -87,29 +64,31 @@ def cnprog_paginator(context): pages_outside_leading_range = [n + context["pages"] for n in range(0, -NUM_PAGES_OUTSIDE_RANGE, -1)] elif (context["page"] > context["pages"] - TRAILING_PAGE_RANGE): in_trailing_range = True - page_numbers = [n for n in range(context["pages"] - TRAILING_PAGE_RANGE_DISPLAYED + 1, context["pages"] + 1) if n > 0 and n <= context["pages"]] + page_numbers = [n for n in range(context["pages"] - TRAILING_PAGE_RANGE_DISPLAYED + 1, context["pages"] + 1) + if n > 0 and n <= context["pages"]] pages_outside_trailing_range = [n + 1 for n in range(0, NUM_PAGES_OUTSIDE_RANGE)] else: - page_numbers = [n for n in range(context["page"] - ADJACENT_PAGES, context["page"] + ADJACENT_PAGES + 1) if n > 0 and n <= context["pages"]] + page_numbers = [n for n in range(context["page"] - ADJACENT_PAGES, context["page"] + ADJACENT_PAGES + 1) if + n > 0 and n <= context["pages"]] pages_outside_leading_range = [n + context["pages"] for n in range(0, -NUM_PAGES_OUTSIDE_RANGE, -1)] pages_outside_trailing_range = [n + 1 for n in range(0, NUM_PAGES_OUTSIDE_RANGE)] extend_url = context.get('extend_url', '') return { - "base_url": context["base_url"], - "is_paginated": context["is_paginated"], - "previous": context["previous"], - "has_previous": context["has_previous"], - "next": context["next"], - "has_next": context["has_next"], - "page": context["page"], - "pages": context["pages"], - "page_numbers": page_numbers, - "in_leading_range" : in_leading_range, - "in_trailing_range" : in_trailing_range, - "pages_outside_leading_range": pages_outside_leading_range, - "pages_outside_trailing_range": pages_outside_trailing_range, - "extend_url" : extend_url + "base_url": context["base_url"], + "is_paginated": context["is_paginated"], + "previous": context["previous"], + "has_previous": context["has_previous"], + "next": context["next"], + "has_next": context["has_next"], + "page": context["page"], + "pages": context["pages"], + "page_numbers": page_numbers, + "in_leading_range" : in_leading_range, + "in_trailing_range" : in_trailing_range, + "pages_outside_leading_range": pages_outside_leading_range, + "pages_outside_trailing_range": pages_outside_trailing_range, + "extend_url" : extend_url } @register.inclusion_tag("pagesize.html") @@ -119,12 +98,12 @@ def cnprog_pagesize(context): """ if (context["is_paginated"]): return { - "base_url": context["base_url"], - "pagesize" : context["pagesize"], - "is_paginated": context["is_paginated"] + "base_url": context["base_url"], + "pagesize" : context["pagesize"], + "is_paginated": context["is_paginated"] } - + @register.simple_tag def get_score_badge(user): BADGE_TEMPLATE = '%(reputation)s' @@ -145,83 +124,30 @@ def get_score_badge(user): '') BADGE_TEMPLATE = smart_unicode(BADGE_TEMPLATE, encoding='utf-8', strings_only=False, errors='strict') return mark_safe(BADGE_TEMPLATE % { - 'reputation' : user.reputation, - 'gold' : user.gold, - 'silver' : user.silver, - 'bronze' : user.bronze, - 'badgesword' : _('badges'), - 'reputationword' : _('reputation points'), + 'reputation' : user.reputation, + 'gold' : user.gold, + 'silver' : user.silver, + 'bronze' : user.bronze, + 'badgesword' : _('badges'), + 'reputationword' : _('reputation points'), }) - -#@register.simple_tag -#def get_score_badge_by_details(rep, gold, silver, bronze): -# BADGE_TEMPLATE = '%(reputation)s' -# if gold > 0 : -# BADGE_TEMPLATE = '%s%s' % (BADGE_TEMPLATE, '' -# '' -# '%(gold)s' -# '') -# if silver > 0: -# BADGE_TEMPLATE = '%s%s' % (BADGE_TEMPLATE, '' -# '' -# '%(silver)s' -# '') -# if bronze > 0: -# BADGE_TEMPLATE = '%s%s' % (BADGE_TEMPLATE, '' -# '' -# '%(bronze)s' -# '') -# BADGE_TEMPLATE = smart_unicode(BADGE_TEMPLATE, encoding='utf-8', strings_only=False, errors='strict') -# return mark_safe(BADGE_TEMPLATE % { -# 'reputation' : rep, -# 'gold' : gold, -# 'silver' : silver, -# 'bronze' : bronze, -# 'repword' : _('reputation points'), -# 'badgeword' : _('badges'), -# }) - + + @register.simple_tag def get_age(birthday): current_time = datetime.datetime(*time.localtime()[0:6]) year = birthday.year month = birthday.month day = birthday.day - diff = current_time - datetime.datetime(year,month,day,0,0,0) + diff = current_time - datetime.datetime(year, month, day, 0, 0, 0) return diff.days / 365 -#@register.simple_tag -#def get_total_count(up_count, down_count): -# return up_count + down_count - -#@register.simple_tag -#def format_number(value): -# strValue = str(value) -# if len(strValue) <= 3: -# return strValue -# result = '' -# first = '' -# pattern = re.compile('(-?\d+)(\d{3})') -# m = re.match(pattern, strValue) -# while m != None: -# first = m.group(1) -# second = m.group(2) -# result = ',' + second + result -# strValue = first + ',' + second -# m = re.match(pattern, strValue) -# return first + result - -#@register.simple_tag -#def convert2tagname_list(question): -# question['tagnames'] = [name for name in question['tagnames'].split(u' ')] -# return '' - @register.simple_tag def diff_date(date, limen=2): if not date: return _('unknown') - - now = datetime.datetime.now()#datetime(*time.localtime()[0:6])#??? + + now = datetime.datetime.now() diff = now - date days = diff.days hours = int(diff.seconds/3600) @@ -237,27 +163,9 @@ def diff_date(date, limen=2): elif days == 1: return _('yesterday') elif minutes >= 60: - return ungettext('%(hr)d hour ago','%(hr)d hours ago',hours) % {'hr':hours} + return ungettext('%(hr)d hour ago', '%(hr)d hours ago', hours) % {'hr':hours} else: - return ungettext('%(min)d min ago','%(min)d mins ago',minutes) % {'min':minutes} - -#@register.simple_tag -#def get_latest_changed_timestamp(): -# try: -# from time import localtime, strftime -# from os import path -# root = settings.SITE_SRC_ROOT -# dir = ( -# root, -# '%s/forum' % root, -# '%s/templates' % root, -# ) -# stamp = (path.getmtime(d) for d in dir) -# latest = max(stamp) -# timestr = strftime("%H:%M %b-%d-%Y %Z", localtime(latest)) -# except: -# timestr = '' -# return timestr + return ungettext('%(min)d min ago', '%(min)d mins ago', minutes) % {'min':minutes} @register.simple_tag def media(url): @@ -267,66 +175,36 @@ def media(url): return posixpath.normpath(url) class ItemSeparatorNode(template.Node): - def __init__(self,separator): + def __init__(self, separator): sep = separator.strip() - if sep[0] == sep[-1] and sep[0] in ('\'','"'): + if sep[0] == sep[-1] and sep[0] in ('\'', '"'): sep = sep[1:-1] else: raise template.TemplateSyntaxError('separator in joinitems tag must be quoted') self.content = sep - def render(self,context): - return self.content -#class JoinItemListNode(template.Node): -# def __init__(self,separator=ItemSeparatorNode("''"), items=()): -# self.separator = separator -# self.items = items -# def render(self,context): -# out = [] -# empty_re = re.compile(r'^\s*$') -# for item in self.items: -# bit = item.render(context) -# if not empty_re.search(bit): -# out.append(bit) -# return self.separator.render(context).join(out) -# -#@register.tag(name="joinitems") -#def joinitems(parser,token): -# try: -# tagname,junk,sep_token = token.split_contents() -# except ValueError: -# raise template.TemplateSyntaxError("joinitems tag requires 'using \"separator html\"' parameters") -# if junk == 'using': -# sep_node = ItemSeparatorNode(sep_token) -# else: -# raise template.TemplateSyntaxError("joinitems tag requires 'using \"separator html\"' parameters") -# nodelist = [] -# while True: -# nodelist.append(parser.parse(('separator','endjoinitems'))) -# next = parser.next_token() -# if next.contents == 'endjoinitems': -# break - -# return JoinItemListNode(separator=sep_node,items=nodelist) + def render(self, context): + return self.content class BlockMediaUrlNode(template.Node): - def __init__(self,nodelist): - self.items = nodelist - def render(self,context): + def __init__(self, nodelist): + self.items = nodelist + + def render(self, context): prefix = '///' + settings.FORUM_SCRIPT_ALIAS + 'm/' url = '' if self.items: - url += '/' + url += '/' for item in self.items: url += item.render(context) url = skins.find_media_source(url) url = prefix + url out = posixpath.normpath(url) - return out.replace(' ','') + return out.replace(' ', '') @register.tag(name='blockmedia') -def blockmedia(parser,token): +def blockmedia(parser, token): try: tagname = token.split_contents() except ValueError: diff --git a/forum/utils/mail.py b/forum/utils/mail.py index b118d6f..8f6ee50 100644 --- a/forum/utils/mail.py +++ b/forum/utils/mail.py @@ -140,6 +140,9 @@ def send_template_email(recipients, template, context): t.render(Context(context)) def create_and_send_mail_messages(messages): + if not settings.EMAIL_HOST: + return + sender = Header(unicode(settings.APP_SHORT_NAME), 'utf-8') sender.append('<%s>' % unicode(settings.DEFAULT_FROM_EMAIL)) sender = u'%s <%s>' % (unicode(settings.APP_SHORT_NAME), unicode(settings.DEFAULT_FROM_EMAIL)) -- 2.39.5