* Add feedback view by nominee
* Refactor EncryptedTextField * Add feedback model managers * Add templatetag to get person from author email See #973 - Legacy-Id: 5574
This commit is contained in:
parent
4fec10183d
commit
29064193a3
|
@ -1,6 +1,3 @@
|
|||
import os
|
||||
|
||||
import tempfile
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
|
||||
|
@ -17,14 +14,9 @@ class EncryptedTextField(models.TextField):
|
|||
comments = getattr(instance, 'comments')
|
||||
nomcom = getattr(instance, 'nomcom')
|
||||
cert_file = nomcom.public_key.path
|
||||
comments_file = tempfile.NamedTemporaryFile(delete=False)
|
||||
comments_file.write(comments)
|
||||
comments_file.close()
|
||||
|
||||
code, out, error = pipe("%s smime -encrypt -in %s %s" % (settings.OPENSSL_COMMAND,
|
||||
comments_file.name,
|
||||
cert_file))
|
||||
os.unlink(comments_file.name)
|
||||
code, out, error = pipe("%s smime -encrypt -in /dev/stdin %s" % (settings.OPENSSL_COMMAND,
|
||||
cert_file), comments)
|
||||
if not error:
|
||||
instance.comments = out
|
||||
return out
|
||||
|
|
|
@ -2,6 +2,14 @@ from django.db import models
|
|||
from django.db.models.query import QuerySet
|
||||
|
||||
|
||||
class MixinManager(object):
|
||||
def __getattr__(self, attr, *args):
|
||||
try:
|
||||
return getattr(self.__class__, attr, *args)
|
||||
except AttributeError:
|
||||
return getattr(self.get_query_set(), attr, *args)
|
||||
|
||||
|
||||
class NomineePositionQuerySet(QuerySet):
|
||||
|
||||
def get_by_nomcom(self, nomcom):
|
||||
|
@ -23,16 +31,10 @@ class NomineePositionQuerySet(QuerySet):
|
|||
return self.by_state('declined')
|
||||
|
||||
|
||||
class NomineePositionManager(models.Manager):
|
||||
class NomineePositionManager(models.Manager, MixinManager):
|
||||
def get_query_set(self):
|
||||
return NomineePositionQuerySet(self.model)
|
||||
|
||||
def __getattr__(self, attr, *args):
|
||||
try:
|
||||
return getattr(self.__class__, attr, *args)
|
||||
except AttributeError:
|
||||
return getattr(self.get_query_set(), attr, *args)
|
||||
|
||||
|
||||
class NomineeManager(models.Manager):
|
||||
def get_by_nomcom(self, nomcom):
|
||||
|
@ -53,12 +55,29 @@ class PositionQuerySet(QuerySet):
|
|||
return self.filter(is_open=False)
|
||||
|
||||
|
||||
class PositionManager(models.Manager):
|
||||
class PositionManager(models.Manager, MixinManager):
|
||||
def get_query_set(self):
|
||||
return PositionQuerySet(self.model)
|
||||
|
||||
def __getattr__(self, attr, *args):
|
||||
try:
|
||||
return getattr(self.__class__, attr, *args)
|
||||
except AttributeError:
|
||||
return getattr(self.get_query_set(), attr, *args)
|
||||
|
||||
class FeedbackQuerySet(QuerySet):
|
||||
|
||||
def get_by_nomcom(self, nomcom):
|
||||
return self.filter(nomcom=nomcom)
|
||||
|
||||
def by_type(self, type):
|
||||
return self.filter(type=type)
|
||||
|
||||
def comments(self):
|
||||
return self.by_type('comment')
|
||||
|
||||
def questionnaires(self):
|
||||
return self.by_type('questio')
|
||||
|
||||
def nominations(self):
|
||||
return self.by_type('nomina')
|
||||
|
||||
|
||||
class FeedbackManager(models.Manager, MixinManager):
|
||||
def get_query_set(self):
|
||||
return FeedbackQuerySet(self.model)
|
||||
|
|
|
@ -13,7 +13,8 @@ from ietf.group.models import Group
|
|||
from ietf.name.models import NomineePositionState, FeedbackType
|
||||
from ietf.dbtemplate.models import DBTemplate
|
||||
|
||||
from ietf.nomcom.managers import NomineePositionManager, NomineeManager, PositionManager
|
||||
from ietf.nomcom.managers import NomineePositionManager, NomineeManager, \
|
||||
PositionManager, FeedbackManager
|
||||
from ietf.nomcom.utils import (initialize_templates_for_group,
|
||||
initialize_questionnaire_for_position,
|
||||
initialize_requirements_for_position)
|
||||
|
@ -125,7 +126,7 @@ class Position(models.Model):
|
|||
verbose_name_plural = 'Positions'
|
||||
|
||||
def __unicode__(self):
|
||||
return u"%s: %s" % (self.nomcom, self.name)
|
||||
return self.name
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
created = not self.id
|
||||
|
@ -158,9 +159,14 @@ class Feedback(models.Model):
|
|||
user = models.ForeignKey(User, blank=True, null=True)
|
||||
time = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
objects = FeedbackManager()
|
||||
|
||||
def __unicode__(self):
|
||||
return u"%s - %s" % (self.author, self.nominee)
|
||||
|
||||
class Meta:
|
||||
ordering = ['time']
|
||||
|
||||
# ----- adding south rules to help introspection -----
|
||||
|
||||
add_introspection_rules([], ["^ietf\.nomcom\.fields\.EncryptedTextField"])
|
||||
|
|
|
@ -3,10 +3,12 @@ import tempfile
|
|||
|
||||
from django import template
|
||||
from django.conf import settings
|
||||
from django.template.defaultfilters import linebreaksbr
|
||||
|
||||
from ietf.utils.pipe import pipe
|
||||
from ietf.ietfauth.decorators import has_role
|
||||
|
||||
from ietf.person.models import Person
|
||||
from ietf.nomcom.models import Feedback
|
||||
from ietf.nomcom.utils import get_nomcom_by_year, get_user_email, retrieve_nomcom_private_key
|
||||
|
||||
|
@ -40,6 +42,15 @@ def add_num_nominations(user, position, nominee):
|
|||
return '<span title="%d earlier comments from you on %s as %s">%s</span> ' % (count, nominee, position, mark)
|
||||
|
||||
|
||||
@register.filter
|
||||
def get_person(email):
|
||||
person = email
|
||||
if email:
|
||||
persons = Person.objects.filter(email__address__in=[email])
|
||||
person = persons and persons[0].name or person
|
||||
return person
|
||||
|
||||
|
||||
@register.simple_tag
|
||||
def decrypt(string, request, year):
|
||||
key = retrieve_nomcom_private_key(request, year)
|
||||
|
@ -60,4 +71,4 @@ def decrypt(string, request, year):
|
|||
if error:
|
||||
return '<-Encripted text [Your private key is invalid]->'
|
||||
|
||||
return out
|
||||
return linebreaksbr(out)
|
||||
|
|
|
@ -8,6 +8,7 @@ urlpatterns = patterns('ietf.nomcom.views',
|
|||
url(r'^(?P<year>\d{4})/private/nominate/$', 'private_nominate', name='nomcom_private_nominate'),
|
||||
url(r'^(?P<year>\d{4})/private/feedback/$', 'private_feedback', name='nomcom_private_feedback'),
|
||||
url(r'^(?P<year>\d{4})/private/view-feedback/$', 'view_feedback', name='nomcom_view_feedback'),
|
||||
url(r'^(?P<year>\d{4})/private/view-feedback/nominee/(?P<nominee_id>\d+)$', 'view_feedback_nominee', name='nomcom_view_feedback_nominee'),
|
||||
url(r'^(?P<year>\d{4})/private/merge/$', 'private_merge', name='nomcom_private_merge'),
|
||||
url(r'^(?P<year>\d{4})/private/send-reminder-mail/$', 'send_reminder_mail', name='nomcom_send_reminder_mail'),
|
||||
url(r'^(?P<year>\d{4})/private/edit-members/$', EditMembersFormPreview(EditMembersForm), name='nomcom_edit_members'),
|
||||
|
|
|
@ -3,7 +3,7 @@ from django.conf import settings
|
|||
from django.contrib.auth.decorators import login_required
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.http import HttpResponse, Http404, HttpResponseRedirect
|
||||
from django.shortcuts import render_to_response
|
||||
from django.shortcuts import render_to_response, get_object_or_404
|
||||
from django.template import RequestContext
|
||||
from django.template.loader import render_to_string
|
||||
from django.utils import simplejson
|
||||
|
@ -13,7 +13,7 @@ from ietf.utils.mail import send_mail
|
|||
|
||||
from ietf.dbtemplate.models import DBTemplate
|
||||
from ietf.dbtemplate.views import template_edit
|
||||
from ietf.name.models import NomineePositionState
|
||||
from ietf.name.models import NomineePositionState, FeedbackType
|
||||
|
||||
from ietf.nomcom.decorators import member_required, private_key_required
|
||||
from ietf.nomcom.forms import (EditPublicKeyForm, NominateForm, FeedbackForm, MergeForm,
|
||||
|
@ -306,10 +306,27 @@ def feedback(request, year, public):
|
|||
@private_key_required
|
||||
def view_feedback(request, year):
|
||||
nomcom = get_nomcom_by_year(year)
|
||||
nominees = Nominee.objects.get_by_nomcom(nomcom).distinct()
|
||||
|
||||
return render_to_response('nomcom/view_feedback.html',
|
||||
{'year': year,
|
||||
'selected': 'view_feedback',
|
||||
'nominees': nominees,
|
||||
'nomcom': nomcom}, RequestContext(request))
|
||||
|
||||
|
||||
@member_required(role='member')
|
||||
@private_key_required
|
||||
def view_feedback_nominee(request, year, nominee_id):
|
||||
nomcom = get_nomcom_by_year(year)
|
||||
nominee = get_object_or_404(Nominee, id=nominee_id)
|
||||
feedback_types = FeedbackType.objects.all()
|
||||
|
||||
return render_to_response('nomcom/view_feedback_nominee.html',
|
||||
{'year': year,
|
||||
'selected': 'view_feedback',
|
||||
'nominee': nominee,
|
||||
'feedback_types': feedback_types,
|
||||
'nomcom': nomcom}, RequestContext(request))
|
||||
|
||||
|
||||
|
|
|
@ -8,4 +8,21 @@
|
|||
|
||||
<h2>List of Nominees</h2>
|
||||
|
||||
<table class="ietf-table ietf-doctable">
|
||||
<tr>
|
||||
<th>Nominee</th>
|
||||
<th>Nominations</th>
|
||||
<th>Comments</th>
|
||||
<th>Questionnaires</th>
|
||||
</tr>
|
||||
{% for nominee in nominees %}
|
||||
<tr class="{{ forloop.counter|divisibleby:2|yesno:"oddrow,evenrow" }}">
|
||||
<td><a href="{% url nomcom_view_feedback_nominee year nominee.id %}">{{ nominee.email.person.name }}</td>
|
||||
<td>{{ nominee.feedback_set.nominations.count }}</td>
|
||||
<td>{{ nominee.feedback_set.comments.count }}</td>
|
||||
<td>{{ nominee.feedback_set.questionnaires.count }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
64
ietf/templates/nomcom/view_feedback_nominee.html
Normal file
64
ietf/templates/nomcom/view_feedback_nominee.html
Normal file
|
@ -0,0 +1,64 @@
|
|||
{% extends "nomcom/nomcom_private_base.html" %}
|
||||
|
||||
{% load nomcom_tags %}
|
||||
|
||||
{% block pagehead %}
|
||||
{{ block.super }}
|
||||
<script type="text/javascript" src="/js/lib/jquery-1.4.2.min.js"></script>
|
||||
<script type="text/javascript" src="/js/yui/yui-20100305.js"></script>
|
||||
<script type="text/javascript" src="/js/base.js"></script>
|
||||
{% endblock pagehead %}
|
||||
|
||||
{% block subtitle %} - View comments of {{ nominee.email.person.name }}{% endblock %}
|
||||
|
||||
{% block nomcom_content %}
|
||||
|
||||
<p>Back to list of <a href="{% url nomcom_view_feedback year %}">nominees</a></p>
|
||||
|
||||
<h2>Feedback of {{ nominee.email.person.name }} </h2>
|
||||
|
||||
<div id="mytabs" class="yui-navset">
|
||||
<ul class="yui-nav">
|
||||
{% for ft in feedback_types %}
|
||||
<li><a href="#{{ ft.name }}"><em>{{ ft.name }}</em></a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
Pick the feedback type to view from the list immediately above
|
||||
<div class="yui-content">
|
||||
{% for ft in feedback_types %}
|
||||
<div id="{{ ft.name }}">
|
||||
{% for feedback in nominee.feedback_set.all %}
|
||||
{% ifequal feedback.type.slug ft.slug %}
|
||||
<div>
|
||||
<h3 class="ietf-divider">From {{ feedback.author|get_person|default:"Anonymous" }} ({{ feedback.time|date:"Y-m-d" }})</h3>
|
||||
<b>Positions:</b> {{ feedback.positions.all|join:"," }}
|
||||
<p>
|
||||
{% decrypt feedback.comments request year %}
|
||||
</p>
|
||||
</div>
|
||||
{% endifequal %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
var tabView = new YAHOO.widget.TabView('mytabs');
|
||||
var url = location.href.split('#');
|
||||
if (url[1]) {
|
||||
url[1] = "#"+url[1];
|
||||
var tabs = tabView.get('tabs');
|
||||
for (var i = 0; i < tabs.length; i++) {
|
||||
if (url[1].indexOf(tabs[i].get('href')) == 0) {
|
||||
tabView.set('activeIndex', i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
{% endblock %}
|
Loading…
Reference in a new issue