Skip to content

Commit c7d58d6

Browse files
committed
First draft of new liaison statement model, import SDOs as groups,
start on liaison statement importing - Legacy-Id: 3309
1 parent 99886e9 commit c7d58d6

File tree

8 files changed

+191
-6
lines changed

8 files changed

+191
-6
lines changed

ietf/announcements/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ class Meta:
8888
db_table = 'scheduled_announcements'
8989

9090

91-
if settings.USE_DB_REDESIGN_PROXY_CLASSES or hasattr(settings, "IMPORTING_ANNOUNCEMENTS"):
91+
if settings.USE_DB_REDESIGN_PROXY_CLASSES or hasattr(settings, "IMPORTING_FROM_OLD_SCHEMA"):
9292
import datetime
9393

9494
from person.models import Email, Person

ietf/liaisons/admin.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#coding: utf-8
22
from django import template
3+
from django.conf import settings
34
from django.contrib import admin
45
from django.contrib.admin.util import unquote
56
from django.core.exceptions import PermissionDenied
@@ -18,7 +19,8 @@
1819

1920
class FromBodiesAdmin(admin.ModelAdmin):
2021
list_display = ['body_name', 'contact_link', 'other_sdo']
21-
admin.site.register(FromBodies, FromBodiesAdmin)
22+
if not settings.USE_DB_REDESIGN_PROXY_CLASSES:
23+
admin.site.register(FromBodies, FromBodiesAdmin)
2224

2325

2426
class LiaisonDetailAdmin(admin.ModelAdmin):

ietf/liaisons/models.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,3 +305,41 @@ class Meta:
305305
# removed edit_inline
306306
# removed num_in_admin
307307
# removed raw_id_admin
308+
309+
if settings.USE_DB_REDESIGN_PROXY_CLASSES or hasattr(settings, "IMPORTING_FROM_OLD_SCHEMA"):
310+
from redesign.name.models import LiaisonStatementPurposeName
311+
from redesign.person.models import Person
312+
from redesign.group.models import Group
313+
314+
class LiaisonStatement(models.Model):
315+
title = models.CharField(blank=True, max_length=255)
316+
purpose = models.ForeignKey(LiaisonStatementPurposeName)
317+
body = models.TextField(blank=True)
318+
deadline = models.DateField(null=True, blank=True)
319+
320+
related_to = models.ForeignKey('LiaisonDetail', blank=True, null=True)
321+
322+
from_body = models.ForeignKey(Group, related_name="liaisonstatement_from_set", null=True, blank=True, help_text="From body, if it exists")
323+
from_name = models.CharField(max_length=255, help_text="Name of the sender body")
324+
to_body = models.ForeignKey(Group, related_name="liaisonstatement_to_set", null=True, blank=True, help_text="to body, if it exists")
325+
to_name = models.CharField(max_length=255, help_text="Name of the recipient body")
326+
to_contact = models.CharField(blank=True, max_length=255)
327+
328+
reply_to = models.CharField(blank=True, max_length=255)
329+
330+
response_contact = models.CharField(blank=True, max_length=255)
331+
technical_contact = models.CharField(blank=True, max_length=255)
332+
cc = models.TextField(blank=True)
333+
334+
submitted = models.DateTimeField(null=True, blank=True)
335+
submitted_by = models.ForeignKey(Person)
336+
modified = models.DateTimeField(null=True, blank=True)
337+
approved = models.DateTimeField(null=True, blank=True)
338+
339+
action_taken = models.BooleanField(default=False)
340+
341+
#submitter_name = models.CharField(blank=True, null=True, max_length=255)
342+
#submitter_email = models.CharField(blank=True, null=True, max_length=255)
343+
344+
def __unicode__(self):
345+
return self.title or "<no title>"

redesign/group/models.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
import datetime
88

99
class GroupInfo(models.Model):
10-
time = models.DateTimeField(default=datetime.datetime.now) # should probably have auto_now=True
10+
time = models.DateTimeField(default=datetime.datetime.now)
1111
name = models.CharField(max_length=80)
12-
acronym = models.CharField(max_length=16, db_index=True)
12+
acronym = models.CharField(max_length=16, blank=True, db_index=True)
1313
state = models.ForeignKey(GroupStateName, null=True)
1414
type = models.ForeignKey(GroupTypeName, null=True)
1515
parent = models.ForeignKey('Group', blank=True, null=True)

