Skip to content

Commit 9308948

Browse files
committed
Add person, affiliation and country (through django-countries) to
DocumentAuthor, rename author field to email and make it optional (for modeling old email-less submissions), remove the authors many to many referencing field from Document as it is not really pointing the right place. Update the Secretariat tools to show affiliation and country. Add migration for getting rid of the fake email addresses that the migration script created some years ago (just set the author email field to null). - Legacy-Id: 12739
1 parent e381dac commit 9308948

43 files changed

Lines changed: 329 additions & 142 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

ietf/api/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,9 +212,9 @@ def dehydrate(self, bundle, for_list=True):
212212
if not foreign_obj:
213213
if not self.null:
214214
if callable(self.attribute):
215-
raise ApiFieldError("The related resource for resource %s could not be found." % (previous_obj))
215+
raise ApiFieldError(u"The related resource for resource %s could not be found." % (previous_obj))
216216
else:
217-
raise ApiFieldError("The model '%r' has an empty attribute '%s' and doesn't allow a null value." % (previous_obj, attr))
217+
raise ApiFieldError(u"The model '%r' has an empty attribute '%s' and doesn't allow a null value." % (previous_obj, attr))
218218
return None
219219

220220
fk_resource = self.get_related_resource(foreign_obj)

ietf/bin/find-submission-confirmation-email-in-postfix-log

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ if "<" in from_email:
6666

6767
submission = Submission.objects.filter(name=draft).latest('submission_date')
6868
document = Document.objects.get(name=draft)
69-
emails = [ author.address for author in document.authors.all() ]
69+
emails = [ author.email.address for author in document.documentauthor_set.all() if author.email ]
7070

