Modified:
/trunk/pirate-politics/ajaxapi/views.py
/trunk/pirate-politics/gae_comments_settings.py
/trunk/pirate-politics/new_templates/_issue.html
/trunk/pirate-politics/new_templates/_rightcol.html
/trunk/pirate-politics/new_templates/_solution.html
/trunk/pirate-politics/new_templates/argument_detail.html
/trunk/pirate-politics/new_templates/base.html
/trunk/pirate-politics/new_templates/helloworld.html
/trunk/pirate-politics/new_templates/issue_detail.html
/trunk/pirate-politics/new_templates/issues.html
/trunk/pirate-politics/new_templates/register.html
/trunk/pirate-politics/new_templates/solution_detail.html
/trunk/pirate-politics/new_templates/solutions.html
/trunk/pirate-politics/new_templates/submit_issue.html
/trunk/pirate-politics/new_templates/submit_nay_argument.html
/trunk/pirate-politics/new_templates/submit_solution.html
/trunk/pirate-politics/new_templates/submit_yea_argument.html
/trunk/pirate-politics/new_templates/user_profile.html
/trunk/pirate-politics/new_templates/welcome.html
/trunk/pirate-politics/pirate_consensus/models.py
/trunk/pirate-politics/pirate_consensus/templatetags/consensustags.py
/trunk/pirate-politics/pirate_core/forms.py
/trunk/pirate-politics/pirate_core/middleware.py
/trunk/pirate-politics/pirate_core/templatetags/pp_url.py
/trunk/pirate-politics/pirate_core/templatetags/tag_helpers.py
/trunk/pirate-politics/pirate_core/views.py
/trunk/pirate-politics/pirate_deliberation/models.py
/trunk/pirate-politics/pirate_deliberation/templatetags/argumenttags.py
/trunk/pirate-politics/pirate_issues/forms.py
/trunk/pirate-politics/pirate_issues/models.py
/trunk/pirate-politics/pirate_issues/templatetags/issuetags.py
/trunk/pirate-politics/pirate_issues/templatetags/solutiontags.py
/trunk/pirate-politics/pirate_issues/templatetags/topictags.py
/trunk/pirate-politics/pirate_login/views.py
/trunk/pirate-politics/pirate_ranking/models.py
/trunk/pirate-politics/pirate_reputation/models.py
/trunk/pirate-politics/pirate_reputation/templatetags/reputationtags.py
/trunk/pirate-politics/pirate_social/models.py
/trunk/pirate-politics/pirate_social/templatetags/feedtags.py
/trunk/pirate-politics/pirate_social/templatetags/subscriptiontags.py
/trunk/pirate-politics/pirate_sources/templatetags/sourcetags.py
/trunk/pirate-politics/settings.py
/trunk/pirate-politics/urls.py
=======================================
--- /trunk/pirate-politics/ajaxapi/views.py Thu Feb 17 01:26:13 2011
+++ /trunk/pirate-politics/ajaxapi/views.py Thu May 12 16:29:42 2011
@@ -1,13 +1,14 @@
# Create your views here.
-from pirate_consensus.models import Consensus
+from pirate_consensus.models import Consensus, RatingVote, UpDownVote
from django.utils import simplejson
from django.http import HttpResponse, HttpResponseRedirect
-from pirate_consensus.models import UpDownVote
from pirate_sources.models import URLSource
from tagging.models import Tag
import datetime
from django.shortcuts import get_object_or_404,redirect
from django.contrib.contenttypes.models import ContentType
+from pirate_flags.models import Flag, UserFlag
+from django.contrib.auth.models import User
from pirate_ranking.models import vote_created_callback
@@ -23,6 +24,61 @@
if isinstance(request.session['last_visited'],list):
return redirect(request.session['last_visited'][-1][0])
+
+def flagvote(request):
+
+ if not request.user.is_authenticated():
+ #needs to popup registration dialog instead
+ return HttpResponse(simplejson.dumps({'FAIL':True}), #need a
better non-auth error here, interferes with view
+ mimetype='application/json')
+
+ if request.method == 'POST':
+ vote = int(request.POST[u'vote'])
+ pk = int(request.POST[u'pk'])
+ flag_type = str(request.POST['flag_type'])
+ user_pk = int(request.POST['user'])
+ if request.user.pk != user_pk:
+ return HttpResponse(simplejson.dumps({'FAIL':True}),
+ mimetype='application/json')
+ user = User(pk=user_pk)
+ flag = Flag.objects.get(object_pk=pk, flag_type=flag_type)
+ uflag, created =
UserFlag.objects.get_or_create(user=user,flag=flag)
+ cons = Consensus.objects.get(object_pk=pk)
+ count = 0
+ v=bool(vote)
+ votestr = ''
+ if uflag.mode == v and not created:
+ if v == True:
+ flag.votes = flag.votes - 1
+ count = flag.votes
+ votestr = 'vote_up_flat'
+ elif v == False:
+ flag.counters = flag.counters - 1
+ count = flag.counters
+ votestr = 'vote_down_flat'
+ flag.save()
+ aso_rep_delete.send(sender=user, event_score=1, user=user,
initiator=user,
dimension=ReputationDimension.objects.get('Flag'),related_object=cons) #
delete reputation is flag removed
+ uflag.delete()
+ elif created:
+ uflag.mode = v
+ if v == True:
+ flag.votes = flag.votes + 1
+ count = flag.votes
+ votestr = 'vote_up_acti'
+ elif v == False:
+ flag.counters = flag.counters + 1
+ count = flag.counters
+ votestr = 'vote_down_acti'
+ uflag.save()
+ flag.save()
+ aso_rep_event.send(sender=user, event_score=1,
user=flag.content_object.user, initiator=user,
dimension=ReputationDimension.objects.get('Flag'),related_object=cons) #
register reputation for flag creation
+ imgsrc = '/static/voteimgs/' + votestr + '.gif'
+ results = {'FAIL':False, 'count':count, 'modes':str(vote ==
0), 'imgsrc':imgsrc}
+ if 'application/json' in request.META.get('HTTP_ACCEPT', ''):
+ return HttpResponse(simplejson.dumps(results),
+ mimetype='application/json')
+
+
def add_tag(request):
if not request.user.is_authenticated():
@@ -46,7 +102,53 @@
return HttpResponse(simplejson.dumps(results),
mimetype='application/json')
-
+def starvote(request):
+ '''
+ This is the POST function that is the django part of the
Ajax/Javascript
+ asynchronous voting function. The function receives a request from a
+ consensus object, and creates/deletes a UpDownVote object as requested
from
+ the Javascript that calls this function.
+
+ Returns: JSON object containing an updated count to modify vote totals
in UI,
+ and a image filename to modify graphical elements of the UI.
+ '''
+
+ if not request.user.is_authenticated():
+ #needs to popup registration dialog instead
+ return HttpResponse(simplejson.dumps({'FAIL':True}), #need a
better non-auth error here, interferes with view
+ mimetype='application/json')
+
+ if request.method == 'POST':
+
+ pk = int(request.POST[u'pk'])
+ vote_str = request.POST[u'vote']
+
+ consensus = Consensus.objects.get(object_pk=pk)
+
+ if vote_str == -99:
+ try:
+ st = RatingVote.objects.get(user=request.user,
object_pk=pk)
+ st.delete()
+ aso_rep_delete.send(sender=request.user, event_score=1,
user=consensus.content_object.user, initiator=request.user,
dimension=ReputationDimension.objects.get('Quality
Vote'),related_object=consensus) # register reputation for voting
+ except:
+ pass
+ else:
+ try:
+ old = RatingVote.objects.get(user=request.user,
object_pk=pk)
+ if old.vote_pos != vote_str:
+ old.vote_pos = vote_str
+ old.save()
+ vote_created_callback(sender=request.user,
parent=consensus,vote_type=vote_str)
+
+ except:
+ st = RatingVote(user=request.user, parent=consensus,
vote_pos=vote_str, object_pk=pk)
+ st.save()
+ aso_rep_event.send(sender=request.user, event_score=1,
user=consensus.content_object.user, initiator=request.user,
dimension=ReputationDimension.objects.get('Quality
Vote'),related_object=consensus) # register reputation for voting
+ vote_created_callback(sender=request.user,
parent=consensus,vote_type=vote_str)
+ results = {'FAIL':False, 'vote_str':vote_str }
+ if 'application/json' in request.META.get('HTTP_ACCEPT', ''):
+ return HttpResponse(simplejson.dumps(results),
+ mimetype='application/json')
def vote(request):
'''
@@ -58,7 +160,7 @@
Returns: JSON object containing an updated count to modify vote totals
in UI,
and a image filename to modify graphical elements of the UI.
'''
-
+
vote_dict = {'up':1,'down':-1,'neut':0}
if not request.user.is_authenticated():
#needs to popup registration dialog instead
@@ -99,6 +201,57 @@
if 'application/json' in request.META.get('HTTP_ACCEPT', ''):
return HttpResponse(simplejson.dumps(results),
mimetype='application/json')
+
+
+
+def spectrumvote(request):
+ '''
+ This is the POST function that is the django part of the
Ajax/Javascript
+ asynchronous voting function. The function receives a request from a
+ consensus object, and creates/deletes a UpDownVote object as requested
from
+ the Javascript that calls this function.
+
+ Returns: JSON object containing an updated count to modify vote totals
in UI,
+ and a image filename to modify graphical elements of the UI.
+ '''
+
+ if not request.user.is_authenticated():
+ #needs to popup registration dialog instead
+ return HttpResponse(simplejson.dumps({'FAIL':True}), #need a
better non-auth error here, interferes with view
+ mimetype='application/json')
+
+ if request.method == 'POST':
+
+ pk = int(request.POST[u'pk'])
+ vote_str = int(request.POST[u'vote'])
+
+ consensus = Consensus.objects.get(object_pk=pk)
+
+ if vote_str == -99:
+ try:
+ st = UpDownVote.objects.get(user=request.user,
object_pk=pk)
+ st.delete()
+ aso_rep_delete.send(sender=request.user, event_score=1,
user=consensus.content_object.user, initiator=request.user,
dimension=ReputationDimension.objects.get('Opinion
Vote'),related_object=consensus)
+ except:
+ raise ValueError('Tried to cancel a vote that doesnt
exist')
+ else:
+ try:
+ old = UpDownVote.objects.get(user=request.user,
object_pk=pk)
+ if old.vote_type != vote_str:
+ old.vote_type = vote_str
+ old.save()
+ vote_created_callback(sender=request.user,
parent=consensus,vote_type=vote_str) #for calculating rankings
+
+ except Exception, e:
+ st = UpDownVote(user=request.user, parent=consensus,
vote_type=vote_str, object_pk=pk)
+ st.save()
+ aso_rep_event.send(sender=request.user, event_score=1,
user=consensus.content_object.user, initiator=request.user,
dimension=ReputationDimension.objects.get('Opinion
Vote'),related_object=consensus) # register reputation for voting
+ vote_created_callback(sender=request.user,
parent=consensus,vote_type=vote_str)
+ results = {'FAIL':False, 'vote_str':vote_str }
+ if 'application/json' in request.META.get('HTTP_ACCEPT', ''):
+ return HttpResponse(simplejson.dumps(results),
+ mimetype='application/json')
+
##########DEPRECATED!!!#############################
#populates database with voting content for testing. I know it's ugly as
hell, but I had this in it's own file and was having some import issues,
thought
=======================================
--- /trunk/pirate-politics/gae_comments_settings.py Tue Jan 18 12:02:33 2011
+++ /trunk/pirate-politics/gae_comments_settings.py Thu May 12 16:29:42 2011
@@ -1,5 +1,10 @@
from django.contrib.comments import Comment
+from pirate_forum.models import ForumBlob
+#from pirate_actions.models import Action
+#from pirate_issues.models import Problem, Solution, Policy
+
FIELD_INDEXES = {
Comment: {'indexed': ['object_pk']},
-}
+ ForumBlob: {'unindexed': ['description']},
+}
=======================================
--- /trunk/pirate-politics/new_templates/_issue.html Thu Feb 17 09:27:41
2011
+++ /trunk/pirate-politics/new_templates/_issue.html Thu May 12 16:29:42
2011
@@ -12,6 +12,7 @@
<div class="issue">
+ <div class="issueback">
<div class="bullet">
{% if request.user.is_authenticated %}
<h1> {{ iss_obj.interest|floatformat:0 }}
@@ -23,7 +24,7 @@
<!-- <div class="bullet_daylight"></div>
<div class="bullet_verdict"></div> -->
</div>
- <div class="issueback">
+
<div class="issueinformation">
<div class="issheader">
@@ -33,7 +34,7 @@
{% pp_comment_count
object=iss_obj.content_object.id %}
{% if not request.object %}
- submitted to <a href="{% pp_url
template='issues.html' object=iss_obj.content_object.topic
dimension=request.dimension %}">{{ iss_obj.content_object.topic.text
}}</a> by <a href="{% pp_url template='user_profile.html'
object=iss_obj.content_object.user %}">{{
iss_obj.content_object.user.username }}</a> | {% endif %}{{
iss_obj.content_object.solutions }} solution{{
iss_obj.content_object.solutions|pluralize }} | {{
iss_obj.content_object.arguments }} argument{{
iss_obj.content_object.arguments|pluralize }} | {{ pp_comment.count }}
comment{{ pp_comment.count|pluralize}}
+ submitted to <a href="{% pp_url
template='issues.html' object=iss_obj.content_object.topic
dimension=request.dimension %}">{{ iss_obj.content_object.topic.text
}}</a> by <a href="{% pp_url template='user_profile.html' dimension='i'
object=iss_obj.content_object.user %}">{{
iss_obj.content_object.user.username }}</a> | {% endif %}{{
iss_obj.content_object.solutions }} solution{{
iss_obj.content_object.solutions|pluralize }} | {{
iss_obj.content_object.arguments }} argument{{
iss_obj.content_object.arguments|pluralize }} | {{ pp_comment.count }}
comment{{ pp_comment.count|pluralize}}
{% endpp_comment_count %}
=======================================
--- /trunk/pirate-politics/new_templates/_rightcol.html Thu Feb 17 09:27:41
2011
+++ /trunk/pirate-politics/new_templates/_rightcol.html Thu May 12 16:29:42
2011
@@ -6,7 +6,7 @@
{% load solutiontags %}
{% load sourcetags %}
{% load tag_helpers %}
-{% load usertags %}
+{% load logintags %}
<ul class="d">
{% pp_user_login_form request=request
return_path=request.META.PATH_INFO return_query=request.META.QUERY_STRING %}
=======================================
--- /trunk/pirate-politics/new_templates/_solution.html Thu Feb 17 01:26:13
2011
+++ /trunk/pirate-politics/new_templates/_solution.html Thu May 12 16:29:42
2011
@@ -8,27 +8,22 @@
{% load commenttags %}
{% load tag_helpers %}
- {% if iss_obj.content_object %}
+ {% if iss_obj.content_object %}
<div class="issue">
- <div class="bullet">
- {% if request.user.is_authenticated %}
- <h1> {{ iss_obj.interest|floatformat:0 }}
- </h1>
- {% else %}
- <h1> {{ iss_obj.interest|floatformat:0 }}
- </h1>
- {% endif %}
- <!-- <div class="bullet_daylight"></div>
- <div class="bullet_verdict"></div> -->
- </div>
+
<div class="issueback">
+ <div class="bullet">
+ <h1> {{ iss_obj.interest|floatformat:0 }}</h1>
+ </div>
+
+
<div class="issueinformation">
<div class="issheader"><a href="{% pp_url template='solution_detail.html'
object=iss_obj.content_object %}"> {{iss_obj.content_object.name}}
</a></div>
<div class="iss_col1">
{% pp_comment_count
object=iss_obj.content_object.id %}
-submitted by <a href="{% pp_url template='user_profile.html'
object=iss_obj.content_object.user%}">
{{iss_obj.content_object.user.username}} </a> | {{ pp_comment.count }}
comment{{ pp_comment.count|pluralize}} |
{{iss_obj.content_object.arguments}}
argument{{iss_obj.content_object.arguments|pluralize}}
+submitted by <a href="{% pp_url template='user_profile.html' dimension='i'
object=iss_obj.content_object.user%}">
{{iss_obj.content_object.user.username}} </a> | {{ pp_comment.count }}
comment{{ pp_comment.count|pluralize}} |
{{iss_obj.content_object.arguments}}
argument{{iss_obj.content_object.arguments|pluralize}}
{% endpp_comment_count %}
</div>
=======================================
--- /trunk/pirate-politics/new_templates/argument_detail.html Thu Feb 17
01:26:13 2011
+++ /trunk/pirate-politics/new_templates/argument_detail.html Thu May 12
16:29:42 2011
@@ -6,6 +6,10 @@
{% load tag_helpers %}
{% load commenttags %}
{% load markup %}
+
+{% block title %}
+{% if request.object %}{{ request.object.name|title }} {% endif %} Details
+{% endblock %}
{% block browser_bar %}
@@ -30,16 +34,14 @@
{{request.object.name}}<br>
{% pp_comment_count object=request.object.id %}
-<div class="userinfo">submitted by <a href="{% pp_url
template='user_profile.html'
object=request.object.user%}">{{request.object.user.username}}</a>
+<div class="userinfo">submitted by <a href="{% pp_url
template='user_profile.html' dimension='i'
object=request.object.user%}">{{request.object.user.username}}</a>
{{request.object.submit_date|date:"(d/m/Y h:sA)"}}| {{ pp_comment.count
}} comment{{ pp_comment.count|pluralize}} |
interest:{{pp_consensus.consensus.interest|floatformat}}</div>
-
<div class="buttons">
- {% include '_voting.html' %}
+<div class="iss_button">
{% ifequal request.object.user request.user %}
-<div class="edit">
{% ifequal
request.object.arg_type.arg "yea" %}
<a href="{% pp_url
template='submit_yea_argument.html' object=request.object %}" class="small
button blue">edit</a>
@@ -53,6 +55,8 @@
{% endifequal %}
</div>
+ {% include '_voting.html' %}
+
{% endpp_comment_count %}
=======================================
--- /trunk/pirate-politics/new_templates/base.html Thu Feb 17 09:27:41 2011
+++ /trunk/pirate-politics/new_templates/base.html Thu May 12 16:29:42 2011
@@ -1,6 +1,6 @@
{% load pp_url %}
{% load topictags %}
-{% load usertags %}
+{% load logintags %}
{% load reputationtags %}
{% load notificationtags %}
@@ -16,9 +16,9 @@
<link rel="shortcut icon" href="/static/favicon.ico" />
- <link rel="stylesheet" type="text/css" href="/static/style_fix.css" />
-
- <title> {% block title %} {{request.path|cut:"/"|cut:".html"|capfirst}}
- OpenAssembly {% endblock %}</title>
+ <link rel="stylesheet" type="text/css" href="/static/style_fix_1_02.css"
/>
+
+ <title> {% block title %} {{request.path|cut:"/"|cut:".html"|
capfirst}}{% endblock %} - OpenAssembly.org </title>
{% block css %}
{% endblock %}
@@ -144,9 +144,9 @@
<li><a href="{% pp_url template='topics.html' dimension='hot' start=0
end=20 %}">topics</a></li>
<li><a href="{% pp_url template='issues.html' dimension='hot' start=0
end=20 %}">issues</a></li>
<li><a href="{% pp_url template='solutions.html'
dimension='hot' start=0 end=20 %}">solutions</a></li>
- <li><a href="/platform.html">platform</a></li>
+ {# <li><a href="/platform.html">platform</a></li> #}
{% if request.user.is_authenticated %}
- <li><a href="{% pp_url template='user_profile.html'
object=request.user%}">profile</a></li>
+ <li><a href="{% pp_url template='user_profile.html' dimension='i'
object=request.user%}">profile</a></li>
{% else %}
<li><a href="{% pp_url template='register.html'
return_path=request.META.PATH_INFO
return_query=request.META.QUERY_STRING %}">profile</a></li>
{% endif %}
@@ -176,12 +176,12 @@
{% if request.user.username %}
{% pp_get_reputation user=request.user %}
<ul>hello
- <li><a href="{% pp_url template='user_profile.html'
object=request.user%}">{{request.user.username}}</a></li> |
+ <li>{{request.user.username}}</li> |
{% pp_has_mail user=request.user %}
{% if pp_messages.has_mail %}
- <li><a class="mailbutton" href="{% pp_url
template='user_profile.html' object=request.user%}" ></a> </li> |
+ <li><a class="mailbutton" href="{% pp_url
template='user_profile.html' dimension='m' object=request.user%}" ></a>
</li> |
{% else %}
- <li><a class="nomailbutton" href="{% pp_url
template='user_profile.html' object=request.user%}" ></a> </li> |
+ <li><a class="nomailbutton" href="{% pp_url
template='user_profile.html' dimension='m' object=request.user%}" ></a>
</li> |
{% endif %}
{% endpp_has_mail %}
<li>rep: {{ pp_reputation.reputation }}</li> |
=======================================
--- /trunk/pirate-politics/new_templates/helloworld.html Thu Feb 10
15:02:05 2011
+++ /trunk/pirate-politics/new_templates/helloworld.html Thu May 12
16:29:42 2011
@@ -1,6 +1,6 @@
{% extends 'base.html' %}
{% load pp_url %}
-{% load usertags %}
+{% load logintags %}
{% block title %}Register Page{% endblock %}
{% block css %}
=======================================
--- /trunk/pirate-politics/new_templates/issue_detail.html Thu Feb 17
09:27:41 2011
+++ /trunk/pirate-politics/new_templates/issue_detail.html Thu May 12
16:29:42 2011
@@ -13,8 +13,8 @@
{% load commenttags %}
{% block title %}
-{% if request.object %}{{ request.object.name|title }}{% endif %} Details
-{% endblock title %}
+{% if request.object %}{{ request.object.name|title }} {% endif %} Details
+{% endblock %}
{% block browser_bar %}
@@ -47,7 +47,7 @@
<div class="info">
-submitted by <a href="{% pp_url template='user_profile.html'
object=pp_issue.issue.user%}">{{pp_issue.issue.user.username}}</a>
+submitted by <a href="{% pp_url template='user_profile.html' dimension='i'
object=pp_issue.issue.user%}">{{pp_issue.issue.user.username}}</a>
=======================================
--- /trunk/pirate-politics/new_templates/issues.html Thu Feb 17 01:26:13
2011
+++ /trunk/pirate-politics/new_templates/issues.html Thu May 12 16:29:42
2011
@@ -8,7 +8,7 @@
{% load solutiontags %}
{% block title %}
-{% if request.object %}{{ request.object.text }}{% endif %} Issues
+{% if request.object %}{{ request.object.text }}{% else %}All {%
endif %}{{request.dimension|title}} Issues
{% endblock title %}
{% block css %}
@@ -55,8 +55,6 @@
</div>
{% endif %}
{% endpp_get_issue_list %}
-
-
</div>
<div class="rightcol">
=======================================
--- /trunk/pirate-politics/new_templates/register.html Thu Feb 17 09:27:41
2011
+++ /trunk/pirate-politics/new_templates/register.html Thu May 12 16:29:42
2011
@@ -1,6 +1,6 @@
{% extends 'base.html' %}
{% load pp_url %}
-{% load usertags %}
+{% load logintags %}
{% block title %}Register Page{% endblock %}
{% block css %}
=======================================
--- /trunk/pirate-politics/new_templates/solution_detail.html Thu Feb 17
09:27:41 2011
+++ /trunk/pirate-politics/new_templates/solution_detail.html Thu May 12
16:29:42 2011
@@ -13,8 +13,8 @@
{% load commenttags %}
{% block title %}
-{% if request.object %}{{ request.object.text }}{% endif %} Issues
-{% endblock title %}
+{% if request.object %}{{ request.object.name|title }} {% endif %} Details
+{% endblock %}
{% block browser_bar %}
@@ -41,7 +41,7 @@
<div class="issheader">{{pp_solution.solution.name}}</div>
-<div class="userinfo">submitted by <a href="{% pp_url
template='user_profile.html'
object=pp_solution.solution.user%}">{{pp_solution.solution.user.username}}</a>
+<div class="userinfo">submitted by <a href="{% pp_url
template='user_profile.html' dimension='i'
object=pp_solution.solution.user%}">{{pp_solution.solution.user.username}}</a>
{% pp_comment_count object=pp_solution.solution.id %}
=======================================
--- /trunk/pirate-politics/new_templates/solutions.html Thu Feb 17 01:26:13
2011
+++ /trunk/pirate-politics/new_templates/solutions.html Thu May 12 16:29:42
2011
@@ -8,6 +8,9 @@
{% load solutiontags %}
{% load commenttags %}
+{% block title %}
+{% if request.object %}{{ request.object.text }}{% else %}All {%
endif %}{{request.dimension|title}} Solutions
+{% endblock %}
{% block browser_bar %}
<ul>
=======================================
--- /trunk/pirate-politics/new_templates/submit_issue.html Thu Feb 17
01:26:13 2011
+++ /trunk/pirate-politics/new_templates/submit_issue.html Thu May 12
16:29:42 2011
@@ -3,7 +3,7 @@
{% load issuetags %}
{% block title %}Submit New Issue{% endblock %}
-{% block css %}
+{% block browser_bar %}
{% endblock %}
@@ -11,11 +11,11 @@
<div class="stage">
<div class="issuemask">
- <div class="submissionbound">
+
{% if request.object %}
{% pp_issue_form POST=request.POST path=request.path user=request.user
object=request.object %}
- <div class="add">
- <h2> {{pp_issue.contextname }}</h2>
+ <div class="pagehead">{{pp_issue.contextname }}</div>
+ <div class="submissionbound">
<div class="errors">{{ pp_issue.form.errors }}</div>
<form method="post" action="">
Summary of Issue: <br>{{ pp_issue.form.name }}<br>
@@ -24,12 +24,11 @@
{% csrf_token %}
<input type="submit" class="button green" value="Submit Issue" />
</form>
- </div>
{% endpp_issue_form %}
{% else %}
{% pp_issue_form POST=request.POST path=request.path user=request.user %}
- <div class="add">
- <h2>{{pp_issue.contextname }}</h2>
+ <div class="pagehead">{{pp_issue.contextname }}</div>
+ <div class="submissionbound">
<div class="errors">{{ pp_issue.form.errors }}</div>
<form method="post" action="">
{% if not pp_issue.has_topic %} Topic: <br>
{{pp_issue.form.topics}}<br>{% endif %}
@@ -39,7 +38,6 @@
{% csrf_token %}
<input type="submit" class="button green" value="Submit Issue" />
</form>
- </div>
{% endpp_issue_form %}
{% endif %}
{% include '_tutorial.html' %}
=======================================
--- /trunk/pirate-politics/new_templates/submit_nay_argument.html Thu Feb
17 01:26:13 2011
+++ /trunk/pirate-politics/new_templates/submit_nay_argument.html Thu May
12 16:29:42 2011
@@ -12,7 +12,6 @@
<div class="issuemask">
<div class="submissionbound">
{% pp_argument_form POST=request.POST path=request.path
object=request.object user=request.user arg_type='nay' %}
- <div class="add">
<h2>Submit a new Nay argument for <br>{{request.object.name}}</h2>
<div class="errors">{{ pp_argumentation.form.errors }}</div>
<form method="post" action="">
@@ -22,7 +21,6 @@
{% csrf_token %}
<input type="submit" class="button green" value="Submit Nay" />
</form>
- </div>
{% include '_tutorial.html' %}
</div>
<div class="rightcol">
=======================================
--- /trunk/pirate-politics/new_templates/submit_solution.html Wed Feb 9
00:35:14 2011
+++ /trunk/pirate-politics/new_templates/submit_solution.html Thu May 12
16:29:42 2011
@@ -10,11 +10,13 @@
{% block content%}
<div class="stage">
- <div clre,sexyass="issuemask">
+ <div class="issuemask">
+
+ <div class="pagehead">Submit a new solution for:
{{request.object.name}}</div>
+
<div class="submissionbound">
{% pp_solution_form POST=request.POST path=request.path
object=request.object request=request %}
- <div class="add">
- <h2>Submit a new solution for: <br>{{request.object.name}}</h2>
+
<div class="errors">{{ pp_solution.form.errors }}</div>
<form method="post" action="">
Summary of Solution: <br>{{ pp_solution.form.name }}<br>
@@ -23,7 +25,6 @@
{% csrf_token %}
<input type="submit" class="button green" value="Submit Solution" />
</form>
- </div>
{% include '_tutorial.html' %}
</div>
=======================================
--- /trunk/pirate-politics/new_templates/submit_yea_argument.html Thu Feb
17 01:26:13 2011
+++ /trunk/pirate-politics/new_templates/submit_yea_argument.html Thu May
12 16:29:42 2011
@@ -13,7 +13,6 @@
<div class="submissionbound">
<h2>Submit a new Yea argument for:
<fragrobr>{{request.object.name}}</h2>
{% pp_argument_form POST=request.POST object=request.object
user=request.user arg_type='yea' %}
- <div class="add">
<div class="errors">{{ pp_argumentation.form.errors }}</div>
<form method="post" action="">
Summary of Argument: <br>{{ pp_argumentation.form.name }}<br>
@@ -22,7 +21,6 @@
{% csrf_token %}
<input type="submit" class="button green" value="Submit Yea" />
</form>
- </div>
{% include '_tutorial.html' %}
</div>
=======================================
--- /trunk/pirate-politics/new_templates/user_profile.html Thu Feb 17
01:26:13 2011
+++ /trunk/pirate-politics/new_templates/user_profile.html Thu May 12
16:29:42 2011
Binary file, no diff available.
=======================================
--- /trunk/pirate-politics/new_templates/welcome.html Thu Feb 17 09:27:41
2011
+++ /trunk/pirate-politics/new_templates/welcome.html Thu May 12 16:29:42
2011
@@ -1,6 +1,6 @@
{% extends 'base.html' %}
{% load pp_url %}
-{% load usertags %}
+{% load logintags %}
{% block title %}OpenAssembly.org{% endblock %}
{% block css %}
@@ -15,20 +15,47 @@
<div class="issuemask">
- <div class="pagehead">Welcome to OpenAssembly: Alpha</div>
-
<div class="issuebound">
<div class="welcome">
- <p> OpenAssembly is a problem/solution website
built for user-driven political discussion. The objective of this
discussion is the development of non-partisan, well cited, and innovative
ideas that improve our democracy, government, and society. OpenAssembly is
an alpha, meaning that it is still in it's infancy, and in the future will
host new features such as an event system, support for issue/geographical
subgroups, electioneering systems, and a intelligent online representative
for each user. </p>
-
-<p>The intelligent representative is an Artificial Intelligence (AI) that
will bring interesting new discussions to your attention, allow you to form
dynamic coalitions with other users, aid in your evaluation of other users,
engage in proxy voting if authorized, and much more. This intelligent
representive first learns your preferences based on your activity on
OpenAssembly. Once it has learned those preferences the representative will
ensure your opinion is considered, even if you are not online. The
intelligent representatives will work together to bridge the gaps between
communities and allow for the formation of dynamic voting blocs. They will
also allow users to compare their own political interests with others like
never before. Perhaps some will even discover we are not so different after
all.</p>
+ <h2>Our Vision</h2>
+
+ <p>We must reinstate the voice of the reasonable
citizens in our Republic. Important issues are drowned out by the media
echo chamber and distorted by the government. We must cooperatively work
together to develop policies that work, keep a watchful eye on unethical
government officials and corporations, and organize to produce positive
change for the future of our country.
+
+ <p><h3><a href="/register.html">Join the
Discussion and Make a Difference.</a></h3></p>
+
+ <h3> Sounds great, but how? </h3>
+
+ <ul>
+ <li><b> Discuss, Debate, and Decide:</b>
OpenAssembly features a forum where you can discuss issues that are of
interest to you, deliberate over the pros and cons of those issues, and
vote on what's important to you. Earn badges and reputation as a master of
political argumentation or a creative problem solver. </li>
+
+ <li><b>Discovery:</b> Our adaptive platform
learns your political preferences to improve your experience. The adaptive
platform
+will recommend new issues that you would be interested in, help you find
interesting people to connect with, and allow for detailed analysis of the
opinions in the community.</li>
+
+ <li><b> Organize:</b> Join coalitions of
citizens that focus on issues you are most passionate about. Attend
political events, meetings, or operations with other members to influence
the real world. Photos and reputation reports confirm your activism and
allow others to trust you, because only through trust can we ensure
cooperation! </li>
+
+ <li><b> Trusted and Secure:</b> OpenAssembly
features state-of-the-art reputation systems and trust networks. These
systems prevent malicious actors from distorting the results of voting.
Permissions layers protect trusted users when political strategy cannot be
public.</li>
+
+
+ <li><b> Open and Free:</b> OpenAssembly is
open source and will always be free. We are not here to harvest your
political information for advertisers. OpenAssembly operates on a donation
model.</li>
+
+ </ul>
+
+<p> We would appreciate support from developers, web designers or graphic
designers. OpenAssembly is based on <a
href="http://pirate-politics.org">pirate-politics</a>. The site runs on <a
href="http://www.allbuttonspressed.com/projects/django-nonrel">Django-nonrel</a>
and Google App Engine.
+
+
+
+
+ {% comment %} <p> OpenAssembly is a problem/solution
website built for user-driven political discussion. The objective of this
discussion is the development of non-partisan, well cited, and innovative
ideas that improve our democracy, government, and society. OpenAssembly is
an alpha, meaning that it is still in it's infancy, and in the future will
host new features such as an event system, support for issue/geographical
subgroups, electioneering systems, and a intelligent online representative
for each user. </p>
+
+<p>The intelligent representative is an Artificial Intelligence (AI) that
will bring interesting new discussions to your attention, allow you to form
dynamic coalitions with other users, aid in your evaluation of other users,
engage in proxy voting if authorized, and much more. This intelligent
representative first learns your preferences based on your activity on
OpenAssembly. Once it has learned those preferences the representative will
ensure your opinion is considered, even if you are not online. The
intelligent representatives will work together to bridge the gaps between
communities and allow for the formation of dynamic voting blocs. They will
also allow users to compare their own political interests with others like
never before. Perhaps some will even discover we are not so different after
all.</p>
<p> The current phase of OpenAssembly is highly important as the content
generated by users now will be used to aid research and development of this
intelligent representative. Those that take part in the discussion at this
stage can take an active role in the development of these features if
desired and all users who participate in OpenAssembly: Alpha will receive a
special badge showing their support at such an early stage of
development.</p>
<p><h3><a href="/register.html">Join the Discussion</a></h3></p>
- <p> We would also love support from developers. OpenAssembly is an open
source project based on <a
href="http://pirate-politics.org">pirate-politics</a>. The site runs on
Django-nonrel and Google App Engine, and any developer with knowledge of
Python/Django or web design is welcome to join our code sprints.</p>
+ <p> </p> {% endcomment %}
+
</div>
</div>
<div class="rightcol">
=======================================
--- /trunk/pirate-politics/pirate_consensus/models.py Thu Feb 17 01:26:13
2011
+++ /trunk/pirate-politics/pirate_consensus/models.py Thu May 12 16:29:42
2011
@@ -8,23 +8,107 @@
from django.contrib.auth.models import User
from pirate_signals.models import vote_created
-#Generic conesensus object that acts as parent for all votes
+
+""" Spectrum and Rating classes hold denormalized
+ counts for all votes/ratings so that the
+ ranking algorithm requires only 3 DB hits rather
+ than many.
+
+ This could be accomplished in 1 DB hit by denormalizing these values
into
+ the consensus object, but then each value would unnecesarily
+ be accessed each time consensus information is required.
+"""
+
+class Spectrum(models.Model):
+ #holds spectrum values for calculation of ranking, spectrum is not
weighted
+ spectrum1 = models.IntegerField(default=0)
+ spectrum2 = models.IntegerField(default=0)
+ spectrum3 = models.IntegerField(default=0)
+ spectrum4 = models.IntegerField(default=0)
+ spectrum5 = models.IntegerField(default=0)
+ spectrum6 = models.IntegerField(default=0)
+ spectrum7 = models.IntegerField(default=0)
+ spectrum8 = models.IntegerField(default=0)
+ spectrum9 = models.IntegerField(default=0)
+ spectrum10 = models.IntegerField(default=0)
+ spectrum11 = models.IntegerField(default=0)
+
+ def save_vote(self, vote):
+ setattr(self, 'spectrum' + str(vote), getattr(self,'spectrum' +
str(vote))+1)
+ self.save()
+
+ def del_vote(self,vote):
+ setattr(self, 'rating' + str(vote), getattr(self,'rating' +
str(vote))-1)
+ #TODO: save rating_w and increment rating_n
+ self.save()
+
+ def get_list(self):
+ return [(i-6, getattr(self,'spectrum' + str(i))) for i in
range(1,12)]
+
+class Rating(models.Model):
+ #ratings
+ rating1 = models.IntegerField(default=0)
+ rating2 = models.IntegerField(default=0)
+ rating3 = models.IntegerField(default=0)
+ rating4 = models.IntegerField(default=0)
+ rating5 = models.IntegerField(default=0)
+
+ #average weights based on rating reputation of rating users
+ rating_w1 = models.FloatField(default=0.0)
+ rating_w2 = models.FloatField(default=0.0)
+ rating_w3 = models.FloatField(default=0.0)
+ rating_w4 = models.FloatField(default=0.0)
+ rating_w5 = models.FloatField(default=0.0)
+
+
+ def save_vote(self,vote):
+ setattr(self, 'rating' + str(vote), getattr(self,'rating' +
str(vote))+1)
+ #TODO: save rating_w and increment rating_n
+ self.save()
+
+ def del_vote(self,vote):
+ setattr(self, 'rating' + str(vote), getattr(self,'rating' +
str(vote))-1)
+ #TODO: save rating_w and increment rating_n
+ self.save()
+
+ def get_list(self):
+ #TODO: Implement weighted voting on ratings
+ #w = getattr(self,'rating_w' + str(i))/getattr(self,'rating_n' +
str(i))
+ w = 1.0
+ return [(i, w, getattr(self,'rating' + str(i))) for i in
range(1,6)]
+
+#Generic conesensus object that acts as parent for all agree/disagree/votes
class Consensus(models.Model):
- parent_pk = models.IntegerField()
- submit_date = models.DateTimeField(_('date/time submitted'),
auto_now_add=True)
+ parent_pk = models.IntegerField()
+ submit_date = models.DateTimeField(_('date/time
submitted'),auto_now_add=True)
content_type = models.ForeignKey(ContentType,
verbose_name=_('content type'),
related_name="content_type_set_for_%(class)s")
object_pk = models.IntegerField(_('object ID'))
content_object = generic.GenericForeignKey(ct_field="content_type",
fk_field="object_pk")
- votes = models.IntegerField(default = 0)
+ #number of children
+ votes = models.IntegerField(default=0)
+ ratings = models.IntegerField(default=0)
+ #denormalized ranking values
interest = models.FloatField(default=0.0)
controversy = models.FloatField(default=0.0)
is_edittable = models.BooleanField(default=True) #refers to edittable
property of parent, nullified by a vote
+ #related to children vote types, to allow for ranked/weighted voting
+ vote_type = models.ForeignKey(ContentType,
+ verbose_name=_('vote content type'),
+
related_name="vote_content_type_set_for_%(class)s")
+ child_vote_type = models.ForeignKey(ContentType,
+ verbose_name=_('child vote content
type'),
+
related_name="child_vote_content_type_set_for_%(class)s", blank=True,
null=True)
+ spectrum = models.ForeignKey(Spectrum, verbose_name=_('spectrum
votes'), null=True)
+ rating = models.ForeignKey(Rating, verbose_name=_('rating votes'),
null=True)
+
+
def __unicode__(self):
return str(self.content_type) + ':' + str(self.object_pk)
+
#This is the basic voting object utilized within Reddit-like consensus
class UpDownVote(models.Model):
@@ -35,11 +119,12 @@
user = models.ForeignKey(User, verbose_name=_('user'),
blank=True, null=True,
related_name="%(class)s_ratings")
vote_type = models.IntegerField() #For simplicity upvote == 1,
downvote == -1, neut == 0
+ object_pk = models.IntegerField(_('Object_PK'))
class Meta:
unique_together = (('parent', 'user'),)
- verbose_name = _('vote')
- verbose_name_plural = _('votes')
+ verbose_name = _('Up/Down Vote')
+ verbose_name_plural = _('Up/Down Votes')
def __unicode__(self):
return "%s: %s" % (self.user, self.vote_type)
@@ -47,13 +132,118 @@
def save(self, force_insert=False, force_update=False):
if self.submit_date is None:
self.submit_date = datetime.datetime.now()
+ self.parent.votes += 1 #update consensus object vote count
super(UpDownVote, self).save(force_insert, force_update)
+
+ spec = self.parent.spectrum
+ if spec != None:
+ spec.save_vote(self.vote_type)
+ else:
+ spec = Spectrum()
+ spec.save()
+
+ self.parent.spectrum = spec
+ spec.save_vote(self.vote_type)
+
+
+ self.parent.save()
+
+
+class RankedVote(models.Model):
+ """Facilitates ranked voting methods such as the Schulz voting
algorithm.
+ The correctness of the ranking can be checked via the template
tags,
+ or via the javascript interface. Incorrect rankings should not be
allowed.
+
+ """
+ parent = models.ForeignKey(Consensus,
+ verbose_name=_('parent'))
+ submit_date = models.DateTimeField(_('date/time submitted'),
default=None)
+ user = models.ForeignKey(User, verbose_name=_('user'),
+ blank=True, null=True,
related_name="%(class)s_ratings")
+ vote_rank = models.IntegerField()
+
+ class Meta:
+ unique_together = (('parent', 'user'),)
+ verbose_name = _('ranked vote')
+ verbose_name_plural = _('ranked votes')
+
+ def __unicode__(self):
+ return "%s: %s" % (self.user, self.vote_rank)
+
+ def save(self, force_insert=False, force_update=False):
+ if self.submit_date is None:
+ self.submit_date = datetime.datetime.now()
+ super(UpDownVote, self).save(force_insert, force_update)
self.parent.votes += 1 #update consensus object vote count
self.parent.save()
- #upvotes = models.IntegerField()
+class WeightedVote(models.Model):
+ """Facilitates all classes of weighted voting algorithms
+ All weights must add up to max. Otherwise vote is not valid.
+ """
+ parent = models.ForeignKey(Consensus,
+ verbose_name=_('parent'))
+ submit_date = models.DateTimeField(_('date/time submitted'),
default=None)
+ user = models.ForeignKey(User, verbose_name=_('user'),
+ blank=True, null=True,
related_name="%(class)s_ratings")
+ vote_weight = models.FloatField() #should add up to 1
+
+ class Meta:
+ unique_together = (('parent', 'user'),)
+ verbose_name = _('weighted vote')
+ verbose_name_plural = _('weighted votes')
+
+ def __unicode__(self):
+ return "%s: %s" % (self.user, self.vote_weight)
+
+ def save(self, force_insert=False, force_update=False):
+ if self.submit_date is None:
+ self.submit_date = datetime.datetime.now()
+ super(UpDownVote, self).save(force_insert, force_update)
+ self.parent.votes += 1 #update consensus object vote count
+ self.parent.save()
+
+class RatingVote(models.Model):
+ """
+ Star Vote used for ranking items in a range from [0:N] where N is the
number
+ of stars specified via the ajax/javascript star rating functionality.
+ """
+ parent = models.ForeignKey(Consensus,
+ verbose_name=_('parent'))
+ submit_date = models.DateTimeField(_('date/time submitted'),
default=None)
+ user = models.ForeignKey(User, verbose_name=_('user'),
+ blank=True, null=True,
related_name="%(class)s_ratings")
+ vote_pos = models.IntegerField() #should add up to 1
+ object_pk = models.IntegerField(_('Object_PK'))
+
+ class Meta:
+ unique_together = (('object_pk', 'user'),)
+ verbose_name = _('star rating')
+ verbose_name_plural = _('star ratings')
+
+ def __unicode__(self):
+ return "%s: %s" % (self.user, self.vote_pos)
+
+ def save(self, force_insert=False, force_update=False):
+ if self.submit_date is None:
+ self.submit_date = datetime.datetime.now()
+ super(RatingVote, self).save(force_insert, force_update)
+ self.parent.ratings += 1 #update consensus object vote count
+ rate = self.parent.rating
+ if rate != None:
+ rate.save_vote(self.vote_pos)
+ else:
+ rating = Rating()
+ rating.save()
+ self.parent.rating = rating
+
+ self.parent.save()
+
###SIGNALS
admin.site.register(Consensus)
admin.site.register(UpDownVote)
-
+admin.site.register(RankedVote)
+admin.site.register(WeightedVote)
+admin.site.register(RatingVote)
+
=======================================
--- /trunk/pirate-politics/pirate_consensus/templatetags/consensustags.py
Thu Feb 10 14:21:57 2011
+++ /trunk/pirate-politics/pirate_consensus/templatetags/consensustags.py
Thu May 12 16:29:42 2011
@@ -7,12 +7,36 @@
from django.contrib.contenttypes.models import ContentType
from pirate_core.views import HttpRedirectException, namespace_get
-from pirate_consensus.models import UpDownVote, Consensus
+from pirate_consensus.models import UpDownVote, Consensus, RankedVote,
WeightedVote, RatingVote
+
+from pirate_core.widgets import HorizRadioRenderer
from customtags.decorators import block_decorator
register = template.Library()
block = block_decorator(register)
+RATINGS_CHOICES = (
+ (1,"Poor"),
+ (2,"Low"),
+ (3,"Acceptable"),
+ (4,"Good"),
+ (5,"Excellent")
+)
+
+SPECTRUM_CHOICES = (
+ (1,"Extremely Disagree"),
+ (2,"Strongly Disagree"),
+ (3,"Disagree"),
+ (4,"Mostly Disagree"),
+ (5,"Point of Contention"),
+ (6,"Meh"),
+ (7,"Slightly Agree"),
+ (8,"Mostly Agree"),
+ (9,"Agree"),
+ (10,"Strongly Agree"),
+ (11,"Extremely Agree"),
+)
+
get_namespace = namespace_get('pp_consensus')
#retrieves a consensus object, places that object into the context. Within
this tag block an {include} should populate the html with a
consensus_widget that uses the context provided by this tag to create the
fields for voting and observing the consensus object.
@@ -24,61 +48,236 @@
namespace = get_namespace(context)
object_pk = kwargs.pop('object', None)
- small = kwargs.pop('small', None)
+
if object_pk is None:
raise ValueError("pp_consensus_get tag requires that a consensus
object be passed "
"to it assigned to the 'object=' argument,
and that the str "
"be assigned the string value 'consensus.")
user = kwargs.pop('user', None)
- try: namespace['consensus'] =
Consensus.objects.get(object_pk=object_pk)
- except: raise ValueError("pp_consensus_get tag requires that the
object reference by 'object_pk' argument be referenced by an existing
consensus object.")
- namespace['upvotes'] = UpDownVote.objects.filter(vote_type=1,parent=
namespace['consensus']).count()
- namespace['downvotes'] =
UpDownVote.objects.filter(vote_type=-1,parent=
namespace['consensus']).count()
- namespace['neutvotes'] = UpDownVote.objects.filter(vote_type=0,parent=
namespace['consensus']).count()
-
- namespace['interest'] = namespace['consensus'].interest
- namespace['controversy'] = namespace['consensus'].controversy
-
- #user specific rendering of vote images
- try:
- v =
int(UpDownVote.objects.get(user=user,parent=namespace['consensus']).vote_type)
- except:
- v = None
- typeup = 'flat'
- typeneut = 'flat'
- typedown = 'flat'
- if v != None:
- if v == 1:
- typeup = 'acti'
- elif v == 0:
- typeneut = 'acti'
- elif v == -1:
- typedown = 'acti'
- if small == None:
- namespace['upvoteimg'] = "/static/voteimgs/up_arrow_" + typeup
+ ".png"
- namespace['hasupvoted'] = v == 1
- namespace['neutvoteimg'] = "/static/voteimgs/neut_arrow_" +
typeneut + ".png"
- namespace['hasneutvoted'] = v == 0
- namespace['downvoteimg'] = "/static/voteimgs/down_arrow_" +
typedown + ".png"
- namespace['hasdownvoted'] = v == -1
+ try:
+ namespace['consensus'] = Consensus.objects.get(object_pk=object_pk)
+
+ namespace['interest'] = namespace['consensus'].interest
+ namespace['controversy'] = namespace['consensus'].controversy
+
+ #user specific rendering of vote info
+ #if available include it, else set to None
+ try:
+ updown =
UpDownVote.objects.get(user=user,parent=namespace['consensus']).vote_type
+ except:
+ updown = None
+ try:
+ rate =
RatingVote.objects.get(user=user,parent=namespace['consensus']).vote_pos
+ except:
+ rate = None
+ namespace['user_updown'] = updown
+ namespace['user_rating'] = rate
+
+ except:
+ namespace['consensus'] = None
+ output = nodelist.render(context)
+ context.pop()
+
+ return output
+
+#Creates fields for creation of a consensus object, to be added to the
object that is being referenced. This form includes settings for time
constraints, if allowed at the global level. Some objects such as issues
require a consensus object and therefore do not have a form attached.
+@block
+def pp_consensus_form(context, nodelist, *args, **kwargs):
+ """
+ Populates the context with a ConsensusForm, allowing users to select
what
+ voting type is applied to the object or the objects children.
+
+ Unless the number of related objects is limited, for example solutions
to
+ a problem, plurality voting is required. As the number of objects
considered
+ for voting increases, it becomes increasingly impossible to rank or
apply
+ weighted voting to the entire set.
+ """
+ context.push()
+ namespace = get_namespace(context)
+
+ obj = kwargs.pop('object', None)
+ POST = kwargs.pop('POST', None)
+
+
+ if POST is not None and POST.get("form_id") == "pp_consensus_form":
+
+ form = ConsensusForm(POST)
+ if form.is_valid():
+ vote_type = form.cleaned_data['vote_type']
+ if vote_type == "Ranked Voting":
+ vt = ContentType.objects.get_for_model(RankedVote)
+ elif vote_type == "Up/Down Voting":
+ vt = ContentType.objects.get_for_model(UpDownVote)
+ elif vote_type == "Weighted Voting":
+ vt = ContentType.objects.get_for_model(WeightedVote)
+
+ con = Consensus.objects.get(object_pk=obj.pk)
+
+ if obj.child != None:
+ con.child_vote_type = vt
+ con.save()
+
+ namespace['complete'] = True
+ namespace['vote_type'] = con.child_vote_type
else:
- namespace['upvoteimg'] = "/static/voteimgs/up_arrow_" + typeup
+ "_small.png"
- namespace['hasupvoted'] = v == 1
- namespace['neutvoteimg'] = "/static/voteimgs/neut_arrow_" +
typeneut + "_small.png"
- namespace['hasneutvoted'] = v == 0
- namespace['downvoteimg'] = "/static/voteimgs/down_arrow_" +
typedown + "_small.png"
- namespace['hasdownvoted'] = v == -1
-
+ form = ConsensusForm()
+ con = Consensus.objects.get(object_pk=obj.pk)
+ if con.child_vote_type != None:
+ namespace['complete'] = True
+ namespace['vote_type'] = con.child_vote_type
+ else:
+ namespace['complete'] = False
+ namespace['form'] = form
+
+
+ output = nodelist.render(context)
+ context.pop()
+
+ return output
+
+@block
+def pp_rating_form(context, nodelist, *args, **kwargs):
+ """
+ Populates the context with a RatingForm, allowing users to select what
+ voting type is applied to the object or the objects children.
+
+ Unless the number of related objects is limited, for example solutions
to
+ a problem, plurality voting is required. As the number of objects
considered
+ for voting increases, it becomes increasingly impossible to rank or
apply
+ weighted voting to the entire set.
+ """
+ context.push()
+ namespace = get_namespace(context)
+
+ obj = kwargs.pop('object', None)
+ POST = kwargs.pop('POST', None)
+ user = kwargs.get('user', None)
+
+
+ if POST is not None and POST.get("form_id") == "pp_rating_form":
+
+ form = RatingForm(POST)
+ if form.is_valid():
+ rating = form.cleaned_data['rating']
+ consensus = Consensus.objects.get(object_pk=objpk)
+ st = RatingVote(user=user, parent=consensus, vote_pos=rating)
+ else:
+ try:
+ prev_rating =
RatingVote.objects.get(user=user,object_pk=obj.pk)
+ form = RatingForm(initial={'rating':prev_rating.vote_pos})
+ except: form = RatingForm()
+
+ namespace['form'] = form
+
+
output = nodelist.render(context)
context.pop()
return output
-#Creates fields for creation of a consensus object, to be added to the
object that is being referenced. This form includes settings for time
constraints, if allowed at the global level. Some objects such as issues
require a consensus object and therefore do not have a form attached.
@block
-def pp_conensus_form(context, nodelist, *args, **kwargs):
- pass
+def pp_spectrum_form(context, nodelist, *args, **kwargs):
+ """
+ Populates the context with a SpectrumForm, allowing users to select
what
+ voting type is applied to the object or the objects children.
+
+ Unless the number of related objects is limited, for example solutions
to
+ a problem, plurality voting is required. As the number of objects
considered
+ for voting increases, it becomes increasingly impossible to rank or
apply
+ weighted voting to the entire set.
+ """
+ context.push()
+ namespace = get_namespace(context)
+
+ obj = kwargs.pop('object', None)
+ POST = kwargs.pop('POST', None)
+ user = kwargs.get('user', None)
+
+
+ if POST is not None and POST.get("form_id") == "pp_spectrum_form":
+
+ form = SpectrumForm(POST)
+ if form.is_valid():
+ rating = form.cleaned_data['spectrum']
+ consensus = Consensus.objects.get(object_pk=objpk)
+ st = RatingVote(user=user, parent=consensus, vote_pos=rating)
+ else:
+ try:
+ prev_rating =
UpDownVote.objects.get(user=user,object_pk=obj.pk)
+ form = SpectrumForm(initial={'spectrum':prev_rating.vote_type})
+ except: form = SpectrumForm()
+
+ namespace['form'] = form
+
+
+ output = nodelist.render(context)
+ context.pop()
+
+ return output
+
+
+@block
+def pp_rating_js(context, nodelist, *args, **kwargs):
+
+ context.push()
+ namespace = get_namespace(context)
+
+ obj = kwargs.get('object',None)
+
+ if obj:
+ RET = """
+ $(function(){
+ $("#stars-wrapper-rate""" + str(obj.id) + """").stars({
+ inputType: "select",
+ callback: function(ui, type, value){
+ starvote(""" + str(obj.id) + """, value);
+ },
+ captionEl: $("#stars-cap-rate"),
+ cancelTitle:'Cancel Rating',
+ cancelValue:-99
+ });
+ });
+ """
+ else: RET = ""
+ namespace['rating_js'] = RET
+
+ output = nodelist.render(context)
+ context.pop()
+
+ return output
+
+@block
+def pp_spectrum_js(context, nodelist, *args, **kwargs):
+
+ context.push()
+ namespace = get_namespace(context)
+
+ obj = kwargs.get('object',None)
+
+ if obj:
+ RET = """
+ $(function(){
+ $("#stars-wrapper-spec""" + str(obj.id) + """").stars({
+ inputType: "select",
+ callback: function(ui, type, value){
+ spectrumvote(""" + str(obj.id) + """, value);
+ },
+ spectrum:true,
+ captionEl: $("#stars-cap-spec"),
+ cancelTitle:'Cancel Vote',
+ cancelValue:-99
+
+ });
+ });
+ """
+ else: RET = ""
+ namespace['spectrum_js'] = RET
+
+ output = nodelist.render(context)
+ context.pop()
+
+ return output
#: render a <link> tag required to be added to the template at the
appropriate locations.
@block
@@ -94,18 +293,29 @@
def pp_consensus_info(context, nodelist, *args, **kwargs):
pass
+
+VOTE_TYPES = (('Ranked Voting', 'Ranked Voting'), ('Weighted
Voting','Weighted Voting'), ('Up/Down Voting','Up/Down Voting'))
+
#This shouldn't really be used in practice, consensus objects are
generally automatically generated
-class ConsensusForm(forms.ModelForm):
+class ConsensusForm(forms.Form):
'''
This form is used to allow creation and modification of consensus
objects. The form_id
- field is hidden and static and is used to allow the pp_conensus_form
tag to identify
+ field is hidden and static and is used to allow the pp_consensus_form
tag to identify
whether the POST included with the submission pertains to issues or
does not.
By convention, the value of this hidden field should be the same as
the tag that
will process the form.
'''
-
- class Meta:
- model = Consensus
-
- form_id = forms.CharField(widget=forms.HiddenInput(),
initial="pp_conensus_form")
+
+ form_id = forms.CharField(widget=forms.HiddenInput(),
initial="pp_consensus_form")
+ vote_type =
forms.ChoiceField(widget=forms.RadioSelect(renderer=HorizRadioRenderer),
+ choices=VOTE_TYPES, required=True,
+ label="Vote Type",initial="")
+
+class RatingForm(forms.Form):
+ form_id = forms.CharField(widget=forms.HiddenInput(),
initial="pp_rating_form")
+ rating = forms.ChoiceField(choices=RATINGS_CHOICES)
+
+class SpectrumForm(forms.Form):
+ form_id = forms.CharField(widget=forms.HiddenInput(),
initial="pp_spectrum_form")
+ spectrum = forms.ChoiceField(choices=SPECTRUM_CHOICES)
=======================================
--- /trunk/pirate-politics/pirate_core/forms.py Thu Feb 17 01:26:13 2011
+++ /trunk/pirate-politics/pirate_core/forms.py Thu May 12 16:29:42 2011
@@ -78,7 +78,6 @@
self._fields['_initial'] = self._initial
self._form_ids = []
self._fields['_form_ids'] = self._form_ids
-
base_fields = SortedDict()
self._fields['base_fields'] = base_fields
@@ -92,6 +91,11 @@
self._forms.append(form)
self._add_fields_for_form(form, base_fields)
self._generate_class()
+ self._render(base_fields)
+
+ def _render(self, base_fields):
+ for name, field in base_fields.items():
+ base_fields[name].rendered = field.widget.render(name,
self._initial[name], {'id':hashlib.md5(name).hexdigest()})
def _add_fields_for_form(self, form, base_fields):
"""
@@ -116,27 +120,28 @@
self._form_ids.append(field)
elif name not in base_fields:
- base_fields[name] = field
-
# The initial value of the form should be preserved, even
if it is not default
- if name in form.initial:
- self._initial[name] = form.initial[name]
+ self._initial[name] = field.initial
+ base_fields[name] = field
elif base_fields[name].__class__ is not field.__class__:
raise ValueError("Fields with the same name '%s' are of
different "
"types." % name)
elif base_fields[name].widget.__class__ is not
field.widget.__class__:
raise ValueError("Fields with the same name '%s' use
different "
- "widgets." % name)
- elif self._initial[name] != form.initial[name]:
- raise ValueError("The initial values of two fields with
the same "
- "name '%s' do not match ('%s' vs. '%s')"
- % (name, self._initial[name],
form.initial[name]))
+ "widgets." % name)
+ #elif self._initial[name] != form.initial[name]:
+ # raise ValueError("The initial values of two fields with
the same "
+ # "name '%s' do not match ('%s' vs. '%s')"
+ # % (name, self._initial[name],
form.initial[name]))
elif hasattr(base_fields[name], 'choices') and \
hasattr(field, 'choices') and \
set(base_fields[name].choices) != set(field.choices):
raise ValueError("Choice fields with same name '%s' have
different "
"choices." % name)
+
+
+
def _generate_class(self):
if not hasattr(self, 'ComboForm'):
@@ -207,6 +212,7 @@
def save(self, commit=True):
for form in self.__class__._forms:
form.save(commit)
+
self.ComboForm = ComboForm
=======================================
--- /trunk/pirate-politics/pirate_core/middleware.py Wed Feb 9 00:35:14
2011
+++ /trunk/pirate-politics/pirate_core/middleware.py Thu May 12 16:29:42
2011
@@ -30,7 +30,8 @@
if content_type_id is not None and obj_id is not None:
content_type = ContentType.objects.get(pk=content_type_id)
- request.object =
content_type.get_object_for_this_type(pk=obj_id)
+ try: request.object =
content_type.get_object_for_this_type(pk=obj_id)
+ except: pass
if start is not None and end is not None:
request.start = int(start)
@@ -57,8 +58,9 @@
request_path = request.get_full_path()
name = request_path
- if request_path != '/favicon.ico' and
request_path[0:7] != '/submit' and request_path != '/vote/' and
request_path != '/jCollapsible.min.js':
- try:
+ if request_path != '/favicon.ico' and
request_path[0:7] != '/submit' and request_path != '/vote/' and
request_path != '/logout/':
+ try: request.session['currently_visiting']
+ except: request.session['currently_visiting'] =
request_path
if request.session['currently_visiting'] != request_path:
try:
visit_list = list(request.session['last_visited'])
@@ -93,13 +95,11 @@
try:
if name != None:
try:
- if visit_list[-1] != (name,request_path):
visit_list.append((name, request_path))
+ if visit_list[-1][0] != name:
visit_list.append((name, request_path))
except: visit_list.append((name, request_path))
except KeyError: pass #first visit
request.session['last_visited'] = visit_list
- except KeyError: pass
-
- if request_path != '/favicon.ico' and
request_path[:8] != '/submit' and request_path != '/vote/' and
request_path != '/jCollapsible.min.js':
+ if request_path != '/favicon.ico' and
request_path[0:7] != '/submit' and request_path != '/vote/' and
request_path != '/logout/':
request.session['currently_visiting'] = request_path
class AddToBuiltinsMiddleware(object):
=======================================
--- /trunk/pirate-politics/pirate_core/templatetags/pp_url.py Wed Feb 9
00:35:14 2011
+++ /trunk/pirate-politics/pirate_core/templatetags/pp_url.py Thu May 12
16:29:42 2011
@@ -61,7 +61,6 @@
>>> topic.delete()
'''
- print kwargs
obj = kwargs.pop('object', None)
start = kwargs.pop('start', None)
=======================================
--- /trunk/pirate-politics/pirate_core/templatetags/tag_helpers.py Thu Feb
17 01:26:13 2011
+++ /trunk/pirate-politics/pirate_core/templatetags/tag_helpers.py Thu May
12 16:29:42 2011
@@ -4,8 +4,6 @@
import datetime
from django.contrib.contenttypes.models import ContentType
from tagging.models import Tag, TaggedItem
-from pirate_issues.models import Issue, Solution
-from pirate_deliberation.models import Argument
from django.db.models import get_model
from pirate_core.helpers import clean_html
@@ -39,14 +37,14 @@
c_type = ContentType.objects.get_for_model(model)
- taglist = ""
+ taglist = []
for t in tags:
rels = RelationshipEvent.objects.all() #breaking modularity
saves some DB space here, RelationShip event stores the info we need
rels = rels.filter(ini_object_pk=t.pk,tar_object_pk=obj.pk)
count = rels.count()
- link = '<li><a href="/tag_detail.html?_t=' + str(c_type.id)
+ '&_o=' + str(t.id) + '">' + str(t.name) + " (" + str(count) + ")"
+"</a></li>"
- taglist += link
+ link = '<a href="/tag_detail.html?_t=' + str(c_type.id)
+ '&_o=' + str(t.id) + '">' + str(t.name) + " (" + str(count) + ")" +"</a>"
+ taglist.append(link)
return taglist
@@ -131,6 +129,29 @@
context.pop()
return output
+@block
+def pp_has_tags(context, nodelist, *args, **kwargs):
+ '''
+ Returns True if "object" has a Tag model associated with it.
+ '''
+
+ context.push()
+ namespace = get_namespace(context)
+
+ obj = kwargs.get('object',None)
+
+ l = Tag.objects.get_for_object(obj)
+ count = l.count()
+ if count > 0: ret = True
+ else: ret = False
+
+ namespace['has_tags'] = ret
+
+ output = nodelist.render(context)
+ context.pop()
+ return output
+
+
@block
def pp_get_tags_for_object(context, nodelist, *args, **kwargs):
'''
@@ -168,7 +189,8 @@
namespace = get_namespace(context)
obj = kwargs.get('object',None)
- tags = get_link_tag_list(obj)
+ try: tags = get_link_tag_list(obj)
+ except: tags = ""
namespace['tags'] = tags
#namespace['tags'].extend(tags1)
@@ -221,7 +243,8 @@
obj = kwargs.get('object',None)
POST = kwargs.get('POST',None)
tag = kwargs.get('tag',None)
- user = kwargs.get('user',None)
+ user = kwargs.get('user',None)
+ path = kwargs.get('path',None)
if POST and POST.get("form_id") == "pp_tag_form":
if tag != None:
@@ -237,8 +260,9 @@
Tag.objects.add_tag(obj, clean_tag)
tag =
TaggedItem.objects.get(tag_name=clean_tag,object_id=obj.pk)
new_tag = tag.tag
-
relationship_event.send(sender=new_tag,obj=new_tag,parent=obj,initiator=user)
- raise
HttpRedirectException(HttpResponseRedirect(obj.get_absolute_url()))
+
try:relationship_event.send(sender=new_tag,obj=new_tag,parent=obj,initiator=user)
+ except: namespace['errors'] = "You've already used
that tag for this object"
+ #raise HttpRedirectException(HttpResponseRedirect(path))
else:
form = TagForm()
=======================================
--- /trunk/pirate-politics/pirate_core/views.py Wed Feb 9 00:35:14 2011
+++ /trunk/pirate-politics/pirate_core/views.py Thu May 12 16:29:42 2011
@@ -18,13 +18,13 @@
significant modifications to the *.html files.
"""
- template_dict = {u'issue':'issue_detail.html',
u'solution':'solution_detail.html',
-
u'argument':'argument_detail.html',u'profile':'user_profile.html',u'topic':u'issues.html'}
+ template_dict = {u'issue':'detail.html', u'solution':'detail.html',
+
u'argument':'detail.html',u'profile':'user_profile.html',u'topic':u'issues.html'}
try:
ret = template_dict[model]
return ret
except:
- return '/'
+ return 'detail.html'
def home_page(request):
return redirect('welcome.html')
=======================================
--- /trunk/pirate-politics/pirate_deliberation/models.py Tue Feb 8
19:28:28 2011
+++ /trunk/pirate-politics/pirate_deliberation/models.py Thu May 12
16:29:42 2011
@@ -3,9 +3,11 @@
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
-from pirate_issues.models import Issue, Solution
from pirate_core import template_for_model
from tagging.models import Tag
+from django.utils.translation import ugettext as _
+from pirate_forum.models import ForumBlob
+
#Stance is a type of argument -- probably specified by admin
class Stance(models.Model):
@@ -16,17 +18,21 @@
# An argument of {arg_type} that is attached to an Issue
#This should be a pirate-wikipage instance
-class Argument(models.Model):
- name = models.CharField(max_length=64)
- pub_date = models.DateTimeField('date_published', blank=True,null=True)
- parent = models.ForeignKey(Solution) #Issue
- user = models.ForeignKey(User, related_name='arg_author')
- text = models.TextField(max_length=1200)
- arg_type = models.ForeignKey(Stance)
- #comments = generic.GenericRelation(Comment)
+class Argument(ForumBlob):
+ stance = models.ForeignKey(Stance)
+
+ class Meta:
+ verbose_name = _('argument')
+ #help_text = _('Supply an Argument for your position.')
def __unicode__(self):
- return self.name
+ return self._meta.verbose_name
+
+ def get_verbose_name(self):
+ return self._meta.verbose_name
+
+ def get_blob_key(self):
+ return 'r'
def taggable(self):
return True
@@ -34,7 +40,7 @@
#This must be added to all classes that can be tagged
def get_absolute_url(self):
content_type = ContentType.objects.get_for_model(self.__class__)
- path = template_for_model(str(content_type)) + "?_t=" +
str(content_type.pk) + "&_o=" + str(self.pk)
+ path = "detail?_t=" + str(content_type.pk) + "&_o=" + str(self.pk)
return path
admin.site.register(Stance)
=======================================
--- /trunk/pirate-politics/pirate_deliberation/templatetags/argumenttags.py
Thu Feb 17 01:26:13 2011
+++ /trunk/pirate-politics/pirate_deliberation/templatetags/argumenttags.py
Thu May 12 16:29:42 2011
@@ -2,15 +2,15 @@
from django import forms
from django.http import HttpResponseRedirect
import datetime
-from pirate_issues.models import Topic, Issue, Solution
from django.contrib.contenttypes.models import ContentType
from pirate_deliberation.models import Argument, Stance
from pirate_consensus.models import Consensus, UpDownVote
from pirate_reputation.models import ReputationDimension
from pirate_core.helpers import clean_html
+from pirate_deliberation.forms import ArgumentForm
+from pirate_deliberation.choices import ARG_TYPES_DICT
from pirate_core import HttpRedirectException, namespace_get, FormMixin
-from pirate_issues.models import Topic, Issue
from pirate_signals.models import aso_rep_event,notification_send,
relationship_event
@@ -20,14 +20,13 @@
get_namespace = namespace_get('pp_argumentation')
-
@block
def pp_get_arg_types(context, nodelist, *args, **kwargs):
"""This block tag grabs all available Stances.
Can be used in the following manner:
{% pp_get_arg_types %}
- Do stuff with {{ pp_argumentation.arg_type_list }}
+ Do stuff with {{ pp_blob.arg_type_list }}
{% endpp_get_arg_types %}"""
context.push()
@@ -79,9 +78,9 @@
rng = (0,20)
if obj:
- arg_list = arg_list.filter(parent__id=obj.id).order_by('-pub_date')
+ arg_list =
arg_list.filter(parent_pk=obj.id).order_by('-created_dt')
if arg_type:
- arg_list = arg_list.filter(arg_type__id=arg_type.id)
+ arg_list = arg_list.filter(stance=arg_type)
if rng:
arg_list = arg_list[start:end]
if arg_list == None:
@@ -108,16 +107,15 @@
POST = kwargs.get('POST',None)
obj = kwargs.get('object', None)
- arg_type = kwargs.get('arg_type', None)
+ arg_type = kwargs.get('dimension', None)
user = kwargs.get('user',None)
if isinstance(arg_type, unicode):
+ arg_type = ARG_TYPES_DICT[arg_type]
arg_type, created = Stance.objects.get_or_create(arg=arg_type)
-
- if isinstance(obj, Solution):
- solution = obj
- arg = None
- elif isinstance(obj, Argument):
+ else: raise ValueError("dimension must be provided to the argument
form.")
+
+ if isinstance(obj, Argument):
arg = obj
solution = arg.parent
else: arg, solution = (None, None)
@@ -125,16 +123,8 @@
if POST and POST.get("form_id") == "pp_argument_form" and user != None:
form = ArgumentForm(POST) if arg is None else ArgumentForm(POST,
instance=arg)
if form.is_valid() and user.is_authenticated():
- new_arg = form.save(commit=False)
- new_arg.pub_date = datetime.datetime.now()
- new_arg.parent = solution
- new_arg.user = user
- new_arg.text = clean_html(new_arg.text)
- new_arg.name = clean_html(new_arg.name)
- new_arg.arg_type = arg_type
- new_arg.save()
- contype = ContentType.objects.get_for_model(Argument)
- obj_pk = new_arg.pk
+ new_arg = form.save()
+
cons, is_new =
Consensus.objects.get_or_create(content_type=contype,
object_pk=obj_pk,parent_pk=new_arg.parent.id)
@@ -142,36 +132,14 @@
aso_rep_event.send(sender=new_arg,event_score=4,
user=new_arg.user, dimension=ReputationDimension.objects.get('Argument
Author'))
notification_send.send(sender=new_arg.user,obj=new_arg,reply_to=new_arg.parent)
relationship_event.send(sender=new_arg,obj=new_arg,parent=new_arg.parent)
- new_arg.parent.arguments += 1
- new_arg.parent.issue.arguments +=1
- new_arg.parent.issue.save()
- new_arg.parent.save()
raise
HttpRedirectException(HttpResponseRedirect(new_arg.get_absolute_url()))
else: namespace['errors'] = form.errors
else:
form = ArgumentForm() if arg is None else
ArgumentForm(instance=arg)
-
+ namespace['help_text'] = 'Supply a ' + str(arg_type) + ' Argument
for your position.'
namespace['form'] = form
output = nodelist.render(context)
context.pop()
- return output
-
-
-class ArgumentForm(forms.ModelForm, FormMixin):
-
- def save(self, commit=True):
- new_arg = super(ArgumentForm, self).save(commit=commit)
- return new_arg
-
- class Meta:
- model = Argument
- exclude = ('parent','user','arg_type','pub_date',)
-
- form_id = forms.CharField(widget=forms.HiddenInput(),
initial="pp_argument_form")
- text = forms.CharField(widget=forms.Textarea)
- name = forms.CharField(label="name", max_length=64,
- widget=forms.TextInput(
- attrs={'size':'50', 'class':'inputText'}))
-
+ return output
=======================================
--- /trunk/pirate-politics/pirate_issues/forms.py Wed Mar 17 16:40:43 2010
+++ /trunk/pirate-politics/pirate_issues/forms.py Thu May 12 16:29:42 2011
@@ -0,0 +1,86 @@
+from django import forms
+from django.forms.extras import SelectDateWidget
+from pirate_issues.models import Problem, Solution, Policy
+from pirate_topics.models import Topic
+from pirate_forum.forms import BlobForm
+from pirate_core.forms import FormMixin
+from pirate_core.widgets import HorizRadioRenderer
+from django.contrib.contenttypes.models import ContentType
+import datetime
+from markitup.widgets import MarkItUpWidget
+
+
+class ProblemForm(forms.ModelForm, FormMixin):
+
+ def save(self, commit=True):
+ newo = super(ProblemForm, self).save(commit=commit)
+ if newo.created_dt == None:
+ newo.created_dt = datetime.datetime.now()
+ newo.child = ContentType.objects.get_for_model(Solution)
+ children = 0
+ newo.modified_dt = datetime.datetime.now()
+ return newo
+
+ class Meta:
+ model = Problem
+ exclude =
('parent','parent_pk', 'parent_type', 'user', 'child', 'children', 'permission_req', 'created_dt' , 'modified_dt'
)
+
+ form_id = forms.CharField(widget=forms.HiddenInput(),
initial="pp_problem_form")
+ summary = forms.CharField( max_length=100,
+ widget=forms.TextInput(
+ attrs={'size':'50', 'class':'inputText'}),label="Summary
of Problem")
+ description =
forms.CharField(widget=MarkItUpWidget(),label="Description")
+ location = forms.CharField(label="Location", max_length=100,
+ widget=forms.TextInput(
+ attrs={'size':'50', 'class':'inputText'}),required=False)
+ deadline_dt = forms.DateField(widget =
SelectDateWidget(),required=False,label="Deadline")
+
+
+class SolutionForm(forms.ModelForm, FormMixin):
+ '''
+ This form is used to allow creation and modification of issue objects.
+ It extends FormMixin in order to provide a create() class method, which
+ is used to process POST, path, and object variables in a consistant
way,
+ and in order to automatically provide the form with a form_id.
+ '''
+
+ def save(self, commit=True):
+ new_issue = super(SolutionForm, self).save(commit=commit)
+ return new_issue
+
+ class Meta:
+ model = Solution
+ exclude =
('parent', 'parent_pk', 'parent_type', 'user', 'child', 'children', 'permission_req', 'created_dt' , 'modified_dt', 'deadline_dt'
)
+
+ #need to grab user from authenticatio
+ form_id = forms.CharField(widget=forms.HiddenInput(),
initial="pp_solution_form")
+ summary = forms.CharField( max_length=100,
+ widget=forms.TextInput(
+ attrs={'size':'50', 'class':'inputText'}), label="Summary
of Solution")
+ description =
forms.CharField(widget=MarkItUpWidget(),label="Description")
+
+
+class PolicyForm(forms.ModelForm, FormMixin):
+
+ def save(self, commit=True):
+ newo = super(PolicyForm, self).save(commit=commit)
+ if newo.created_dt == None:
+ newo.created_dt = datetime.datetime.now()
+ newo.modified_dt = datetime.datetime.now()
+ return newo
+
+ class Meta:
+ model = Policy
+ exclude =
('parent', 'parent_pk', 'parent_type', 'user', 'child', 'children', 'permission_req', 'created_dt' , 'modified_dt' , 'deadline_dt')
+
+ form_id = forms.CharField(widget=forms.HiddenInput(),
initial="pp_policy_form")
+ summary = forms.CharField( max_length=100,
+ widget=forms.TextInput(
+ attrs={'size':'50', 'class':'inputText'}),label="Summary
of Policy Statement")
+ description = forms.CharField(widget=MarkItUpWidget(),label="Details
of Policy")
+ location = forms.CharField(label="Location", max_length=100,
+ widget=forms.TextInput(
+ attrs={'size':'50', 'class':'inputText'}),required=False)
+
+
+
=======================================
--- /trunk/pirate-politics/pirate_issues/models.py Thu Feb 17 01:26:13 2011
+++ /trunk/pirate-politics/pirate_issues/models.py Thu May 12 16:29:42 2011
@@ -9,77 +9,77 @@
#from ModuleDeliberation.models import Comment
from django.utils.translation import ugettext as _
from pirate_core.views import template_for_model
-
-# First, define the Manager subclass.
-class TopicManager(models.Manager):
- def get_query_set(self):
- return super(TopicManager,
self).get_query_set().exclude(text="__NULL__")
-
-class NullManager(models.Manager):
- def null_dimension(self):
- return self.get_or_create(text="__NULL__")[0]
-
-#Topic: Category to place issues, includes parent and child for
hierarchical topics
-class Topic(models.Model):
- text = models.CharField(max_length=140, unique = True)
- description = models.CharField(max_length=600, unique=True)
- submit_date = models.DateTimeField('date published', auto_now_add=True)
- parent = models.ForeignKey('self', null=True, blank=True)
- objects = NullManager()
- clean_objects = TopicManager()
-
- def __unicode__(self):
- return self.text[:20]
+from pirate_forum.models import ForumBlob
+from pirate_topics.models import Topic
#A specific issue of political concern. Are authors important?
#This should be a pirate-wikipage instance
-class Issue(models.Model):
- topic = models.ForeignKey(Topic, blank= True, null = True)
- name = models.CharField(max_length=100, blank=True, unique=True)
- submit_date = models.DateTimeField('date_published',auto_now_add=True)
- text = models.TextField(max_length=1200)
- user = models.ForeignKey(User, blank=True, null=True)
- solutions = models.IntegerField(default=0,blank=True,null=True)
- arguments = models.IntegerField(default=0, blank = True , null = True)
+class Problem(ForumBlob):
class Meta:
- verbose_name = _('issue')
-
- def __unicode__(self):
- return self.name
-
- def taggable(self):
- return True
-
- #This must be added to all classes that can be tagged
+ verbose_name = _('problem')
+
+ def get_absolute_url(self):
+ content_type = ContentType.objects.get_for_model(self.__class__)
+ path = template_for_model(str(content_type)) + "?_t=" +
str(content_type.pk) + "&_o=" + str(self.pk)
+ return path
+
+ def get_verbose_name(self):
+ return self._meta.verbose_name
+
+ def is_root(self):
+ return False
+
+ def get_blob_key(self):
+ return 'p'
+
+ def get_child_blob_key(self):
+ return 's'
+
+
+class Solution(ForumBlob):
+
+ class Meta:
+ verbose_name = _('solution')
+
def get_absolute_url(self):
content_type = ContentType.objects.get_for_model(self.__class__)
path = template_for_model(str(content_type)) + "?_t=" +
str(content_type.pk) + "&_o=" + str(self.pk)
return path
-
-
-class Solution(models.Model):
- issue = models.ForeignKey(Issue, blank=True, null=True)
- name = models.CharField(max_length=100, blank=True, null=True,
unique=True)
- text = models.TextField(max_length=1200)
- submit_date = models.DateTimeField('date_published',auto_now_add=True)
- user = models.ForeignKey(User ,blank=True, null=True)
- arguments = models.IntegerField(default=0)
-
- def __unicode__(self):
- return self.name[0:10]
-
- def taggable(self):
- return True
+
+ def get_verbose_name(self):
+ return self._meta.verbose_name
+
+ def is_root(self):
+ return False
+
+ def get_blob_key(self):
+ return 's'
+
+
+class Policy(ForumBlob):
+
+ class Meta:
+ verbose_name = _('policy')
def get_absolute_url(self):
content_type = ContentType.objects.get_for_model(self.__class__)
path = template_for_model(str(content_type)) + "?_t=" +
str(content_type.pk) + "&_o=" + str(self.pk)
return path
-admin.site.register(Topic)
-admin.site.register(Issue)
+ def get_verbose_name(self):
+ return self._meta.verbose_name
+
+ def is_root(self):
+ return False
+
+ def get_blob_key(self):
+ return 'l'
+
+
+admin.site.register(Problem)
admin.site.register(Solution)
+admin.site.register(Policy)
###SIGNALS
comment_was_posted.connect(update_issue_comment_count)
=======================================
--- /trunk/pirate-politics/pirate_issues/templatetags/issuetags.py Thu Feb
17 01:26:13 2011
+++ /trunk/pirate-politics/pirate_issues/templatetags/issuetags.py Thu May
12 16:29:42 2011
@@ -6,7 +6,8 @@
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from pirate_core import HttpRedirectException, namespace_get, FormMixin
-from pirate_issues.models import Topic, Issue
+from pirate_issues.models import Problem
+from pirate_topics.models import Topic
from pirate_consensus.models import UpDownVote, Consensus
from django.utils.translation import ugettext as _
from pirate_reputation.models import ReputationDimension
@@ -242,29 +243,30 @@
obj = kwargs.get('object',None)
user = kwargs.get('user',None)
- #try:
- # This topic has to be set here because this is how the form
- # is going to know how to set the default choice to be the same
- # as the passed-in argument
- if POST and POST.get("form_id") == "pp_issue_form" and user is not
None:
+ if isinstance(obj, Issue):
+ topic = obj.topic
+ issue = obj
+ namespace['contextname'] = "Edit issue " + str(issue.name)
+ namespace['has_topic'] = True
+
+ elif isinstance(obj,Topic):
+ topic = obj
+ issue = None
+ namespace['contextname'] = "Create issue on " + str(topic.text)
+ namespace['has_topic'] = True
+
+ else:
+ issue, topic = (None, None)
+ namespace['contextname'] = "Create issue on topic of your choice"
+ namespace['has_topic'] = False
+
+ if POST and POST.get("form_id") == "pp_issue_form" and user is not
None:
+
if isinstance(obj, Issue):
- topic = obj.topic
- issue = obj
- namespace['contextname'] = "Edit issue " + str(issue.name)
- namespace['has_topic'] = True
form = IssueForm(POST, instance=issue)
-
- elif isinstance(obj,Topic):
- topic = obj
- issue = None
- namespace['contextname'] = "Create issue on " + str(topic.text)
- namespace['has_topic'] = True
+ elif isinstance(obj, Topic):
form = IssueForm(POST)
-
- else:
- issue, topic = (None, None)
- namespace['contextname'] = "Create issue on topic of your
choice"
- namespace['has_topic'] = False
+ else:
form = TopicIssueForm(POST)
@@ -292,7 +294,7 @@
if is_new: #if this is a new issue/consensus, send signal for
reputation
aso_rep_event.send(sender=issue,event_score=3,
user=issue.user, dimension=ReputationDimension.objects.get('Issue Author'))
- relationship_event.send(sender=issue,obj=issue,parent=None)
+
relationship_event.send(sender=issue,obj=issue,parent=issue.topic)
raise
HttpRedirectException(HttpResponseRedirect(issue.get_absolute_url()))
else: namespace['errors'] = form.errors
@@ -325,30 +327,6 @@
return output
-
-class IssueForm(forms.ModelForm, FormMixin):
- '''
- This form is used to allow creation and modification of issue objects.
- It extends FormMixin in order to provide a create() class method, which
- is used to process POST, path, and object variables in a consistant
way,
- and in order to automatically provide the form with a form_id.
- '''
-
- def save(self, commit=True):
- new_issue = super(IssueForm, self).save(commit=commit)
- return new_issue
-
- class Meta:
- model = Issue
- exclude = ('solutions','arguments','user','topic',)
-
- #need to grab user from authenticatio
- form_id = forms.CharField(widget=forms.HiddenInput(),
initial="pp_issue_form")
- name = forms.CharField(label="text", max_length=100,
- widget=forms.TextInput(
- attrs={'size':'50', 'class':'inputText'}))
- text = forms.CharField(widget=forms.Textarea)
-
class TopicIssueForm(forms.ModelForm, FormMixin):
'''
@@ -363,7 +341,7 @@
return new_issue
class Meta:
- model = Issue
+ model = Problem
exclude = ('solutions','arguments','user',)
#need to grab user from authenticatio
=======================================
--- /trunk/pirate-politics/pirate_issues/templatetags/solutiontags.py Thu
Feb 17 01:26:13 2011
+++ /trunk/pirate-politics/pirate_issues/templatetags/solutiontags.py Thu
May 12 16:29:42 2011
@@ -6,7 +6,7 @@
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from pirate_core import HttpRedirectException, namespace_get, FormMixin
-from pirate_issues.models import Topic, Issue, Solution
+from pirate_issues.models import Problem, Solution
from pirate_consensus.models import UpDownVote, Consensus
from django.utils.translation import ugettext as _
from pirate_reputation.models import ReputationDimension
=======================================
--- /trunk/pirate-politics/pirate_issues/templatetags/topictags.py Thu Feb
17 01:26:13 2011
+++ /trunk/pirate-politics/pirate_issues/templatetags/topictags.py Thu May
12 16:29:42 2011
@@ -2,7 +2,7 @@
from django import forms
from django.http import HttpResponseRedirect
-from pirate_issues.models import Topic, Issue
+from pirate_issues.models import Topic
from pirate_core.views import HttpRedirectException, namespace_get
from customtags.decorators import block_decorator
=======================================
--- /trunk/pirate-politics/pirate_login/views.py Wed Feb 9 00:35:14 2011
+++ /trunk/pirate-politics/pirate_login/views.py Thu May 12 16:29:42 2011
@@ -4,7 +4,8 @@
from pirate_core import HttpRedirectException, namespace_get, FormMixin
def logout_view(request):
- try: goto = request.currently_visiting
- except: goto = '/issues.html?_s=0&_e=20&_d=hot'
+ try:goto = request.session['currently_visiting']
+ except: print request.session
+ #except: goto = '/issues.html?_s=0&_e=20&_d=hot'
logout(request)
return HttpResponseRedirect(goto)
=======================================
--- /trunk/pirate-politics/pirate_ranking/models.py Thu Feb 17 01:26:13 2011
+++ /trunk/pirate-politics/pirate_ranking/models.py Thu May 12 16:29:42 2011
@@ -7,9 +7,8 @@
from django.contrib import admin
from pirate_signals.models import vote_created
from django.contrib.contenttypes.models import ContentType
-from pirate_issues.models import Solution
import math, datetime
-
+from pirate_consensus.models import Rating, Spectrum
# Create your models here.
@@ -46,67 +45,104 @@
return 0
-def calc_controversial(obj):
- up = UpDownVote.objects.filter(parent=obj,vote_type=1).count() #This
expensive operation needs to be optimized
- down = UpDownVote.objects.filter(parent=obj,vote_type=-1).count()
- neut = UpDownVote.objects.filter(parent=obj,vote_type=0).count()
-
- #difference from Distant Date to make time discount more gradual
- timeDiff = (obj.submit_date - datetime.datetime(2010, 7, 5, 20, 16,
19, 539498)).seconds
- timeNormFactor=(obj.submit_date - datetime.datetime.now()).seconds
-
- timeDiscounting=timeDiff/timeNormFactor
-
- score=(up+down-neut)*timeDiscounting
+def calc_controversial(dt, spectrum, rating):
+ x = 0 # weighted votes
+ mag = 0 #magnitude of votes
+ #compute the mean
+ for k, num in spectrum:
+ x += k * num
+ mag += num
+ if mag != 0:
+ mean = x / mag
+ #compute the sd
+ tot = 0
+ for k, num in spectrum: #TODO: INEFFICIENT, needs better solution
+ for i in range(num):
+ tot += math.pow((k - mean),2)
+ sd = math.sqrt(tot/mag)
+ else:
+ mean = 0.0
+ sd = 0.0
+ score = sd * math.log(mag) * dt
return score
-def calc_hot(obj):
- up = UpDownVote.objects.filter(parent=obj,vote_type=1).count() #This
expensive operation needs to be optimized
- down = UpDownVote.objects.filter(parent=obj,vote_type=-1).count()
- neut = UpDownVote.objects.filter(parent=obj,vote_type=0).count()
- #calculate time difference between some arbitrary date to lessen score
of old posts
- #time = (obj.submit_date - datetime.datetime(2010, 7, 5, 20, 16, 19,
539498)).seconds
- x = up - down
+def calc_hot(dt, spectrum, rating):
+ #get spectrum list ex: [(-5,246), (-4,45), ... ,(5,121)]
+ x = 0
+ for k, num in spectrum:
+ x += k * num
+ r = 0.0
+ tot = 0.0
+
+ for k, weight, num in rating:
+ r += k * num * weight
+ tot += num
+ if tot != 0: r = r/tot #get average rating
+ else: r = 0.0
+
+ if r != 0: x = x * r
+ else: pass
#general score according to up - vote, need to work in way to make
neut important...
if x > 0: y = 1
elif x == 0: y = 0
else: y = -1
#now if the obj is siginficant, i.e. been viewed extensively we take
into account it's popularity
- k = abs(x)
- if k > 1: z = k
- else: z = 1
+ z = abs(x)
#now calculate final score
- score = math.log(z) + y
+ score = (3 * math.log(z) + y) * dt
return score
#When a vote is created via the consensus engine, this callback updates
#the issue ranked score, for each dimension
def vote_created_callback(sender, **kwargs):
#udpate hot
- cons = kwargs.pop('parent',None)
- vt = kwargs.pop('vote_type',None)
- pis = cons.content_object #parent of the consensus object
- #For the HOT dimension
- ###TODO: Only should rerank when a unique user creates a vote. If a
user
- ### has created a vote before it should not be counted toward the
reranking.
- ### This closes a process that allows users to maliciously inflate hot
ranking
-
- sols = [( ('hot', calc_hot(cons)), ('cont', calc_controversial(cons))
) ]
-
- ###I don't know why, but this fails if it's where it should be up
above...
- from pirate_ranking.models import Ranking
- for scores in sols:
- for dim, sc in scores:
- try:
- obj = Ranking.objects.get(object_pk=pis.id, dimension=dim)
- obj.score = sc
- obj.save()
- except:
- contype = ContentType.objects.get_for_model(pis)
- newrank =
Ranking(content_object=pis,dimension=dim,score=sc,consensus_pk=cons.id,content_type=contype,object_pk=pis.id)
- newrank.save()
-
+ try:
+ cons = kwargs.pop('parent',None)
+ vt = kwargs.pop('vote_type',None)
+ pis = cons.content_object #parent of the consensus object
+ #For the HOT dimension
+ ###TODO: Only should rerank when a unique user creates a vote. If
a user
+ ### has created a vote before it should not be counted toward the
reranking.
+ ### This closes a process that allows users to maliciously inflate
hot ranking
+
+ try: spectrum = cons.spectrum.get_list()
+ except: #add spectrum to consensus if first vote
+ sp = Spectrum()
+ cons.spectrum = sp
+ sp.save()
+ cons.save()
+ spectrum = cons.spectrum.get_list()
+ try: rating = cons.rating.get_list()
+ except: #add rating to consensus if first rating
+ rt = Rating()
+ cons.rating = rt
+ rt.save()
+ cons.save()
+ rating = cons.rating.get_list()
+ dt = cons.submit_date
+ timeDiff = (dt - datetime.datetime(2010, 7, 5, 20, 16, 19,
539498)).seconds
+ timeNormFactor=(dt - datetime.datetime.now()).seconds
+
+ dt=timeDiff/float(timeNormFactor)
+
+ sols = [( ('hot', calc_hot(dt, spectrum, rating)), ('cont',
calc_controversial(dt, spectrum, rating)) ) ]
+
+ ###I don't know why, but this fails if it's where it should be up
above...
+ from pirate_ranking.models import Ranking
+ for scores in sols:
+ for dim, sc in scores:
+ try:
+ obj = Ranking.objects.get(object_pk=pis.id,
dimension=dim)
+ obj.score = sc
+ obj.save()
+ except:
+ contype = ContentType.objects.get_for_model(pis)
+ newrank =
Ranking(content_object=pis,dimension=dim,score=sc,consensus_pk=cons.id,content_type=contype,object_pk=pis.id)
+ newrank.save()
+ except:
+ raise
+
vote_created.connect(vote_created_callback)
admin.site.register(Ranking)
=======================================
--- /trunk/pirate-politics/pirate_reputation/models.py Fri Jan 21 16:05:49
2011
+++ /trunk/pirate-politics/pirate_reputation/models.py Thu May 12 16:29:42
2011
@@ -5,6 +5,7 @@
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
+import datetime
from pirate_signals.models import aso_rep_event,aso_rep_delete
=======================================
--- /trunk/pirate-politics/pirate_reputation/templatetags/reputationtags.py
Thu Feb 17 01:26:13 2011
+++ /trunk/pirate-politics/pirate_reputation/templatetags/reputationtags.py
Thu May 12 16:29:42 2011
@@ -5,7 +5,7 @@
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from tagging.models import Tag, TaggedItem
-from pirate_reputation.models import ReputationManager, Reputation,
ReputationDimension
+from pirate_reputation.models import ReputationManager, Reputation,
ReputationDimension, ReputationEvent
from pirate_core import HttpRedirectException, namespace_get, FormMixin,
template_for_model
from customtags.decorators import block_decorator
@@ -14,6 +14,63 @@
get_namespace = namespace_get('pp_reputation')
+
+@block
+def pp_get_reputation_events_graph(context, nodelist, *args, **kwargs):
+ '''
+ This block tag can create or process forms to get tags.
+ Usage is as follows:
+
+ {% pp_get_reputation_events_graph user=request.object x=8 y=100 %}
+ Do stuff with {{ pp_reputation.graph_html }}
+ {% endpp_get_reputation %}
+
+ This template tag dynamically generates the html required for a (x,y)
graph
+ where x is the activity rate and y is the time dimension. This graph
shows
+ users a basic idea of the user's activity rate.
+
+ '''
+
+ context.push()
+ namespace = get_namespace(context)
+
+ user = kwargs.get('user',None)
+ x = kwargs.get('x', None)
+ y = kwargs.get('y', None)
+
+
+
+@block
+def pp_get_reputation_events(context, nodelist, *args, **kwargs):
+ '''
+ This block tag can create or process forms to get tags.
+ Usage is as follows:
+
+ {% pp_get_reputation_events user=request.object %}
+ Do stuff with {{ pp_reputation.reputation_events }}.
+ {% endpp_get_reputation %}
+
+ '''
+
+ context.push()
+ namespace = get_namespace(context)
+
+ user = kwargs.get('user',None)
+
+ if user is not None and isinstance(user, User):
+ #get argument score
+ scores = {}
+ tot_score = 0
+ rep = ReputationEvent.objects.filter(initiator=user)
+ else:
+ rep = []
+
+ namespace['reputation_events'] = rep
+
+ output = nodelist.render(context)
+ context.pop()
+ return output
+
@block
def pp_get_reputation(context, nodelist, *args, **kwargs):
'''
=======================================
--- /trunk/pirate-politics/pirate_social/models.py Thu Feb 17 01:27:45 2011
+++ /trunk/pirate-politics/pirate_social/models.py Thu May 12 16:29:42 2011
@@ -20,7 +20,7 @@
class RelationshipEvent(models.Model):
initiator = models.ForeignKey(User, verbose_name=_('initiator user'),
related_name=_('initiator'))
- target = models.ForeignKey(User, verbose_name=_('target user'),
related_name=_('target'), null=True)
+ target = models.ForeignKey(User, verbose_name=_('target user'),
related_name=_('target'), blank=True,null=True)
created_on = models.DateTimeField(_('date/time occured'),
auto_now_add=True)
ini_content_type = models.ForeignKey(ContentType,
verbose_name=_('initiator content
type'),
@@ -29,8 +29,8 @@
ini_content_object =
generic.GenericForeignKey(ct_field="ini_content_type",
fk_field="ini_object_pk")
tar_content_type = models.ForeignKey(ContentType,
verbose_name=_('target content
type'),
-
related_name="tar_content_type_set_for_%(class)s", null=True)
- tar_object_pk = models.IntegerField(_('target object ID'), null=True)
+
related_name="tar_content_type_set_for_%(class)s")
+ tar_object_pk = models.IntegerField(_('target object ID'))
tar_content_object =
generic.GenericForeignKey(ct_field="tar_content_type",
fk_field="tar_object_pk")
@@ -54,20 +54,21 @@
if initiator == None:
try: initiator = obj.user
except: pass
- if parent != None: rel = RelationshipEvent(initiator=initiator,
+ if parent != None:
+ try: target_user = parent.user
+ except: target_user = None
+
+ rel = RelationshipEvent(initiator=initiator,
ini_object_pk=obj.pk,
ini_content_type=ini_c_type,
tar_object_pk=parent.pk,
tar_content_type=parent_c_type,
- target=parent.user)
+ target=target_user)
else: rel = RelationshipEvent(initiator=initiator,
ini_object_pk=obj.pk,
ini_content_type=ini_c_type)
- try:
- rel.full_clean()
- rel.save()
- except ValidationError, e:
- pass #This RelationshipEvent already exists
+ rel.full_clean()
+ rel.save()
=======================================
--- /trunk/pirate-politics/pirate_social/templatetags/feedtags.py Thu Feb
17 01:27:45 2011
+++ /trunk/pirate-politics/pirate_social/templatetags/feedtags.py Thu May
12 16:29:42 2011
@@ -32,6 +32,15 @@
subs = subs.filter(subscriber=user)
eval_str = ""
+
+ """To facilitate feeds, we have to use a bit of eval() trickery.
+ The string 'eval_str' consists of a series of OR operations
+ on relationship events, that allow the system to filter out
+ all relationship events where the initiator is in the list
+ of subscriptions."""
+ #TODO: in the future we need to filter this list on specific types
+ # of content, so that we don't needlessly return objs such as
tagging
+ # for the generic feed, but still allow for tagging for specific
activity viewing
query_dict = {}
for s in subs:
u = s.subscribee
=======================================
--- /trunk/pirate-politics/pirate_social/templatetags/subscriptiontags.py
Thu Feb 17 01:27:45 2011
+++ /trunk/pirate-politics/pirate_social/templatetags/subscriptiontags.py
Thu May 12 16:29:42 2011
@@ -34,6 +34,27 @@
output = nodelist.render(context)
context.pop()
+ return output
+
+@block
+def pp_get_subscribers_for_user(context, nodelist, *args, **kwargs):
+ context.push()
+ namespace = get_namespace(context)
+
+ user = kwargs.pop('user', None)
+ if user is None:
+ raise ValueError("pp_subscription_form tag requires that a User
object be passed "
+ "to it assigned to the 'user=' argument")
+
+ subs = Subscription.objects.all()
+ subs = subs.filter(subscribee=user)
+ count = subs.count()
+
+ namespace['subscribers'] = subs
+ namespace['count'] = count
+ output = nodelist.render(context)
+ context.pop()
+
return output
@block
@@ -54,6 +75,26 @@
output = nodelist.render(context)
context.pop()
+ return output
+
+@block
+def pp_subscribee_count(context, nodelist, *args, **kwargs):
+ context.push()
+ namespace = get_namespace(context)
+
+ user = kwargs.pop('user', None)
+ if user is None:
+ raise ValueError("pp_subscription_form tag requires that a User
object be passed "
+ "to it assigned to the 'user=' argument")
+
+ subs = Subscription.objects.all()
+ subs = subs.filter(subscriber=user)
+ count = subs.count()
+
+ namespace['count'] = count
+ output = nodelist.render(context)
+ context.pop()
+
return output
@block
@@ -81,6 +122,40 @@
output = nodelist.render(context)
context.pop()
+ return output
+
+
+@block
+def pp_end_subscription_form(context, nodelist, *args, **kwargs):
+
+ context.push()
+ namespace = get_namespace(context)
+
+ # this tag only works if a valid pair is assigned to the 'object='
argument
+ POST = kwargs.get('POST', None)
+ subscriber = kwargs.pop('subscriber', None)
+ subscribee = kwargs.pop('subscribee', None)
+ if subscriber is None:
+ raise ValueError("pp_subscription_form tag requires that a object
be passed "
+ "to it assigned to the 'subscriber='
argument")
+ if subscribee is None:
+ raise ValueError("pp_subscription_form tag requires that a object
be passed "
+ "to it assigned to the 'subscribee='
argument")
+
+
+ if POST and POST.get("form_id") == "pp_subscription_form":
+ form = SubscriptionForm(POST)
+ if form.is_valid():
+ sub =
Subscription.objects.get(subscriber=subscriber,subscribee=subscribee)
+ sub.delete()
+ c_type = ContentType.objects.get_for_model(subscribee)
+ raise
HttpRedirectException(HttpResponseRedirect("/user_profile.html?_t=" +
str(c_type.pk) + "&_o=" + str(subscribee.pk) + "&_d=i"))
+ else: form = SubscriptionForm()
+
+ if subscriber != subscribee: namespace['form'] = form
+ output = nodelist.render(context)
+ context.pop()
+
return output
@@ -108,7 +183,7 @@
sub =
Subscription(subscriber=subscriber,subscribee=subscribee,created_dt=datetime.datetime.now())
sub.save()
c_type = ContentType.objects.get_for_model(subscribee)
- raise
HttpRedirectException(HttpResponseRedirect("/user_profile.html?_t=" +
str(c_type.pk) + "&_o=" + str(subscribee.pk)))
+ raise
HttpRedirectException(HttpResponseRedirect("/user_profile.html?_t=" +
str(c_type.pk) + "&_o=" + str(subscribee.pk) + "&_d=i"))
else: form = SubscriptionForm()
if subscriber != subscribee: namespace['form'] = form
=======================================
--- /trunk/pirate-politics/pirate_sources/templatetags/sourcetags.py Thu
Feb 17 01:26:13 2011
+++ /trunk/pirate-politics/pirate_sources/templatetags/sourcetags.py Thu
May 12 16:29:42 2011
@@ -66,7 +66,7 @@
new_source.save()
path = obj.get_absolute_url()
- raise HttpRedirectException(HttpResponseRedirect(path))
+ #raise HttpRedirectException(HttpResponseRedirect(path))
else:
view_url = obj.get_absolute_url()
upload_url, upload_data = prepare_upload(request, view_url)
@@ -122,9 +122,9 @@
new_source.object_pk = obj.pk
new_source.content_object = obj
new_source.save()
- else: print form
- path = obj.get_absolute_url()
- raise HttpRedirectException(HttpResponseRedirect(path))
+ else: namespace['errors'] = "Not a valide URL"
+ #path = obj.get_absolute_url()
+ #raise HttpRedirectException(HttpResponseRedirect(path))
else:
form = URLSourceForm() if source is None else
URLSourceForm(instance=source)
=======================================
--- /trunk/pirate-politics/settings.py Thu Feb 17 01:26:13 2011
+++ /trunk/pirate-politics/settings.py Thu May 12 16:29:42 2011
@@ -6,7 +6,7 @@
SITE_ID = 1
INSTALLED_APPS = (
- 'djangoappengine',
+ 'dbindexer',
'djangotoolbox',
'django.contrib.auth',
'django.contrib.contenttypes',
@@ -31,15 +31,29 @@
'pirate_sources',
'pirate_comments',
'pirate_badges',
+ 'pirate_flags',
'pirate_social',
+ 'pirate_forum',
+ 'pirate_topics',
+ 'markitup',
+ 'djangoappengine',
)
+MARKITUP_MEDIA_URL = '/static/'
+MARKITUP_FILTER = ('markdown.markdown', {'safe_mode':
True,'previewParserPath':'/markitup/preview/'})
+MARKITUP_SET = 'markitup/sets/markdown'
+MARKITUP_SKIN = 'markitup/skins/simple'
+
+JQUERY_URL = '/static/jquery-1.4.2.min.js'
ADMIN_MEDIA_PREFIX = '/media/admin/'
+TEST_RUNNER = 'djangotoolbox.test.CapturingTestSuiteRunner'
+
+
import os
-TEMPLATE_DIRS = (os.path.join(os.path.dirname(__file__), 'new_templates'),)
+TEMPLATE_DIRS =
(os.path.join(os.path.dirname(__file__), 'templates_alpha'),)
FAIL_SILENTLY = True
@@ -67,3 +81,15 @@
"django.contrib.messages.context_processors.messages",
"django.core.context_processors.request",
)
+
+DATABASE_ENGINE = 'djangoappengine.db'
+
+try:
+ import dbindexer
+ DATABASES['native'] = DATABASES['default']
+ DATABASES['default'] =
{'ENGINE': 'djangoappengine.db', 'TARGET': 'native', 'datastore_path':'/home/fragro/appstore/django_appstore','history_path':'/home/fragro/appstore/django_histstore'}
+ DBINDEXER_SITECONF = 'dbindexes'
+ MIDDLEWARE_CLASSES = ('dbindexer.middleware.DBIndexerMiddleware',) + \
+ MIDDLEWARE_CLASSES
+except ImportError:
+ pass
=======================================
--- /trunk/pirate-politics/urls.py Sun Feb 6 23:05:17 2011
+++ /trunk/pirate-politics/urls.py Thu May 12 16:29:42 2011
@@ -7,7 +7,7 @@
from django.contrib import admin
from hello.views import hello_view, setup_admin
from pirate_core import redirectable, home_page
-from ajaxapi.views import vote, generate_vote_content, delete_source,
add_tag
+from ajaxapi.views import vote, generate_vote_content, delete_source,
add_tag, starvote, spectrumvote, flagvote
from pirate_login.views import logout_view
from pirate_sources.models import URLSource
@@ -24,9 +24,13 @@
(r'^helloworld/', hello_view),
(r'^sourcedelete/(?P<object_id>\d+)/$', delete_source),
(r'^vote/', vote),
+ (r'^starvote/', starvote),
+ (r'^flagvote/', flagvote),
+ (r'^spectrumvote/', spectrumvote),
(r'^add_tag/', add_tag),
(r'^generate_vote_content/', generate_vote_content),
(r'^comments/', include('django.contrib.comments.urls')),
+ (r'^markitup/', include('markitup.urls')),
(r'^logout/', logout_view),
)