Antoine Nguyen avatar Antoine Nguyen committed e2317b7

Initial import

Comments (0)

Files changed (19)

+.*~$
+^[^\.]+\.pyc
+include README.rst
+Django CMS simple poll plugin
+=============================
+
+Simple poll plugin for `Django CMS <http://django-cms.org>`_.
+
+Requirements
+------------
+
+* `Django CMS >= 2.2 <http://django-cms.org>`_
+* `South >= 0.7.3 <http://south.aeracode.org/>`_
+
+Installation
+------------
+
+#. Open the *settings.py* file and add ``cmsplugin_poll`` to the
+``INSTALLED_APPS`` variable.
+
+#. Run the following command::
+
+   $ ./manage.py migrate
+
+#. Open the *urls.py* file and add the following to ``urlpatterns``::
+
+   url(r'^poll/', include('cmsplugin_poll.urls')),
+
Add a comment to this file

cmsplugin_poll/__init__.py

Empty file added.

cmsplugin_poll/admin.py

+import datetime
+from cmsplugin_poll.models import Poll, Choice
+from django.contrib import admin
+from django.utils.translation import ugettext_lazy as _
+
+def make_closed(modeladmin, request, queryset):
+    queryset.update(close_date=datetime.datetime.now())
+make_closed.short_description = _("Close selected polls")
+
+class ChoiceInline(admin.TabularInline):
+    model = Choice
+    extra = 5
+
+class PollAdmin(admin.ModelAdmin):
+    fieldsets = [
+        (None,                  {"fields": ["question"]}),
+        ("Date information",    {"fields": ["pub_date"]})
+        ]
+    inlines = [ChoiceInline]
+    actions = [make_closed]
+
+    list_display = ("question", "pub_date", "votes", "close_date")
+    list_filter = ["pub_date"]
+    search_fields = ["question"]
+    date_hierarchy = "pub_date"
+
+admin.site.register(Poll, PollAdmin)

cmsplugin_poll/cms_plugins.py

+from cms.plugin_base import CMSPluginBase
+from cms.plugin_pool import plugin_pool
+from cmsplugin_poll.models import *
+from django.utils.translation import ugettext as _
+
+class CMSPollPlugin(CMSPluginBase):
+    model = PollPlugin
+    name = _("Simple poll plugin")
+    render_template = "cmsplugin_poll/detail.html"
+
+    def render(self, context, instance, placeholder):
+        context.update({
+                "poll" : instance.poll,
+                })
+        return context
+
+plugin_pool.register_plugin(CMSPollPlugin)

cmsplugin_poll/migrations/0001_initial.py

