Better app and model names. Some model hygiene. Added admin.
- Legacy-Id: 9993
This commit is contained in:
parent
c0acadf222
commit
7649397f5b
|
@ -14,7 +14,7 @@ from ietf.doc.utils import needed_ballot_positions
|
||||||
from ietf.person.models import Person
|
from ietf.person.models import Person
|
||||||
from ietf.group.models import Group, Role
|
from ietf.group.models import Group, Role
|
||||||
from ietf.doc.models import Document
|
from ietf.doc.models import Document
|
||||||
from ietf.eventmail.utils import gather_addresses
|
from ietf.mailtoken.utils import gather_addresses
|
||||||
|
|
||||||
def email_state_changed(request, doc, text):
|
def email_state_changed(request, doc, text):
|
||||||
to = [x.strip() for x in doc.notify.replace(';', ',').split(',')]
|
to = [x.strip() for x in doc.notify.replace(';', ',').split(',')]
|
||||||
|
|
|
@ -15,7 +15,7 @@ from ietf.utils.test_utils import TestCase
|
||||||
from ietf.utils.mail import outbox
|
from ietf.utils.mail import outbox
|
||||||
from ietf.utils.test_data import make_test_data
|
from ietf.utils.test_data import make_test_data
|
||||||
from ietf.utils.test_utils import login_testing_unauthorized
|
from ietf.utils.test_utils import login_testing_unauthorized
|
||||||
from ietf.eventmail.utils import gather_addresses
|
from ietf.mailtoken.utils import gather_addresses
|
||||||
|
|
||||||
|
|
||||||
class EditPositionTests(TestCase):
|
class EditPositionTests(TestCase):
|
||||||
|
|
|
@ -27,7 +27,7 @@ from ietf.message.utils import infer_message
|
||||||
from ietf.name.models import BallotPositionName
|
from ietf.name.models import BallotPositionName
|
||||||
from ietf.person.models import Person
|
from ietf.person.models import Person
|
||||||
from ietf.utils.mail import send_mail_text, send_mail_preformatted
|
from ietf.utils.mail import send_mail_text, send_mail_preformatted
|
||||||
from ietf.eventmail.utils import gather_addresses
|
from ietf.mailtoken.utils import gather_addresses
|
||||||
|
|
||||||
BALLOT_CHOICES = (("yes", "Yes"),
|
BALLOT_CHOICES = (("yes", "Yes"),
|
||||||
("noobj", "No Objection"),
|
("noobj", "No Objection"),
|
||||||
|
|
|
@ -37,7 +37,7 @@ from ietf.person.models import Person, Email
|
||||||
from ietf.secr.lib.template import jsonapi
|
from ietf.secr.lib.template import jsonapi
|
||||||
from ietf.utils.mail import send_mail, send_mail_message
|
from ietf.utils.mail import send_mail, send_mail_message
|
||||||
from ietf.utils.textupload import get_cleaned_text_file_content
|
from ietf.utils.textupload import get_cleaned_text_file_content
|
||||||
from ietf.eventmail.utils import gather_addresses
|
from ietf.mailtoken.utils import gather_addresses
|
||||||
|
|
||||||
class ChangeStateForm(forms.Form):
|
class ChangeStateForm(forms.Form):
|
||||||
state = forms.ModelChoiceField(State.objects.filter(used=True, type="draft-iesg"), empty_label=None, required=True)
|
state = forms.ModelChoiceField(State.objects.filter(used=True, type="draft-iesg"), empty_label=None, required=True)
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
from django.conf.urls import patterns, url
|
|
||||||
from django.views.generic import RedirectView
|
|
||||||
from django.core.urlresolvers import reverse_lazy
|
|
||||||
|
|
||||||
urlpatterns = patterns('ietf.eventmail.views',
|
|
||||||
url(r'^$', RedirectView.as_view(url=reverse_lazy('eventmail_show_patterns'), permanent=True)),
|
|
||||||
url(r'^event/$', 'show_patterns', name='eventmail_show_patterns' ),
|
|
||||||
url(r'^event/(?P<eventmail_slug>[-\w]+)/$', 'show_patterns' ),
|
|
||||||
url(r'^recipient/$', 'show_ingredients' ),
|
|
||||||
url(r'^recipient/(?P<ingredient_slug>[-\w]+)/$', 'show_ingredients' ),
|
|
||||||
)
|
|
|
@ -1,24 +0,0 @@
|
||||||
# Copyright The IETF Trust 2015, All Rights Reserved
|
|
||||||
|
|
||||||
from inspect import getsourcelines
|
|
||||||
|
|
||||||
from django.shortcuts import render
|
|
||||||
|
|
||||||
from ietf.eventmail.models import Recipe, Ingredient
|
|
||||||
|
|
||||||
def show_patterns(request, eventmail_slug=None):
|
|
||||||
recipes = Recipe.objects.all()
|
|
||||||
if eventmail_slug:
|
|
||||||
recipes = recipes.filter(slug=eventmail_slug) # TODO better 404 behavior here and below
|
|
||||||
return render(request,'eventmail/show_patterns.html',{'eventmail_slug':eventmail_slug,
|
|
||||||
'recipes':recipes})
|
|
||||||
def show_ingredients(request, ingredient_slug=None):
|
|
||||||
ingredients = Ingredient.objects.all()
|
|
||||||
if ingredient_slug:
|
|
||||||
ingredients = ingredients.filter(slug=ingredient_slug)
|
|
||||||
for ingredient in ingredients:
|
|
||||||
fname = 'gather_%s'%ingredient.slug
|
|
||||||
if hasattr(ingredient,fname):
|
|
||||||
ingredient.code = ''.join(getsourcelines(getattr(ingredient,fname))[0])
|
|
||||||
return render(request,'eventmail/ingredient.html',{'ingredient_slug':ingredient_slug,
|
|
||||||
'ingredients':ingredients})
|
|
17
ietf/mailtoken/admin.py
Normal file
17
ietf/mailtoken/admin.py
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
from ietf.mailtoken.models import MailToken, Recipient
|
||||||
|
|
||||||
|
class RecipientAdmin(admin.ModelAdmin):
|
||||||
|
list_display = [ 'slug', 'desc', 'template', 'has_code', ]
|
||||||
|
def has_code(self, obj):
|
||||||
|
return hasattr(obj,'gather_%s'%obj.slug)
|
||||||
|
has_code.boolean = True
|
||||||
|
admin.site.register(Recipient, RecipientAdmin)
|
||||||
|
|
||||||
|
|
||||||
|
class MailTokenAdmin(admin.ModelAdmin):
|
||||||
|
list_display = [ 'slug', 'desc', ]
|
||||||
|
filter_horizontal = [ 'recipients' ]
|
||||||
|
admin.site.register(MailToken, MailTokenAdmin)
|
||||||
|
|
|
@ -11,25 +11,32 @@ class Migration(migrations.Migration):
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Ingredient',
|
name='MailToken',
|
||||||
|
fields=[
|
||||||
|
('slug', models.CharField(max_length=32, serialize=False, primary_key=True)),
|
||||||
|
('desc', models.TextField(blank=True)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'ordering': ['slug'],
|
||||||
|
},
|
||||||
|
bases=(models.Model,),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Recipient',
|
||||||
fields=[
|
fields=[
|
||||||
('slug', models.CharField(max_length=32, serialize=False, primary_key=True)),
|
('slug', models.CharField(max_length=32, serialize=False, primary_key=True)),
|
||||||
('desc', models.TextField(blank=True)),
|
('desc', models.TextField(blank=True)),
|
||||||
('template', models.CharField(max_length=512, null=True, blank=True)),
|
('template', models.CharField(max_length=512, null=True, blank=True)),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
|
'ordering': ['slug'],
|
||||||
},
|
},
|
||||||
bases=(models.Model,),
|
bases=(models.Model,),
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.AddField(
|
||||||
name='Recipe',
|
model_name='mailtoken',
|
||||||
fields=[
|
name='recipients',
|
||||||
('slug', models.CharField(max_length=32, serialize=False, primary_key=True)),
|
field=models.ManyToManyField(to='mailtoken.Recipient', null=True, blank=True),
|
||||||
('desc', models.TextField(blank=True)),
|
preserve_default=True,
|
||||||
('ingredients', models.ManyToManyField(to='eventmail.Ingredient', null=True, blank=True)),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
},
|
|
||||||
bases=(models.Model,),
|
|
||||||
),
|
),
|
||||||
]
|
]
|
|
@ -3,16 +3,28 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.template import Template, Context
|
from django.template import Template, Context
|
||||||
|
|
||||||
class Recipe(models.Model):
|
class MailToken(models.Model):
|
||||||
slug = models.CharField(max_length=32, primary_key=True)
|
slug = models.CharField(max_length=32, primary_key=True)
|
||||||
desc = models.TextField(blank=True)
|
desc = models.TextField(blank=True)
|
||||||
ingredients = models.ManyToManyField('Ingredient', null=True, blank=True)
|
recipients = models.ManyToManyField('Recipient', null=True, blank=True)
|
||||||
|
|
||||||
class Ingredient(models.Model):
|
class Meta:
|
||||||
|
ordering = ["slug"]
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
|
return self.slug
|
||||||
|
|
||||||
|
class Recipient(models.Model):
|
||||||
slug = models.CharField(max_length=32, primary_key=True)
|
slug = models.CharField(max_length=32, primary_key=True)
|
||||||
desc = models.TextField(blank=True)
|
desc = models.TextField(blank=True)
|
||||||
template = models.CharField(max_length=512, null=True, blank=True)
|
template = models.CharField(max_length=512, null=True, blank=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
ordering = ["slug"]
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
|
return self.slug
|
||||||
|
|
||||||
def gather(self, **kwargs):
|
def gather(self, **kwargs):
|
||||||
retval = []
|
retval = []
|
||||||
if hasattr(self,'gather_%s'%self.slug):
|
if hasattr(self,'gather_%s'%self.slug):
|
||||||
|
@ -45,73 +57,73 @@ class Ingredient(models.Model):
|
||||||
addrs = []
|
addrs = []
|
||||||
if 'doc' in kwargs:
|
if 'doc' in kwargs:
|
||||||
for reldoc in kwargs['doc'].related_that_doc(['conflrev','tohist','tois','tops']):
|
for reldoc in kwargs['doc'].related_that_doc(['conflrev','tohist','tois','tops']):
|
||||||
addrs.extend(Ingredient.objects.get(slug='doc_authors').gather(**{'doc':reldoc.document}))
|
addrs.extend(Recipient.objects.get(slug='doc_authors').gather(**{'doc':reldoc.document}))
|
||||||
return addrs
|
return addrs
|
||||||
|
|
||||||
def gather_doc_affecteddoc_group_chairs(self, **kwargs):
|
def gather_doc_affecteddoc_group_chairs(self, **kwargs):
|
||||||
addrs = []
|
addrs = []
|
||||||
if 'doc' in kwargs:
|
if 'doc' in kwargs:
|
||||||
for reldoc in kwargs['doc'].related_that_doc(['conflrev','tohist','tois','tops']):
|
for reldoc in kwargs['doc'].related_that_doc(['conflrev','tohist','tois','tops']):
|
||||||
addrs.extend(Ingredient.objects.get(slug='doc_group_chairs').gather(**{'doc':reldoc.document}))
|
addrs.extend(Recipient.objects.get(slug='doc_group_chairs').gather(**{'doc':reldoc.document}))
|
||||||
return addrs
|
return addrs
|
||||||
|
|
||||||
def make_ingredients():
|
def make_recipients():
|
||||||
|
|
||||||
Ingredient.objects.all().delete()
|
Recipient.objects.all().delete()
|
||||||
Ingredient.objects.create(slug='iesg',
|
Recipient.objects.create(slug='iesg',
|
||||||
desc='The IESG',
|
desc='The IESG',
|
||||||
template='The IESG <iesg@ietf.org>')
|
template='The IESG <iesg@ietf.org>')
|
||||||
Ingredient.objects.create(slug='ietf_announce',
|
Recipient.objects.create(slug='ietf_announce',
|
||||||
desc='The IETF Announce list',
|
desc='The IETF Announce list',
|
||||||
template='IETF-Announce <ietf-announce@ietf.org>')
|
template='IETF-Announce <ietf-announce@ietf.org>')
|
||||||
Ingredient.objects.create(slug='rfc_editor',
|
Recipient.objects.create(slug='rfc_editor',
|
||||||
desc='The RFC Editor',
|
desc='The RFC Editor',
|
||||||
template='<rfc-editor@rfc-editor.org>')
|
template='<rfc-editor@rfc-editor.org>')
|
||||||
Ingredient.objects.create(slug='iesg_secretary',
|
Recipient.objects.create(slug='iesg_secretary',
|
||||||
desc='The Secretariat',
|
desc='The Secretariat',
|
||||||
template='<iesg-secretary@ietf.org>')
|
template='<iesg-secretary@ietf.org>')
|
||||||
Ingredient.objects.create(slug='doc_authors',
|
Recipient.objects.create(slug='doc_authors',
|
||||||
desc="The document's authors",
|
desc="The document's authors",
|
||||||
template='{{doc.name}}@ietf.org')
|
template='{{doc.name}}@ietf.org')
|
||||||
Ingredient.objects.create(slug='doc_notify',
|
Recipient.objects.create(slug='doc_notify',
|
||||||
desc="The addresses in the document's notify field",
|
desc="The addresses in the document's notify field",
|
||||||
template='{{doc.notify}}')
|
template='{{doc.notify}}')
|
||||||
Ingredient.objects.create(slug='doc_group_chairs',
|
Recipient.objects.create(slug='doc_group_chairs',
|
||||||
desc="The document's group chairs (if the document is assigned to a working or research group)",
|
desc="The document's group chairs (if the document is assigned to a working or research group)",
|
||||||
template=None)
|
template=None)
|
||||||
Ingredient.objects.create(slug='doc_affecteddoc_authors',
|
Recipient.objects.create(slug='doc_affecteddoc_authors',
|
||||||
desc="The authors of the subject documents of a conflict-review or status-change",
|
desc="The authors of the subject documents of a conflict-review or status-change",
|
||||||
template=None)
|
template=None)
|
||||||
Ingredient.objects.create(slug='doc_affecteddoc_group_chairs',
|
Recipient.objects.create(slug='doc_affecteddoc_group_chairs',
|
||||||
desc="The chairs of groups of the subject documents of a conflict-review or status-change",
|
desc="The chairs of groups of the subject documents of a conflict-review or status-change",
|
||||||
template=None)
|
template=None)
|
||||||
Ingredient.objects.create(slug='doc_shepherd',
|
Recipient.objects.create(slug='doc_shepherd',
|
||||||
desc="The document's shepherd",
|
desc="The document's shepherd",
|
||||||
template='{% if doc.shepherd %}{{doc.shepherd.address}}{% endif %}' )
|
template='{% if doc.shepherd %}{{doc.shepherd.address}}{% endif %}' )
|
||||||
Ingredient.objects.create(slug='doc_ad',
|
Recipient.objects.create(slug='doc_ad',
|
||||||
desc="The document's responsible Area Director",
|
desc="The document's responsible Area Director",
|
||||||
template='{% if doc.ad %}{{doc.ad.email_address}}{% endif %}' )
|
template='{% if doc.ad %}{{doc.ad.email_address}}{% endif %}' )
|
||||||
Ingredient.objects.create(slug='doc_group_mail_list',
|
Recipient.objects.create(slug='doc_group_mail_list',
|
||||||
desc="The list address of the document's group",
|
desc="The list address of the document's group",
|
||||||
template=None )
|
template=None )
|
||||||
Ingredient.objects.create(slug='conflict_review_stream_owner',
|
Recipient.objects.create(slug='conflict_review_stream_owner',
|
||||||
desc="The stream owner of a document being reviewed for IETF stream conflicts",
|
desc="The stream owner of a document being reviewed for IETF stream conflicts",
|
||||||
template='{% ifequal doc.type_id "conflrev" %}{% ifequal doc.stream_id "ise" %}<rfc-ise@rfc-editor.org>{% endifequal %}{% ifequal doc.stream_id "irtf" %}<irtf-chair@irtf.org>{% endifequal %}{% endifequal %}')
|
template='{% ifequal doc.type_id "conflrev" %}{% ifequal doc.stream_id "ise" %}<rfc-ise@rfc-editor.org>{% endifequal %}{% ifequal doc.stream_id "irtf" %}<irtf-chair@irtf.org>{% endifequal %}{% endifequal %}')
|
||||||
Ingredient.objects.create(slug='iana_approve',
|
Recipient.objects.create(slug='iana_approve',
|
||||||
desc="IANA's draft approval address",
|
desc="IANA's draft approval address",
|
||||||
template='IANA <drafts-approval@icann.org>')
|
template='IANA <drafts-approval@icann.org>')
|
||||||
|
|
||||||
def make_recipes():
|
def make_mailtokens():
|
||||||
|
|
||||||
Recipe.objects.all().delete()
|
MailToken.objects.all().delete()
|
||||||
|
|
||||||
r = Recipe.objects.create(slug='ballot_saved',
|
m = MailToken.objects.create(slug='ballot_saved',
|
||||||
desc='Recipients when a new ballot position (with discusses, other blocking positions, or comments) is saved')
|
desc='Recipients when a new ballot position (with discusses, other blocking positions, or comments) is saved')
|
||||||
r.ingredients = Ingredient.objects.filter(slug__in=['iesg'])
|
m.recipients = Recipient.objects.filter(slug__in=['iesg'])
|
||||||
|
|
||||||
r = Recipe.objects.create(slug='ballot_saved_cc',
|
m = MailToken.objects.create(slug='ballot_saved_cc',
|
||||||
desc='Copied when a new ballot position (with discusses, other blocking positions, or comments) is saved')
|
desc='Copied when a new ballot position (with discusses, other blocking positions, or comments) is saved')
|
||||||
r.ingredients = Ingredient.objects.filter(slug__in=['doc_authors',
|
m.recipients = Recipient.objects.filter(slug__in=['doc_authors',
|
||||||
'doc_group_chairs',
|
'doc_group_chairs',
|
||||||
'doc_shepherd',
|
'doc_shepherd',
|
||||||
'doc_affecteddoc_authors',
|
'doc_affecteddoc_authors',
|
||||||
|
@ -119,9 +131,9 @@ def make_recipes():
|
||||||
'conflict_review_stream_owner',
|
'conflict_review_stream_owner',
|
||||||
])
|
])
|
||||||
|
|
||||||
r = Recipe.objects.create(slug='ballot_deferred',
|
m = MailToken.objects.create(slug='ballot_deferred',
|
||||||
desc='Recipients when a ballot is deferred to or undeferred from a future telechat')
|
desc='Recipients when a ballot is deferred to or undeferred from a future telechat')
|
||||||
r.ingredients = Ingredient.objects.filter(slug__in=['iesg',
|
m.recipients = Recipient.objects.filter(slug__in=['iesg',
|
||||||
'iesg_secretary',
|
'iesg_secretary',
|
||||||
'doc_group_chairs',
|
'doc_group_chairs',
|
||||||
'doc_notify',
|
'doc_notify',
|
||||||
|
@ -132,13 +144,13 @@ def make_recipes():
|
||||||
'conflict_review_stream_owner',
|
'conflict_review_stream_owner',
|
||||||
])
|
])
|
||||||
|
|
||||||
r = Recipe.objects.create(slug='ballot_approved_ietf_stream',
|
m = MailToken.objects.create(slug='ballot_approved_ietf_stream',
|
||||||
desc='Recipients when an IETF stream document ballot is approved')
|
desc='Recipients when an IETF stream document ballot is approved')
|
||||||
r.ingredients = Ingredient.objects.filter(slug__in=['ietf_announce'])
|
m.recipients = Recipient.objects.filter(slug__in=['ietf_announce'])
|
||||||
|
|
||||||
r = Recipe.objects.create(slug='ballot_approved_ietf_stream_cc',
|
m = MailToken.objects.create(slug='ballot_approved_ietf_stream_cc',
|
||||||
desc='Copied when an IETF stream document ballot is approved')
|
desc='Copied when an IETF stream document ballot is approved')
|
||||||
r.ingredients = Ingredient.objects.filter(slug__in=['iesg',
|
m.recipients = Recipient.objects.filter(slug__in=['iesg',
|
||||||
'doc_notify',
|
'doc_notify',
|
||||||
'doc_ad',
|
'doc_ad',
|
||||||
'doc_authors',
|
'doc_authors',
|
||||||
|
@ -148,8 +160,8 @@ def make_recipes():
|
||||||
'rfc_editor',
|
'rfc_editor',
|
||||||
])
|
])
|
||||||
|
|
||||||
r = Recipe.objects.create(slug='ballot_approved_ietf_stream_iana',
|
m = MailToken.objects.create(slug='ballot_approved_ietf_stream_iana',
|
||||||
desc='Recipients for IANA message when an IETF stream document ballot is approved')
|
desc='Recipients for IANA message when an IETF stream document ballot is approved')
|
||||||
r.ingredients = Ingredient.objects.filter(slug__in=['iana_approve'])
|
m.recipients = Recipient.objects.filter(slug__in=['iana_approve'])
|
||||||
|
|
||||||
|
|
|
@ -5,29 +5,29 @@ from tastypie.constants import ALL, ALL_WITH_RELATIONS # pyflakes:ignore
|
||||||
|
|
||||||
from ietf import api
|
from ietf import api
|
||||||
|
|
||||||
from ietf.eventmail.models import * # pyflakes:ignore
|
from ietf.mailtoken.models import * # pyflakes:ignore
|
||||||
|
|
||||||
|
|
||||||
class IngredientResource(ModelResource):
|
class RecipientResource(ModelResource):
|
||||||
class Meta:
|
class Meta:
|
||||||
queryset = Ingredient.objects.all()
|
queryset = Recipient.objects.all()
|
||||||
#resource_name = 'ingredient'
|
#resource_name = 'recipient'
|
||||||
filtering = {
|
filtering = {
|
||||||
"slug": ALL,
|
"slug": ALL,
|
||||||
"desc": ALL,
|
"desc": ALL,
|
||||||
"template": ALL,
|
"template": ALL,
|
||||||
}
|
}
|
||||||
api.eventmail.register(IngredientResource())
|
api.mailtoken.register(RecipientResource())
|
||||||
|
|
||||||
class RecipeResource(ModelResource):
|
class MailTokenResource(ModelResource):
|
||||||
ingredients = ToManyField(IngredientResource, 'ingredients', null=True)
|
recipients = ToManyField(RecipientResource, 'recipients', null=True)
|
||||||
class Meta:
|
class Meta:
|
||||||
queryset = Recipe.objects.all()
|
queryset = MailToken.objects.all()
|
||||||
#resource_name = 'recipe'
|
#resource_name = 'mailtoken'
|
||||||
filtering = {
|
filtering = {
|
||||||
"slug": ALL,
|
"slug": ALL,
|
||||||
"desc": ALL,
|
"desc": ALL,
|
||||||
"ingredients": ALL_WITH_RELATIONS,
|
"recipients": ALL_WITH_RELATIONS,
|
||||||
}
|
}
|
||||||
api.eventmail.register(RecipeResource())
|
api.mailtoken.register(MailTokenResource())
|
||||||
|
|
|
@ -2,42 +2,42 @@ from django.core.urlresolvers import reverse as urlreverse
|
||||||
|
|
||||||
from ietf.utils.test_utils import TestCase
|
from ietf.utils.test_utils import TestCase
|
||||||
from ietf.utils.test_data import make_test_data
|
from ietf.utils.test_data import make_test_data
|
||||||
from ietf.eventmail.models import Ingredient
|
from ietf.mailtoken.models import Recipient
|
||||||
|
|
||||||
class EventMailTests(TestCase):
|
class EventMailTests(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
make_test_data()
|
make_test_data()
|
||||||
|
|
||||||
def test_show_patterns(self):
|
def test_show_tokens(self):
|
||||||
|
|
||||||
url = urlreverse('ietf.eventmail.views.show_patterns')
|
url = urlreverse('ietf.mailtoken.views.show_tokens')
|
||||||
r = self.client.get(url)
|
r = self.client.get(url)
|
||||||
self.assertEqual(r.status_code, 200)
|
self.assertEqual(r.status_code, 200)
|
||||||
self.assertTrue('ballot_saved_cc' in r.content)
|
self.assertTrue('ballot_saved_cc' in r.content)
|
||||||
|
|
||||||
url = urlreverse('ietf.eventmail.views.show_patterns',kwargs=dict(eventmail_slug='ballot_saved_cc'))
|
url = urlreverse('ietf.mailtoken.views.show_tokens',kwargs=dict(mailtoken_slug='ballot_saved_cc'))
|
||||||
r = self.client.get(url)
|
r = self.client.get(url)
|
||||||
self.assertEqual(r.status_code, 200)
|
self.assertEqual(r.status_code, 200)
|
||||||
self.assertTrue('ballot_saved_cc' in r.content)
|
self.assertTrue('ballot_saved_cc' in r.content)
|
||||||
|
|
||||||
def test_show_recipients(self):
|
def test_show_recipients(self):
|
||||||
|
|
||||||
url = urlreverse('ietf.eventmail.views.show_ingredients')
|
url = urlreverse('ietf.mailtoken.views.show_recipients')
|
||||||
r = self.client.get(url)
|
r = self.client.get(url)
|
||||||
self.assertEqual(r.status_code, 200)
|
self.assertEqual(r.status_code, 200)
|
||||||
self.assertTrue('bogus' in r.content)
|
self.assertTrue('bogus' in r.content)
|
||||||
|
|
||||||
url = urlreverse('ietf.eventmail.views.show_ingredients',kwargs=dict(ingredient_slug='bogus'))
|
url = urlreverse('ietf.mailtoken.views.show_recipients',kwargs=dict(recipient_slug='bogus'))
|
||||||
r = self.client.get(url)
|
r = self.client.get(url)
|
||||||
self.assertEqual(r.status_code, 200)
|
self.assertEqual(r.status_code, 200)
|
||||||
self.assertTrue('bogus' in r.content)
|
self.assertTrue('bogus' in r.content)
|
||||||
|
|
||||||
class IngredientTests(TestCase):
|
class RecipientTests(TestCase):
|
||||||
|
|
||||||
def test_ingredient_functions(self):
|
def test_recipient_functions(self):
|
||||||
draft = make_test_data()
|
draft = make_test_data()
|
||||||
ingredient = Ingredient.objects.first()
|
recipient = Recipient.objects.first()
|
||||||
for funcname in [name for name in dir(ingredient) if name.startswith('gather_')]:
|
for funcname in [name for name in dir(recipient) if name.startswith('gather_')]:
|
||||||
func=getattr(ingredient,funcname)
|
func=getattr(recipient,funcname)
|
||||||
func(**{'doc':draft,'group':draft.group})
|
func(**{'doc':draft,'group':draft.group})
|
11
ietf/mailtoken/urls.py
Normal file
11
ietf/mailtoken/urls.py
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
from django.conf.urls import patterns, url
|
||||||
|
from django.views.generic import RedirectView
|
||||||
|
from django.core.urlresolvers import reverse_lazy
|
||||||
|
|
||||||
|
urlpatterns = patterns('ietf.mailtoken.views',
|
||||||
|
url(r'^$', RedirectView.as_view(url=reverse_lazy('mailtoken_show_tokens'), permanent=True)),
|
||||||
|
url(r'^token/$', 'show_tokens', name='mailtoken_show_tokens' ),
|
||||||
|
url(r'^token/(?P<mailtoken_slug>[-\w]+)/$', 'show_tokens' ),
|
||||||
|
url(r'^recipient/$', 'show_recipients' ),
|
||||||
|
url(r'^recipient/(?P<recipient_slug>[-\w]+)/$', 'show_recipients' ),
|
||||||
|
)
|
|
@ -1,20 +1,20 @@
|
||||||
|
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
|
|
||||||
from ietf.eventmail.models import Recipe
|
from ietf.mailtoken.models import MailToken
|
||||||
|
|
||||||
def gather_addresses(slug,**kwargs):
|
def gather_addresses(slug,**kwargs):
|
||||||
|
|
||||||
addrs = []
|
addrs = []
|
||||||
|
|
||||||
try:
|
try:
|
||||||
recipe = Recipe.objects.get(slug=slug)
|
mailtoken = MailToken.objects.get(slug=slug)
|
||||||
except ObjectDoesNotExist:
|
except ObjectDoesNotExist:
|
||||||
# TODO remove the raise here, or find a better way to detect runtime misconfiguration
|
# TODO remove the raise here, or find a better way to detect runtime misconfiguration
|
||||||
raise
|
raise
|
||||||
return addrs
|
return addrs
|
||||||
|
|
||||||
for ingredient in recipe.ingredients.all():
|
for recipient in mailtoken.recipients.all():
|
||||||
addrs.extend(ingredient.gather(**kwargs))
|
addrs.extend(recipient.gather(**kwargs))
|
||||||
|
|
||||||
return addrs
|
return addrs
|
24
ietf/mailtoken/views.py
Normal file
24
ietf/mailtoken/views.py
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# Copyright The IETF Trust 2015, All Rights Reserved
|
||||||
|
|
||||||
|
from inspect import getsourcelines
|
||||||
|
|
||||||
|
from django.shortcuts import render
|
||||||
|
|
||||||
|
from ietf.mailtoken.models import MailToken, Recipient
|
||||||
|
|
||||||
|
def show_tokens(request, mailtoken_slug=None):
|
||||||
|
mailtokens = MailToken.objects.all()
|
||||||
|
if mailtoken_slug:
|
||||||
|
mailtokens = mailtokens.filter(slug=mailtoken_slug) # TODO better 404 behavior here and below
|
||||||
|
return render(request,'mailtoken/token.html',{'mailtoken_slug':mailtoken_slug,
|
||||||
|
'mailtokens':mailtokens})
|
||||||
|
def show_recipients(request, recipient_slug=None):
|
||||||
|
recipients = Recipient.objects.all()
|
||||||
|
if recipient_slug:
|
||||||
|
recipients = recipients.filter(slug=recipient_slug)
|
||||||
|
for recipient in recipients:
|
||||||
|
fname = 'gather_%s'%recipient.slug
|
||||||
|
if hasattr(recipient,fname):
|
||||||
|
recipient.code = ''.join(getsourcelines(getattr(recipient,fname))[0])
|
||||||
|
return render(request,'mailtoken/recipient.html',{'recipient_slug':recipient_slug,
|
||||||
|
'recipients':recipients})
|
|
@ -212,7 +212,6 @@ INSTALLED_APPS = (
|
||||||
'ietf.community',
|
'ietf.community',
|
||||||
'ietf.dbtemplate',
|
'ietf.dbtemplate',
|
||||||
'ietf.doc',
|
'ietf.doc',
|
||||||
'ietf.eventmail',
|
|
||||||
'ietf.group',
|
'ietf.group',
|
||||||
'ietf.idindex',
|
'ietf.idindex',
|
||||||
'ietf.iesg',
|
'ietf.iesg',
|
||||||
|
@ -220,6 +219,7 @@ INSTALLED_APPS = (
|
||||||
'ietf.ipr',
|
'ietf.ipr',
|
||||||
'ietf.liaisons',
|
'ietf.liaisons',
|
||||||
'ietf.mailinglists',
|
'ietf.mailinglists',
|
||||||
|
'ietf.mailtoken',
|
||||||
'ietf.meeting',
|
'ietf.meeting',
|
||||||
'ietf.message',
|
'ietf.message',
|
||||||
'ietf.name',
|
'ietf.name',
|
||||||
|
|
|
@ -13,22 +13,22 @@
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Recipient</th>
|
<th>Recipient</th>
|
||||||
<th>Event</th>
|
<th>Events</th>
|
||||||
<th>Template</th>
|
<th>Template</th>
|
||||||
<th>Code</th>
|
<th>Code</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for ingredient in ingredients %}
|
{% for recipient in recipients %}
|
||||||
<tr>
|
<tr>
|
||||||
<td><span title="{{ingredient.desc}}">{{ingredient.slug}}</span></td>
|
<td><span title="{{recipient.desc}}">{{recipient.slug}}</span></td>
|
||||||
<td>
|
<td>
|
||||||
{% for recipe in ingredient.recipe_set.all %}
|
{% for mailtoken in recipient.mailtoken_set.all %}
|
||||||
<a href="{% url 'ietf.eventmail.views.show_patterns' recipe.slug %}" title="{{recipe.desc}}">{{recipe.slug}}{% if not forloop.last %}, {%endif%}
|
<a href="{% url 'ietf.mailtoken.views.show_tokens' mailtoken.slug %}" title="{{mailtoken.desc}}">{{mailtoken.slug}}{% if not forloop.last %}, {%endif%}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</td>
|
</td>
|
||||||
<td>{{ingredient.template}}</td>
|
<td>{{recipient.template}}</td>
|
||||||
<td>{% if ingredient.code %}<pre>{{ingredient.code}}</pre>{% endif %}</td>
|
<td>{% if recipient.code %}<pre>{{recipient.code}}</pre>{% endif %}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
|
@ -17,13 +17,13 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for recipe in recipes %}
|
{% for mailtoken in mailtokens %}
|
||||||
<tr>
|
<tr>
|
||||||
<td><span title="{{recipe.desc}}">{{recipe.slug}}</span></td>
|
<td><span title="{{mailtoken.desc}}">{{mailtoken.slug}}</span></td>
|
||||||
<td>
|
<td>
|
||||||
{% for ingredient in recipe.ingredients.all %}
|
{% for recipient in mailtoken.recipients.all %}
|
||||||
{% comment %}<span title="{{ingredient.desc}}">{{ingredient.slug}}</span>{% endcomment %}
|
{% comment %}<span title="{{recipient.desc}}">{{recipient.slug}}</span>{% endcomment %}
|
||||||
<a href="{% url 'ietf.eventmail.views.show_ingredients' ingredient.slug %}" title="{{ingredient.desc}}">{{ingredient.slug}}</a>{% if not forloop.last %}, {% endif %}
|
<a href="{% url 'ietf.mailtoken.views.show_recipients' recipient.slug %}" title="{{recipient.desc}}">{{recipient.slug}}</a>{% if not forloop.last %}, {% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
|
@ -35,7 +35,7 @@ urlpatterns = patterns('',
|
||||||
(r'^accounts/settings/', include('ietf.cookies.urls')),
|
(r'^accounts/settings/', include('ietf.cookies.urls')),
|
||||||
(r'^doc/', include('ietf.doc.urls')),
|
(r'^doc/', include('ietf.doc.urls')),
|
||||||
(r'^drafts/', include('ietf.doc.redirect_drafts_urls')),
|
(r'^drafts/', include('ietf.doc.redirect_drafts_urls')),
|
||||||
(r'^eventmail/',include('ietf.eventmail.urls')),
|
(r'^mailtoken/',include('ietf.mailtoken.urls')),
|
||||||
(r'^feed/', include('ietf.feed_urls')),
|
(r'^feed/', include('ietf.feed_urls')),
|
||||||
(r'^group/', include('ietf.group.urls')),
|
(r'^group/', include('ietf.group.urls')),
|
||||||
(r'^help/', include('ietf.help.urls')),
|
(r'^help/', include('ietf.help.urls')),
|
||||||
|
|
|
@ -12,7 +12,7 @@ from ietf.ipr.models import HolderIprDisclosure, IprDocRel, IprDisclosureStateNa
|
||||||
from ietf.meeting.models import Meeting
|
from ietf.meeting.models import Meeting
|
||||||
from ietf.name.models import StreamName
|
from ietf.name.models import StreamName
|
||||||
from ietf.person.models import Person, Email
|
from ietf.person.models import Person, Email
|
||||||
from ietf.eventmail.models import Recipe, Ingredient
|
from ietf.mailtoken.models import MailToken, Recipient
|
||||||
|
|
||||||
def create_person(group, role_name, name=None, username=None, email_address=None, password=None):
|
def create_person(group, role_name, name=None, username=None, email_address=None, password=None):
|
||||||
"""Add person/user/email and role."""
|
"""Add person/user/email and role."""
|
||||||
|
@ -334,9 +334,9 @@ def make_test_data():
|
||||||
# EventMail tokens used by the views
|
# EventMail tokens used by the views
|
||||||
# This won't allow testing the results of the production configuration - if we want to do that, we'll need to
|
# This won't allow testing the results of the production configuration - if we want to do that, we'll need to
|
||||||
# extract the production data either directly, or as a fixture
|
# extract the production data either directly, or as a fixture
|
||||||
ingredient = Ingredient.objects.create(slug='bogus_ingredient',desc='Bogus Ingredient',template='bogus@example.com')
|
recipient = Recipient.objects.create(slug='bogus_recipient',desc='Bogus Recipient',template='bogus@example.com')
|
||||||
for slug in [u'ballot_approved_ietf_stream', u'ballot_approved_ietf_stream_cc', u'ballot_approved_ietf_stream_iana', u'ballot_deferred', u'ballot_saved', u'ballot_saved_cc']:
|
for slug in [u'ballot_approved_ietf_stream', u'ballot_approved_ietf_stream_cc', u'ballot_approved_ietf_stream_iana', u'ballot_deferred', u'ballot_saved', u'ballot_saved_cc']:
|
||||||
r=Recipe.objects.create(slug=slug,desc=slug)
|
m = MailToken.objects.create(slug=slug,desc=slug)
|
||||||
r.ingredients=[ingredient]
|
m.recipients=[recipient]
|
||||||
|
|
||||||
return draft
|
return draft
|
||||||
|
|
Loading…
Reference in a new issue