Port and proxy liaison views to new schema and add a bunch of tests
- Legacy-Id: 3350
This commit is contained in:
parent
bbe959623b
commit
b9e1753ef6
|
@ -1,14 +1,14 @@
|
|||
from redesign.person.models import Person
|
||||
from redesign.group.models import Role
|
||||
|
||||
from ietf.liaisons.proxy import proxy_personify_role
|
||||
|
||||
LIAISON_EDIT_GROUPS = ['Secretariat'] # this is not working anymore, refers to old auth model
|
||||
|
||||
|
||||
def get_ietf_chair():
|
||||
try:
|
||||
return Person.objects.get(email__role__name="chair", email__role__group__acronym="ietf")
|
||||
except Person.DoesNotExist:
|
||||
return proxy_personify_role(Role.objects.get(name="chair", group__acronym="ietf"))
|
||||
except Role.DoesNotExist:
|
||||
return None
|
||||
|
||||
|
||||
|
@ -18,14 +18,14 @@ def get_iesg_chair():
|
|||
|
||||
def get_iab_chair():
|
||||
try:
|
||||
return Person.objects.get(email__role__name="chair", email__role__group__acronym="iab")
|
||||
except Person.DoesNotExist:
|
||||
return proxy_personify_role(Role.objects.get(name="chair", group__acronym="iab"))
|
||||
except Role.DoesNotExist:
|
||||
return None
|
||||
|
||||
|
||||
def get_iab_executive_director():
|
||||
try:
|
||||
return Person.objects.get(email__role__name="execdir", email__role__group__acronym="iab")
|
||||
return proxy_personify_role(Role.objects.get(name="execdir", group__acronym="iab"))
|
||||
except Person.DoesNotExist:
|
||||
return None
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# Copyright The IETF Trust 2007, All Rights Reserved
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.syndication.feeds import Feed, FeedDoesNotExist
|
||||
from django.utils.feedgenerator import Atom1Feed
|
||||
from django.db.models import Q
|
||||
|
@ -8,6 +9,9 @@ from ietf.idtracker.models import Acronym
|
|||
from datetime import datetime, time
|
||||
import re
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
from ietf.liaisons.proxy import LiaisonDetailProxy as LiaisonDetail
|
||||
|
||||
# A slightly funny feed class, the 'object' is really
|
||||
# just a dict with some parameters that items() uses
|
||||
# to construct a queryset.
|
||||
|
@ -24,6 +28,15 @@ class Liaisons(Feed):
|
|||
if bits[0] == 'from':
|
||||
if len(bits) != 2:
|
||||
raise FeedDoesNotExist
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
from redesign.group.models import Group
|
||||
try:
|
||||
group = Group.objects.get(acronym=bits[1])
|
||||
obj['filter'] = { 'from_group': group }
|
||||
obj['title'] = u'Liaison Statements from %s' % group.name
|
||||
return obj
|
||||
except Group.DoesNotExist:
|
||||
raise FeedDoesNotExist
|
||||
try:
|
||||
acronym = Acronym.objects.get(acronym=bits[1])
|
||||
obj['filter'] = {'from_id': acronym.acronym_id}
|
||||
|
@ -49,16 +62,22 @@ class Liaisons(Feed):
|
|||
if bits[0] == 'to':
|
||||
if len(bits) != 2:
|
||||
raise FeedDoesNotExist
|
||||
# The schema uses two different fields for the same
|
||||
# basic purpose, depending on whether it's a Secretariat-submitted
|
||||
# or Liaison-tool-submitted document.
|
||||
obj['q'] = [ (Q(by_secretariat=0) & Q(to_body__icontains=bits[1])) | (Q(by_secretariat=1) & Q(submitter_name__icontains=bits[1])) ]
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
obj['filter'] = dict(to_name__icontains=bits[1])
|
||||
else:
|
||||
# The schema uses two different fields for the same
|
||||
# basic purpose, depending on whether it's a Secretariat-submitted
|
||||
# or Liaison-tool-submitted document.
|
||||
obj['q'] = [ (Q(by_secretariat=0) & Q(to_body__icontains=bits[1])) | (Q(by_secretariat=1) & Q(submitter_name__icontains=bits[1])) ]
|
||||
obj['title'] = 'Liaison Statements where to matches %s' % bits[1]
|
||||
return obj
|
||||
if bits[0] == 'subject':
|
||||
if len(bits) != 2:
|
||||
raise FeedDoesNotExist
|
||||
obj['q'] = [ Q(title__icontains=bits[1]) | Q(uploads__file_title__icontains=bits[1]) ]
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
obj['q'] = [ Q(title__icontains=bits[1]) | Q(attachments__title__icontains=bits[1]) ]
|
||||
else:
|
||||
obj['q'] = [ Q(title__icontains=bits[1]) | Q(uploads__file_title__icontains=bits[1]) ]
|
||||
obj['title'] = 'Liaison Statements where subject matches %s' % bits[1]
|
||||
return obj
|
||||
raise FeedDoesNotExist
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import datetime
|
||||
import datetime, os
|
||||
from email.utils import parseaddr
|
||||
|
||||
from django import forms
|
||||
|
@ -14,11 +14,14 @@ from ietf.liaisons.utils import IETFHM
|
|||
from ietf.liaisons.widgets import (FromWidget, ReadOnlyWidget, ButtonWidget,
|
||||
ShowAttachmentsWidget, RelatedLiaisonWidget)
|
||||
from ietf.liaisons.models import LiaisonStatement, LiaisonStatementPurposeName
|
||||
from ietf.liaisons.proxy import LiaisonDetailProxy
|
||||
from redesign.group.models import Group
|
||||
from redesign.person.models import Person
|
||||
from redesign.doc.models import Document
|
||||
|
||||
|
||||
class LiaisonForm(forms.Form):
|
||||
person = forms.ModelChoiceField(Person.objects.all())
|
||||
from_field = forms.ChoiceField(widget=FromWidget, label=u'From')
|
||||
replyto = forms.CharField(label=u'Reply to')
|
||||
organization = forms.ChoiceField()
|
||||
|
@ -64,15 +67,16 @@ class LiaisonForm(forms.Form):
|
|||
self.fake_person = None
|
||||
self.person = get_person_for_user(user)
|
||||
if kwargs.get('data', None):
|
||||
kwargs['data'].update({'person': self.person.pk})
|
||||
if is_secretariat(self.user) and 'from_fake_user' in kwargs['data'].keys():
|
||||
self.fake_person = Person.objects.get(pk=kwargs['data']['from_fake_user'])
|
||||
kwargs['data'].update({'person': self.fake_person.pk})
|
||||
else:
|
||||
kwargs['data'].update({'person': self.person.pk})
|
||||
|
||||
self.instance = kwargs.pop("instance", None)
|
||||
|
||||
super(LiaisonForm, self).__init__(*args, **kwargs)
|
||||
|
||||
|
||||
# now copy in values from instance, like a ModelForm
|
||||
if self.instance:
|
||||
for name, field in self.fields.iteritems():
|
||||
|
@ -120,8 +124,7 @@ class LiaisonForm(forms.Form):
|
|||
assert NotImplemented
|
||||
|
||||
def set_replyto_field(self):
|
||||
email = self.person.email_address()
|
||||
self.fields['replyto'].initial = email
|
||||
self.fields['replyto'].initial = self.person.email()[1]
|
||||
|
||||
def set_organization_field(self):
|
||||
assert NotImplemented
|
||||
|
@ -193,7 +196,7 @@ class LiaisonForm(forms.Form):
|
|||
return self.hm.get_entity_by_key(organization_key)
|
||||
|
||||
def get_poc(self, organization):
|
||||
return ', '.join([i.email_address() for i in organization.get_poc()])
|
||||
return ', '.join(u"%s <%s>" % i.email() for i in organization.get_poc())
|
||||
|
||||
def clean_cc1(self):
|
||||
value = self.cleaned_data.get('cc1', '')
|
||||
|
@ -223,7 +226,7 @@ class LiaisonForm(forms.Form):
|
|||
def save(self, *args, **kwargs):
|
||||
l = self.instance
|
||||
if not l:
|
||||
l = LiaisonStatement()
|
||||
l = LiaisonDetailProxy()
|
||||
|
||||
l.title = self.cleaned_data["title"]
|
||||
l.purpose = LiaisonStatementPurposeName.objects.get(order=self.cleaned_data["purpose"])
|
||||
|
@ -238,11 +241,11 @@ class LiaisonForm(forms.Form):
|
|||
|
||||
l.modified = now
|
||||
l.submitted = datetime.datetime.combine(self.cleaned_data["submitted_date"], now.time())
|
||||
if self.cleaned_data.get("approval"): # FIXME
|
||||
if not l.approved:
|
||||
l.approved = now
|
||||
if not l.approved:
|
||||
l.approved = now
|
||||
|
||||
self.save_extra_fields(l)
|
||||
|
||||
l.save() # we have to save here to make sure we get an id for the attachments
|
||||
self.save_attachments(l)
|
||||
|
||||
|
@ -250,23 +253,19 @@ class LiaisonForm(forms.Form):
|
|||
|
||||
def save_extra_fields(self, liaison):
|
||||
from_entity = self.get_from_entity()
|
||||
print from_entity, type(from_entity)
|
||||
print self.cleaned_data.get("from_field")
|
||||
liason.from_name = from_entity.name
|
||||
print from_entity.obj # FIXME? c.get("from_field")
|
||||
liason.from_group = from_entity.obj
|
||||
liason.from_contact = self.person # FIXME?
|
||||
liaison.from_name = from_entity.name
|
||||
liaison.from_group = from_entity.obj
|
||||
liaison.from_contact = self.cleaned_data["person"].email_address()
|
||||
|
||||
organization = self.get_to_entity()
|
||||
liason.to_name = organization.name
|
||||
print organization.obj # FIXME? self.cleaned_data.get('organization')
|
||||
liason.to_group = organization.obj
|
||||
liason.to_contact = self.get_poc(organization)
|
||||
|
||||
liaison.to_name = organization.name
|
||||
liaison.to_group = organization.obj
|
||||
liaison.to_contact = self.get_poc(organization)
|
||||
|
||||
liaison.cc = self.get_cc(from_entity, organization)
|
||||
|
||||
def save_attachments(self, instance):
|
||||
return # FIXME
|
||||
written = instance.attachments.all().count()
|
||||
for key in self.files.keys():
|
||||
title_key = key.replace('file', 'title')
|
||||
if not key.startswith('attach_file_') or not title_key in self.data.keys():
|
||||
|
@ -277,13 +276,16 @@ class LiaisonForm(forms.Form):
|
|||
extension = '.' + extension[1]
|
||||
else:
|
||||
extension = ''
|
||||
attach = Uploads.objects.create(
|
||||
file_title = self.data.get(title_key),
|
||||
person = self.person,
|
||||
detail = instance,
|
||||
file_extension = extension,
|
||||
written += 1
|
||||
name = instance.name() + ("-attachment-%s" % written)
|
||||
attach = Document.objects.create(
|
||||
title = self.data.get(title_key),
|
||||
type_id = "liaison",
|
||||
name = name,
|
||||
external_url = name + extension, # strictly speaking not necessary, but just for the time being ...
|
||||
)
|
||||
attach_file = open('%sfile%s%s' % (settings.LIAISON_ATTACH_PATH, attach.pk, attach.file_extension), 'w')
|
||||
instance.attachments.add(attach)
|
||||
attach_file = open(os.path.join(settings.LIAISON_ATTACH_PATH, attach.name + extension), 'w')
|
||||
attach_file.write(attached_file.read())
|
||||
attach_file.close()
|
||||
|
||||
|
@ -380,21 +382,13 @@ class OutgoingLiaisonForm(LiaisonForm):
|
|||
return self.cleaned_data['to_poc']
|
||||
|
||||
def save_extra_fields(self, liaison):
|
||||
raise NotImplemented
|
||||
super(OutgoingLiaisonForm, self).save_extra_fields(liaison)
|
||||
from_entity = self.get_from_entity()
|
||||
needs_approval = from_entity.needs_approval(self.person)
|
||||
if not needs_approval or self.cleaned_data.get('approved', False):
|
||||
approved = True
|
||||
approval_date = datetime.datetime.now()
|
||||
liaison.approved = datetime.datetime.now()
|
||||
else:
|
||||
approved = False
|
||||
approval_date = None
|
||||
approval = OutgoingLiaisonApproval.objects.create(
|
||||
approved = approved,
|
||||
approval_date = approval_date)
|
||||
liaison.approval = approval
|
||||
liaison.save()
|
||||
liaison.approved = None
|
||||
|
||||
def clean_to_poc(self):
|
||||
value = self.cleaned_data.get('to_poc', None)
|
||||
|
|
59
ietf/liaisons/mails.py
Normal file
59
ietf/liaisons/mails.py
Normal file
|
@ -0,0 +1,59 @@
|
|||
from django.conf import settings
|
||||
from django.template.loader import render_to_string
|
||||
from django.core.urlresolvers import reverse as urlreverse
|
||||
|
||||
from ietf.liaisons.mail import IETFEmailMessage
|
||||
|
||||
def send_liaison_by_email(liaison, fake=False):
|
||||
if not liaison.is_pending(): # this conditional should definitely be at the caller, not here
|
||||
return notify_pending_by_email(liaison, fake)
|
||||
|
||||
subject = u'New Liaison Statement, "%s"' % (liaison.title)
|
||||
from_email = settings.LIAISON_UNIVERSAL_FROM
|
||||
to_email = liaison.to_poc.split(',')
|
||||
cc = liaison.cc1.split(',')
|
||||
if liaison.technical_contact:
|
||||
cc += liaison.technical_contact.split(',')
|
||||
if liaison.response_contact:
|
||||
cc += liaison.response_contact.split(',')
|
||||
bcc = ['statements@ietf.org']
|
||||
body = render_to_string('liaisons/liaison_mail.txt',
|
||||
{'liaison': liaison,
|
||||
'url': settings.IDTRACKER_BASE_URL + urlreverse("liaison_detail", kwargs=dict(object_id=liaison.pk))
|
||||
})
|
||||
mail = IETFEmailMessage(subject=subject,
|
||||
to=to_email,
|
||||
from_email=from_email,
|
||||
cc = cc,
|
||||
bcc = bcc,
|
||||
body = body)
|
||||
# rather than this fake stuff, it's probably better to start a
|
||||
# debug SMTP server as explained in the Django docs
|
||||
if not fake:
|
||||
mail.send()
|
||||
return mail
|
||||
|
||||
def notify_pending_by_email(liaison, fake):
|
||||
from ietf.liaisons.utils import IETFHM
|
||||
|
||||
from_entity = IETFHM.get_entity_by_key(liaison.from_raw_code)
|
||||
if not from_entity:
|
||||
return None
|
||||
to_email = []
|
||||
for person in from_entity.can_approve():
|
||||
to_email.append('%s <%s>' % person.email())
|
||||
subject = u'New Liaison Statement, "%s" needs your approval' % (liaison.title)
|
||||
from_email = settings.LIAISON_UNIVERSAL_FROM
|
||||
body = render_to_string('liaisons/pending_liaison_mail.txt',
|
||||
{'liaison': liaison,
|
||||
'url': settings.IDTRACKER_BASE_URL + urlreverse("liaison_detail", kwargs=dict(object_id=liaison.pk)),
|
||||
'approve_url': settings.IDTRACKER_BASE_URL + urlreverse("liaison_approval_detail", kwargs=dict(object_id=liaison.pk))
|
||||
})
|
||||
mail = IETFEmailMessage(subject=subject,
|
||||
to=to_email,
|
||||
from_email=from_email,
|
||||
body = body)
|
||||
if not fake:
|
||||
mail.send()
|
||||
return mail
|
||||
|
|
@ -5,6 +5,7 @@ from django.core.exceptions import ObjectDoesNotExist
|
|||
from django.db import models
|
||||
from django.template.loader import render_to_string
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.urlresolvers import reverse as urlreverse
|
||||
from ietf.idtracker.models import Acronym, PersonOrOrgInfo, Area, IESGLogin
|
||||
from ietf.liaisons.mail import IETFEmailMessage
|
||||
from ietf.ietfauth.models import LegacyLiaisonUser
|
||||
|
@ -143,6 +144,7 @@ class LiaisonDetail(models.Model):
|
|||
from_email = settings.LIAISON_UNIVERSAL_FROM
|
||||
body = render_to_string('liaisons/pending_liaison_mail.txt',
|
||||
{'liaison': self,
|
||||
'url': settings.IDTRACKER_BASE_URL + urlreverse("liaison_detail", kwargs=dict(object_id=liaison.pk))
|
||||
})
|
||||
mail = IETFEmailMessage(subject=subject,
|
||||
to=to_email,
|
||||
|
@ -166,6 +168,8 @@ class LiaisonDetail(models.Model):
|
|||
bcc = ['statements@ietf.org']
|
||||
body = render_to_string('liaisons/liaison_mail.txt',
|
||||
{'liaison': self,
|
||||
'url': settings.IDTRACKER_BASE_URL + urlreverse("liaison_detail", kwargs=dict(object_id=liaison.pk)),
|
||||
'approve_url': settings.IDTRACKER_BASE_URL + urlreverse("liaison_approval_detail", kwargs=dict(object_id=liaison.pk))
|
||||
})
|
||||
mail = IETFEmailMessage(subject=subject,
|
||||
to=to_email,
|
||||
|
@ -289,6 +293,8 @@ class Uploads(models.Model):
|
|||
detail = models.ForeignKey(LiaisonDetail)
|
||||
def __str__(self):
|
||||
return self.file_title
|
||||
def filename(self):
|
||||
return "file%s%s" % (self.file_id, self.file_extension)
|
||||
class Meta:
|
||||
db_table = 'uploads'
|
||||
|
||||
|
@ -320,12 +326,12 @@ if settings.USE_DB_REDESIGN_PROXY_CLASSES or hasattr(settings, "IMPORTING_FROM_O
|
|||
|
||||
related_to = models.ForeignKey('LiaisonStatement', blank=True, null=True)
|
||||
|
||||
from_group = models.ForeignKey(Group, related_name="liaisonstatement_from_set", null=True, blank=True, help_text="From body, if it exists")
|
||||
from_group = models.ForeignKey(Group, related_name="liaisonstatement_from_set", null=True, blank=True, help_text="Sender group, if it exists")
|
||||
from_name = models.CharField(max_length=255, help_text="Name of the sender body")
|
||||
from_contact = models.ForeignKey(Email, blank=True, null=True)
|
||||
to_group = models.ForeignKey(Group, related_name="liaisonstatement_to_set", null=True, blank=True, help_text="To body, if it exists")
|
||||
to_group = models.ForeignKey(Group, related_name="liaisonstatement_to_set", null=True, blank=True, help_text="Recipient group, if it exists")
|
||||
to_name = models.CharField(max_length=255, help_text="Name of the recipient body")
|
||||
to_contact = models.CharField(blank=True, max_length=255, help_text="Contacts at to body")
|
||||
to_contact = models.CharField(blank=True, max_length=255, help_text="Contacts at recipient body")
|
||||
|
||||
reply_to = models.CharField(blank=True, max_length=255)
|
||||
|
||||
|
|
|
@ -96,14 +96,22 @@ class LiaisonDetailProxy(LiaisonStatement):
|
|||
@property
|
||||
def from_raw_body(self):
|
||||
return self.from_name
|
||||
|
||||
def raw_codify(self, group):
|
||||
if not group:
|
||||
return ""
|
||||
if group.type_id in ("sdo", "wg", "area"):
|
||||
return "%s_%s" % (group.type_id, group.id)
|
||||
return group.acronym
|
||||
|
||||
#from_raw_code = models.CharField(blank=True, null=True, max_length=255)
|
||||
@property
|
||||
def from_raw_code(self):
|
||||
return self.from_group_id
|
||||
return self.raw_codify(self.from_group)
|
||||
#to_raw_code = models.CharField(blank=True, null=True, max_length=255)
|
||||
@property
|
||||
def to_raw_code(self):
|
||||
return self.to_body_id
|
||||
return self.raw_codify(self.to_group)
|
||||
#approval = models.ForeignKey(OutgoingLiaisonApproval, blank=True, null=True)
|
||||
@property
|
||||
def approval(self):
|
||||
|
@ -134,54 +142,10 @@ class LiaisonDetailProxy(LiaisonStatement):
|
|||
class Meta:
|
||||
proxy = True
|
||||
|
||||
def notify_pending_by_email(self, fake):
|
||||
raise NotImplemented
|
||||
from ietf.liaisons.utils import IETFHM
|
||||
|
||||
from_entity = IETFHM.get_entity_by_key(self.from_raw_code)
|
||||
if not from_entity:
|
||||
return None
|
||||
to_email = []
|
||||
for person in from_entity.can_approve():
|
||||
to_email.append('%s <%s>' % person.email())
|
||||
subject = 'New Liaison Statement, "%s" needs your approval' % (self.title)
|
||||
from_email = settings.LIAISON_UNIVERSAL_FROM
|
||||
body = render_to_string('liaisons/pending_liaison_mail.txt',
|
||||
{'liaison': self,
|
||||
})
|
||||
mail = IETFEmailMessage(subject=subject,
|
||||
to=to_email,
|
||||
from_email=from_email,
|
||||
body = body)
|
||||
if not fake:
|
||||
mail.send()
|
||||
return mail
|
||||
|
||||
def send_by_email(self, fake=False):
|
||||
raise NotImplemented
|
||||
if self.is_pending():
|
||||
return self.notify_pending_by_email(fake)
|
||||
subject = 'New Liaison Statement, "%s"' % (self.title)
|
||||
from_email = settings.LIAISON_UNIVERSAL_FROM
|
||||
to_email = self.to_poc.split(',')
|
||||
cc = self.cc1.split(',')
|
||||
if self.technical_contact:
|
||||
cc += self.technical_contact.split(',')
|
||||
if self.response_contact:
|
||||
cc += self.response_contact.split(',')
|
||||
bcc = ['statements@ietf.org']
|
||||
body = render_to_string('liaisons/liaison_mail.txt',
|
||||
{'liaison': self,
|
||||
})
|
||||
mail = IETFEmailMessage(subject=subject,
|
||||
to=to_email,
|
||||
from_email=from_email,
|
||||
cc = cc,
|
||||
bcc = bcc,
|
||||
body = body)
|
||||
if not fake:
|
||||
mail.send()
|
||||
return mail
|
||||
# grab this from module instead of stuffing in on the model
|
||||
from ietf.liaisons.mails import send_liaison_by_email
|
||||
return send_liaison_by_email(self, fake)
|
||||
|
||||
def is_pending(self):
|
||||
return not self.approved
|
||||
|
@ -190,7 +154,10 @@ class UploadsProxy(Document):
|
|||
#file_id = models.AutoField(primary_key=True)
|
||||
@property
|
||||
def file_id(self):
|
||||
return int(self.external_url.split(".")[0])
|
||||
if self.external_url.startswith(self.name):
|
||||
return self.name # new data
|
||||
else:
|
||||
return int(self.external_url.split(".")[0][len(file):]) # old data
|
||||
#file_title = models.CharField(blank=True, max_length=255)
|
||||
@property
|
||||
def file_title(self):
|
||||
|
@ -208,6 +175,14 @@ class UploadsProxy(Document):
|
|||
@property
|
||||
def detail(self):
|
||||
return self.liaisonstatement_set.all()[0]
|
||||
|
||||
def filename(self):
|
||||
return self.external_url
|
||||
class Meta:
|
||||
proxy = True
|
||||
|
||||
def proxy_personify_role(role):
|
||||
"""Turn role into person with email() method using email from role."""
|
||||
p = role.email.person
|
||||
p.email = lambda: (p.name, role.email.address)
|
||||
return p
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import datetime
|
||||
import datetime, os, shutil
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.urlresolvers import reverse as urlreverse
|
||||
import django.test
|
||||
from StringIO import StringIO
|
||||
from pyquery import PyQuery
|
||||
|
||||
from ietf.utils.test_utils import SimpleUrlTestCase, canonicalize_feed, canonicalize_sitemap, login_testing_unauthorized
|
||||
|
@ -76,6 +77,15 @@ def make_liaison_models():
|
|||
class LiaisonManagementTestCase(django.test.TestCase):
|
||||
fixtures = ['names']
|
||||
|
||||
def setUp(self):
|
||||
self.liaison_dir = os.path.abspath("tmp-liaison-dir")
|
||||
os.mkdir(self.liaison_dir)
|
||||
|
||||
settings.LIAISON_ATTACH_PATH = self.liaison_dir
|
||||
|
||||
def tearDown(self):
|
||||
shutil.rmtree(self.liaison_dir)
|
||||
|
||||
def test_taken_care_of(self):
|
||||
make_test_data()
|
||||
liaison = make_liaison_models()
|
||||
|
@ -96,13 +106,44 @@ class LiaisonManagementTestCase(django.test.TestCase):
|
|||
self.assertEquals(len(q('form input[name=do_action_taken]')), 1)
|
||||
|
||||
# mark action taken
|
||||
r = self.client.post(url, dict(do_action_taken=1))
|
||||
r = self.client.post(url, dict(do_action_taken="1"))
|
||||
self.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertEquals(len(q('form input[name=do_action_taken]')), 0)
|
||||
liaison = LiaisonStatement.objects.get(id=liaison.id)
|
||||
self.assertTrue(liaison.action_taken)
|
||||
|
||||
def test_approval(self):
|
||||
make_test_data()
|
||||
liaison = make_liaison_models()
|
||||
# has to come from WG to need approval
|
||||
liaison.from_group = Group.objects.get(acronym="mars")
|
||||
liaison.approved = None
|
||||
liaison.save()
|
||||
|
||||
url = urlreverse('liaison_approval_detail', kwargs=dict(object_id=liaison.pk))
|
||||
# this liaison is for a WG so we need the AD for the area
|
||||
login_testing_unauthorized(self, "ad", url)
|
||||
|
||||
# normal get
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertEquals(len(q('form input[name=do_approval]')), 1)
|
||||
|
||||
# approve
|
||||
mailbox_before = len(mail_outbox)
|
||||
r = self.client.post(url, dict(do_approval="1"))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
liaison = LiaisonStatement.objects.get(id=liaison.id)
|
||||
self.assertTrue(liaison.approved)
|
||||
from django.core import mail
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
self.assertTrue("Liaison Statement" in mail.outbox[-1].subject)
|
||||
#self.assertEquals(len(mail_outbox), mailbox_before + 1)
|
||||
#self.assertTrue("Liaison Statement" in mail_outbox[-1]["Subject"])
|
||||
|
||||
def test_edit_liaison(self):
|
||||
make_test_data()
|
||||
liaison = make_liaison_models()
|
||||
|
@ -117,6 +158,9 @@ class LiaisonManagementTestCase(django.test.TestCase):
|
|||
self.assertEquals(len(q('form input[name=from_field]')), 1)
|
||||
|
||||
# edit
|
||||
attachments_before = liaison.attachments.count()
|
||||
test_file = StringIO("hello world")
|
||||
test_file.name = "unnamed"
|
||||
r = self.client.post(url,
|
||||
dict(from_field="from",
|
||||
replyto="replyto@example.com",
|
||||
|
@ -124,14 +168,17 @@ class LiaisonManagementTestCase(django.test.TestCase):
|
|||
to_poc="to_poc@example.com",
|
||||
response_contact="responce_contact@example.com",
|
||||
technical_contact="technical_contact@example.com",
|
||||
cc1="cc1@example.com",
|
||||
cc1="cc@example.com",
|
||||
purpose="4",
|
||||
deadline_date=(liaison.deadline + datetime.timedelta(days=1)).strftime("%Y-%m-%d"),
|
||||
title="title",
|
||||
submitted_date=(liaison.submitted + datetime.timedelta(days=1)).strftime("%Y-%m-%d"),
|
||||
body="body",
|
||||
attach_file_1=test_file,
|
||||
attach_title_1="attachment",
|
||||
))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
new_liaison = LiaisonStatement.objects.get(id=liaison.id)
|
||||
self.assertEquals(new_liaison.from_name, "from")
|
||||
self.assertEquals(new_liaison.reply_to, "replyto@example.com")
|
||||
|
@ -139,7 +186,7 @@ class LiaisonManagementTestCase(django.test.TestCase):
|
|||
self.assertEquals(new_liaison.to_contact, "to_poc@example.com")
|
||||
self.assertEquals(new_liaison.response_contact, "responce_contact@example.com")
|
||||
self.assertEquals(new_liaison.technical_contact, "technical_contact@example.com")
|
||||
self.assertEquals(new_liaison.cc, "cc1@example.com")
|
||||
self.assertEquals(new_liaison.cc, "cc@example.com")
|
||||
self.assertEquals(new_liaison.purpose, LiaisonStatementPurposeName.objects.get(order=4))
|
||||
self.assertEquals(new_liaison.deadline, liaison.deadline + datetime.timedelta(days=1)),
|
||||
self.assertEquals(new_liaison.title, "title")
|
||||
|
@ -147,7 +194,174 @@ class LiaisonManagementTestCase(django.test.TestCase):
|
|||
self.assertEquals(new_liaison.body, "body")
|
||||
self.assertTrue(new_liaison.modified > liaison.modified)
|
||||
|
||||
# test links and edit button
|
||||
self.assertEquals(new_liaison.attachments.count(), attachments_before + 1)
|
||||
attachment = new_liaison.attachments.order_by("-name")[0]
|
||||
self.assertEquals(attachment.title, "attachment")
|
||||
with open(os.path.join(self.liaison_dir, attachment.external_url)) as f:
|
||||
written_content = f.read()
|
||||
|
||||
test_file.seek(0)
|
||||
self.assertEquals(written_content, test_file.read())
|
||||
|
||||
def test_add_incoming_liaison(self):
|
||||
make_test_data()
|
||||
liaison = make_liaison_models()
|
||||
|
||||
url = urlreverse('add_liaison') + "?incoming=1"
|
||||
login_testing_unauthorized(self, "secretary", url)
|
||||
|
||||
# get
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertEquals(len(q('form textarea[name=body]')), 1)
|
||||
|
||||
# add new
|
||||
test_file = StringIO("hello world")
|
||||
test_file.name = "unnamed"
|
||||
from_group = Group.objects.filter(type="sdo")[0]
|
||||
to_group = Group.objects.get(acronym="mars")
|
||||
submitter = Person.objects.get(user__username="marschairman")
|
||||
today = datetime.date.today()
|
||||
related_liaison = liaison
|
||||
r = self.client.post(url,
|
||||
dict(from_field="%s_%s" % (from_group.type_id, from_group.pk),
|
||||
from_fake_user=str(submitter.pk),
|
||||
replyto="replyto@example.com",
|
||||
organization="%s_%s" % (to_group.type_id, to_group.pk),
|
||||
response_contact="responce_contact@example.com",
|
||||
technical_contact="technical_contact@example.com",
|
||||
cc1="cc@example.com",
|
||||
purpose="4",
|
||||
deadline_date=(today + datetime.timedelta(days=1)).strftime("%Y-%m-%d"),
|
||||
related_to=str(related_liaison.pk),
|
||||
title="title",
|
||||
submitted_date=today.strftime("%Y-%m-%d"),
|
||||
body="body",
|
||||
attach_file_1=test_file,
|
||||
attach_title_1="attachment",
|
||||
))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
l = LiaisonStatement.objects.all().order_by("-id")[0]
|
||||
self.assertEquals(l.from_group, from_group)
|
||||
self.assertEquals(l.from_contact, submitter.email_address())
|
||||
self.assertEquals(l.reply_to, "replyto@example.com")
|
||||
self.assertEquals(l.to_group, to_group)
|
||||
self.assertEquals(l.response_contact, "responce_contact@example.com")
|
||||
self.assertEquals(l.technical_contact, "technical_contact@example.com")
|
||||
self.assertEquals(l.cc, "cc@example.com")
|
||||
self.assertEquals(l.purpose, LiaisonStatementPurposeName.objects.get(order=4))
|
||||
self.assertEquals(l.deadline, today + datetime.timedelta(days=1)),
|
||||
self.assertEquals(l.related_to, liaison),
|
||||
self.assertEquals(l.title, "title")
|
||||
self.assertEquals(l.submitted.date(), today)
|
||||
self.assertEquals(l.body, "body")
|
||||
self.assertTrue(l.approved)
|
||||
|
||||
self.assertEquals(l.attachments.count(), 1)
|
||||
attachment = l.attachments.all()[0]
|
||||
self.assertEquals(attachment.title, "attachment")
|
||||
with open(os.path.join(self.liaison_dir, attachment.external_url)) as f:
|
||||
written_content = f.read()
|
||||
|
||||
test_file.seek(0)
|
||||
self.assertEquals(written_content, test_file.read())
|
||||
|
||||
def test_add_outgoing_liaison(self):
|
||||
make_test_data()
|
||||
liaison = make_liaison_models()
|
||||
|
||||
url = urlreverse('add_liaison')
|
||||
login_testing_unauthorized(self, "secretary", url)
|
||||
|
||||
# get
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertEquals(len(q('form textarea[name=body]')), 1)
|
||||
|
||||
# add new
|
||||
test_file = StringIO("hello world")
|
||||
test_file.name = "unnamed"
|
||||
from_group = Group.objects.get(acronym="mars")
|
||||
to_group = Group.objects.filter(type="sdo")[0]
|
||||
submitter = Person.objects.get(user__username="marschairman")
|
||||
today = datetime.date.today()
|
||||
related_liaison = liaison
|
||||
r = self.client.post(url,
|
||||
dict(from_field="%s_%s" % (from_group.type_id, from_group.pk),
|
||||
from_fake_user=str(submitter.pk),
|
||||
approved="",
|
||||
replyto="replyto@example.com",
|
||||
to_poc="to_poc@example.com",
|
||||
organization="%s_%s" % (to_group.type_id, to_group.pk),
|
||||
other_organization="",
|
||||
response_contact="responce_contact@example.com",
|
||||
technical_contact="technical_contact@example.com",
|
||||
cc1="cc@example.com",
|
||||
purpose="4",
|
||||
deadline_date=(today + datetime.timedelta(days=1)).strftime("%Y-%m-%d"),
|
||||
related_to=str(related_liaison.pk),
|
||||
title="title",
|
||||
submitted_date=today.strftime("%Y-%m-%d"),
|
||||
body="body",
|
||||
attach_file_1=test_file,
|
||||
attach_title_1="attachment",
|
||||
))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
l = LiaisonStatement.objects.all().order_by("-id")[0]
|
||||
self.assertEquals(l.from_group, from_group)
|
||||
self.assertEquals(l.from_contact, submitter.email_address())
|
||||
self.assertEquals(l.reply_to, "replyto@example.com")
|
||||
self.assertEquals(l.to_group, to_group)
|
||||
self.assertEquals(l.to_contact, "to_poc@example.com")
|
||||
self.assertEquals(l.response_contact, "responce_contact@example.com")
|
||||
self.assertEquals(l.technical_contact, "technical_contact@example.com")
|
||||
self.assertEquals(l.cc, "cc@example.com")
|
||||
self.assertEquals(l.purpose, LiaisonStatementPurposeName.objects.get(order=4))
|
||||
self.assertEquals(l.deadline, today + datetime.timedelta(days=1)),
|
||||
self.assertEquals(l.related_to, liaison),
|
||||
self.assertEquals(l.title, "title")
|
||||
self.assertEquals(l.submitted.date(), today)
|
||||
self.assertEquals(l.body, "body")
|
||||
self.assertTrue(not l.approved)
|
||||
|
||||
self.assertEquals(l.attachments.count(), 1)
|
||||
attachment = l.attachments.all()[0]
|
||||
self.assertEquals(attachment.title, "attachment")
|
||||
with open(os.path.join(self.liaison_dir, attachment.external_url)) as f:
|
||||
written_content = f.read()
|
||||
|
||||
test_file.seek(0)
|
||||
self.assertEquals(written_content, test_file.read())
|
||||
|
||||
# try adding statement to non-predefined organization
|
||||
r = self.client.post(url,
|
||||
dict(from_field="%s_%s" % (from_group.type_id, from_group.pk),
|
||||
from_fake_user=str(submitter.pk),
|
||||
approved="1",
|
||||
replyto="replyto@example.com",
|
||||
to_poc="to_poc@example.com",
|
||||
organization="othersdo",
|
||||
other_organization="Mars Institute",
|
||||
response_contact="responce_contact@example.com",
|
||||
technical_contact="technical_contact@example.com",
|
||||
cc1="cc@example.com",
|
||||
purpose="4",
|
||||
deadline_date=(today + datetime.timedelta(days=1)).strftime("%Y-%m-%d"),
|
||||
related_to=str(related_liaison.pk),
|
||||
title="new title",
|
||||
submitted_date=today.strftime("%Y-%m-%d"),
|
||||
body="body",
|
||||
))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
l = LiaisonStatement.objects.all().order_by("-id")[0]
|
||||
self.assertEquals(l.to_group, None)
|
||||
self.assertEquals(l.to_name, "Mars Institute")
|
||||
|
||||
|
||||
if not settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
# the above tests only work with the new schema
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
from redesign.group.models import Group, Role
|
||||
from redesign.person.models import Person
|
||||
from ietf.liaisons.proxy import proxy_personify_role
|
||||
|
||||
from ietf.liaisons.accounts import (is_ietfchair, is_iabchair, is_iab_executive_director,
|
||||
get_ietf_chair, get_iab_chair, get_iab_executive_director,
|
||||
is_secretariat)
|
||||
|
@ -9,10 +13,6 @@ IABCHAIR = {'name': u'The IAB Chair', 'address': u'iab-chair@iab.org'}
|
|||
IABEXECUTIVEDIRECTOR = {'name': u'The IAB Executive Director', 'address': u'execd@iab.org'}
|
||||
|
||||
|
||||
def get_all_sdo_managers():
|
||||
return list(Person.objects.filter(email__role__name="liaiman", email__role__group__state="active").distinct())
|
||||
|
||||
|
||||
class FakePerson(object):
|
||||
|
||||
def __init__(self, name, address):
|
||||
|
@ -28,15 +28,11 @@ class FakePerson(object):
|
|||
# schema) way - unfortunately, it's never been strong enough to do so
|
||||
# fine-grained enough so the form code also has some rules
|
||||
|
||||
def all_sdo_managers():
|
||||
return [proxy_personify_role(r) for r in Role.objects.filter(group__type="sdo", name="liaiman").select_related("email").distinct()]
|
||||
|
||||
def role_persons_with_fixed_email(group, role_name):
|
||||
from redesign.group.models import Role
|
||||
res = []
|
||||
for r in Role.objects.filter(group=group, name=role_name).select_related("email"):
|
||||
p = r.email.person
|
||||
# proxy hack to make email() return the right address
|
||||
p.email = (lambda name, address: (lambda: (name, address)))(p.name, r.email.address)
|
||||
res.append(p)
|
||||
return res
|
||||
return [proxy_personify_role(r) for r in Role.objects.filter(group=group, name=role_name).select_related("email").distinct()]
|
||||
|
||||
class Entity(object):
|
||||
|
||||
|
@ -94,7 +90,7 @@ class IETFEntity(Entity):
|
|||
return [self.poc]
|
||||
|
||||
def full_user_list(self):
|
||||
result = get_all_sdo_managers()
|
||||
result = all_sdo_managers()
|
||||
result.append(get_ietf_chair())
|
||||
return result
|
||||
|
||||
|
@ -123,7 +119,7 @@ class IABEntity(Entity):
|
|||
return [self.chair]
|
||||
|
||||
def full_user_list(self):
|
||||
result = get_all_sdo_managers()
|
||||
result = all_sdo_managers()
|
||||
result += [get_iab_chair(), get_iab_executive_director()]
|
||||
return result
|
||||
|
||||
|
@ -131,7 +127,7 @@ class IABEntity(Entity):
|
|||
class AreaEntity(Entity):
|
||||
|
||||
def get_poc(self):
|
||||
return [i.person for i in self.obj.areadirector_set.all()]
|
||||
return role_persons_with_fixed_email(self.obj, "ad")
|
||||
|
||||
def get_cc(self, person=None):
|
||||
return [FakePerson(**IETFCHAIR)]
|
||||
|
@ -151,7 +147,7 @@ class AreaEntity(Entity):
|
|||
return self.get_poc()
|
||||
|
||||
def full_user_list(self):
|
||||
result = get_all_sdo_managers()
|
||||
result = all_sdo_managers()
|
||||
result += self.get_poc()
|
||||
return result
|
||||
|
||||
|
@ -189,7 +185,7 @@ class WGEntity(Entity):
|
|||
return role_persons_with_fixed_email(self.obj.parent, "ad") if self.obj.parent else []
|
||||
|
||||
def full_user_list(self):
|
||||
result = get_all_sdo_managers()
|
||||
result = all_sdo_managers()
|
||||
result += self.get_poc()
|
||||
return result
|
||||
|
||||
|
@ -332,8 +328,7 @@ class WGEntityManager(EntityManager):
|
|||
return WGEntity(name=obj.group_acronym.name, obj=obj)
|
||||
|
||||
def can_send_on_behalf(self, person):
|
||||
wgs = set([i.group_acronym.pk for i in person.wgchair_set.all()])
|
||||
wgs = wgs.union([i.group_acronym.pk for i in person.wgsecretary_set.all()])
|
||||
wgs = Group.objects.filter(role__email__person=person, role__name__in=("chair", "secretary")).values_list('pk', flat=True)
|
||||
query_filter = {'pk__in': wgs}
|
||||
return self.get_managed_list(query_filter)
|
||||
|
||||
|
@ -347,7 +342,6 @@ class SDOEntityManager(EntityManager):
|
|||
def __init__(self, pk=None, name=None, queryset=None):
|
||||
super(SDOEntityManager, self).__init__(pk, name, queryset)
|
||||
if self.queryset == None:
|
||||
from redesign.group.models import Group
|
||||
self.queryset = Group.objects.filter(type="sdo")
|
||||
|
||||
def get_managed_list(self):
|
||||
|
|
|
@ -177,19 +177,26 @@ def liaison_approval_list(request):
|
|||
def liaison_approval_detail(request, object_id):
|
||||
person = get_person_for_user(request.user)
|
||||
approval_codes = IETFHM.get_all_can_approve_codes(person)
|
||||
to_approve = LiaisonDetail.objects.filter(approval__isnull=False, approval__approved=False, from_raw_code__in=approval_codes).order_by("-submitted_date")
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
to_approve = approvable_liaison_statements(approval_codes).order_by("-submitted")
|
||||
else:
|
||||
to_approve = LiaisonDetail.objects.filter(approval__isnull=False, approval__approved=False, from_raw_code__in=approval_codes).order_by("-submitted_date")
|
||||
|
||||
if request.method=='POST' and request.POST.get('do_approval', False):
|
||||
try:
|
||||
liaison = to_approve.get(pk=object_id)
|
||||
approval = liaison.approval
|
||||
if not approval:
|
||||
approval = OutgoingLiaisonApproval.objects.create(approved=True, approval_date=datetime.datetime.now())
|
||||
liaison.approval = approval
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
liaison.approved = datetime.datetime.now()
|
||||
liaison.save()
|
||||
else:
|
||||
approval.approved=True
|
||||
approval.save()
|
||||
approval = liaison.approval
|
||||
if not approval:
|
||||
approval = OutgoingLiaisonApproval.objects.create(approved=True, approval_date=datetime.datetime.now())
|
||||
liaison.approval = approval
|
||||
liaison.save()
|
||||
else:
|
||||
approval.approved=True
|
||||
approval.save()
|
||||
if not settings.DEBUG:
|
||||
liaison.send_by_email()
|
||||
else:
|
||||
|
|
|
@ -14,7 +14,7 @@ Purpose: {% if liaison.purpose_text %}{{ liaison.purpose_text }}{% else %}{{ lia
|
|||
Body: {{ liaison.body }}
|
||||
Attachment(s):
|
||||
{% for file in liaison.uploads_set.all %}
|
||||
{{ file.file_title }} https://datatracker.ietf.org/documents/LIAISON/file{{ file.file_id }}{{ file.file_extension }}
|
||||
{{ file.file_title }} https://datatracker.ietf.org/documents/LIAISON/file{{ file.filename }}
|
||||
{% empty %}
|
||||
No document has been attached
|
||||
{% endfor %}
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
{% autoescape off %}Title: {{ liaison.title }}
|
||||
Submission Date: {{ liaison.submitted_date }}
|
||||
URL of the IETF Web page: {% url liaison_detail object_id=liaison.pk %}
|
||||
URL of the IETF Web page: {{ url }}
|
||||
{% if liaison.deadline_date %}Please reply by {{ liaison.deadline_date }}{% endif %}
|
||||
From: {{ liaison.from_body }} ({{ liaison.person }} <{{ liaison.replyto|default:liaison.from_email }}>)
|
||||
To: {{ liaison.to_body }} ({{ liaison.to_poc }})
|
||||
Cc: {{ liaison.cc1 }}
|
||||
Reponse Contact: {{ liaison.response_contact }}
|
||||
Technical Contact: {{ liaison.technical_contact }}
|
||||
Purpose: {% if liaison.purpose_text %}{{ liaison.purpose_text }}{% else %}{{ liaison.purpose.purpose_text }}{% endif %}
|
||||
Purpose: {% if liaison.purpose_text %}{{ liaison.purpose_text }}{% else %}{{ liaison.purpose }}{% endif %}
|
||||
{% if liaison.related_to %}Referenced liaison: {% if liaison.related_to.title %}{{ liaison.related_to.title }}{% else %}Liaison #{{ liaison.related_to.pk }}{% endif %} ({% url liaison_detail object_id=liaison.related_to.pk %}){% endif %}
|
||||
Body: {{ liaison.body }}
|
||||
Attachment(s):
|
||||
Attachments:
|
||||
{% for file in liaison.uploads_set.all %}
|
||||
{{ file.file_title }} https://datatracker.ietf.org/documents/LIAISON/file{{ file.file_id }}{{ file.file_extension }}
|
||||
{{ file.file_title }} https://datatracker.ietf.org/documents/LIAISON/{{ file.filename }}
|
||||
{% empty %}
|
||||
No document has been attached
|
||||
{% endfor %}
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
<td>
|
||||
{% if liaison.by_secretariat %}
|
||||
{% for file in liaison.uploads_set.all %}
|
||||
<a href="https://datatracker.ietf.org/documents/LIAISON/file{{ file.file_id }}{{ file.file_extension }}">{{ file.file_title|escape }}</a><br/>
|
||||
<a href="https://datatracker.ietf.org/documents/LIAISON/{{ file.filename }}">{{ file.file_title|escape }}</a><br/>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<a href="{{ liaison.detail_id }}/">{{ liaison.title|escape }}</a>
|
||||
|
|
|
@ -2,22 +2,22 @@ The following liaison statement will remain pending (and not public available) i
|
|||
{% load ietf_filters %}{% autoescape off %}
|
||||
Title: {{ liaison.title|clean_whitespace }}
|
||||
Submission Date: {{ liaison.submitted_date }}
|
||||
URL of the IETF Web page: {% url liaison_approval_detail liaison.pk %}
|
||||
URL of the IETF Web page: {{ url }}
|
||||
{% if liaison.deadline_date %}Please reply by {{ liaison.deadline_date }}{% endif %}
|
||||
From: {{ liaison.from_body }} ({{ liaison.person }} <{{ liaison.replyto|default:liaison.from_email }}>)
|
||||
To: {{ liaison.to_body }} ({{ liaison.to_poc }})
|
||||
Cc: {{ liaison.cc1 }}
|
||||
Reponse Contact: {{ liaison.response_contact }}
|
||||
Technical Contact: {{ liaison.technical_contact }}
|
||||
Purpose: {% if liaison.purpose_text %}{{ liaison.purpose_text }}{% else %}{{ liaison.purpose.purpose_text }}{% endif %}
|
||||
Purpose: {% if liaison.purpose_text %}{{ liaison.purpose_text }}{% else %}{{ liaison.purpose }}{% endif %}
|
||||
{% if liaison.related_to %}Referenced liaison: {% if liaison.related_to.title %}{{ liaison.related_to.title }}{% else %}Liaison #{{ liaison.related_to.pk }}{% endif %} ({% url liaison_detail object_id=liaison.related_to.pk %}){% endif %}
|
||||
Body: {{ liaison.body }}
|
||||
Attachment(s):
|
||||
Attachments:
|
||||
{% for file in liaison.uploads_set.all %}
|
||||
{{ file.file_title }} https://datatracker.ietf.org/documents/LIAISON/file{{ file.file_id }}{{ file.file_extension }}
|
||||
{{ file.file_title }} https://datatracker.ietf.org/documents/LIAISON/{{ file.filename }}
|
||||
{% empty %}
|
||||
No document has been attached
|
||||
{% endfor %}
|
||||
{% endautoescape %}
|
||||
|
||||
Please visit {% url liaison_approval_detail liaison.pk %} in order to approve the liaison statement.
|
||||
Please visit {{ approve_url }} in order to approve the liaison statement.
|
||||
|
|
|
@ -76,9 +76,11 @@ def make_test_data():
|
|||
email=email)
|
||||
|
||||
# group chair
|
||||
u = User.objects.create(username="marschairman")
|
||||
p = Person.objects.create(
|
||||
name="WG Chair Man",
|
||||
ascii="WG Chair Man",
|
||||
user=u
|
||||
)
|
||||
wgchair = Email.objects.create(
|
||||
address="wgchairman@ietf.org",
|
||||
|
|
|
@ -17,7 +17,7 @@ class Acronym(Group):
|
|||
#acronym_id = models.AutoField(primary_key=True)
|
||||
@property
|
||||
def acronym_id(self):
|
||||
raise NotImplemented
|
||||
return self.id
|
||||
#acronym = models.CharField(max_length=12) # same name
|
||||
#name = models.CharField(max_length=100) # same name
|
||||
#name_key = models.CharField(max_length=50, editable=False)
|
||||
|
|
|
@ -83,9 +83,11 @@ def get_body(name, raw_code):
|
|||
t = raw_code.split("_")
|
||||
if len(t) == 2:
|
||||
if t[0] == "area":
|
||||
b = lookup_group(acronym=Acronym.objects.get(pk=t[1]), type="area")
|
||||
elif t[0] == "group":
|
||||
b = lookup_group(acronym=Acronym.objects.get(pk=t[1]), type="wg")
|
||||
b = lookup_group(acronym=Acronym.objects.get(pk=t[1]).acronym, type="area")
|
||||
elif t[0] == "wg":
|
||||
b = lookup_group(acronym=Acronym.objects.get(pk=t[1]).acronym, type="wg")
|
||||
elif t[0] == "sdo":
|
||||
b = lookup_group(name=SDOs.objects.get(pk=t[1]).name, type="sdo")
|
||||
|
||||
if not b:
|
||||
b = lookup_group(acronym=raw_code)
|
||||
|
@ -190,7 +192,7 @@ for o in LiaisonDetail.objects.all().order_by("pk"):
|
|||
attachment.name = l.name() + ("-attachment-%s" % (i + 1))
|
||||
attachment.time = l.submitted
|
||||
# we should fixup the filenames, but meanwhile, store it here
|
||||
attachment.external_url = "%s%s" % (u.file_id, u.file_extension)
|
||||
attachment.external_url = "file%s%s" % (u.file_id, u.file_extension)
|
||||
attachment.save()
|
||||
|
||||
DocAlias.objects.get_or_create(document=attachment, name=attachment.name)
|
||||
|
|
Loading…
Reference in a new issue