Merged [6465] and [6466] from rjsparks@nostrum.com:
Added the ability to send reminders to complete questionnaires to nominees in the accepted state. Changed the send_reminders management command to not take any arguments and run against all active nomcoms. Removed bugs from the send_reminders management command and added tests for it. Adjusted several dbtemplate titles and content. Fixes bug 1157 - Legacy-Id: 6471 Note: SVN reference [6465] has been migrated to Git commit22f356434a
Note: SVN reference [6466] has been migrated to Git commita461e6c4a4
This commit is contained in:
parent
47071ecade
commit
d649fd5e10
|
@ -96,8 +96,8 @@ $position: Position</field>
|
|||
</field>
|
||||
<field to="group.group" name="group" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object p="8" model="dbtemplate.dbtemplate">
|
||||
<field type="CharField" name="path">/nomcom/defaults/email/nomination_reminder.txt</field>
|
||||
<object pk="8" model="dbtemplate.dbtemplate">
|
||||
<field type="CharField" name="path">/nomcom/defaults/email/nomination_accept_reminder.txt</field>
|
||||
<field type="CharField" name="title">Email sent to nominees asking them to accept (or decline) the nominations.</field>
|
||||
<field type="TextField" name="variables">$positions: Nomination positions</field>
|
||||
<field to="name.dbtemplatetypename" name="type" rel="ManyToOneRel">plain</field>
|
||||
|
@ -114,7 +114,7 @@ If you accept, you will need to fill out a questionnaire.
|
|||
Best regards,</field>
|
||||
<field to="group.group" name="group" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object p="9" model="dbtemplate.dbtemplate">
|
||||
<object pk="9" model="dbtemplate.dbtemplate">
|
||||
<field type="CharField" name="path">/nomcom/defaults/email/nomination_receipt.txt</field>
|
||||
<field type="CharField" name="title">Email sent to nominator to get a confirmation mail containing feedback in cleartext</field>
|
||||
<field type="TextField" name="variables">$nominee: Full name of the nominee
|
||||
|
@ -137,7 +137,7 @@ $comments
|
|||
Thank you,</field>
|
||||
<field to="group.group" name="group" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object p="10" model="dbtemplate.dbtemplate">
|
||||
<object pk="10" model="dbtemplate.dbtemplate">
|
||||
<field type="CharField" name="path">/nomcom/defaults/email/feedback_receipt.txt</field>
|
||||
<field type="CharField" name="title">Email sent to feedback author to get a confirmation mail containing feedback in cleartext</field>
|
||||
<field type="TextField" name="variables">$nominee: Full name of the nominee
|
||||
|
@ -158,4 +158,18 @@ $comments
|
|||
Thank you,</field>
|
||||
<field to="group.group" name="group" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="11" model="dbtemplate.dbtemplate">
|
||||
<field type="CharField" name="path">/nomcom/defaults/email/questionnaire_reminder.txt</field>
|
||||
<field type="CharField" name="title">Email sent to nominees reminding them to complete a questionnaire</field>
|
||||
<field type="TextField" name="variables">$positions: Nomination positions</field>
|
||||
<field to="name.dbtemplatetypename" name="type" rel="ManyToOneRel">plain</field>
|
||||
<field type="TextField" name="content">
|
||||
Thank you for accepting your nomination for the position of $position.
|
||||
|
||||
Please remember to complete and return the questionnaire for this position at your earliest opportunity.
|
||||
The questionaire is repeated below for your convenience.
|
||||
|
||||
--------</field>
|
||||
<field to="group.group" name="group" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
</django-objects>
|
||||
|
|
|
@ -1,48 +1,35 @@
|
|||
import datetime
|
||||
import syslog
|
||||
from optparse import make_option
|
||||
from django.core.management.base import BaseCommand
|
||||
from ietf.nomcom.models import NomCom, NomineePosition
|
||||
from nomcom.utils import send_accept_reminder_to_nominee,send_questionnaire_reminder_to_nominee
|
||||
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
|
||||
from ietf.nomcom.models import Nominee, NomCom
|
||||
from nomcom.utils import send_reminder_to_nominee
|
||||
def log(message):
|
||||
syslog.syslog(message)
|
||||
|
||||
def is_time_to_send(nomcom,send_date,nomination_date):
|
||||
if nomcom.reminder_interval:
|
||||
days_passed = (send_date - nomination_date).days
|
||||
return days_passed > 0 and days_passed % nomcom.reminder_interval == 0
|
||||
else:
|
||||
return bool(nomcom.reminderdates_set.filter(date=send_date))
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = (u"Send reminders to nominees")
|
||||
option_list = BaseCommand.option_list + (
|
||||
make_option('--nomcom-year', dest='year', help='NomCom year'),)
|
||||
help = (u"Send acceptance and questionnaire reminders to nominees")
|
||||
|
||||
def handle(self, *args, **options):
|
||||
year = options.get('year', None)
|
||||
help_message = 'Usage: send_reminders --nomcom-year <nomcom-year>'
|
||||
|
||||
if not year:
|
||||
raise CommandError(help_message)
|
||||
|
||||
try:
|
||||
nomcom = NomCom.objects.get(group__acronym__icontains=year,
|
||||
group__state__slug='active')
|
||||
except NomCom.DoesNotExist:
|
||||
raise CommandError("NomCom %s does not exist or it isn't active" % year)
|
||||
|
||||
today = datetime.date.today()
|
||||
|
||||
if nomcom.reminder_interval:
|
||||
nominees = Nominee.objects.get_by_nomcom(nomcom).not_duplicated().filter(nomineeposition__state='pending').distinct()
|
||||
for nominee in nominees:
|
||||
for nominee_position in nominee.nomineeposition_set.all():
|
||||
nomination_date = nominee_position.time.date()
|
||||
if not (today - nomination_date).days <= 0:
|
||||
if (today - nomination_date).days % nomcom.reminder_interval == 0:
|
||||
send_reminder_to_nominee(nominee_position)
|
||||
syslog.syslog(u"Sent reminder to %s" % nominee_position.nominee.email.address)
|
||||
print u"Sent reminder to %s" % nominee_position.nominee.email.address
|
||||
else:
|
||||
if nomcom.reminderdates_set.filter(date=today):
|
||||
nominees = Nominee.objects.get_by_nomcom(nomcom).not_duplicated().filter(nomineeposition__state='pending').distinct()
|
||||
for nominee in nominees:
|
||||
for nominee_position in nominee.nomineeposition_set.pending():
|
||||
send_reminder_to_nominee(nominee_position)
|
||||
syslog.syslog(u"Sent reminder to %s" % nominee_position.nominee.email.address)
|
||||
print u"Sent reminder (by dates) to %s" % nominee_position.nominee.email.address
|
||||
for nomcom in NomCom.objects.filter(group__state__slug='active'):
|
||||
for state in ('pending','accepted'):
|
||||
for nominee_position in NomineePosition.objects.filter(nominee__nomcom=nomcom,
|
||||
state=state,
|
||||
nominee__duplicated__isnull=True):
|
||||
if is_time_to_send(nomcom, datetime.date.today(), nominee_position.time.date()):
|
||||
if state=='pending':
|
||||
send_accept_reminder_to_nominee(nominee_position)
|
||||
log('Sent accept reminder to %s' % nominee_position.nominee.email.address)
|
||||
elif state=='accepted':
|
||||
send_questionnaire_reminder_to_nominee(nominee_position)
|
||||
log('Sent questionnaire reminder to %s' % nominee_position.nominee.email.address)
|
||||
else:
|
||||
pass
|
||||
|
|
329
ietf/nomcom/migrations/0004_split_reminder_template.py
Normal file
329
ietf/nomcom/migrations/0004_split_reminder_template.py
Normal file
|
@ -0,0 +1,329 @@
|
|||
# encoding: utf-8
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import DataMigration
|
||||
from django.db import models
|
||||
|
||||
import textwrap
|
||||
from ietf.dbtemplate.models import DBTemplate
|
||||
from ietf.name.models import DBTemplateTypeName
|
||||
from ietf.group.models import Group
|
||||
|
||||
new_template_content = textwrap.dedent("""\
|
||||
Thank you for accepting your nomination for the position of $position.
|
||||
|
||||
Please remember to complete and return the questionnaire for this position at your earliest opportunity.
|
||||
The questionaire is repeated below for your convenience.
|
||||
|
||||
--------
|
||||
|
||||
""")
|
||||
|
||||
class Migration(DataMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
for group_name in ['defaults','nomcom2013']:
|
||||
template = DBTemplate.objects.get(path='/nomcom/%s/email/nomination_reminder.txt'%group_name)
|
||||
template.path='/nomcom/%s/email/nomination_accept_reminder.txt'%group_name
|
||||
template.title='Email sent to nominees reminding them to accept (or decline) the nominations.'
|
||||
template.save()
|
||||
# variables below are copied from the current reminder template. It's not clear this value is what it should be
|
||||
DBTemplate.objects.create(path='/nomcom/%s/email/questionnaire_reminder.txt'%group_name,
|
||||
title='Email sent to nominees reminding them to submit completed questionnaires.',
|
||||
variables='$positions: Nomination positions',
|
||||
type=DBTemplateTypeName.objects.get(slug='plain'),
|
||||
content=new_template_content,
|
||||
group= None if group_name=='defaults' else Group.objects.get(acronym='nomcom2013'),
|
||||
)
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
for group_name in ['defaults','nomcom2013']:
|
||||
template = DBTemplate.objects.get(path='/nomcom/%s/email/nomination_accept_reminder.txt'%group_name)
|
||||
template.path='/nomcom/%s/email/nomination_reminder.txt'%group_name
|
||||
template.title='Email sent to nominees asking them to accept (or decline) the nominations.'
|
||||
template.save()
|
||||
DBTemplate.objects.filter(path='/nomcom/%s/email/questionnaire_reminder.txt'%group_name).delete()
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||
},
|
||||
'auth.permission': {
|
||||
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
|
||||
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
'auth.user': {
|
||||
'Meta': {'object_name': 'User'},
|
||||
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
|
||||
},
|
||||
'contenttypes.contenttype': {
|
||||
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
},
|
||||
'dbtemplate.dbtemplate': {
|
||||
'Meta': {'object_name': 'DBTemplate'},
|
||||
'content': ('django.db.models.fields.TextField', [], {}),
|
||||
'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']", 'null': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'path': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.DBTemplateTypeName']"}),
|
||||
'variables': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
'doc.document': {
|
||||
'Meta': {'object_name': 'Document'},
|
||||
'abstract': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'ad': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'ad_document_set'", 'null': 'True', 'to': "orm['person.Person']"}),
|
||||
'authors': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['person.Email']", 'symmetrical': 'False', 'through': "orm['doc.DocumentAuthor']", 'blank': 'True'}),
|
||||
'expires': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'external_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
|
||||
'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']", 'null': 'True', 'blank': 'True'}),
|
||||
'intended_std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.IntendedStdLevelName']", 'null': 'True', 'blank': 'True'}),
|
||||
'internal_comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'primary_key': 'True'}),
|
||||
'note': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'notify': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||
'order': ('django.db.models.fields.IntegerField', [], {'default': '1', 'blank': 'True'}),
|
||||
'pages': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'rev': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}),
|
||||
'shepherd': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'shepherd_document_set'", 'null': 'True', 'to': "orm['person.Person']"}),
|
||||
'states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.StdLevelName']", 'null': 'True', 'blank': 'True'}),
|
||||
'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.StreamName']", 'null': 'True', 'blank': 'True'}),
|
||||
'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['name.DocTagName']", 'null': 'True', 'blank': 'True'}),
|
||||
'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.DocTypeName']", 'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
'doc.documentauthor': {
|
||||
'Meta': {'ordering': "['document', 'order']", 'object_name': 'DocumentAuthor'},
|
||||
'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Email']"}),
|
||||
'document': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.Document']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'order': ('django.db.models.fields.IntegerField', [], {'default': '1'})
|
||||
},
|
||||
'doc.state': {
|
||||
'Meta': {'ordering': "['type', 'order']", 'object_name': 'State'},
|
||||
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'next_states': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'previous_states'", 'blank': 'True', 'to': "orm['doc.State']"}),
|
||||
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'db_index': 'True'}),
|
||||
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.StateType']"}),
|
||||
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
},
|
||||
'doc.statetype': {
|
||||
'Meta': {'object_name': 'StateType'},
|
||||
'label': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'slug': ('django.db.models.fields.CharField', [], {'max_length': '30', 'primary_key': 'True'})
|
||||
},
|
||||
'group.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
'acronym': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '40', 'db_index': 'True'}),
|
||||
'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']", 'null': 'True', 'blank': 'True'}),
|
||||
'charter': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'related_name': "'chartered_group'", 'unique': 'True', 'null': 'True', 'to': "orm['doc.Document']"}),
|
||||
'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'list_archive': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||
'list_email': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
|
||||
'list_subscribe': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
|
||||
'parent': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']", 'null': 'True', 'blank': 'True'}),
|
||||
'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupStateName']", 'null': 'True'}),
|
||||
'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupTypeName']", 'null': 'True'}),
|
||||
'unused_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'unused_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['name.DocTagName']", 'symmetrical': 'False', 'blank': 'True'})
|
||||
},
|
||||
'name.dbtemplatetypename': {
|
||||
'Meta': {'ordering': "['order']", 'object_name': 'DBTemplateTypeName'},
|
||||
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
|
||||
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
},
|
||||
'name.doctagname': {
|
||||
'Meta': {'ordering': "['order']", 'object_name': 'DocTagName'},
|
||||
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
|
||||
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
},
|
||||
'name.doctypename': {
|
||||
'Meta': {'ordering': "['order']", 'object_name': 'DocTypeName'},
|
||||
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
|
||||
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
},
|
||||
'name.feedbacktype': {
|
||||
'Meta': {'ordering': "['order']", 'object_name': 'FeedbackType'},
|
||||
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
|
||||
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
},
|
||||
'name.groupstatename': {
|
||||
'Meta': {'ordering': "['order']", 'object_name': 'GroupStateName'},
|
||||
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
|
||||
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
},
|
||||
'name.grouptypename': {
|
||||
'Meta': {'ordering': "['order']", 'object_name': 'GroupTypeName'},
|
||||
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
|
||||
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
},
|
||||
'name.intendedstdlevelname': {
|
||||
'Meta': {'ordering': "['order']", 'object_name': 'IntendedStdLevelName'},
|
||||
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
|
||||
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
},
|
||||
'name.nomineepositionstate': {
|
||||
'Meta': {'ordering': "['order']", 'object_name': 'NomineePositionState'},
|
||||
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
|
||||
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
},
|
||||
'name.stdlevelname': {
|
||||
'Meta': {'ordering': "['order']", 'object_name': 'StdLevelName'},
|
||||
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
|
||||
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
},
|
||||
'name.streamname': {
|
||||
'Meta': {'ordering': "['order']", 'object_name': 'StreamName'},
|
||||
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
|
||||
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
},
|
||||
'nomcom.feedback': {
|
||||
'Meta': {'ordering': "['time']", 'object_name': 'Feedback'},
|
||||
'author': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'comments': ('ietf.nomcom.fields.EncryptedTextField', [], {}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'nomcom': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.NomCom']"}),
|
||||
'nominees': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['nomcom.Nominee']", 'null': 'True', 'blank': 'True'}),
|
||||
'positions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['nomcom.Position']", 'null': 'True', 'blank': 'True'}),
|
||||
'subject': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.FeedbackType']", 'null': 'True', 'blank': 'True'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
'nomcom.nomcom': {
|
||||
'Meta': {'object_name': 'NomCom'},
|
||||
'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'initial_text': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'public_key': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
|
||||
'reminder_interval': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'send_questionnaire': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
|
||||
},
|
||||
'nomcom.nomination': {
|
||||
'Meta': {'object_name': 'Nomination'},
|
||||
'candidate_email': ('django.db.models.fields.EmailField', [], {'max_length': '255'}),
|
||||
'candidate_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'candidate_phone': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||
'comments': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.Feedback']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'nominator_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'nominee': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.Nominee']"}),
|
||||
'position': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.Position']"}),
|
||||
'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
|
||||
},
|
||||
'nomcom.nominee': {
|
||||
'Meta': {'unique_together': "(('email', 'nomcom'),)", 'object_name': 'Nominee'},
|
||||
'duplicated': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.Nominee']", 'null': 'True', 'blank': 'True'}),
|
||||
'email': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Email']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'nomcom': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.NomCom']"}),
|
||||
'nominee_position': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['nomcom.Position']", 'through': "orm['nomcom.NomineePosition']", 'symmetrical': 'False'})
|
||||
},
|
||||
'nomcom.nomineeposition': {
|
||||
'Meta': {'ordering': "['nominee']", 'unique_together': "(('position', 'nominee'),)", 'object_name': 'NomineePosition'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'nominee': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.Nominee']"}),
|
||||
'position': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.Position']"}),
|
||||
'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.NomineePositionState']"}),
|
||||
'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'})
|
||||
},
|
||||
'nomcom.position': {
|
||||
'Meta': {'object_name': 'Position'},
|
||||
'description': ('django.db.models.fields.TextField', [], {}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'incumbent': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Email']"}),
|
||||
'is_open': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'nomcom': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.NomCom']"}),
|
||||
'questionnaire': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'questionnaire'", 'null': 'True', 'to': "orm['dbtemplate.DBTemplate']"}),
|
||||
'requirement': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'requirement'", 'null': 'True', 'to': "orm['dbtemplate.DBTemplate']"})
|
||||
},
|
||||
'nomcom.reminderdates': {
|
||||
'Meta': {'object_name': 'ReminderDates'},
|
||||
'date': ('django.db.models.fields.DateField', [], {}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'nomcom': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.NomCom']"})
|
||||
},
|
||||
'person.email': {
|
||||
'Meta': {'object_name': 'Email'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'address': ('django.db.models.fields.CharField', [], {'max_length': '64', 'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']", 'null': 'True'}),
|
||||
'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'})
|
||||
},
|
||||
'person.person': {
|
||||
'Meta': {'object_name': 'Person'},
|
||||
'address': ('django.db.models.fields.TextField', [], {'max_length': '255', 'blank': 'True'}),
|
||||
'affiliation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||
'ascii': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'ascii_short': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||
'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'null': 'True', 'blank': 'True'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['nomcom']
|
379
ietf/nomcom/migrations/0005_default_template_edits.py
Normal file
379
ietf/nomcom/migrations/0005_default_template_edits.py
Normal file
|
@ -0,0 +1,379 @@
|
|||
# encoding: utf-8
|
||||
import datetime
|
||||
import textwrap
|
||||
from south.db import db
|
||||
from south.v2 import DataMigration
|
||||
from django.db import models
|
||||
from ietf.dbtemplate.models import DBTemplate
|
||||
|
||||
|
||||
class Migration(DataMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
for template in DBTemplate.objects.filter(title__startswith="Questionnaire sent to the nomine"):
|
||||
template.title = self.change_nomine_to_nominee(template.title)
|
||||
template.save()
|
||||
|
||||
direct_substitutions = {
|
||||
|
||||
'Email sent to nominator to get a confirmation mail containing feedback in cleartext'
|
||||
:'Email sent confirming nomination with provided comments in cleartext',
|
||||
|
||||
'Email sent to feedback author to get a confirmation mail containing feedback in cleartext'
|
||||
:'Email sent confirming feedback with provided comments in cleartext',
|
||||
|
||||
'Header of the email that contains the questionnaire sent to the nomine'
|
||||
:'Header of the email that contains the questionnaire sent to the nominee',
|
||||
|
||||
}
|
||||
|
||||
for str in direct_substitutions:
|
||||
DBTemplate.objects.filter(title=str).update(title=direct_substitutions[str])
|
||||
|
||||
template = DBTemplate.objects.get(group=None,title__startswith="Email sent to nominees when")
|
||||
template.content = textwrap.dedent("""\
|
||||
You have been nominated for the position of $position.
|
||||
|
||||
Please follow one of the links below to accept or decline this nomination.
|
||||
|
||||
Accept: http://$domain$accept_url
|
||||
|
||||
Decline: http://$domain$decline_url
|
||||
|
||||
If you accept, you will receive a questionnaire for the position in a subsequent email.
|
||||
|
||||
Best Regards,
|
||||
""")
|
||||
template.save()
|
||||
|
||||
template = DBTemplate.objects.get(group=None,title__startswith="Email sent to nominators and secretariat")
|
||||
template.content = textwrap.dedent("""\
|
||||
A new nomination has been received.
|
||||
|
||||
Nominator: $nominator ($nominator_email)
|
||||
Nominee: $nominee ($nominee_email)
|
||||
Position: $position
|
||||
""")
|
||||
template.save()
|
||||
|
||||
|
||||
template = DBTemplate.objects.get(group=None,title__startswith="Header of the email that contains")
|
||||
template.content = textwrap.dedent("""\
|
||||
Hi $nominee, this is the questionnaire for the position $position.
|
||||
Please follow the directions in the questionnaire closely - you may see that some changes have been made from previous years, so please take note.
|
||||
|
||||
We look forward to reading your questionnaire response! If you have any administrative questions, please send mail to nomcom-chair@ietf.org. Thank you!
|
||||
""")
|
||||
template.save()
|
||||
|
||||
template = DBTemplate.objects.get(group=None,title__startswith="Email sent to nominees reminding them to accept ")
|
||||
template.content = textwrap.dedent("""\
|
||||
This is a reminder that you have been nominated for the position of $position.
|
||||
The Nomcom would like to know if you are willing to be considered.
|
||||
|
||||
Please follow one of the links below to accept or decline this nomination.
|
||||
|
||||
Accept: http://$domain$accept_url
|
||||
|
||||
Decline: http://$domain$decline_url
|
||||
|
||||
If you accept, you will receive a questionnaire for the position in a subsequent email.
|
||||
|
||||
Best Regards,
|
||||
""")
|
||||
template.save()
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
pass
|
||||
|
||||
def change_nomine_to_nominee(self,string):
|
||||
p=string.find('[')
|
||||
if p<0:
|
||||
return string+"e"
|
||||
else:
|
||||
return string[:p]+"e "+string[p:]
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||
},
|
||||
'auth.permission': {
|
||||
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
|
||||
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
'auth.user': {
|
||||
'Meta': {'object_name': 'User'},
|
||||
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
|
||||
},
|
||||
'contenttypes.contenttype': {
|
||||
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
},
|
||||
'dbtemplate.dbtemplate': {
|
||||
'Meta': {'object_name': 'DBTemplate'},
|
||||
'content': ('django.db.models.fields.TextField', [], {}),
|
||||
'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']", 'null': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'path': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.DBTemplateTypeName']"}),
|
||||
'variables': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
'doc.document': {
|
||||
'Meta': {'object_name': 'Document'},
|
||||
'abstract': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'ad': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'ad_document_set'", 'null': 'True', 'to': "orm['person.Person']"}),
|
||||
'authors': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['person.Email']", 'symmetrical': 'False', 'through': "orm['doc.DocumentAuthor']", 'blank': 'True'}),
|
||||
'expires': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'external_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
|
||||
'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']", 'null': 'True', 'blank': 'True'}),
|
||||
'intended_std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.IntendedStdLevelName']", 'null': 'True', 'blank': 'True'}),
|
||||
'internal_comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'primary_key': 'True'}),
|
||||
'note': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'notify': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||
'order': ('django.db.models.fields.IntegerField', [], {'default': '1', 'blank': 'True'}),
|
||||
'pages': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'rev': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}),
|
||||
'shepherd': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'shepherd_document_set'", 'null': 'True', 'to': "orm['person.Person']"}),
|
||||
'states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.StdLevelName']", 'null': 'True', 'blank': 'True'}),
|
||||
'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.StreamName']", 'null': 'True', 'blank': 'True'}),
|
||||
'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['name.DocTagName']", 'null': 'True', 'blank': 'True'}),
|
||||
'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.DocTypeName']", 'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
'doc.documentauthor': {
|
||||
'Meta': {'ordering': "['document', 'order']", 'object_name': 'DocumentAuthor'},
|
||||
'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Email']"}),
|
||||
'document': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.Document']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'order': ('django.db.models.fields.IntegerField', [], {'default': '1'})
|
||||
},
|
||||
'doc.state': {
|
||||
'Meta': {'ordering': "['type', 'order']", 'object_name': 'State'},
|
||||
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'next_states': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'previous_states'", 'blank': 'True', 'to': "orm['doc.State']"}),
|
||||
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'db_index': 'True'}),
|
||||
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.StateType']"}),
|
||||
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
},
|
||||
'doc.statetype': {
|
||||
'Meta': {'object_name': 'StateType'},
|
||||
'label': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'slug': ('django.db.models.fields.CharField', [], {'max_length': '30', 'primary_key': 'True'})
|
||||
},
|
||||
'group.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
'acronym': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '40', 'db_index': 'True'}),
|
||||
'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']", 'null': 'True', 'blank': 'True'}),
|
||||
'charter': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'related_name': "'chartered_group'", 'unique': 'True', 'null': 'True', 'to': "orm['doc.Document']"}),
|
||||
'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'list_archive': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||
'list_email': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
|
||||
'list_subscribe': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
|
||||
'parent': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']", 'null': 'True', 'blank': 'True'}),
|
||||
'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupStateName']", 'null': 'True'}),
|
||||
'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupTypeName']", 'null': 'True'}),
|
||||
'unused_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'unused_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['name.DocTagName']", 'symmetrical': 'False', 'blank': 'True'})
|
||||
},
|
||||
'name.dbtemplatetypename': {
|
||||
'Meta': {'ordering': "['order']", 'object_name': 'DBTemplateTypeName'},
|
||||
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
|
||||
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
},
|
||||
'name.doctagname': {
|
||||
'Meta': {'ordering': "['order']", 'object_name': 'DocTagName'},
|
||||
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
|
||||
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
},
|
||||
'name.doctypename': {
|
||||
'Meta': {'ordering': "['order']", 'object_name': 'DocTypeName'},
|
||||
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
|
||||
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
},
|
||||
'name.feedbacktype': {
|
||||
'Meta': {'ordering': "['order']", 'object_name': 'FeedbackType'},
|
||||
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
|
||||
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
},
|
||||
'name.groupstatename': {
|
||||
'Meta': {'ordering': "['order']", 'object_name': 'GroupStateName'},
|
||||
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
|
||||
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
},
|
||||
'name.grouptypename': {
|
||||
'Meta': {'ordering': "['order']", 'object_name': 'GroupTypeName'},
|
||||
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
|
||||
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
},
|
||||
'name.intendedstdlevelname': {
|
||||
'Meta': {'ordering': "['order']", 'object_name': 'IntendedStdLevelName'},
|
||||
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
|
||||
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
},
|
||||
'name.nomineepositionstate': {
|
||||
'Meta': {'ordering': "['order']", 'object_name': 'NomineePositionState'},
|
||||
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
|
||||
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
},
|
||||
'name.stdlevelname': {
|
||||
'Meta': {'ordering': "['order']", 'object_name': 'StdLevelName'},
|
||||
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
|
||||
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
},
|
||||
'name.streamname': {
|
||||
'Meta': {'ordering': "['order']", 'object_name': 'StreamName'},
|
||||
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
|
||||
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
},
|
||||
'nomcom.feedback': {
|
||||
'Meta': {'ordering': "['time']", 'object_name': 'Feedback'},
|
||||
'author': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'comments': ('ietf.nomcom.fields.EncryptedTextField', [], {}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'nomcom': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.NomCom']"}),
|
||||
'nominees': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['nomcom.Nominee']", 'null': 'True', 'blank': 'True'}),
|
||||
'positions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['nomcom.Position']", 'null': 'True', 'blank': 'True'}),
|
||||
'subject': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.FeedbackType']", 'null': 'True', 'blank': 'True'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
'nomcom.nomcom': {
|
||||
'Meta': {'object_name': 'NomCom'},
|
||||
'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'initial_text': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'public_key': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
|
||||
'reminder_interval': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'send_questionnaire': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
|
||||
},
|
||||
'nomcom.nomination': {
|
||||
'Meta': {'object_name': 'Nomination'},
|
||||
'candidate_email': ('django.db.models.fields.EmailField', [], {'max_length': '255'}),
|
||||
'candidate_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'candidate_phone': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||
'comments': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.Feedback']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'nominator_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'nominee': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.Nominee']"}),
|
||||
'position': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.Position']"}),
|
||||
'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
|
||||
},
|
||||
'nomcom.nominee': {
|
||||
'Meta': {'unique_together': "(('email', 'nomcom'),)", 'object_name': 'Nominee'},
|
||||
'duplicated': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.Nominee']", 'null': 'True', 'blank': 'True'}),
|
||||
'email': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Email']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'nomcom': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.NomCom']"}),
|
||||
'nominee_position': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['nomcom.Position']", 'through': "orm['nomcom.NomineePosition']", 'symmetrical': 'False'})
|
||||
},
|
||||
'nomcom.nomineeposition': {
|
||||
'Meta': {'ordering': "['nominee']", 'unique_together': "(('position', 'nominee'),)", 'object_name': 'NomineePosition'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'nominee': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.Nominee']"}),
|
||||
'position': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.Position']"}),
|
||||
'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.NomineePositionState']"}),
|
||||
'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'})
|
||||
},
|
||||
'nomcom.position': {
|
||||
'Meta': {'object_name': 'Position'},
|
||||
'description': ('django.db.models.fields.TextField', [], {}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'incumbent': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Email']"}),
|
||||
'is_open': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'nomcom': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.NomCom']"}),
|
||||
'questionnaire': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'questionnaire'", 'null': 'True', 'to': "orm['dbtemplate.DBTemplate']"}),
|
||||
'requirement': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'requirement'", 'null': 'True', 'to': "orm['dbtemplate.DBTemplate']"})
|
||||
},
|
||||
'nomcom.reminderdates': {
|
||||
'Meta': {'object_name': 'ReminderDates'},
|
||||
'date': ('django.db.models.fields.DateField', [], {}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'nomcom': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.NomCom']"})
|
||||
},
|
||||
'person.email': {
|
||||
'Meta': {'object_name': 'Email'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'address': ('django.db.models.fields.CharField', [], {'max_length': '64', 'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']", 'null': 'True'}),
|
||||
'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'})
|
||||
},
|
||||
'person.person': {
|
||||
'Meta': {'object_name': 'Person'},
|
||||
'address': ('django.db.models.fields.TextField', [], {'max_length': '255', 'blank': 'True'}),
|
||||
'affiliation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||
'ascii': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'ascii_short': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||
'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'null': 'True', 'blank': 'True'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['nomcom']
|
|
@ -1,6 +1,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import os
|
||||
import tempfile
|
||||
import datetime
|
||||
|
||||
from ietf.utils import TestCase
|
||||
from django.db import IntegrityError
|
||||
|
@ -9,6 +10,7 @@ from django.core.files import File
|
|||
from django.contrib.formtools.preview import security_hash
|
||||
|
||||
from ietf.utils.test_utils import login_testing_unauthorized
|
||||
from ietf.utils.mail import outbox
|
||||
|
||||
|
||||
from ietf.person.models import Email, Person
|
||||
|
@ -20,7 +22,8 @@ from ietf.nomcom.models import NomineePosition, Position, Nominee, \
|
|||
NomineePositionState, Feedback, FeedbackType, \
|
||||
Nomination
|
||||
from ietf.nomcom.forms import EditChairForm, EditMembersForm
|
||||
from ietf.nomcom.utils import get_nomcom_by_year
|
||||
from ietf.nomcom.utils import get_nomcom_by_year, get_or_create_nominee
|
||||
from ietf.nomcom.management.commands.send_reminders import Command, is_time_to_send
|
||||
|
||||
|
||||
class NomcomViewsTest(TestCase):
|
||||
|
@ -653,3 +656,63 @@ class FeedbackTest(TestCase):
|
|||
|
||||
os.unlink(self.privatekey_file.name)
|
||||
os.unlink(self.cert_file.name)
|
||||
|
||||
class ReminderCommandTest(TestCase):
|
||||
perma_fixtures = ['names', 'nomcom_templates']
|
||||
|
||||
def setUp(self):
|
||||
nomcom_test_data()
|
||||
self.nomcom = get_nomcom_by_year(NOMCOM_YEAR)
|
||||
|
||||
gen = Position.objects.get(nomcom=self.nomcom,name='GEN')
|
||||
rai = Position.objects.get(nomcom=self.nomcom,name='RAI')
|
||||
iab = Position.objects.get(nomcom=self.nomcom,name='IAB')
|
||||
|
||||
today = datetime.date.today()
|
||||
t_minus_3 = today - datetime.timedelta(days=3)
|
||||
t_minus_4 = today - datetime.timedelta(days=4)
|
||||
n = get_or_create_nominee(self.nomcom,"Nominee 1","nominee1@example.org",gen,None)
|
||||
np = n.nomineeposition_set.get(position=gen)
|
||||
np.time = t_minus_3
|
||||
np.save()
|
||||
n = get_or_create_nominee(self.nomcom,"Nominee 1","nominee1@example.org",iab,None)
|
||||
np = n.nomineeposition_set.get(position=iab)
|
||||
np.state = NomineePositionState.objects.get(slug='accepted')
|
||||
np.time = t_minus_3
|
||||
np.save()
|
||||
n = get_or_create_nominee(self.nomcom,"Nominee 2","nominee2@example.org",rai,None)
|
||||
np = n.nomineeposition_set.get(position=rai)
|
||||
np.time = t_minus_4
|
||||
np.save()
|
||||
|
||||
def test_is_time_to_send(self):
|
||||
self.nomcom.reminder_interval = 4
|
||||
today = datetime.date.today()
|
||||
self.assertTrue(is_time_to_send(self.nomcom,today+datetime.timedelta(days=4),today))
|
||||
for delta in range(4):
|
||||
self.assertFalse(is_time_to_send(self.nomcom,today+datetime.timedelta(days=delta),today))
|
||||
self.nomcom.reminder_interval = None
|
||||
self.assertFalse(is_time_to_send(self.nomcom,today,today))
|
||||
self.nomcom.reminderdates_set.create(date=today)
|
||||
self.assertTrue(is_time_to_send(self.nomcom,today,today))
|
||||
|
||||
def test_command(self):
|
||||
c = Command()
|
||||
messages_before=len(outbox)
|
||||
self.nomcom.reminder_interval = 3
|
||||
self.nomcom.save()
|
||||
c.handle(None,None)
|
||||
self.assertEqual(len(outbox), messages_before + 2)
|
||||
self.assertTrue('nominee1@example.org' in outbox[-1]['To'])
|
||||
self.assertTrue('please complete' in outbox[-1]['Subject'])
|
||||
self.assertTrue('nominee1@example.org' in outbox[-2]['To'])
|
||||
self.assertTrue('please accept' in outbox[-2]['Subject'])
|
||||
messages_before=len(outbox)
|
||||
self.nomcom.reminder_interval = 4
|
||||
self.nomcom.save()
|
||||
c.handle(None,None)
|
||||
self.assertEqual(len(outbox), messages_before + 1)
|
||||
self.assertTrue('nominee2@example.org' in outbox[-1]['To'])
|
||||
self.assertTrue('please accept' in outbox[-1]['Subject'])
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from django.conf.urls.defaults import patterns, url
|
||||
from django.views.generic.simple import direct_to_template
|
||||
from django.views.generic.simple import direct_to_template, redirect_to
|
||||
from ietf.utils.lazy import reverse_lazy
|
||||
from ietf.nomcom.forms import EditChairForm, EditChairFormPreview, \
|
||||
EditMembersForm, EditMembersFormPreview
|
||||
|
||||
|
@ -17,7 +18,8 @@ urlpatterns = patterns('ietf.nomcom.views',
|
|||
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/edit/nominee/(?P<nominee_id>\d+)$', 'edit_nominee', name='nomcom_edit_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/send-reminder-mail/$', redirect_to, { 'url': reverse_lazy('nomcom_send_reminder_mail',kwargs={'year':year,'type':'accept'})}),
|
||||
url(r'^(?P<year>\d{4})/private/send-reminder-mail/(?P<type>\w+)/$', 'send_reminder_mail', name='nomcom_send_reminder_mail'),
|
||||
url(r'^(?P<year>\d{4})/private/edit-members/$', EditMembersFormPreview(EditMembersForm), name='nomcom_edit_members'),
|
||||
url(r'^(?P<year>\d{4})/private/edit-chair/$', EditChairFormPreview(EditChairForm), name='nomcom_edit_chair'),
|
||||
url(r'^(?P<year>\d{4})/private/edit-nomcom/$', 'edit_nomcom', name='nomcom_edit_nomcom'),
|
||||
|
|
|
@ -32,7 +32,8 @@ HOME_TEMPLATE = 'home.rst'
|
|||
INEXISTENT_PERSON_TEMPLATE = 'email/inexistent_person.txt'
|
||||
NOMINEE_EMAIL_TEMPLATE = 'email/new_nominee.txt'
|
||||
NOMINATION_EMAIL_TEMPLATE = 'email/new_nomination.txt'
|
||||
NOMINEE_REMINDER_TEMPLATE = 'email/nomination_reminder.txt'
|
||||
NOMINEE_ACCEPT_REMINDER_TEMPLATE = 'email/nomination_accept_reminder.txt'
|
||||
NOMINEE_QUESTIONNAIRE_REMINDER_TEMPLATE = 'email/questionnaire_reminder.txt'
|
||||
NOMINATION_RECEIPT_TEMPLATE = 'email/nomination_receipt.txt'
|
||||
FEEDBACK_RECEIPT_TEMPLATE = 'email/feedback_receipt.txt'
|
||||
|
||||
|
@ -40,7 +41,8 @@ DEFAULT_NOMCOM_TEMPLATES = [HOME_TEMPLATE,
|
|||
INEXISTENT_PERSON_TEMPLATE,
|
||||
NOMINEE_EMAIL_TEMPLATE,
|
||||
NOMINATION_EMAIL_TEMPLATE,
|
||||
NOMINEE_REMINDER_TEMPLATE,
|
||||
NOMINEE_ACCEPT_REMINDER_TEMPLATE,
|
||||
NOMINEE_QUESTIONNAIRE_REMINDER_TEMPLATE,
|
||||
NOMINATION_RECEIPT_TEMPLATE,
|
||||
FEEDBACK_RECEIPT_TEMPLATE]
|
||||
|
||||
|
@ -107,7 +109,7 @@ def initialize_questionnaire_for_position(position):
|
|||
content=header_template.content)
|
||||
questionnaire = DBTemplate.objects.create(
|
||||
group=position.nomcom.group,
|
||||
title=template.title + '[%s]' % position.name,
|
||||
title=template.title + ' [%s]' % position.name,
|
||||
path='/nomcom/' + position.nomcom.group.acronym + '/' + str(position.id) + '/' + QUESTIONNAIRE_TEMPLATE,
|
||||
variables=template.variables,
|
||||
type_id=template.type_id,
|
||||
|
@ -191,15 +193,15 @@ def validate_public_key(public_key):
|
|||
return (not error, error)
|
||||
|
||||
|
||||
def send_reminder_to_nominee(nominee_position):
|
||||
def send_accept_reminder_to_nominee(nominee_position):
|
||||
today = datetime.date.today().strftime('%Y%m%d')
|
||||
subject = 'IETF Nomination Information'
|
||||
subject = 'Reminder: please accept (or decline) your nomination.'
|
||||
from_email = settings.NOMCOM_FROM_EMAIL
|
||||
domain = Site.objects.get_current().domain
|
||||
position = nominee_position.position
|
||||
nomcom = position.nomcom
|
||||
nomcom_template_path = '/nomcom/%s/' % nomcom.group.acronym
|
||||
mail_path = nomcom_template_path + NOMINEE_REMINDER_TEMPLATE
|
||||
mail_path = nomcom_template_path + NOMINEE_ACCEPT_REMINDER_TEMPLATE
|
||||
nominee = nominee_position.nominee
|
||||
to_email = nominee.email.address
|
||||
|
||||
|
@ -229,11 +231,42 @@ def send_reminder_to_nominee(nominee_position):
|
|||
body += '\n\n%s' % render_to_string(path, context)
|
||||
send_mail_text(None, to_email, from_email, subject, body)
|
||||
|
||||
def send_questionnaire_reminder_to_nominee(nominee_position):
|
||||
today = datetime.date.today().strftime('%Y%m%d')
|
||||
subject = 'Reminder: please complete the Nomcom questionnaires for your nomination.'
|
||||
from_email = settings.NOMCOM_FROM_EMAIL
|
||||
domain = Site.objects.get_current().domain
|
||||
position = nominee_position.position
|
||||
nomcom = position.nomcom
|
||||
nomcom_template_path = '/nomcom/%s/' % nomcom.group.acronym
|
||||
mail_path = nomcom_template_path + NOMINEE_QUESTIONNAIRE_REMINDER_TEMPLATE
|
||||
nominee = nominee_position.nominee
|
||||
to_email = nominee.email.address
|
||||
|
||||
def send_reminder_to_nominees(nominees):
|
||||
for nominee in nominees:
|
||||
for nominee_position in nominee.nomineeposition_set.pending():
|
||||
send_reminder_to_nominee(nominee_position)
|
||||
hash = get_hash_nominee_position(today, nominee_position.id)
|
||||
|
||||
context = {'nominee': nominee,
|
||||
'position': position,
|
||||
'domain': domain,
|
||||
}
|
||||
body = render_to_string(mail_path, context)
|
||||
path = '%s%d/%s' % (nomcom_template_path, position.id, QUESTIONNAIRE_TEMPLATE)
|
||||
body += '\n\n%s' % render_to_string(path, context)
|
||||
send_mail_text(None, to_email, from_email, subject, body)
|
||||
|
||||
def send_reminder_to_nominees(nominees,type):
|
||||
addrs = []
|
||||
if type=='accept':
|
||||
for nominee in nominees:
|
||||
for nominee_position in nominee.nomineeposition_set.pending():
|
||||
send_accept_reminder_to_nominee(nominee_position)
|
||||
addrs.append(nominee_position.nominee.email.address)
|
||||
elif type=='questionnaire':
|
||||
for nominee in nominees:
|
||||
for nominee_position in nominee.nomineeposition_set.accepted():
|
||||
send_questionnaire_reminder_to_nominee(nominee_position)
|
||||
addrs.append(nominee_position.nominee.email.address)
|
||||
return addrs
|
||||
|
||||
|
||||
def get_or_create_nominee(nomcom, candidate_name, candidate_email, position, author):
|
||||
|
|
|
@ -31,11 +31,9 @@ from ietf.nomcom.forms import (NominateForm, FeedbackForm, QuestionnaireForm,
|
|||
from ietf.nomcom.models import Position, NomineePosition, Nominee, Feedback, NomCom, ReminderDates
|
||||
from ietf.nomcom.utils import (get_nomcom_by_year, store_nomcom_private_key,
|
||||
get_hash_nominee_position, send_reminder_to_nominees,
|
||||
HOME_TEMPLATE, NOMINEE_REMINDER_TEMPLATE)
|
||||
HOME_TEMPLATE, NOMINEE_ACCEPT_REMINDER_TEMPLATE,NOMINEE_QUESTIONNAIRE_REMINDER_TEMPLATE)
|
||||
from ietf.ietfauth.utils import role_required
|
||||
|
||||
import debug
|
||||
|
||||
def index(request):
|
||||
nomcom_list = Group.objects.filter(type__slug='nomcom').order_by('acronym')
|
||||
for nomcom in nomcom_list:
|
||||
|
@ -166,11 +164,27 @@ def private_index(request, year):
|
|||
|
||||
|
||||
@role_required("Nomcom Chair", "Nomcom Advisor")
|
||||
def send_reminder_mail(request, year):
|
||||
def send_reminder_mail(request, year, type):
|
||||
nomcom = get_nomcom_by_year(year)
|
||||
nominees = Nominee.objects.get_by_nomcom(nomcom).not_duplicated().filter(nomineeposition__state='pending').distinct()
|
||||
nomcom_template_path = '/nomcom/%s/' % nomcom.group.acronym
|
||||
mail_path = nomcom_template_path + NOMINEE_REMINDER_TEMPLATE
|
||||
|
||||
if type=='accept':
|
||||
interesting_state = 'pending'
|
||||
mail_path = nomcom_template_path + NOMINEE_ACCEPT_REMINDER_TEMPLATE
|
||||
reminder_description = 'accept (or decline) a nomination'
|
||||
selected_tab = 'send_accept_reminder'
|
||||
elif type=='questionnaire':
|
||||
interesting_state = 'accepted'
|
||||
mail_path = nomcom_template_path + NOMINEE_QUESTIONNAIRE_REMINDER_TEMPLATE
|
||||
reminder_description = 'complete the questionnaire for a nominated position'
|
||||
selected_tab = 'send_questionnaire_reminder'
|
||||
else:
|
||||
raise Http404
|
||||
|
||||
nominees = Nominee.objects.get_by_nomcom(nomcom).not_duplicated().filter(nomineeposition__state=interesting_state).distinct()
|
||||
annotated_nominees = list(nominees)
|
||||
for nominee in annotated_nominees:
|
||||
nominee.interesting_positions = [x.position.name for x in nominee.nomineeposition_set.all() if x.state.slug==interesting_state]
|
||||
mail_template = DBTemplate.objects.filter(group=nomcom.group, path=mail_path)
|
||||
mail_template = mail_template and mail_template[0] or None
|
||||
message = None
|
||||
|
@ -179,16 +193,21 @@ def send_reminder_mail(request, year):
|
|||
selected_nominees = request.POST.getlist('selected')
|
||||
selected_nominees = nominees.filter(id__in=selected_nominees)
|
||||
if selected_nominees:
|
||||
send_reminder_to_nominees(selected_nominees)
|
||||
message = ('success', 'An query has been sent to each person, asking them to accept (or decline) the nominations')
|
||||
addrs = send_reminder_to_nominees(selected_nominees,type)
|
||||
if addrs:
|
||||
message = ('success', 'A copy of "%s" has been sent to %s'%(mail_template.title,", ".join(addrs)))
|
||||
else:
|
||||
message = {'warning', 'No messages were sent.'}
|
||||
else:
|
||||
message = ('warning', "Please, select some nominee")
|
||||
message = ('warning', "Please, select at least one nominee")
|
||||
return render_to_response('nomcom/send_reminder_mail.html',
|
||||
{'nomcom': nomcom,
|
||||
'year': year,
|
||||
'nominees': nominees,
|
||||
'nominees': annotated_nominees,
|
||||
'mail_template': mail_template,
|
||||
'selected': 'send_reminder_mail',
|
||||
'selected': selected_tab,
|
||||
'reminder_description': reminder_description,
|
||||
'state_description': NomineePositionState.objects.get(slug=interesting_state).name,
|
||||
'message': message}, RequestContext(request))
|
||||
|
||||
|
||||
|
|
|
@ -19,7 +19,8 @@
|
|||
{% if user|is_chair:year %} |
|
||||
{% if selected == "feedback_pending" %}<span class="selected">Pending Feedback</span>{% else %}<a href="{% url nomcom_view_feedback_pending year %}">Pending Feedback</a>{% endif %} |
|
||||
{% if selected == "feedback_email" %}<span class="selected">Enter Email Feedback</span>{% else %}<a href="{% url nomcom_private_feedback_email year %}">Enter Email Feedback</a>{% endif %} |
|
||||
{% if selected == "send_reminder_mail" %}<span class="selected">Send Reminder</span>{% else %}<a href="{% url nomcom_send_reminder_mail year %}">Send Reminder</a>{% endif %}
|
||||
{% if selected == "send_accept_reminder" %}<span class="selected">Send Accept Reminder</span>{% else %}<a href="{% url nomcom_send_reminder_mail year "accept" %}">Send Accept Reminder</a>{% endif %} |
|
||||
{% if selected == "send_questionnaire_reminder" %}<span class="selected">Send Questionnaire Reminder</span>{% else %}<a href="{% url nomcom_send_reminder_mail year "questionnaire" %}">Send Questionnaire Reminder</a>{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if user|is_chair:year %}
|
||||
|
|
|
@ -33,8 +33,6 @@
|
|||
<h2>List of nominees by position</h2>
|
||||
|
||||
<p>The following is a list of registered nominees.
|
||||
{% if is_chair %}(You can <a href="{% url nomcom_send_reminder_mail year %}">request confirmation</a> from nominees if they haven't
|
||||
replied to the nomination notification they have received.){% endif %}</p>
|
||||
|
||||
<div class="content">
|
||||
|
||||
|
|
|
@ -1,18 +1,15 @@
|
|||
{% extends "nomcom/nomcom_private_base.html" %}
|
||||
{% load ietf_filters %}
|
||||
|
||||
{% block subtitle %} - Send reminder emails {% endblock %}
|
||||
{% block subtitle %} - Send reminder messages {% endblock %}
|
||||
|
||||
{% block nomcom_content %}
|
||||
|
||||
<h2>Request nomination acceptance from the listed nominees</h2>
|
||||
<h2>Send a message to the selected nominees reminding them to {{reminder_description}}</h2>
|
||||
|
||||
<p>
|
||||
An query will be sent to each person, asking them to accept (or decline) the nomination.
|
||||
<p>These are the nominees that are in the '{{state_description}}' state for the listed positions. </p>
|
||||
|
||||
The list has been pre-populated with the selected list of nominees
|
||||
|
||||
The message that will be sent is shown below the address entry form.
|
||||
</p>
|
||||
<p>The message that will be sent is shown below the list of nominees. </p>
|
||||
|
||||
<form method="post" action="">
|
||||
<h3>Nominees who have not responded</h2>
|
||||
|
@ -31,7 +28,7 @@ The message that will be sent is shown below the address entry form.
|
|||
<tr class="{{ forloop.counter|divisibleby:2|yesno:"oddrow,evenrow" }}">
|
||||
<td><input class="batch-select" type="checkbox" value="{{ nominee.id }}" name="selected" checked="checked"/></td>
|
||||
<td>{{ nominee }}</td>
|
||||
<td>{% for nominee_position in nominee.nomineeposition_set.all %}{% ifequal nominee_position.state.slug "pending" %} {{ nominee_position.position.name }}, {% endifequal %}{% endfor %}</td>
|
||||
<td>{{nominee.interesting_positions|join:", "}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
@ -46,6 +43,6 @@ The message that will be sent is shown below the address entry form.
|
|||
|
||||
<p>The message that will be sent is as follows: {% if mail_template %}<a href="{% url nomcom_edit_template year mail_template.id %}">(Edit the message)</a>{% endif %}</p>
|
||||
|
||||
{% include mail_template.path %}
|
||||
<pre>{{ mail_template.content|wrap_text:80|escape }}</pre>
|
||||
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
|
Loading…
Reference in a new issue