from django import template
from django import forms
from django.http import HttpResponse, HttpResponseRedirect
from django.utils import simplejson
from django.shortcuts import get_object_or_404
from django.contrib.contenttypes.models import ContentType
from pirate_topics.models import MyGroup
from django.db.models import Q
from pirate_core.views import HttpRedirectException, namespace_get
from pirate_consensus.models import UpDownVote, Consensus, ConfirmRankedVote, RankedVote, WeightedVote, RankedDecision, RatingVote, SpectrumHolder
from pirate_core.widgets import HorizRadioRenderer
from customtags.decorators import block_decorator
register = template.Library()
block = block_decorator(register)
RATINGS_CHOICES = (
(1, "Empty of Value"),
(2, "Poor"),
(3, "OK"),
(4, "Good"),
(5, "Excellent"),
)
SPECTRUM_CHOICES = {
1: "Never!",
2: "Strongly Disagree",
3: "Disagree",
4: "Mostly Disagree",
5: "Pt. of Contention",
6: "Meh",
7: "Slightly Agree",
8: "Mostly Agree",
9: "Agree",
10: "Strongly Agree",
11: "Extremely Agree",
}
SPECTRUM_COLORS = {
1: "#e11010",
2: "#e13310",
3: "#e15610",
4: "#e17810",
5: "#e19b10",
6: "#e1be10",
7: "#e1e110",
8: "#bee110",
9: "#9be110",
10: "#78e110",
11: "#56e110",
}
get_namespace = namespace_get('pp_consensus')
@block
[docs]def pp_get_ranked_decision(context, nodelist, *args, **kwargs):
context.push()
namespace = get_namespace(context)
obj = kwargs.pop('object', None)
try:
rv = RankedDecision.objects.get(parent=obj)
except:
rv = None
namespace['ranked_decision'] = rv
output = nodelist.render(context)
context.pop()
return output
@block
[docs]def pp_get_ranked_vote(context, nodelist, *args, **kwargs):
context.push()
namespace = get_namespace(context)
user = kwargs.pop('user', None)
obj = kwargs.pop('object', None)
if user.is_authenticated():
rv = RankedVote.objects.filter(user=user, parent=obj)
rv = rv.order_by('ranked_vote')
namespace['objects'] = [(i.nom_cons, i) for i in rv]
if rv.count() > 0:
namespace['ranked_vote'] = True
else:
namespace['ranked_vote'] = None
try:
rnk = ConfirmRankedVote.objects.get(user=user, parent=obj)
namespace['confirmranked'] = rnk.confirm
namespace['winner'] = rnk
except:
namespace['confirmranked'] = False
output = nodelist.render(context)
context.pop()
return output
#returns teh updownvotes pertaining to an object and a user
@block
[docs]def pp_get_votes(context, nodelist, *args, **kwargs):
context.push()
namespace = get_namespace(context)
user = kwargs.pop('user', None)
obj = kwargs.pop('object', None)
votes = UpDownVote.objects.filter(object_pk=obj.pk).filter(user=user).order_by('vote')
namespace['votes'] = votes
namespace['count'] = votes.count()
output = nodelist.render(context)
context.pop()
return output
#returns the reporting percentage of a consensus object
@block
[docs]def pp_get_reporting_percentage(context, nodelist, *args, **kwargs):
context.push()
namespace = get_namespace(context)
obj = kwargs.pop('object', None)
topic = kwargs.pop('group', None)
votes = UpDownVote.objects.filter(object_pk=obj.pk)
groups = MyGroup.objects.filter(topic=topic)
try:
namespace['reporting'] = votes.count() / float(groups.count())
except:
namespace['reporting'] = 0.0
output = nodelist.render(context)
context.pop()
return output
@block
[docs]def pp_consensus_get(context, nodelist, *args, **kwargs):
#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.
context.push()
namespace = get_namespace(context)
object_pk = kwargs.pop('object', None)
if object_pk is None:
raise ValueError("pp_consensus_get tag requires that a object id 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)
namespace['interest'] = namespace['consensus'].interest
namespace['controversy'] = namespace['consensus'].controversy
namespace['votes'] = namespace['consensus'].votes
namespace['content_type'] = namespace['consensus'].content_type
#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
except:
updown = None
try:
rate = RatingVote.objects.get(user=user, parent=namespace['consensus']).vote
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
@block
@block
@block
[docs]def pp_rating_js(context, nodelist, *args, **kwargs):
context.push()
namespace = get_namespace(context)
obj = kwargs.get('object', None)
user = kwargs.get('user', None)
ctype = ContentType.objects.get_for_model(obj)
if obj:
if user.is_authenticated():
RET = """
$(function(){
$("#stars-wrapper-rate""" + str(obj.id) + """").stars({
inputType: "select",
callback: function(ui, type, value){
starvote(""" + "'" + str(obj.id) + "'" + """, value, """ + "'" + str(user.pk) + "', " + "'" + str(obj.pk) + "', " + "'" + str(ctype.pk) + "'" + """);
},
captionEl: $("#stars-cap-rate"),
cancelTitle:'Cancel Rating',
cancelValue:-99
});
});
"""
else:
RET = """
$(function(){
$("#stars-wrapper-rate""" + str(obj.id) + """").stars({
inputType: "select",
callback: function(ui, type, value){
js_redirect('/p/register');
},
captionEl: $("#stars-cap-rate"),
cancelTitle:'Cancel Rating',
cancelValue:-99
});
});
"""
else:
RET = ""
namespace['rating_js'] = RET
output = nodelist.render(context)
context.pop()
return output
@block
[docs]def pp_spectrum_js(context, nodelist, *args, **kwargs):
context.push()
namespace = get_namespace(context)
obj = kwargs.get('object', None)
user = kwargs.get('user', None)
ctype = ContentType.objects.get_for_model(obj)
if obj:
if user.is_authenticated():
RET = """
$(function(){
$("#stars-wrapper-spec""" + str(obj.id) + """").stars({
inputType: "select",
callback: function(ui, type, value){
spectrumvote(""" + "'" + str(obj.id) + "'" + """, value, """ + "'" + str(user.pk) + "', " + "'" + str(obj.pk) + "', " + "'" + str(ctype.pk) + "'" + """);
},
spectrum:true,
captionEl: $("#stars-cap-spec"),
cancelTitle:'Cancel Vote',
cancelValue:-99
});
});
"""
else:
RET = """
$(function(){
$("#stars-wrapper-spec""" + str(obj.id) + """").stars({
inputType: "select",
callback: function(ui, type, value){
js_redirect('/p/register');
},
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
@block
[docs]def pp_consensus_chart(context, nodelist, *args, **kwargs):
"""
Does a Temp Check by grabbing the opinion data as well
as voting aggregates.
"""
context.push()
namespace = get_namespace(context)
obj = kwargs.get('object', None)
if obj is not None:
#prepare data for highchart
dchart = {'type': 'pie', 'name': 'Temperature Check'}
data = []
if obj.spectrum is not None:
for i in SpectrumHolder.objects.filter(spectrum_pk=obj.spectrum.pk):
if i.value > 0:
data.append({'name': SPECTRUM_CHOICES[int(i.vote)], 'y': i.value, 'color': SPECTRUM_COLORS[int(i.vote)]})
dchart['data'] = data
namespace['chart_data'] = str([dchart])
if dchart['data'] != []:
print dchart['data']
namespace['chart'] = True
if obj.rating is not None:
rating_list = obj.rating.get_list()
tot = 0.0
val = 0.0
for i, weight, num in rating_list:
val += (i * num)
tot += num
if tot > 0:
namespace['mean_information'] = val / tot
else:
namespace['mean_information'] = None
else:
namespace['chart'] = False
output = nodelist.render(context)
context.pop()
return output
#: render a <link> tag required to be added to the template at the appropriate locations.
@block
[docs]def pp_consensus_css(context, nodelist, *args, **kwargs):
pass
# pre-fetches all of the user votes that might be referenced by tags on the page, and stores them in the context, as a performance hack, so that the rendering of each widget does not cause a separate query to the data store. This is optional.
@block
[docs]def pp_consensus_user_block(context, nodelist, *args, **kwargs):
pass
@block
[docs]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