[Python-modules-commits] r13620 - in packages/python-django-voting/trunk/debian/patches (1 file)

ockham-guest at users.alioth.debian.org ockham-guest at users.alioth.debian.org
Fri Jun 25 11:32:38 UTC 2010


    Date: Friday, June 25, 2010 @ 11:32:36
  Author: ockham-guest
Revision: 13620

Remove errant file from patches dir

Deleted:
  packages/python-django-voting/trunk/debian/patches/debian-changes-0+svn73-1

Deleted: packages/python-django-voting/trunk/debian/patches/debian-changes-0+svn73-1
===================================================================
--- packages/python-django-voting/trunk/debian/patches/debian-changes-0+svn73-1	2010-06-25 11:31:06 UTC (rev 13619)
+++ packages/python-django-voting/trunk/debian/patches/debian-changes-0+svn73-1	2010-06-25 11:32:36 UTC (rev 13620)
@@ -1,817 +0,0 @@
-Description: Upstream changes introduced in version 0+svn73-1
- This patch has been created by dpkg-source during the package build.
- Here's the last changelog entry, hopefully it gives details on why
- those changes were made:
- .
- python-django-voting (0+svn73-1) unstable; urgency=low
- .
-   * Initial release (Closes: #581833, LP #575481)
- .
- The person named in the Author field signed this changelog entry.
-Author: Bernhard Reiter <ockham at raz.or.at>
-Bug-Debian: http://bugs.debian.org/581833
-
----
-The information above should follow the Patch Tagging Guidelines, please
-checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
-are templates for supplementary fields that you might want to add:
-
-Origin: <vendor|upstream|other>, <url of original patch>
-Bug: <url in upstream bugtracker>
-Bug-Debian: http://bugs.debian.org/<bugnumber>
-Forwarded: <no|not-needed|url proving that it has been forwarded>
-Reviewed-By: <name and email of someone who approved the patch>
-Last-Update: <YYYY-MM-DD>
-
---- /dev/null
-+++ python-django-voting-0+svn73/build/lib/voting/__init__.py
-@@ -0,0 +1 @@
-+VERSION = (0, 1, None)
-\ No newline at end of file
---- /dev/null
-+++ python-django-voting-0+svn73/build/lib/voting/admin.py
-@@ -0,0 +1,4 @@
-+from django.contrib import admin
-+from voting.models import Vote
-+
-+admin.site.register(Vote)
---- /dev/null
-+++ python-django-voting-0+svn73/build/lib/voting/models.py
-@@ -0,0 +1,37 @@
-+from django.contrib.contenttypes import generic
-+from django.contrib.contenttypes.models import ContentType
-+from django.contrib.auth.models import User
-+from django.db import models
-+
-+from voting.managers import VoteManager
-+
-+SCORES = (
-+    (u'+1', +1),
-+    (u'-1', -1),
-+)
-+
-+class Vote(models.Model):
-+    """
-+    A vote on an object by a User.
-+    """
-+    user         = models.ForeignKey(User)
-+    content_type = models.ForeignKey(ContentType)
-+    object_id    = models.PositiveIntegerField()
-+    object       = generic.GenericForeignKey('content_type', 'object_id')
-+    vote         = models.SmallIntegerField(choices=SCORES)
-+
-+    objects = VoteManager()
-+
-+    class Meta:
-+        db_table = 'votes'
-+        # One vote per user per object
-+        unique_together = (('user', 'content_type', 'object_id'),)
-+
-+    def __unicode__(self):
-+        return u'%s: %s on %s' % (self.user, self.vote, self.object)
-+
-+    def is_upvote(self):
-+        return self.vote == 1
-+
-+    def is_downvote(self):
-+        return self.vote == -1
---- /dev/null
-+++ python-django-voting-0+svn73/build/lib/voting/views.py
-@@ -0,0 +1,153 @@
-+from django.contrib.contenttypes.models import ContentType
-+from django.core.exceptions import ObjectDoesNotExist
-+from django.http import Http404, HttpResponse, HttpResponseRedirect
-+from django.contrib.auth.views import redirect_to_login
-+from django.template import loader, RequestContext
-+from django.utils import simplejson
-+
-+from voting.models import Vote
-+
-+VOTE_DIRECTIONS = (('up', 1), ('down', -1), ('clear', 0))
-+
-+def vote_on_object(request, model, direction, post_vote_redirect=None,
-+        object_id=None, slug=None, slug_field=None, template_name=None,
-+        template_loader=loader, extra_context=None, context_processors=None,
-+        template_object_name='object', allow_xmlhttprequest=False):
-+    """
-+    Generic object vote function.
-+
-+    The given template will be used to confirm the vote if this view is
-+    fetched using GET; vote registration will only be performed if this
-+    view is POSTed.
-+
-+    If ``allow_xmlhttprequest`` is ``True`` and an XMLHttpRequest is
-+    detected by examining the ``HTTP_X_REQUESTED_WITH`` header, the
-+    ``xmlhttp_vote_on_object`` view will be used to process the
-+    request - this makes it trivial to implement voting via
-+    XMLHttpRequest with a fallback for users who don't have JavaScript
-+    enabled.
-+
-+    Templates:``<app_label>/<model_name>_confirm_vote.html``
-+    Context:
-+        object
-+            The object being voted on.
-+        direction
-+            The type of vote which will be registered for the object.
-+    """
-+    if allow_xmlhttprequest and request.is_ajax():
-+        return xmlhttprequest_vote_on_object(request, model, direction,
-+                                             object_id=object_id, slug=slug,
-+                                             slug_field=slug_field)
-+
-+    if extra_context is None: extra_context = {}
-+    if not request.user.is_authenticated():
-+        return redirect_to_login(request.path)
-+
-+    try:
-+        vote = dict(VOTE_DIRECTIONS)[direction]
-+    except KeyError:
-+        raise AttributeError("'%s' is not a valid vote type." % vote_type)
-+
-+    # Look up the object to be voted on
-+    lookup_kwargs = {}
-+    if object_id:
-+        lookup_kwargs['%s__exact' % model._meta.pk.name] = object_id
-+    elif slug and slug_field:
-+        lookup_kwargs['%s__exact' % slug_field] = slug
-+    else:
-+        raise AttributeError('Generic vote view must be called with either '
-+                             'object_id or slug and slug_field.')
-+    try:
-+        obj = model._default_manager.get(**lookup_kwargs)
-+    except ObjectDoesNotExist:
-+        raise Http404, 'No %s found for %s.' % (model._meta.app_label, lookup_kwargs)
-+
-+    if request.method == 'POST':
-+        if post_vote_redirect is not None:
-+            next = post_vote_redirect
-+        elif request.REQUEST.has_key('next'):
-+            next = request.REQUEST['next']
-+        elif hasattr(obj, 'get_absolute_url'):
-+            if callable(getattr(obj, 'get_absolute_url')):
-+                next = obj.get_absolute_url()
-+            else:
-+                next = obj.get_absolute_url
-+        else:
-+            raise AttributeError('Generic vote view must be called with either '
-+                                 'post_vote_redirect, a "next" parameter in '
-+                                 'the request, or the object being voted on '
-+                                 'must define a get_absolute_url method or '
-+                                 'property.')
-+        Vote.objects.record_vote(obj, request.user, vote)
-+        return HttpResponseRedirect(next)
-+    else:
-+        if not template_name:
-+            template_name = '%s/%s_confirm_vote.html' % (
-+                model._meta.app_label, model._meta.object_name.lower())
-+        t = template_loader.get_template(template_name)
-+        c = RequestContext(request, {
-+            template_object_name: obj,
-+            'direction': direction,
-+        }, context_processors)
-+        for key, value in extra_context.items():
-+            if callable(value):
-+                c[key] = value()
-+            else:
-+                c[key] = value
-+        response = HttpResponse(t.render(c))
-+        return response
-+
-+def json_error_response(error_message):
-+    return HttpResponse(simplejson.dumps(dict(success=False,
-+                                              error_message=error_message)))
-+
-+def xmlhttprequest_vote_on_object(request, model, direction,
-+    object_id=None, slug=None, slug_field=None):
-+    """
-+    Generic object vote function for use via XMLHttpRequest.
-+
-+    Properties of the resulting JSON object:
-+        success
-+            ``true`` if the vote was successfully processed, ``false``
-+            otherwise.
-+        score
-+            The object's updated score and number of votes if the vote
-+            was successfully processed.
-+        error_message
-+            Contains an error message if the vote was not successfully
-+            processed.
-+    """
-+    if request.method == 'GET':
-+        return json_error_response(
-+            'XMLHttpRequest votes can only be made using POST.')
-+    if not request.user.is_authenticated():
-+        return json_error_response('Not authenticated.')
-+
-+    try:
-+        vote = dict(VOTE_DIRECTIONS)[direction]
-+    except KeyError:
-+        return json_error_response(
-+            '\'%s\' is not a valid vote type.' % direction)
-+
-+    # Look up the object to be voted on
-+    lookup_kwargs = {}
-+    if object_id:
-+        lookup_kwargs['%s__exact' % model._meta.pk.name] = object_id
-+    elif slug and slug_field:
-+        lookup_kwargs['%s__exact' % slug_field] = slug
-+    else:
-+        return json_error_response('Generic XMLHttpRequest vote view must be '
-+                                   'called with either object_id or slug and '
-+                                   'slug_field.')
-+    try:
-+        obj = model._default_manager.get(**lookup_kwargs)
-+    except ObjectDoesNotExist:
-+        return json_error_response(
-+            'No %s found for %s.' % (model._meta.verbose_name, lookup_kwargs))
-+
-+    # Vote and respond
-+    Vote.objects.record_vote(obj, request.user, vote)
-+    return HttpResponse(simplejson.dumps({
-+        'success': True,
-+        'score': Vote.objects.get_score(obj),
-+    }))
---- /dev/null
-+++ python-django-voting-0+svn73/build/lib/voting/managers.py
-@@ -0,0 +1,203 @@
-+from django.conf import settings
-+from django.db import connection, models
-+
-+try:
-+    from django.db.models.sql.aggregates import Aggregate
-+except ImportError:
-+    supports_aggregates = False
-+else:
-+    supports_aggregates = True
-+
-+from django.contrib.contenttypes.models import ContentType
-+
-+if supports_aggregates:
-+    class CoalesceWrapper(Aggregate):
-+        sql_template = 'COALESCE(%(function)s(%(field)s), %(default)s)'
-+    
-+        def __init__(self, lookup, **extra): 
-+            self.lookup = lookup
-+            self.extra = extra
-+    
-+        def _default_alias(self):
-+            return '%s__%s' % (self.lookup, self.__class__.__name__.lower())
-+        default_alias = property(_default_alias)
-+    
-+        def add_to_query(self, query, alias, col, source, is_summary):
-+            super(CoalesceWrapper, self).__init__(col, source, is_summary, **self.extra)
-+            query.aggregate_select[alias] = self
-+
-+
-+    class CoalesceSum(CoalesceWrapper):
-+        sql_function = 'SUM'
-+
-+
-+    class CoalesceCount(CoalesceWrapper):
-+        sql_function = 'COUNT'
-+
-+
-+class VoteManager(models.Manager):
-+    def get_score(self, obj):
-+        """
-+        Get a dictionary containing the total score for ``obj`` and
-+        the number of votes it's received.
-+        """
-+        ctype = ContentType.objects.get_for_model(obj)
-+        result = self.filter(object_id=obj._get_pk_val(),
-+                             content_type=ctype).extra(
-+            select={
-+                'score': 'COALESCE(SUM(vote), 0)',
-+                'num_votes': 'COALESCE(COUNT(vote), 0)',
-+        }).values_list('score', 'num_votes')[0]
-+
-+        return {
-+            'score': int(result[0]),
-+            'num_votes': int(result[1]),
-+        }
-+
-+    def get_scores_in_bulk(self, objects):
-+        """
-+        Get a dictionary mapping object ids to total score and number
-+        of votes for each object.
-+        """
-+        object_ids = [o._get_pk_val() for o in objects]
-+        if not object_ids:
-+            return {}
-+        
-+        ctype = ContentType.objects.get_for_model(objects[0])
-+        
-+        if supports_aggregates:
-+            queryset = self.filter(
-+                object_id__in = object_ids,
-+                content_type = ctype,
-+            ).values(
-+                'object_id',
-+            ).annotate(
-+                score = CoalesceSum('vote', default='0'),
-+                num_votes = CoalesceCount('vote', default='0'),
-+            )
-+        else:
-+            queryset = self.filter(
-+                object_id__in = object_ids,
-+                content_type = ctype,
-+                ).extra(
-+                    select = {
-+                        'score': 'COALESCE(SUM(vote), 0)',
-+                        'num_votes': 'COALESCE(COUNT(vote), 0)',
-+                    }
-+                ).values('object_id', 'score', 'num_votes')
-+            queryset.query.group_by.append('object_id')
-+        
-+        vote_dict = {}
-+        for row in queryset:
-+            vote_dict[row['object_id']] = {
-+                'score': int(row['score']),
-+                'num_votes': int(row['num_votes']),
-+            }
-+        
-+        return vote_dict
-+
-+    def record_vote(self, obj, user, vote):
-+        """
-+        Record a user's vote on a given object. Only allows a given user
-+        to vote once, though that vote may be changed.
-+
-+        A zero vote indicates that any existing vote should be removed.
-+        """
-+        if vote not in (+1, 0, -1):
-+            raise ValueError('Invalid vote (must be +1/0/-1)')
-+        ctype = ContentType.objects.get_for_model(obj)
-+        try:
-+            v = self.get(user=user, content_type=ctype,
-+                         object_id=obj._get_pk_val())
-+            if vote == 0:
-+                v.delete()
-+            else:
-+                v.vote = vote
-+                v.save()
-+        except models.ObjectDoesNotExist:
-+            if vote != 0:
-+                self.create(user=user, content_type=ctype,
-+                            object_id=obj._get_pk_val(), vote=vote)
-+
-+    def get_top(self, Model, limit=10, reversed=False):
-+        """
-+        Get the top N scored objects for a given model.
-+
-+        Yields (object, score) tuples.
-+        """
-+        ctype = ContentType.objects.get_for_model(Model)
-+        query = """
-+        SELECT object_id, SUM(vote) as %s
-+        FROM %s
-+        WHERE content_type_id = %%s
-+        GROUP BY object_id""" % (
-+            connection.ops.quote_name('score'),
-+            connection.ops.quote_name(self.model._meta.db_table),
-+        )
-+
-+        # MySQL has issues with re-using the aggregate function in the
-+        # HAVING clause, so we alias the score and use this alias for
-+        # its benefit.
-+        if settings.DATABASE_ENGINE == 'mysql':
-+            having_score = connection.ops.quote_name('score')
-+        else:
-+            having_score = 'SUM(vote)'
-+        if reversed:
-+            having_sql = ' HAVING %(having_score)s < 0 ORDER BY %(having_score)s ASC LIMIT %%s'
-+        else:
-+            having_sql = ' HAVING %(having_score)s > 0 ORDER BY %(having_score)s DESC LIMIT %%s'
-+        query += having_sql % {
-+            'having_score': having_score,
-+        }
-+
-+        cursor = connection.cursor()
-+        cursor.execute(query, [ctype.id, limit])
-+        results = cursor.fetchall()
-+
-+        # Use in_bulk() to avoid O(limit) db hits.
-+        objects = Model.objects.in_bulk([id for id, score in results])
-+
-+        # Yield each object, score pair. Because of the lazy nature of generic
-+        # relations, missing objects are silently ignored.
-+        for id, score in results:
-+            if id in objects:
-+                yield objects[id], int(score)
-+
-+    def get_bottom(self, Model, limit=10):
-+        """
-+        Get the bottom (i.e. most negative) N scored objects for a given
-+        model.
-+
-+        Yields (object, score) tuples.
-+        """
-+        return self.get_top(Model, limit, True)
-+
-+    def get_for_user(self, obj, user):
-+        """
-+        Get the vote made on the given object by the given user, or
-+        ``None`` if no matching vote exists.
-+        """
-+        if not user.is_authenticated():
-+            return None
-+        ctype = ContentType.objects.get_for_model(obj)
-+        try:
-+            vote = self.get(content_type=ctype, object_id=obj._get_pk_val(),
-+                            user=user)
-+        except models.ObjectDoesNotExist:
-+            vote = None
-+        return vote
-+
-+    def get_for_user_in_bulk(self, objects, user):
-+        """
-+        Get a dictionary mapping object ids to votes made by the given
-+        user on the corresponding objects.
-+        """
-+        vote_dict = {}
-+        if len(objects) > 0:
-+            ctype = ContentType.objects.get_for_model(objects[0])
-+            votes = list(self.filter(content_type__pk=ctype.id,
-+                                     object_id__in=[obj._get_pk_val() \
-+                                                    for obj in objects],
-+                                     user__pk=user.id))
-+            vote_dict = dict([(vote.object_id, vote) for vote in votes])
-+        return vote_dict
---- /dev/null
-+++ python-django-voting-0+svn73/build/lib/voting/tests/tests.py
-@@ -0,0 +1,86 @@
-+r"""
-+>>> from django.contrib.auth.models import User
-+>>> from voting.models import Vote
-+>>> from voting.tests.models import Item
-+
-+##########
-+# Voting #
-+##########
-+
-+# Basic voting ###############################################################
-+
-+>>> i1 = Item.objects.create(name='test1')
-+>>> users = []
-+>>> for username in ['u1', 'u2', 'u3', 'u4']:
-+...     users.append(User.objects.create_user(username, '%s at test.com' % username, 'test'))
-+>>> Vote.objects.get_score(i1)
-+{'score': 0, 'num_votes': 0}
-+>>> Vote.objects.record_vote(i1, users[0], +1)
-+>>> Vote.objects.get_score(i1)
-+{'score': 1, 'num_votes': 1}
-+>>> Vote.objects.record_vote(i1, users[0], -1)
-+>>> Vote.objects.get_score(i1)
-+{'score': -1, 'num_votes': 1}
-+>>> Vote.objects.record_vote(i1, users[0], 0)
-+>>> Vote.objects.get_score(i1)
-+{'score': 0, 'num_votes': 0}
-+>>> for user in users:
-+...     Vote.objects.record_vote(i1, user, +1)
-+>>> Vote.objects.get_score(i1)
-+{'score': 4, 'num_votes': 4}
-+>>> for user in users[:2]:
-+...     Vote.objects.record_vote(i1, user, 0)
-+>>> Vote.objects.get_score(i1)
-+{'score': 2, 'num_votes': 2}
-+>>> for user in users[:2]:
-+...     Vote.objects.record_vote(i1, user, -1)
-+>>> Vote.objects.get_score(i1)
-+{'score': 0, 'num_votes': 4}
-+
-+>>> Vote.objects.record_vote(i1, user, -2)
-+Traceback (most recent call last):
-+    ...
-+ValueError: Invalid vote (must be +1/0/-1)
-+
-+# Retrieval of votes #########################################################
-+
-+>>> i2 = Item.objects.create(name='test2')
-+>>> i3 = Item.objects.create(name='test3')
-+>>> i4 = Item.objects.create(name='test4')
-+>>> Vote.objects.record_vote(i2, users[0], +1)
-+>>> Vote.objects.record_vote(i3, users[0], -1)
-+>>> Vote.objects.record_vote(i4, users[0], 0)
-+>>> vote = Vote.objects.get_for_user(i2, users[0])
-+>>> (vote.vote, vote.is_upvote(), vote.is_downvote())
-+(1, True, False)
-+>>> vote = Vote.objects.get_for_user(i3, users[0])
-+>>> (vote.vote, vote.is_upvote(), vote.is_downvote())
-+(-1, False, True)
-+>>> Vote.objects.get_for_user(i4, users[0]) is None
-+True
-+
-+# In bulk
-+>>> votes = Vote.objects.get_for_user_in_bulk([i1, i2, i3, i4], users[0])
-+>>> [(id, vote.vote) for id, vote in votes.items()]
-+[(1, -1), (2, 1), (3, -1)]
-+>>> Vote.objects.get_for_user_in_bulk([], users[0])
-+{}
-+
-+>>> for user in users[1:]:
-+...     Vote.objects.record_vote(i2, user, +1)
-+...     Vote.objects.record_vote(i3, user, +1)
-+...     Vote.objects.record_vote(i4, user, +1)
-+>>> list(Vote.objects.get_top(Item))
-+[(<Item: test2>, 4), (<Item: test4>, 3), (<Item: test3>, 2)]
-+>>> for user in users[1:]:
-+...     Vote.objects.record_vote(i2, user, -1)
-+...     Vote.objects.record_vote(i3, user, -1)
-+...     Vote.objects.record_vote(i4, user, -1)
-+>>> list(Vote.objects.get_bottom(Item))
-+[(<Item: test3>, -4), (<Item: test4>, -3), (<Item: test2>, -2)]
-+
-+>>> Vote.objects.get_scores_in_bulk([i1, i2, i3, i4])
-+{1: {'score': 0, 'num_votes': 4}, 2: {'score': -2, 'num_votes': 4}, 3: {'score': -4, 'num_votes': 4}, 4: {'score': -3, 'num_votes': 3}}
-+>>> Vote.objects.get_scores_in_bulk([])
-+{}
-+"""
---- /dev/null
-+++ python-django-voting-0+svn73/build/lib/voting/tests/models.py
-@@ -0,0 +1,10 @@
-+from django.db import models
-+
-+class Item(models.Model):
-+    name = models.CharField(max_length=50)
-+
-+    def __str__(self):
-+        return self.name
-+
-+    class Meta:
-+        ordering = ['name']
---- /dev/null
-+++ python-django-voting-0+svn73/build/lib/voting/tests/runtests.py
-@@ -0,0 +1,8 @@
-+import os, sys
-+os.environ['DJANGO_SETTINGS_MODULE'] = 'voting.tests.settings'
-+
-+from django.test.simple import run_tests
-+
-+failures = run_tests(None, verbosity=9)
-+if failures:
-+    sys.exit(failures)
---- /dev/null
-+++ python-django-voting-0+svn73/build/lib/voting/tests/settings.py
-@@ -0,0 +1,27 @@
-+import os
-+
-+DIRNAME = os.path.dirname(__file__)
-+
-+DATABASE_ENGINE = 'sqlite3'
-+DATABASE_NAME = os.path.join(DIRNAME, 'database.db')
-+
-+#DATABASE_ENGINE = 'mysql'
-+#DATABASE_NAME = 'tagging_test'
-+#DATABASE_USER = 'root'
-+#DATABASE_PASSWORD = ''
-+#DATABASE_HOST = 'localhost'
-+#DATABASE_PORT = '3306'
-+
-+#DATABASE_ENGINE = 'postgresql_psycopg2'
-+#DATABASE_NAME = 'tagging_test'
-+#DATABASE_USER = 'postgres'
-+#DATABASE_PASSWORD = ''
-+#DATABASE_HOST = 'localhost'
-+#DATABASE_PORT = '5432'
-+
-+INSTALLED_APPS = (
-+    'django.contrib.auth',
-+    'django.contrib.contenttypes',
-+    'voting',
-+    'voting.tests',
-+)
---- /dev/null
-+++ python-django-voting-0+svn73/build/lib/voting/templatetags/voting_tags.py
-@@ -0,0 +1,231 @@
-+from django import template
-+from django.utils.html import escape
-+
-+from voting.models import Vote
-+
-+register = template.Library()
-+
-+# Tags
-+
-+class ScoreForObjectNode(template.Node):
-+    def __init__(self, object, context_var):
-+        self.object = object
-+        self.context_var = context_var
-+
-+    def render(self, context):
-+        try:
-+            object = template.resolve_variable(self.object, context)
-+        except template.VariableDoesNotExist:
-+            return ''
-+        context[self.context_var] = Vote.objects.get_score(object)
-+        return ''
-+
-+class ScoresForObjectsNode(template.Node):
-+    def __init__(self, objects, context_var):
-+        self.objects = objects
-+        self.context_var = context_var
-+
-+    def render(self, context):
-+        try:
-+            objects = template.resolve_variable(self.objects, context)
-+        except template.VariableDoesNotExist:
-+            return ''
-+        context[self.context_var] = Vote.objects.get_scores_in_bulk(objects)
-+        return ''
-+
-+class VoteByUserNode(template.Node):
-+    def __init__(self, user, object, context_var):
-+        self.user = user
-+        self.object = object
-+        self.context_var = context_var
-+
-+    def render(self, context):
-+        try:
-+            user = template.resolve_variable(self.user, context)
-+            object = template.resolve_variable(self.object, context)
-+        except template.VariableDoesNotExist:
-+            return ''
-+        context[self.context_var] = Vote.objects.get_for_user(object, user)
-+        return ''
-+
-+class VotesByUserNode(template.Node):
-+    def __init__(self, user, objects, context_var):
-+        self.user = user
-+        self.objects = objects
-+        self.context_var = context_var
-+
-+    def render(self, context):
-+        try:
-+            user = template.resolve_variable(self.user, context)
-+            objects = template.resolve_variable(self.objects, context)
-+        except template.VariableDoesNotExist:
-+            return ''
-+        context[self.context_var] = Vote.objects.get_for_user_in_bulk(objects, user)
-+        return ''
-+
-+class DictEntryForItemNode(template.Node):
-+    def __init__(self, item, dictionary, context_var):
-+        self.item = item
-+        self.dictionary = dictionary
-+        self.context_var = context_var
-+
-+    def render(self, context):
-+        try:
-+            dictionary = template.resolve_variable(self.dictionary, context)
-+            item = template.resolve_variable(self.item, context)
-+        except template.VariableDoesNotExist:
-+            return ''
-+        context[self.context_var] = dictionary.get(item.id, None)
-+        return ''
-+
-+def do_score_for_object(parser, token):
-+    """
-+    Retrieves the total score for an object and the number of votes
-+    it's received and stores them in a context variable which has
-+    ``score`` and ``num_votes`` properties.
-+
-+    Example usage::
-+
-+        {% score_for_object widget as score %}
-+
-+        {{ score.score }}point{{ score.score|pluralize }}
-+        after {{ score.num_votes }} vote{{ score.num_votes|pluralize }}
-+    """
-+    bits = token.contents.split()
-+    if len(bits) != 4:
-+        raise template.TemplateSyntaxError("'%s' tag takes exactly three arguments" % bits[0])
-+    if bits[2] != 'as':
-+        raise template.TemplateSyntaxError("second argument to '%s' tag must be 'as'" % bits[0])
-+    return ScoreForObjectNode(bits[1], bits[3])
-+
-+def do_scores_for_objects(parser, token):
-+    """
-+    Retrieves the total scores for a list of objects and the number of
-+    votes they have received and stores them in a context variable.
-+
-+    Example usage::
-+
-+        {% scores_for_objects widget_list as score_dict %}
-+    """
-+    bits = token.contents.split()
-+    if len(bits) != 4:
-+        raise template.TemplateSyntaxError("'%s' tag takes exactly three arguments" % bits[0])
-+    if bits[2] != 'as':
-+        raise template.TemplateSyntaxError("second argument to '%s' tag must be 'as'" % bits[0])
-+    return ScoresForObjectsNode(bits[1], bits[3])
-+
-+def do_vote_by_user(parser, token):
-+    """
-+    Retrieves the ``Vote`` cast by a user on a particular object and
-+    stores it in a context variable. If the user has not voted, the
-+    context variable will be ``None``.
-+
-+    Example usage::
-+
-+        {% vote_by_user user on widget as vote %}
-+    """
-+    bits = token.contents.split()
-+    if len(bits) != 6:
-+        raise template.TemplateSyntaxError("'%s' tag takes exactly five arguments" % bits[0])
-+    if bits[2] != 'on':
-+        raise template.TemplateSyntaxError("second argument to '%s' tag must be 'on'" % bits[0])
-+    if bits[4] != 'as':
-+        raise template.TemplateSyntaxError("fourth argument to '%s' tag must be 'as'" % bits[0])
-+    return VoteByUserNode(bits[1], bits[3], bits[5])
-+
-+def do_votes_by_user(parser, token):
-+    """
-+    Retrieves the votes cast by a user on a list of objects as a
-+    dictionary keyed with object ids and stores it in a context
-+    variable.
-+
-+    Example usage::
-+
-+        {% votes_by_user user on widget_list as vote_dict %}
-+    """
-+    bits = token.contents.split()
-+    if len(bits) != 6:
-+        raise template.TemplateSyntaxError("'%s' tag takes exactly four arguments" % bits[0])
-+    if bits[2] != 'on':
-+        raise template.TemplateSyntaxError("second argument to '%s' tag must be 'on'" % bits[0])
-+    if bits[4] != 'as':
-+        raise template.TemplateSyntaxError("fourth argument to '%s' tag must be 'as'" % bits[0])
-+    return VotesByUserNode(bits[1], bits[3], bits[5])
-+
-+def do_dict_entry_for_item(parser, token):
-+    """
-+    Given an object and a dictionary keyed with object ids - as
-+    returned by the ``votes_by_user`` and ``scores_for_objects``
-+    template tags - retrieves the value for the given object and
-+    stores it in a context variable, storing ``None`` if no value
-+    exists for the given object.
-+
-+    Example usage::
-+
-+        {% dict_entry_for_item widget from vote_dict as vote %}
-+    """
-+    bits = token.contents.split()
-+    if len(bits) != 6:
-+        raise template.TemplateSyntaxError("'%s' tag takes exactly five arguments" % bits[0])
-+    if bits[2] != 'from':
-+        raise template.TemplateSyntaxError("second argument to '%s' tag must be 'from'" % bits[0])
-+    if bits[4] != 'as':
-+        raise template.TemplateSyntaxError("fourth argument to '%s' tag must be 'as'" % bits[0])
-+    return DictEntryForItemNode(bits[1], bits[3], bits[5])
-+
-+register.tag('score_for_object', do_score_for_object)
-+register.tag('scores_for_objects', do_scores_for_objects)
-+register.tag('vote_by_user', do_vote_by_user)
-+register.tag('votes_by_user', do_votes_by_user)
-+register.tag('dict_entry_for_item', do_dict_entry_for_item)
-+
-+# Simple Tags
-+
-+def confirm_vote_message(object_description, vote_direction):
-+    """
-+    Creates an appropriate message asking the user to confirm the given vote
-+    for the given object description.
-+
-+    Example usage::
-+
-+        {% confirm_vote_message widget.title direction %}
-+    """
-+    if vote_direction == 'clear':
-+        message = 'Confirm clearing your vote for <strong>%s</strong>.'
-+    else:
-+        message = 'Confirm <strong>%s</strong> vote for <strong>%%s</strong>.' % vote_direction
-+    return message % (escape(object_description),)
-+
-+register.simple_tag(confirm_vote_message)
-+
-+# Filters
-+
-+def vote_display(vote, arg=None):
-+    """
-+    Given a string mapping values for up and down votes, returns one
-+    of the strings according to the given ``Vote``:
-+
-+    =========  =====================  =============
-+    Vote type   Argument               Outputs
-+    =========  =====================  =============
-+    ``+1``     ``"Bodacious,Bogus"``  ``Bodacious``
-+    ``-1``     ``"Bodacious,Bogus"``  ``Bogus``
-+    =========  =====================  =============
-+
-+    If no string mapping is given, "Up" and "Down" will be used.
-+
-+    Example usage::
-+
-+        {{ vote|vote_display:"Bodacious,Bogus" }}
-+    """
-+    if arg is None:
-+        arg = 'Up,Down'
-+    bits = arg.split(',')
-+    if len(bits) != 2:
-+        return vote.vote # Invalid arg
-+    up, down = bits
-+    if vote.vote == 1:
-+        return up
-+    return down
-+
-+register.filter(vote_display)
-\ No newline at end of file




More information about the Python-modules-commits mailing list