Add proxy for LiaisonDetail, start porting the view code utils, import various liaison roles and rename a couple of fields on LiaisonStatement to try to make them more self-explanatory

- Legacy-Id: 3321
This commit is contained in:
Ole Laursen 2011-08-17 17:44:40 +00:00
parent 49fb2a7fe7
commit 4a36338031
13 changed files with 896 additions and 65 deletions

View file

@ -1,3 +1,5 @@
from django.conf import settings
from ietf.idtracker.models import Role, PersonOrOrgInfo
@ -141,3 +143,6 @@ def can_edit_liaison(user, liaison):
return (is_sdo_manager_for_outgoing_liaison(person, liaison) or
is_sdo_manager_for_incoming_liaison(person, liaison))
return False
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
from accountsREDESIGN import *

View file

@ -0,0 +1,121 @@
from redesign.person.models import Person
from redesign.group.models import Role
LIAISON_EDIT_GROUPS = ['Secretariat']
def get_ietf_chair():
try:
return Person.objects.get(email__role__name="chair", email__role__group__acronym="ietf")
except Person.DoesNotExist:
return None
def get_iesg_chair():
return get_ietf_chair()
def get_iab_chair():
try:
return Person.objects.get(email__role__name="chair", email__role__group__acronym="iab")
except Person.DoesNotExist:
return None
def get_iab_executive_director():
try:
return Person.objects.get(email__role__name="execdir", email__role__group__acronym="iab")
except Person.DoesNotExist:
return None
def get_person_for_user(user):
return user.get_profile()
def is_areadirector(person):
return bool(Role.objects.filter(email__person=person, name="ad", group__state="active", group__type="area"))
def is_wgchair(person):
return bool(Role.objects.filter(email__person=person, name="chair", group__state="active", group__type="wg"))
def is_wgsecretary(person):
return bool(Role.objects.filter(email__person=person, name="sec", group__state="active", group__type="wg"))
def is_ietfchair(person):
return bool(Role.objects.filter(email__person=person, name="chair", group__acronym="ietf"))
def is_iabchair(person):
return bool(Role.objects.filter(email__person=person, name="chair", group__acronym="iab"))
def is_iab_executive_director(person):
return bool(Role.objects.filter(email__person=person, name="execdir", group__acronym="iab"))
def can_add_outgoing_liaison(user):
person = get_person_for_user(user)
if not person:
return False
if (is_areadirector(person) or is_wgchair(person) or
is_wgsecretary(person) or is_ietfchair(person) or
is_iabchair(person) or is_iab_executive_director(person) or
is_sdo_liaison_manager(person) or is_secretariat(user)):
return True
return False
def is_sdo_liaison_manager(person):
return bool(Role.objects.filter(email__person=person, name="liaiman", group__type="sdo"))
def is_sdo_authorized_individual(person):
return bool(Role.objects.filter(email__person=person, name="auth", group__type="sdo"))
def is_secretariat(user):
return bool(Role.objects.filter(email__person=user.get_profile(), name="auth", group__acronym="secretariat"))
def can_add_incoming_liaison(user):
person = get_person_for_user(user)
if not person:
return False
if (is_sdo_liaison_manager(person) or
is_sdo_authorized_individual(person) or
is_secretariat(user)):
return True
return False
def can_add_liaison(user):
return can_add_incoming_liaison(user) or can_add_outgoing_liaison(user)
def is_sdo_manager_for_outgoing_liaison(person, liaison):
if liaison.from_group and liaison.from_group.type_id == "sdo":
return bool(liaison.from_group.role_set.filter(name="liaiman", email__person=person))
return False
def is_sdo_manager_for_incoming_liaison(person, liaison):
if liaison.to_group and liaison.to_group.type_id == "sdo":
return bool(liaison.to_group.role_set.filter(name="liaiman", email__person=person))
return False
def can_edit_liaison(user, liaison):
if is_secretariat(user):
return True
person = get_person_for_user(user)
if is_sdo_liaison_manager(person):
return (is_sdo_manager_for_outgoing_liaison(person, liaison) or
is_sdo_manager_for_incoming_liaison(person, liaison))
return False

View file