redesign/importing/import-announcements.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
from ietf import settings
99
settings.USE_DB_REDESIGN_PROXY_CLASSES = False
10-
settings.IMPORTING_ANNOUNCEMENTS = True
10+
settings.IMPORTING_FROM_OLD_SCHEMA = True
1111

1212
from django.core import management
1313
management.setup_environ(settings)

redesign/importing/import-groups.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@
1717
from redesign.name.utils import name
1818
from redesign.importing.utils import old_person_to_person
1919
from ietf.idtracker.models import AreaGroup, IETFWG, Area, AreaGroup, Acronym, AreaWGURL, IRTF, ChairsHistory, Role, AreaDirector
20+
from ietf.liaisons.models import SDOs
2021

21-
# imports IETFWG, Area, AreaGroup, Acronym, IRTF, AreaWGURL
22+
# imports IETFWG, Area, AreaGroup, Acronym, IRTF, AreaWGURL, SDOs
2223

2324
# also creates nomcom groups
2425

@@ -41,13 +42,22 @@
4142
rg=name(GroupTypeName, slug="rg", name="RG"),
4243
team=name(GroupTypeName, slug="team", name="Team"),
4344
individ=name(GroupTypeName, slug="individ", name="Individual"),
45+
sdo=name(GroupTypeName, slug="sdo", name="Standards Organization"),
4446
)
4547

48+
# make sure we got the IETF as high-level parent
49+
ietf_group, _ = Group.objects.get_or_create(acronym="ietf")
50+
ietf_group.name = "IETF"
51+
ietf_group.state = state_names["active"]
52+
ietf_group.type = type_names["ietf"]
53+
ietf_group.save()
54+
4655
# make sure we got the IESG so we can use it as parent for areas
4756
iesg_group, _ = Group.objects.get_or_create(acronym="iesg")
4857
iesg_group.name = "IESG"
4958
iesg_group.state = state_names["active"]
5059
iesg_group.type = type_names["ietf"]
60+
iesg_group.parent = ietf_group
5161
iesg_group.save()
5262

5363
# make sure we got the IRTF as parent for RGs
@@ -275,3 +285,12 @@ def import_date_event(name, type_name):
275285
# dormant_date is empty on all so don't bother with that
276286