7171
timestrings = []
7272
for file in [ Path(settings.INTERNET_DRAFT_PATH) / ("%s-%s.txt"%(draft, submission.rev)),

ietf/bin/generate-draft-aliases

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ def get_draft_authors_emails(draft):
6565
" Get list of authors for the given draft."
6666

6767
# This feels 'correct'; however, it creates fairly large delta
68-
return [email.email_address() for email in draft.authors.all()]
68+
return [author.email.email_address() for author in draft.documentauthor_set.all() if author.email.email_address()]
6969

7070
# This gives fairly small delta compared to current state,
7171
# however, it seems to be wrong (doesn't check for emails being

ietf/community/migrations/0004_cleanup_data.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def try_to_uniquify_person(rule, person_qs):
5757

5858

5959
elif rule.rule_type in ["author", "author_rfc"]:
60-
found_persons = list(try_to_uniquify_person(rule, Person.objects.filter(email__documentauthor__id__gte=1).filter(name__icontains=rule.value).distinct()))
60+
found_persons = list(try_to_uniquify_person(rule, Person.objects.filter(documentauthor__id__gte=1).filter(name__icontains=rule.value).distinct()))
6161

6262
if found_persons:
6363
rule.person = found_persons[0]

ietf/community/tests.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def test_rule_matching(self):
3131

3232
rule_state_iesg = SearchRule.objects.create(rule_type="state_iesg", state=State.objects.get(type="draft-iesg", slug="lc"), community_list=clist)
3333

34-
rule_author = SearchRule.objects.create(rule_type="author", state=State.objects.get(type="draft", slug="active"), person=Person.objects.filter(email__documentauthor__document=draft).first(), community_list=clist)
34+
rule_author = SearchRule.objects.create(rule_type="author", state=State.objects.get(type="draft", slug="active"), person=Person.objects.filter(documentauthor__document=draft).first(), community_list=clist)
3535

3636
rule_ad = SearchRule.objects.create(rule_type="ad", state=State.objects.get(type="draft", slug="active"), person=draft.ad, community_list=clist)
3737

@@ -113,7 +113,7 @@ def test_manage_personal_list(self):
113113
r = self.client.post(url, {
114114
"action": "add_rule",
115115
"rule_type": "author_rfc",
116-
"author_rfc-person": Person.objects.filter(email__documentauthor__document=draft).first().pk,
116+
"author_rfc-person": Person.objects.filter(documentauthor__document=draft).first().pk,
117117
"author_rfc-state": State.objects.get(type="draft", slug="rfc").pk,
118118
})
119119
self.assertEqual(r.status_code, 302)

ietf/community/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ def docs_matching_community_list_rule(rule):
8888
elif rule.rule_type.startswith("state_"):
8989
return docs.filter(states=rule.state)
9090
elif rule.rule_type in ["author", "author_rfc"]:
91-
return docs.filter(states=rule.state, documentauthor__author__person=rule.person)
91+
return docs.filter(states=rule.state, documentauthor__person=rule.person)
9292
elif rule.rule_type == "ad":
9393
return docs.filter(states=rule.state, ad=rule.person)
9494
elif rule.rule_type == "shepherd":
@@ -121,7 +121,7 @@ def community_list_rules_matching_doc(doc):
121121
rules |= SearchRule.objects.filter(
122122
rule_type__in=["author", "author_rfc"],
123123
state__in=states,
124-
person__in=list(Person.objects.filter(email__documentauthor__document=doc)),
124+
person__in=list(Person.objects.filter(documentauthor__document=doc)),
125125
)
126126

127127
if doc.ad_id:

ietf/doc/admin.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class DocAliasInline(admin.TabularInline):
2525

2626
class DocAuthorInline(admin.TabularInline):
2727
model = DocumentAuthor
28-
raw_id_fields = ['author', ]
28+
raw_id_fields = ['person', 'email']
2929
extra = 1
3030

3131
class RelatedDocumentInline(admin.TabularInline):
@@ -99,7 +99,7 @@ class DocumentAdmin(admin.ModelAdmin):
9999
list_display = ['name', 'rev', 'group', 'pages', 'intended_std_level', 'author_list', 'time']
100100
search_fields = ['name']
101101
list_filter = ['type']
102-
raw_id_fields = ['authors', 'group', 'shepherd', 'ad']
102+
raw_id_fields = ['group', 'shepherd', 'ad']
103103
inlines = [DocAliasInline, DocAuthorInline, RelatedDocumentInline, ]
104104
form = DocumentForm
105105

@@ -121,7 +121,7 @@ class DocHistoryAdmin(admin.ModelAdmin):
121121
list_display = ['doc', 'rev', 'state', 'group', 'pages', 'intended_std_level', 'author_list', 'time']
122122
search_fields = ['doc__name']
123123
ordering = ['time', 'doc', 'rev']
124-
raw_id_fields = ['doc', 'authors', 'group', 'shepherd', 'ad']
124+
raw_id_fields = ['doc', 'group', 'shepherd', 'ad']
125125

126126
def state(self, instance):
127127
return instance.get_state()
@@ -174,7 +174,7 @@ class BallotPositionDocEventAdmin(DocEventAdmin):
174174
admin.site.register(BallotPositionDocEvent, BallotPositionDocEventAdmin)
175175

176176
class DocumentAuthorAdmin(admin.ModelAdmin):
177-
list_display = ['id', 'document', 'author', 'order']
178-
search_fields = [ 'document__name', 'author__address', ]
177+
list_display = ['id', 'document', 'person', 'email', 'order']
178+
search_fields = [ 'document__name', 'person__name', 'email__address', ]
179179
admin.site.register(DocumentAuthor, DocumentAuthorAdmin)
180180

ietf/doc/factories.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ def states(obj, create, extracted, **kwargs): # pylint: disable=no-self-argument
4646
def authors(obj, create, extracted, **kwargs): # pylint: disable=no-self-argument
4747
if create and extracted:
4848
order = 0
49-
for email in extracted:
50-
DocumentAuthor.objects.create(document=obj, author=email, order=order)
49+
for person in extracted:
50+
DocumentAuthor.objects.create(document=obj, person=person, order=order)
5151
order += 1
5252

5353
@classmethod

ietf/doc/migrations/0020_auto_20170112_0753.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from __future__ import unicode_literals
33

44
from django.db import migrations, models
5+
import django_countries.fields
56

67

78
class Migration(migrations.Migration):
@@ -32,4 +33,84 @@ class Migration(migrations.Migration):
3233
name='formal_languages',
3334
field=models.ManyToManyField(help_text=b'Formal languages used in document', to='name.FormalLanguageName', blank=True),
3435
),
36+
migrations.RemoveField(
37+
model_name='dochistory',
38+
name='authors',
39+
),
40+
migrations.RemoveField(
41+
model_name='document',
42+
name='authors',
43+
),
44+
migrations.AddField(
45+
model_name='dochistoryauthor',
46+
name='affiliation',
47+
field=models.CharField(help_text=b'Organization/company used by author for submission', max_length=100, blank=True),
48+
),
49+
migrations.AddField(
50+
model_name='dochistoryauthor',
51+
name='country',
52+
field=django_countries.fields.CountryField(blank=True, help_text=b'Country used by author for submission', max_length=2),
53+
),
54+
migrations.RenameField(
55+
model_name='dochistoryauthor',
56+
old_name='author',
57+
new_name='email',
58+
),
59+
migrations.AlterField(
60+
model_name='dochistoryauthor',
61+
name='email',
62+
field=models.ForeignKey(blank=True, to='person.Email', help_text=b'Email address used by author for submission', null=True),
63+
),
64+
migrations.AddField(
65+
model_name='dochistoryauthor',
66+
name='person',
67+
field=models.ForeignKey(blank=True, to='person.Person', null=True),
68+
),
69+
migrations.AddField(
70+
model_name='documentauthor',
71+
name='affiliation',
72+
field=models.CharField(help_text=b'Organization/company used by author for submission', max_length=100, blank=True),
73+
),
74+
migrations.AddField(
75+
model_name='documentauthor',
76+
name='country',
77+
field=django_countries.fields.CountryField(blank=True, help_text=b'Country used by author for submission', max_length=2),
78+
),
79+
migrations.RenameField(
80+
model_name='documentauthor',
81+
old_name='author',
82+
new_name='email',
83+
),
84+
migrations.AlterField(
85+
model_name='documentauthor',
86+
name='email',
87+
field=models.ForeignKey(blank=True, to='person.Email', help_text=b'Email address used by author for submission', null=True),
88+
),
89+
migrations.AddField(
90+
model_name='documentauthor',
91+
name='person',
92+
field=models.ForeignKey(blank=True, to='person.Person', null=True),
93+
),
94+
migrations.AlterField(
95+
model_name='dochistoryauthor',
96+
name='document',
97+
field=models.ForeignKey(related_name='documentauthor_set', to='doc.DocHistory'),
98+
),
99+
migrations.AlterField(
100+
model_name='dochistoryauthor',
101+
name='order',
102+
field=models.IntegerField(default=1),
103+
),
104+
migrations.RunSQL("update doc_documentauthor a inner join person_email e on a.email_id = e.address set a.person_id = e.person_id;", migrations.RunSQL.noop),
105+
migrations.RunSQL("update doc_dochistoryauthor a inner join person_email e on a.email_id = e.address set a.person_id = e.person_id;", migrations.RunSQL.noop),
106+
migrations.AlterField(
107+
model_name='documentauthor',
108+
name='person',
109+
field=models.ForeignKey(to='person.Person'),
110+
),
111+
migrations.AlterField(
112+
model_name='dochistoryauthor',
113+
name='person',
114+
field=models.ForeignKey(to='person.Person'),
115+
),
35116
]
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# -*- coding: utf-8 -*-
2+
from __future__ import unicode_literals
3+
4+
from django.db import migrations
5+
6+
def fix_invalid_emails(apps, schema_editor):
7+
Email = apps.get_model("person", "Email")
8+
Role = apps.get_model("group", "Role")
9+
RoleHistory = apps.get_model("group", "RoleHistory")
10+
11+
e = Email.objects.filter(address="unknown-email-Gigi-Karmous-Edwards").first()
12+
if e:
13+
# according to ftp://ietf.org/ietf/97dec/adsl-minutes-97dec.txt
14+
new_e, _ = Email.objects.get_or_create(
15+
address="GiGi.Karmous-Edwards@pulse.com",
16+
primary=e.primary,
17+
active=e.active,
18+
person=e.person,
19+
)
20+
Role.objects.filter(email=e).update(email=new_e)
21+
RoleHistory.objects.filter(email=e).update(email=new_e)
22+
e.delete()
23+
24+
e = Email.objects.filter(address="unknown-email-Pat-Thaler").first()
25+
if e:
26+
# current chair email
27+
new_e = Email.objects.get(address="pat.thaler@broadcom.com")
28+
Role.objects.filter(email=e).update(email=new_e)
29+
RoleHistory.objects.filter(email=e).update(email=new_e)
30+
e.delete()
31+
32+
Email = apps.get_model("person", "Email")
33+
DocumentAuthor = apps.get_model("doc", "DocumentAuthor")
34+
DocHistoryAuthor = apps.get_model("doc", "DocHistoryAuthor")
35+
36+
DocumentAuthor.objects.filter(email__address__startswith="unknown-email-").exclude(email__address__contains="@").update(email=None)
37+
DocHistoryAuthor.objects.filter(email__address__startswith="unknown-email-").exclude(email__address__contains="@").update(email=None)
38+
Email.objects.exclude(address__contains="@").filter(address__startswith="unknown-email-").delete()
39+
40+
class Migration(migrations.Migration):
41+
42+
dependencies = [
43+
('doc', '0020_auto_20170112_0753'),
44+
('person', '0014_auto_20160613_0751'),
45+
('group', '0009_auto_20150930_0758'),
46+
]
47+
48+
operations = [
49+
migrations.RunPython(fix_invalid_emails, migrations.RunPython.noop),
50+
]

0 commit comments

Comments
 (0)