@ -30,12 +30,14 @@ class LiaisonDetailAdmin(admin.ModelAdmin):
# 'response_contact', 'technical_contact', 'purpose', 'purpose_text', 'deadline_date', 'action_taken',
# 'related_to')
raw_id_fields=['person', 'related_to']
admin.site.register(LiaisonDetail, LiaisonDetailAdmin)
if not settings.USE_DB_REDESIGN_PROXY_CLASSES:
admin.site.register(LiaisonDetail, LiaisonDetailAdmin)
class LiaisonPurposeAdmin(admin.ModelAdmin):
ordering = ('purpose_text', )
admin.site.register(LiaisonPurpose, LiaisonPurposeAdmin)
if not settings.USE_DB_REDESIGN_PROXY_CLASSES:
admin.site.register(LiaisonPurpose, LiaisonPurposeAdmin)
class LiaisonManagersAdmin(admin.ModelAdmin):

View file

@ -308,7 +308,8 @@ class Uploads(models.Model):
if settings.USE_DB_REDESIGN_PROXY_CLASSES or hasattr(settings, "IMPORTING_FROM_OLD_SCHEMA"):
from redesign.name.models import LiaisonStatementPurposeName
from redesign.person.models import Person
from redesign.doc.models import Document
from redesign.person.models import Email
from redesign.group.models import Group
class LiaisonStatement(models.Model):
@ -317,13 +318,14 @@ if settings.USE_DB_REDESIGN_PROXY_CLASSES or hasattr(settings, "IMPORTING_FROM_O
body = models.TextField(blank=True)
deadline = models.DateField(null=True, blank=True)
related_to = models.ForeignKey('LiaisonDetail', blank=True, null=True)
related_to = models.ForeignKey('LiaisonStatement', blank=True, null=True)
from_body = 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="From body, if it exists")
from_name = models.CharField(max_length=255, help_text="Name of the sender body")
to_body = models.ForeignKey(Group, related_name="liaisonstatement_to_set", null=True, blank=True, help_text="to body, if it exists")
from_contact = models.ForeignKey(Email)
to_group = models.ForeignKey(Group, related_name="liaisonstatement_to_set", null=True, blank=True, help_text="To body, 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)
to_contact = models.CharField(blank=True, max_length=255, help_text="Contacts at to body")
reply_to = models.CharField(blank=True, max_length=255)
@ -332,14 +334,26 @@ if settings.USE_DB_REDESIGN_PROXY_CLASSES or hasattr(settings, "IMPORTING_FROM_O
cc = models.TextField(blank=True)
submitted = models.DateTimeField(null=True, blank=True)
submitted_by = models.ForeignKey(Person)
modified = models.DateTimeField(null=True, blank=True)
approved = models.DateTimeField(null=True, blank=True)
action_taken = models.BooleanField(default=False)
#submitter_name = models.CharField(blank=True, null=True, max_length=255)
#submitter_email = models.CharField(blank=True, null=True, max_length=255)
attachments = models.ManyToManyField(Document, blank=True)
def name(self):
from django.template.defaultfilters import slugify
if self.from_group:
frm = self.from_group.acronym or self.from_group.name
else:
frm = self.from_name
if self.to_group:
to = self.to_group.acronym or self.to_group.name
else:
to = self.to_name
return slugify("liaison" + " " + self.submitted.strftime("%Y-%m-%d") + " " + frm[:50] + " " + to[:50] + " " + self.title[:115])
def __unicode__(self):
return self.title or "<no title>"
LiaisonDetailOld = LiaisonDetail

152
ietf/liaisons/proxy.py Normal file
View file

@ -0,0 +1,152 @@
from redesign.proxy_utils import TranslatingManager
from ietf.liaisons.models import LiaisonStatement
class LiaisonDetailProxy(LiaisonStatement):
objects = TranslatingManager(dict(meeting_num="number"))
def from_object(self, base):
for f in base._meta.fields:
setattr(self, f.name, getattr(base, f.name))
return self
#detail_id = models.AutoField(primary_key=True)
@property
def detail_id(self):
return self.id
#person = models.ForeignKey(PersonOrOrgInfo, null=True, db_column='person_or_org_tag')
@property
def person(self):
return self.submitted_by
#submitted_date = models.DateField(null=True, blank=True)
@property
def submitted_date(self):
return self.submitted.date()
#last_modified_date = models.DateField(null=True, blank=True)
@property
def last_modified_date(self):
return self.modified.date()
#from_id = models.IntegerField(null=True, blank=True)
@property
def from_id(self):
return self.from_group_id
#to_body = models.CharField(blank=True, null=True, max_length=255)
@property
def to_body(self):
return self.to_name
#title = models.CharField(blank=True, null=True, max_length=255) # same name
#response_contact = models.CharField(blank=True, null=True, max_length=255) # same name
#technical_contact = models.CharField(blank=True, null=True, max_length=255) # same name
#purpose_text = models.TextField(blank=True, null=True, db_column='purpose')
@property
def purpose_text(self):
return ""
#body = models.TextField(blank=True,null=True) # same name
#deadline_date = models.DateField(null=True, blank=True)
@property
def deadline_date(self):
return self.deadline.date()
#cc1 = models.TextField(blank=True, null=True)
@property
def cc1(self):
return self.cc
#cc2 = models.CharField(blank=True, null=True, max_length=50) # unused
#submitter_name = models.CharField(blank=True, null=True, max_length=255)
#submitter_email = models.CharField(blank=True, null=True, max_length=255)
#by_secretariat = models.IntegerField(null=True, blank=True)
@property
def by_secretariat(self):
return False
#to_poc = models.CharField(blank=True, null=True, max_length=255)
@property
def to_poc(self):
return self.to_contact
#to_email = models.CharField(blank=True, null=True, max_length=255) # unused
#purpose = models.ForeignKey(LiaisonPurpose,null=True)
#replyto = models.CharField(blank=True, null=True, max_length=255)
@property
def replyto(self):
return self.reply_to
#from_raw_body = models.CharField(blank=True, null=True, max_length=255)
@property
def from_raw_body(self):
return self.from_name
#from_raw_code = models.CharField(blank=True, null=True, max_length=255)
@property
def from_raw_code(self):
return self.from_group_id
#to_raw_code = models.CharField(blank=True, null=True, max_length=255)
@property
def to_raw_code(self):
return self.to_body_id
#approval = models.ForeignKey(OutgoingLiaisonApproval, blank=True, null=True)
@property
def approval(self):
return bool(self.approved)
#action_taken = models.BooleanField(default=False, db_column='taken_care') # same name
#related_to = models.ForeignKey('LiaisonDetail', blank=True, null=True) # same name
def __str__(self):
return unicode(self)
def __unicode__(self):
return self.title or "<no title>"
def from_body(self):
return self.from_name
def from_sdo(self):
return self.from_group if self.from_group and self.from_group.type_id == "sdo" else None
def from_email(self):
self.from_contact
def get_absolute_url(self):
return '/liaison/%d/' % self.detail_id
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
def is_pending(self):
return not self.approved

View file

@ -1,3 +1,5 @@
from django.conf import settings
from ietf.idtracker.models import Area, IETFWG
from ietf.liaisons.models import SDOs, LiaisonManagers
from ietf.liaisons.accounts import (is_ietfchair, is_iabchair, is_iab_executive_director,
@ -420,3 +422,6 @@ class IETFHierarchyManager(object):
IETFHM = IETFHierarchyManager()
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
from utilsREDESIGN import *

View file

@ -0,0 +1,432 @@
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)
IETFCHAIR = {'name': u'The IETF Chair', 'address': u'chair@ietf.org'}
IESG = {'name': u'The IESG', 'address': u'iesg@ietf.org'}
IAB = {'name': u'The IAB', 'address': u'iab@iab.org'}
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):
self.name = name
self.address = address
def email(self):
return (self.name, self.address)
# the following is a biggish object hierarchy modeling the entity
# names and auth rules for posting liaison statements in a sort of
# semi-declarational way
def role_persons_with_fixed_email(group, role_name):
res = []
for r in Role.objects.filter(group=group, name=role_name).select_related("email"):
p = r.email.person
# evil hack to make email() return the right address
p.email = (lambda email: (lambda x: (x.name, email.address)))(r.email)
res.append(p)
return res
class Entity(object):
poc = []
cc = []
def __init__(self, name, obj=None):
self.name = name
self.obj = obj
def get_poc(self):
if not isinstance(self.poc, list):
return [self.poc]
return self.poc
def get_cc(self, person=None):
if not isinstance(self.cc, list):
return [self.cc]
return self.cc
def get_from_cc(self, person=None):
return []
def needs_approval(self, person=None):
return False
def can_approve(self):
return []
def post_only(self, person, user):
return False
def full_user_list(self):
return False
class IETFEntity(Entity):
poc = FakePerson(**IETFCHAIR)
cc = FakePerson(**IESG)
def get_from_cc(self, person):
result = []
if not is_ietfchair(person):
result.append(self.poc)
result.append(self.cc)
return result
def needs_approval(self, person=None):
if is_ietfchair(person):
return False
return True
def can_approve(self):
return [self.poc]
def full_user_list(self):
result = get_all_sdo_managers()
result.append(get_ietf_chair())
return result
class IABEntity(Entity):
chair = FakePerson(**IABCHAIR)
director = FakePerson(**IABEXECUTIVEDIRECTOR)
poc = [chair, director]
cc = FakePerson(**IAB)
def get_from_cc(self, person):
result = []
if not is_iabchair(person):
result.append(self.chair)
result.append(self.cc)
if not is_iab_executive_director(person):
result.append(self.director)
return result
def needs_approval(self, person=None):
if is_iabchair(person) or is_iab_executive_director(person):
return False
return True
def can_approve(self):
return [self.chair]
def full_user_list(self):
result = get_all_sdo_managers()
result += [get_iab_chair(), get_iab_executive_director()]
return result
class AreaEntity(Entity):
def get_poc(self):
return [i.person for i in self.obj.areadirector_set.all()]
def get_cc(self, person=None):
return [FakePerson(**IETFCHAIR)]
def get_from_cc(self, person):
result = [p for p in role_persons_with_fixed_email(self.obj, "ad") if p != person]
result.append(FakePerson(**IETFCHAIR))
return result
def needs_approval(self, person=None):
# Check if person is an area director
if self.obj.role_set.filter(email__person=person, name="ad"):
return False
return True
def can_approve(self):
return self.get_poc()
def full_user_list(self):
result = get_all_sdo_managers()
result += self.get_poc()
return result
class WGEntity(Entity):
def get_poc(self):
return role_persons_with_fixed_email(self.obj, "chair")
def get_cc(self, person=None):
if self.obj.parent:
result = [p for p in role_persons_with_fixed_email(self.obj.parent, "ad") if p != person]
else:
result = []
if self.obj.list_subscribe:
result.append(FakePerson(name ='%s Discussion List' % self.obj.name,
address = self.obj.list_subscribe))
return result
def get_from_cc(self, person):
result = [p for p in role_persons_with_fixed_email(self.obj, "chair") if p != person]
result += role_persons_with_fixed_email(self.obj.parent, "ad") if self.obj.parent else []
if self.obj.list_subscribe:
result.append(FakePerson(name ='%s Discussion List' % self.obj.name,
address = self.obj.list_subscribe))
return result
def needs_approval(self, person=None):
# Check if person is director of this wg area
if self.obj.parent and self.obj.parent.role_set.filter(email__person=person, name="ad"):
return False
return True
def can_approve(self):
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 += self.get_poc()
return result
class SDOEntity(Entity):
def get_poc(self):
return []
def get_cc(self, person=None):
return role_persons_with_fixed_email(self.obj, "liaiman")
def get_from_cc(self, person=None):
return [p for p in role_persons_with_fixed_email(self.obj, "liaiman") if p != person]
def post_only(self, person, user):
if is_secretariat(user) or self.obj.role_set.filter(email__person=person, name="auth"):
return False
return True
def full_user_list(self):
result = role_persons_with_fixed_email(self.obj, "liaiman")
result += role_persons_with_fixed_email(self.obj, "auth")
return result
class EntityManager(object):
def __init__(self, pk=None, name=None, queryset=None):
self.pk = pk
self.name = name
self.queryset = queryset
def get_entity(self, pk=None):
return Entity(name=self.name)
def get_managed_list(self):
return [(self.pk, self.name)]
def can_send_on_behalf(self, person):
return []
def can_approve_list(self, person):
return []
class IETFEntityManager(EntityManager):
def __init__(self, *args, **kwargs):
super(IETFEntityManager, self).__init__(*args, **kwargs)
self.entity = IETFEntity(name=self.name)
def get_entity(self, pk=None):
return self.entity
def can_send_on_behalf(self, person):
if is_ietfchair(person):
return self.get_managed_list()
return []
def can_approve_list(self, person):
if is_ietfchair(person):
return self.get_managed_list()
return []
class IABEntityManager(EntityManager):
def __init__(self, *args, **kwargs):
super(IABEntityManager, self).__init__(*args, **kwargs)
self.entity = IABEntity(name=self.name)
def get_entity(self, pk=None):
return self.entity
def can_send_on_behalf(self, person):
if (is_iabchair(person) or
is_iab_executive_director(person)):
return self.get_managed_list()
return []
def can_approve_list(self, person):
if (is_iabchair(person) or
is_iab_executive_director(person)):
return self.get_managed_list()
return []
class AreaEntityManager(EntityManager):
def __init__(self, pk=None, name=None, queryset=None):
super(AreaEntityManager, self).__init__(pk, name, queryset)
from redesign.group.proxy import Area
if self.queryset == None:
self.queryset = Area.active_areas()
def get_managed_list(self, query_filter=None):
if not query_filter:
query_filter = {}
return [(u'%s_%s' % (self.pk, i.pk), i.area_acronym.name) for i in self.queryset.filter(**query_filter).order_by('area_acronym__name')]
def get_entity(self, pk=None):
if not pk:
return None
try:
obj = self.queryset.get(pk=pk)
except self.queryset.model.DoesNotExist:
return None
return AreaEntity(name=obj.area_acronym.name, obj=obj)
def can_send_on_behalf(self, person):
query_filter = dict(role__email__person=person, role__name="ad")
return self.get_managed_list(query_filter)
def can_approve_list(self, person):
query_filter = dict(role__email__person=person, role__name="ad")
return self.get_managed_list(query_filter)
class WGEntityManager(EntityManager):
def __init__(self, pk=None, name=None, queryset=None):
super(WGEntityManager, self).__init__(pk, name, queryset)
if self.queryset == None:
from redesign.group.proxy import IETFWG, Area
self.queryset = IETFWG.objects.filter(group_type=1, status=IETFWG.ACTIVE, areagroup__area__status=Area.ACTIVE)
def get_managed_list(self, query_filter=None):
if not query_filter:
query_filter = {}
return [(u'%s_%s' % (self.pk, i.pk), '%s - %s' % (i.group_acronym.acronym, i.group_acronym.name)) for i in self.queryset.filter(**query_filter).order_by('group_acronym__acronym')]
def get_entity(self, pk=None):
if not pk:
return None
try:
obj = self.queryset.get(pk=pk)
except self.queryset.model.DoesNotExist:
return None
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()])
query_filter = {'pk__in': wgs}
return self.get_managed_list(query_filter)
def can_approve_list(self, person):
query_filter = dict(parent__role__email__person=person, parent__role__name="ad")
return self.get_managed_list(query_filter)
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):
return [(u'%s_%s' % (self.pk, i.pk), i.name) for i in self.queryset.order_by('name')]
def get_entity(self, pk=None):
if not pk:
return None
try:
obj = self.queryset.get(pk=pk)
except self.queryset.model.DoesNotExist:
return None
return SDOEntity(name=obj.name, obj=obj)
class IETFHierarchyManager(object):
def __init__(self):
self.managers = {'ietf': IETFEntityManager(pk='ietf', name=u'The IETF'),
'iesg': IETFEntityManager(pk='iesg', name=u'The IESG'),
'iab': IABEntityManager(pk='iab', name=u'The IAB'),
'area': AreaEntityManager(pk='area', name=u'IETF Areas'),
'wg': WGEntityManager(pk='wg', name=u'IETF Working Groups'),
'sdo': SDOEntityManager(pk='sdo', name=u'Standards Development Organizations'),
'othersdo': EntityManager(pk='othersdo', name=u'Other SDOs'),
}
def get_entity_by_key(self, entity_id):
if not entity_id:
return None
id_list = entity_id.split('_', 1)
key = id_list[0]
pk = None
if len(id_list)==2:
pk = id_list[1]
if key not in self.managers.keys():
return None
return self.managers[key].get_entity(pk)
def get_all_entities(self):
entities = []
for manager in self.managers.values():
entities += manager.get_managed_list()
return entities
def get_all_incoming_entities(self):
entities = []
results = []
for key in ['ietf', 'iesg', 'iab']:
results += self.managers[key].get_managed_list()
entities.append(('Main IETF Entities', results))
entities.append(('IETF Areas', self.managers['area'].get_managed_list()))
entities.append(('IETF Working Groups', self.managers['wg'].get_managed_list()))
return entities
def get_all_outgoing_entities(self):
entities = [(self.managers['sdo'].name, self.managers['sdo'].get_managed_list())]
entities += [(self.managers['othersdo'].name, self.managers['othersdo'].get_managed_list())]
return entities
def get_entities_for_person(self, person):
entities = []
results = []
for key in ['ietf', 'iesg', 'iab']:
results += self.managers[key].can_send_on_behalf(person)
if results:
entities.append(('Main IETF Entities', results))
areas = self.managers['area'].can_send_on_behalf(person)
if areas:
entities.append(('IETF Areas', areas))
wgs = self.managers['wg'].can_send_on_behalf(person)
if wgs:
entities.append(('IETF Working Groups', wgs))
return entities
def get_all_can_approve_codes(self, person):
entities = []
for key in ['ietf', 'iesg', 'iab']:
entities += self.managers[key].can_approve_list(person)
entities += self.managers['area'].can_approve_list(person)
entities += self.managers['wg'].can_approve_list(person)
return [i[0] for i in entities]
IETFHM = IETFHierarchyManager()