+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        
+        # Adding model 'Poll'
+        db.create_table('cmsplugin_poll_poll', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('question', self.gf('django.db.models.fields.CharField')(max_length=300)),
+            ('pub_date', self.gf('django.db.models.fields.DateTimeField')()),
+        ))
+        db.send_create_signal('cmsplugin_poll', ['Poll'])
+
+        # Adding model 'Choice'
+        db.create_table('cmsplugin_poll_choice', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('poll', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['cmsplugin_poll.Poll'])),
+            ('choice', self.gf('django.db.models.fields.CharField')(max_length=200)),
+            ('votes', self.gf('django.db.models.fields.IntegerField')(default=0)),
+        ))
+        db.send_create_signal('cmsplugin_poll', ['Choice'])
+
+        # Adding model 'PollPlugin'
+        db.create_table('cmsplugin_pollplugin', (
+            ('cmsplugin_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['cms.CMSPlugin'], unique=True, primary_key=True)),
+            ('poll', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['cmsplugin_poll.Poll'])),
+        ))
+        db.send_create_signal('cmsplugin_poll', ['PollPlugin'])
+
+
+    def backwards(self, orm):
+        
+        # Deleting model 'Poll'
+        db.delete_table('cmsplugin_poll_poll')
+
+        # Deleting model 'Choice'
+        db.delete_table('cmsplugin_poll_choice')
+
+        # Deleting model 'PollPlugin'
+        db.delete_table('cmsplugin_pollplugin')
+
+
+    models = {
+        'cms.cmsplugin': {
+            'Meta': {'object_name': 'CMSPlugin'},
+            'creation_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'language': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
+            'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
+            'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cms.CMSPlugin']", 'null': 'True', 'blank': 'True'}),
+            'placeholder': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cms.Placeholder']", 'null': 'True'}),
+            'plugin_type': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'}),
+            'position': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True', 'blank': 'True'}),
+            'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
+            'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'})
+        },
+        'cms.placeholder': {
+            'Meta': {'object_name': 'Placeholder'},
+            'default_width': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'slot': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'})
+        },
+        'cmsplugin_poll.choice': {
+            'Meta': {'object_name': 'Choice'},
+            'choice': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'poll': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cmsplugin_poll.Poll']"}),
+            'votes': ('django.db.models.fields.IntegerField', [], {'default': '0'})
+        },
+        'cmsplugin_poll.poll': {
+            'Meta': {'object_name': 'Poll'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'pub_date': ('django.db.models.fields.DateTimeField', [], {}),
+            'question': ('django.db.models.fields.CharField', [], {'max_length': '300'})
+        },
+        'cmsplugin_poll.pollplugin': {
+            'Meta': {'object_name': 'PollPlugin', 'db_table': "'cmsplugin_pollplugin'", '_ormbases': ['cms.CMSPlugin']},
+            'cmsplugin_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['cms.CMSPlugin']", 'unique': 'True', 'primary_key': 'True'}),
+            'poll': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cmsplugin_poll.Poll']"})
+        }
+    }
+
+    complete_apps = ['cmsplugin_poll']

cmsplugin_poll/migrations/0002_auto__add_field_poll_close_date.py

+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        
+        # Adding field 'Poll.close_date'
+        db.add_column('cmsplugin_poll_poll', 'close_date', self.gf('django.db.models.fields.DateTimeField')(null=True), keep_default=False)
+
+
+    def backwards(self, orm):
+        
+        # Deleting field 'Poll.close_date'
+        db.delete_column('cmsplugin_poll_poll', 'close_date')
+
+
+    models = {
+        'cms.cmsplugin': {
+            'Meta': {'object_name': 'CMSPlugin'},
+            'creation_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'language': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
+            'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
+            'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cms.CMSPlugin']", 'null': 'True', 'blank': 'True'}),
+            'placeholder': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cms.Placeholder']", 'null': 'True'}),
+            'plugin_type': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'}),
+            'position': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True', 'blank': 'True'}),
+            'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
+            'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'})
+        },
+        'cms.placeholder': {
+            'Meta': {'object_name': 'Placeholder'},
+            'default_width': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'slot': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'})
+        },
+        'cmsplugin_poll.choice': {
+            'Meta': {'object_name': 'Choice'},
+            'choice': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'poll': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cmsplugin_poll.Poll']"}),
+            'votes': ('django.db.models.fields.IntegerField', [], {'default': '0'})
+        },
+        'cmsplugin_poll.poll': {
+            'Meta': {'object_name': 'Poll'},
+            'close_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'pub_date': ('django.db.models.fields.DateTimeField', [], {}),
+            'question': ('django.db.models.fields.CharField', [], {'max_length': '300'})
+        },
+        'cmsplugin_poll.pollplugin': {
+            'Meta': {'object_name': 'PollPlugin', 'db_table': "'cmsplugin_pollplugin'", '_ormbases': ['cms.CMSPlugin']},
+            'cmsplugin_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['cms.CMSPlugin']", 'unique': 'True', 'primary_key': 'True'}),
+            'poll': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cmsplugin_poll.Poll']"})
+        }
+    }
+
+    complete_apps = ['cmsplugin_poll']
Add a comment to this file