277287
# FIXME: missing fields from old: meeting_scheduled, email_keyword, meeting_scheduled_old
288+
289+
# SDOs
290+
for o in SDOs.objects.all().order_by("pk"):
291+
# we import SDOs as groups, this makes it easy to take advantage
292+
# of the rest of the role/person models for authentication and
293+
# authorization
294+
print "importing SDOs", o.pk, o.sdo_name
295+
Group.objects.get_or_create(name=o.sdo_name, type=type_names["sdo"])
296+
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
#!/usr/bin/python
2+
3+
import sys, os, re, datetime, pytz
4+
5+
basedir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../.."))
6+
sys.path = [ basedir ] + sys.path
7+
8+
from ietf import settings
9+
settings.USE_DB_REDESIGN_PROXY_CLASSES = False
10+
settings.IMPORTING_FROM_OLD_SCHEMA = True
11+
12+
from django.core import management
13+
management.setup_environ(settings)
14+
15+
from django.template.defaultfilters import slugify
16+
17+
from ietf.idtracker.models import AreaDirector, IETFWG, Acronym, IRTF
18+
from ietf.liaisons.models import *
19+
from redesign.person.models import *
20+
from redesign.importing.utils import get_or_create_email, old_person_to_person
21+
from redesign.name.models import *
22+
from redesign.name.utils import name
23+
24+
25+
# imports LiaisonDetail, OutgoingLiaisonApproval, Uploads
26+
27+
# todo: LiaisonStatementManager, LiaisonManagers, SDOAuthorizedIndividual
28+
29+
# assumptions:
30+
# - persons have been imported
31+
# - groups have been imported
32+
33+
purpose_mapping = {
34+
1: name(LiaisonStatementPurposeName, "action", "For action"),
35+
2: name(LiaisonStatementPurposeName, "comment", "For comment"),
36+
3: name(LiaisonStatementPurposeName, "info", "For information"),
37+
4: name(LiaisonStatementPurposeName, "response", "In response"),
38+
5: name(LiaisonStatementPurposeName, "other", "Other"),
39+
}
40+
41+
purpose_mapping[None] = purpose_mapping[3] # map unknown to "For information"
42+
43+
system_person = Person.objects.get(name="(System)")
44+
obviously_bogus_date = datetime.date(1970, 1, 1)
45+
46+
bodies = {
47+
'IESG': Group.objects.get(acronym="iesg"),
48+
'IETF': Group.objects.get(acronym="ietf"),
49+
'IAB/ISOC': Group.objects.get(acronym="iab"),
50+
'IAB/IESG': Group.objects.get(acronym="iab"),
51+
'IAB': Group.objects.get(acronym="iab"),
52+
'IETF Transport Directorate': Group.objects.get(acronym="tsvdir"),
53+
'Sigtran': Group.objects.get(acronym="sigtran", type="wg"),
54+
'IETF RAI WG': Group.objects.get(acronym="rai", type="area"),
55+
'IETF Mobile IP WG': Group.objects.get(acronym="mobileip", type="wg"),
56+
}
57+
58+
def get_from_body(name):
59+
# the from body name is a nice case study in how inconsistencies
60+
# build up over time
61+
b = bodies.get(name)
62+
t = name.split()
63+
if not b and name.startswith("IETF"):
64+
if len(t) < 3 or t[2].lower() == "wg":
65+
b = lookup_group(acronym=t[1].lower(), type="wg")
66+
elif t[2].lower() in ("area", "ad"):
67+
print "inside AREA"
68+
b = lookup_group(acronym=t[1].lower(), type="area")
69+
if not b:
70+
b = lookup_group(name=u"%s %s" % (t[1], t[2]), type="area")
71+
72+
if not b and name.endswith(" WG"):
73+
b = lookup_group(acronym=t[-2].lower(), type="wg")
74+
75+
if not b:
76+
b = lookup_group(name=name, type="sdo")
77+
78+
return b
79+
80+
for o in LiaisonDetail.objects.all().order_by("pk"):#[:10]:
81+
print "importing LiaisonDetail", o.pk
82+
83+
try:
84+
l = LiaisonStatement.objects.get(pk=o.pk)
85+
except LiaisonStatement.DoesNotExist:
86+
l = LiaisonStatement(pk=o.pk)
87+
88+
l.title = (o.title or "").strip()
89+
l.purpose = purpose_mapping[o.purpose_id]
90+
if o.purpose_text and not o.purpose and "action" in o.purpose_text.lower():
91+
o.purpose = purpose_mapping[1]
92+
l.body = (o.body or "").strip()
93+
l.deadline = o.deadline_date
94+
95+
l.related_to_id = o.related_to_id # should not dangle as we process ids in turn
96+
97+
def lookup_group(**kwargs):
98+
try:
99+
return Group.objects.get(**kwargs)
100+
except Group.DoesNotExist:
101+
return None
102+
103+
l.from_name = o.from_body()
104+
l.from_body = get_from_body(l.from_name) # try to establish link
105+
continue
106+
107+
l.to_body = o.to_raw_body
108+
l.to_name = o.to_raw_body
109+
l.to_contact = (o.to_poc or "").strip()
110+
111+
l.reply_to = (o.replyto or "").strip()
112+
113+
l.response_contact = (o.response_contact or "").strip()
114+
l.technical_contact = (o.technical_contact or "").strip()
115+
l.cc = (o.cc1 or "").strip()
116+
117+
l.submitted = o.submitted_date
118+
l.submitted_by = old_person_to_person(o.person)
119+
l.modified = o.last_modified_date
120+
l.approved = o.approval and o.approval.approved and (o.approval.approval_date or l.modified or datetime.datetime.now())
121+
122+
l.action_taken = o.action_taken
123+
124+
#l.save()

redesign/name/models.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ class TimeSlotTypeName(NameModel):
7070
"""Session, Break, Registration"""
7171
class ConstraintName(NameModel):
7272
"""Conflict"""
73+
class LiaisonStatementPurposeName(NameModel):
74+
"""For action, For comment, For information, In response, Other"""
7375

7476

7577
def get_next_iesg_states(iesg_state):

0 commit comments

Comments
 (0)