View file

@ -36,6 +36,7 @@ class Acronym(Group):
class Area(Group):
objects = TranslatingManager(dict(area_acronym__acronym="acronym",
area_acronym__name="name",
status=lambda v: ("state", {1: "active", 2: "dormant", 3: "conclude"}[v] )),
always_filter=dict(type="area"))
@ -67,6 +68,10 @@ class Area(Group):
# return AreaWGURL.objects.filter(name=self.area_acronym.name)
def active_wgs(self):
return IETFWG.objects.filter(type="wg", state="active", parent=self).select_related('type', 'state', 'parent').order_by("acronym")
@property
def areadirector_set(self):
return proxied_role_emails(Email.objects.filter(role__group=self, role__name="ad"))
@staticmethod
def active_areas():

View file

@ -106,6 +106,34 @@ for o in ChairsHistory.objects.filter(chair_type=Role.NOMCOM_CHAIR).order_by("st
e.desc = e.get_type_display()
e.save()
# IRTF
for o in IRTF.objects.all():
print "importing IRTF", o.pk, o.acronym
try:
group = Group.objects.get(acronym=o.acronym.lower())
except Group.DoesNotExist:
group = Group(acronym=o.acronym.lower())
group.name = o.name
group.state = state_names["active"] # we assume all to be active
group.type = type_names["rg"]
group.parent = irtf_group
group.comments = o.charter_text or ""
group.save()
# FIXME: missing fields from old: meeting_scheduled
# SDOs
for o in SDOs.objects.all().order_by("pk"):
# we import SDOs as groups, this makes it easy to take advantage
# of the rest of the role/person models for authentication and
# authorization
print "importing SDOs", o.pk, o.sdo_name
Group.objects.get_or_create(name=o.sdo_name, type=type_names["sdo"])
# Area
for o in Area.objects.all():
print "importing Area", o.pk, o.area_acronym.acronym
@ -153,26 +181,6 @@ for o in Area.objects.all():
# FIXME: missing fields from old: extra_email_addresses
# IRTF
for o in IRTF.objects.all():
print "importing IRTF", o.pk, o.acronym
try:
group = Group.objects.get(acronym=o.acronym.lower())
except Group.DoesNotExist:
group = Group(acronym=o.acronym.lower())
group.name = o.name
group.state = state_names["active"] # we assume all to be active
group.type = type_names["rg"]
group.parent = irtf_group
group.comments = o.charter_text or ""
group.save()
# FIXME: missing fields from old: meeting_scheduled
# IETFWG, AreaGroup
for o in IETFWG.objects.all().order_by("pk"):
print "importing IETFWG", o.pk, o.group_acronym.acronym
@ -286,11 +294,3 @@ for o in IETFWG.objects.all().order_by("pk"):
# FIXME: missing fields from old: meeting_scheduled, email_keyword, meeting_scheduled_old
# SDOs
for o in SDOs.objects.all().order_by("pk"):
# we import SDOs as groups, this makes it easy to take advantage
# of the rest of the role/person models for authentication and
# authorization
print "importing SDOs", o.pk, o.sdo_name
Group.objects.get_or_create(name=o.sdo_name, type=type_names["sdo"])

42
redesign/importing/import-liaison.py Normal file → Executable file
View file

@ -14,10 +14,11 @@ management.setup_environ(settings)
from django.template.defaultfilters import slugify
from ietf.idtracker.models import AreaDirector, IETFWG, Acronym, IRTF
from ietf.idtracker.models import Acronym, EmailAddress
from ietf.liaisons.models import *
from redesign.doc.models import Document, DocAlias
from redesign.person.models import *
from redesign.importing.utils import get_or_create_email, old_person_to_person
from redesign.importing.utils import old_person_to_person
from redesign.name.models import *
from redesign.name.utils import name
@ -38,9 +39,11 @@ purpose_mapping = {
5: name(LiaisonStatementPurposeName, "other", "Other"),
}
liaison_attachment_doctype = name(DocTypeName, "liai-att", "Liaison Attachment")
purpose_mapping[None] = purpose_mapping[3] # map unknown to "For information"
system_person = Person.objects.get(name="(System)")
system_email = Email.objects.get(person__name="(System)")
obviously_bogus_date = datetime.date(1970, 1, 1)
bodies = {
@ -140,7 +143,14 @@ for o in LiaisonDetail.objects.all().order_by("pk"):
return None
l.from_name = o.from_body().strip()
l.from_body = get_body(l.from_name, o.from_raw_code) # try to establish link
l.from_group = get_body(l.from_name, o.from_raw_code) # try to establish link
if not o.person:
l.from_contact = system_email
else:
try:
l.from_contact = Email.objects.get(address__iexact=o.from_email().address)
except EmailAddress.DoesNotExist:
l.from_contact = old_person_to_person(o.person).email_address()
if o.by_secretariat:
l.to_name = o.submitter_name
@ -149,7 +159,7 @@ for o in LiaisonDetail.objects.all().order_by("pk"):
else:
l.to_name = o.to_body
l.to_name = l.to_name.strip()
l.to_body = get_body(l.to_name, o.to_raw_code) # try to establish link
l.to_group = get_body(l.to_name, o.to_raw_code) # try to establish link
l.to_contact = (o.to_poc or "").strip()
l.reply_to = (o.replyto or "").strip()
@ -159,10 +169,26 @@ for o in LiaisonDetail.objects.all().order_by("pk"):
l.cc = (o.cc1 or "").strip()
l.submitted = o.submitted_date
l.submitted_by = old_person_to_person(o.person) if o.person else system_person
l.modified = o.last_modified_date
l.approved = o.approval and o.approval.approved and (o.approval.approval_date or l.modified or datetime.datetime.now())
l.approved = o.approval.approval_date or l.modified or datetime.datetime.now() if o.approval and o.approval.approved else None
l.action_taken = o.action_taken
#l.save()
l.save()
l.attachments.all().delete()
for i, u in enumerate(o.uploads_set.order_by("pk")):
attachment = Document()
attachment.title = u.file_title
attachment.type = liaison_attachment_doctype
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.save()
DocAlias.objects.get_or_create(document=attachment, name=attachment.name)
l.attachments.add(attachment)

View file

@ -12,14 +12,16 @@ from django.core import management
management.setup_environ(settings)
from ietf.idtracker.models import AreaDirector, IETFWG, PersonOrOrgInfo, IDAuthor
from ietf.liaisons.models import LiaisonDetail, LiaisonManagers, SDOAuthorizedIndividual
from redesign.person.models import *
from redesign.importing.utils import clean_email_address, get_or_create_email
from redesign.importing.utils import *
# creates system person and email
# imports AreaDirector persons that are connected to an IETFWG,
# persons from IDAuthor, announcement originators from Announcements,
# requesters from WgMeetingSession
# requesters from WgMeetingSession, LiaisonDetail persons,
# LiaisonManagers/SDOAuthorizedIndividual persons
# should probably import
# PersonOrOrgInfo/PostalAddress/EmailAddress/PhoneNumber fully
@ -48,7 +50,7 @@ system_alias = Alias.objects.get_or_create(
)
system_email = Email.objects.get_or_create(
address="",
address="(System)",
defaults=dict(active=True, person=system_person)
)
@ -76,11 +78,30 @@ for o in PersonOrOrgInfo.objects.filter(announcement__announcement_id__gte=1).or
email = get_or_create_email(o, create_fake=False)
# Liaison submitter persons
for o in PersonOrOrgInfo.objects.filter(liaisondetail__pk__gte=1).order_by("pk").distinct():
print "importing LiaisonDetail originator", o.pk, o.first_name.encode('utf-8'), o.last_name.encode('utf-8')
# LiaisonManagers persons
for o in LiaisonManagers.objects.order_by("pk"):
print "importing LiaisonManagers person", o.pk, o.person.first_name.encode('utf-8'), o.person.last_name.encode('utf-8')
email = get_or_create_email(o, create_fake=False)
possibly_import_other_priority_email(email, o.person.email(priority=o.email_priority)[1])
# SDOAuthorizedIndividual persons
for o in PersonOrOrgInfo.objects.filter(sdoauthorizedindividual__pk__gte=1).order_by("pk").distinct():
print "importing SDOAuthorizedIndividual person", o.pk, o.first_name.encode('utf-8'), o.last_name.encode('utf-8')
email = get_or_create_email(o, create_fake=False)
# Liaison persons (these are used as from contacts)
for o in LiaisonDetail.objects.exclude(person=None).order_by("pk"):
print "importing LiaisonDetail person", o.pk, o.person.first_name.encode('utf-8'), o.person.last_name.encode('utf-8')
email = get_or_create_email(o, create_fake=True)
# we may also need to import email address used specifically for
# the document
if "@" in email.address:
addr = o.from_email().address
possibly_import_other_priority_email(email, addr)
# IDAuthor persons
for o in IDAuthor.objects.all().order_by('id').select_related('person').iterator():
@ -89,14 +110,4 @@ for o in IDAuthor.objects.all().order_by('id').select_related('person').iterator
# we may also need to import email address used specifically for
# the document
addr = clean_email_address(o.email() or "")
if addr and addr.lower() != email.address.lower():
try:
e = Email.objects.get(address=addr)
if e.person != email.person or e.active != False:
e.person = email.person
e.active = False
e.save()
except Email.DoesNotExist:
Email.objects.create(address=addr, person=email.person, active=False)
possibly_import_other_priority_email(email, o.email())

View file

@ -18,6 +18,7 @@ from redesign.name.utils import name
from redesign.importing.utils import get_or_create_email
from ietf.idtracker.models import IESGLogin, AreaDirector, PersonOrOrgInfo, WGChair, WGEditor, WGSecretary, WGTechAdvisor, ChairsHistory, Role as OldRole, Acronym, IRTFChair
from ietf.liaisons.models import LiaisonManagers, SDOAuthorizedIndividual
from ietf.proceedings.models import IESGHistory
from ietf.utils.history import *
@ -27,9 +28,10 @@ from ietf.utils.history import *
# - groups have been imported
# imports IESGLogin, AreaDirector, WGEditor, WGChair, IRTFChair,
# WGSecretary, WGTechAdvisor, NomCom chairs from ChairsHistory, IESGHistory
# WGSecretary, WGTechAdvisor, NomCom chairs from ChairsHistory,
# IESGHistory, Role, LiaisonManagers, SDOAuthorizedIndividual
# FIXME: should probably import Role, LegacyWgPassword, LegacyLiaisonUser
# FIXME: should probably import LegacyWgPassword, LegacyLiaisonUser
area_director_role = name(RoleName, "ad", "Area Director")
inactive_area_director_role = name(RoleName, "ex-ad", "Ex-Area Director", desc="Inactive Area Director")
@ -37,7 +39,51 @@ chair_role = name(RoleName, "chair", "Chair")
editor_role = name(RoleName, "editor", "Editor")
secretary_role = name(RoleName, "secr", "Secretary")
techadvisor_role = name(RoleName, "techadv", "Tech Advisor")
exec_director_role = name(RoleName, "execdir", "Executive Director")
adm_director_role = name(RoleName, "admdir", "Administrative Director")
liaison_manager_role = name(RoleName, "liaiman", "Liaison Manager")
authorized_role = name(RoleName, "auth", "Authorized Individual")
# SDOAuthorizedIndividual
for o in SDOAuthorizedIndividual.objects.all().order_by("pk"):
print "importing SDOAuthorizedIndividual", o.pk, o.sdo, o.person
group = Group.objects.get(name=o.sdo.sdo_name, type="sdo")
email = get_or_create_email(o, create_fake=False)
Role.objects.get_or_create(name=authorized_role, group=group, email=email)
# LiaisonManagers
for o in LiaisonManagers.objects.all().order_by("pk"):
print "importing LiaisonManagers", o.pk, o.sdo, o.person
group = Group.objects.get(name=o.sdo.sdo_name, type="sdo")
email = Email.objects.get(address__iexact=o.person.email(priority=o.email_priority)[1])
Role.objects.get_or_create(name=liaison_manager_role, group=group, email=email)
# Role
for o in OldRole.objects.all().order_by('pk'):
acronym = o.role_name.lower()
role = chair_role
if o.id == OldRole.NOMCOM_CHAIR:
continue # handled elsewhere
print "importing Role", o.id, o.role_name
if o.role_name.endswith("Executive Director"):
acronym = acronym[:-(len("Executive Director") + 1)]
role = exec_director_role
if o.id == OldRole.IAD_CHAIR:
acronym = "ietf"
role = adm_director_role
group = Group.objects.get(acronym=acronym)
email = get_or_create_email(o, create_fake=False)
Role.objects.get_or_create(name=role, group=group, email=email)
# WGEditor
for o in WGEditor.objects.all():

View file

@ -64,3 +64,15 @@ def get_or_create_email(o, create_fake):
e.save()
return e
def possibly_import_other_priority_email(email, addr):
addr = clean_email_address(addr or "")
if addr and addr.lower() != email.address.lower():
try:
e = Email.objects.get(address=addr)
if e.person != email.person or e.active != False:
e.person = email.person
e.active = False
e.save()
except Email.DoesNotExist:
Email.objects.create(address=addr, person=email.person, active=False)