cmsplugin_poll/migrations/__init__.py

Empty file added.

cmsplugin_poll/models.py

+from django.db import models
+from django.utils.translation import ugettext_lazy as _
+from cms.models import CMSPlugin
+
+class Poll(models.Model):
+    question = models.CharField(max_length=300)
+    pub_date = models.DateTimeField('date published')
+    close_date = models.DateTimeField('date closed', null=True)
+
+    def __unicode__(self):
+        return unicode(self.question)
+
+    def __repr__(self):
+        return unicode(self)
+
+    @property
+    def votes(self):
+        res = 0
+        for c in self.choice_set.all():
+            res += c.votes
+        return res
+
+    def getrate(self, choice):
+        total = self.votes
+        if not total:
+            return total
+        return choice.votes / float(total) * 100.0
+
+class Choice(models.Model):
+    poll = models.ForeignKey(Poll)
+    choice = models.CharField(max_length=200)
+    votes = models.IntegerField(default=0)
+
+class PollPlugin(CMSPlugin):
+    poll = models.ForeignKey(Poll, verbose_name=_("Poll to display"))
+
+    def __unicode__(self):
+        return self.poll.question
+
+    def __str__(self):
+        return self.poll.question
+

cmsplugin_poll/templates/cmsplugin_poll/detail.html

+{% load i18n %}
+<h3>{% trans "Poll" %}</h3>
+<p><a href="{% url cmsplugin_poll.views.results poll.id %}">{{ poll.question }}</a></p>
+{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
+<form action="{% url cmsplugin_poll.views.vote poll.id %}" method="post">
+  {% csrf_token %}
+  {% for choice in poll.choice_set.all %}
+  <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
+  <label for="choice{{ forloop.counter }}">{{ choice.choice }}</label><br />
+  {% endfor %}
+  <input type="submit" value='{% trans "Vote" %}' />
+</form>

cmsplugin_poll/templates/cmsplugin_poll/latest_polls.html

+{% load i18n %}
+<h3>{% trans "Previous polls" %}</h3>
+{% if polls %}
+<ul>
+  {% for poll in polls %}
+  <li><a href="{% url cmsplugin_poll.views.results poll.id %}">{{ poll.question }}</a></li>
+  {% endfor %}
+</ul>
+{% else %}
+<p>{% trans "No polls are available." %}</p>
+{% endif %}

cmsplugin_poll/templates/cmsplugin_poll/results.html

+{% load i18n poll_tags %}
+<h2>{% trans "Poll results" %}</h2>
+{% if messages %}
+<div class="messages">
+  {% for message in messages %}
+  <span{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}.</span>
+  {% endfor %}
+</div>
+{% endif %}
+<h3>{{ poll.question }}</h3>
+<ul>
+{% for choice in poll.choice_set.all %}
+    <li>{{ choice.choice }} ({{ choice.votes }} vote{{ choice.votes|pluralize }}, {% get_choice_rate poll choice %})</li>
+    <div name="choice" id="{{ choice.votes }}"></div>
+{% endfor %}
+</ul>
Add a comment to this file

cmsplugin_poll/templatetags/__init__.py

Empty file added.

cmsplugin_poll/templatetags/poll_tags.py

+from django.template import Library
+from django.template.loader import render_to_string
+from cmsplugin_poll.models import Poll
+
+register = Library()
+
+@register.simple_tag
+def get_latest_polls(count=5):
+    polls = Poll.objects.all().order_by("-pub_date")[:5]
+    return render_to_string("cmsplugin_poll/latest_polls.html", {
+            "polls" : polls
+            })
+
+@register.simple_tag
+def get_choice_rate(poll, choice):
+    return "%d%%" % poll.getrate(choice)

cmsplugin_poll/tests.py

+"""
+This file demonstrates two different styles of tests (one doctest and one
+unittest). These will both pass when you run "manage.py test".
+
+Replace these with more appropriate tests for your application.
+"""
+
+from django.test import TestCase
+
+class SimpleTest(TestCase):
+    def test_basic_addition(self):
+        """
+        Tests that 1 + 1 always equals 2.
+        """
+        self.failUnlessEqual(1 + 1, 2)
+
+__test__ = {"doctest": """
+Another way to test that 1 + 1 is equal to 2.
+
+>>> 1 + 1 == 2
+True
+"""}
+

cmsplugin_poll/urls.py

+from django.conf.urls.defaults import *
+
+urlpatterns = patterns('cmsplugin_poll.views',
+    (r'^$', 'index'),
+    (r'^(?P<poll_id>\d+)/$', 'detail'),
+    (r'^(?P<poll_id>\d+)/results/$', 'results'),
+    (r'^(?P<poll_id>\d+)/vote/$', 'vote'),
+)

cmsplugin_poll/views.py

+from django.shortcuts import render_to_response, get_object_or_404
+from django.http import HttpResponseRedirect, HttpResponse
+from django.core.urlresolvers import reverse
+from django.template import RequestContext
+from django.contrib import messages
+from django.utils.translation import ugettext_lazy as _
+from models import *
+
+def index(request):
+    polls = Poll.objects.all().order_by("-pub_date")
+    return render_to_response("cmsplugin_poll/latest_polls.html", {
+            "polls" : polls
+            })
+
+def detail(request, poll_id):
+    p = get_object_or_404(Poll, pk=poll_id)
+    return render_to_response("cmsplugin_poll/detail.html", {"poll" : p},
+                              context_instance=RequestContext(request))
+
+def vote(request, poll_id):
+    p = get_object_or_404(Poll, pk=poll_id)
+    if p.close_date is not None:
+        messages.error(request, _("This poll is closed"))
+    elif request.session.get("poll_%d" % p.id, False):
+        messages.error(request, _("You already vote for this poll"))
+    else:
+        try:
+            selected_choice = p.choice_set.get(pk=request.POST['choice'])
+        except (KeyError, Choice.DoesNotExist):
+            messages.error(request, _("You didn't select a choice"))
+        else:
+            selected_choice.votes += 1
+            selected_choice.save()
+            messages.info(request, _("Thank you for your vote"))
+            request.session["poll_%d" % p.id] = True
+    return HttpResponseRedirect(reverse('cmsplugin_poll.views.results', 
+                                        args=(p.id,)))
+
+def results(request, poll_id):
+    p = get_object_or_404(Poll, pk=poll_id)
+    return render_to_response('cmsplugin_poll/results.html', {'poll': p},
+                              context_instance=RequestContext(request))
+
+from setuptools import setup, find_packages
+
+setup(
+    name = "cmsplugin-poll",
+    packages = find_packages(),
+    package_data = {
+        'cmsplugin_poll': [
+            'templates/cmsplugin_poll/*.html'
+        ]
+    },
+    version = "0.1",
+    description = "Simple poll plugin for django-cms 2.2",
+    long_description=open(os.path.join(os.path.dirname(__file__), 'README.rst')).read(),
+    author = "Antoine Nguyen",
+    author_email = "tonio@ngyn.org",
+    url = "http://bitbucket.org/tonioo/cmsplugin-poll",
+    license = "BSD",
+    keywords = ["django", "django-cms", "poll"],
+    classifiers = [
+        "Programming Language :: Python",
+        "Environment :: Web Environment",
+        "Development Status :: 4 - Beta",
+        "Intended Audience :: Developers",
+        "License :: OSI Approved :: BSD License",
+        "Operating System :: OS Independent",
+        "Framework :: Django"
+        ],
+    include_package_data = True,
+    zip_safe = False,
+    install_requires = ['setuptools'],
+    requires = [
+        'django-cms (>= 2.2)',
+        'south'
+        ],
+    )
+    
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.