Skip to content

Commit 0ada078

Browse files
committed
Import document replaces, revamp document relationships a little bit to remove a model, fix bugs
- Legacy-Id: 2730
1 parent 7deeb60 commit 0ada078

4 files changed

Lines changed: 96 additions & 80 deletions

File tree

redesign/doc/admin.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,6 @@
22
from models import *
33
from person.models import *
44

5-
class RelatedDocAdmin(admin.ModelAdmin):
6-
list_display = ["source", "relationship", "target"]
7-
search_fields = ["doc_alias__name", "related_document_set__name", ]
8-
list_display_links = ["relationship", ]
9-
admin.site.register(RelatedDoc, RelatedDocAdmin)
10-
115
class DocumentAdmin(admin.ModelAdmin):
126
list_display = ['name', 'rev', 'state', 'group', 'pages', 'intended_std_level', 'author_list', 'time']
137
search_fields = ['name']

redesign/doc/models.py

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,6 @@
88

99
import datetime
1010

11-
class RelatedDoc(models.Model):
12-
relationship = models.ForeignKey(DocRelationshipName)
13-
doc_alias = models.ForeignKey('DocAlias')
14-
def __unicode__(self):
15-
return "%s %s" % (self.relationship.name, self.doc_alias.name)
16-
source = admin_link("related_document_set")
17-
target = admin_link("doc_alias__document")
18-
1911
class DocumentInfo(models.Model):
2012
"""Any kind of document. Draft, RFC, Charter, IPR Statement, Liaison Statement"""
2113
time = models.DateTimeField() # should probably have auto_now=True
@@ -38,7 +30,6 @@ class DocumentInfo(models.Model):
3830
intended_std_level = models.ForeignKey(IntendedStatusName, blank=True, null=True)
3931
std_level = models.ForeignKey(StdStatusName, blank=True, null=True)
4032
authors = models.ManyToManyField(Email, blank=True, null=True)
41-
related = models.ManyToManyField(RelatedDoc, related_name='related_%(class)s_set', blank=True)
4233
ad = models.ForeignKey(Email, related_name='ad_%(class)s_set', blank=True, null=True)
4334
shepherd = models.ForeignKey(Email, related_name='shepherd_%(class)s_set', blank=True, null=True)
4435
notify = models.CharField(max_length=255, blank=True)
@@ -58,8 +49,16 @@ def latest_event(self, *args, **filter_args):
5849
e = model.objects.filter(doc=self).filter(**filter_args).order_by('-time')[:1]
5950
return e[0] if e else None
6051

52+
class RelatedDocument(models.Model):
53+
document = models.ForeignKey('Document') # source
54+
doc_alias = models.ForeignKey('DocAlias') # target
55+
relationship = models.ForeignKey(DocRelationshipName)
56+
def __unicode__(self):
57+
return u"%s %s %s" % (self.document.name, self.relationship.name.lower(), self.doc_alias.name)
58+
6159
class Document(DocumentInfo):
6260
name = models.CharField(max_length=255, primary_key=True) # immutable
61+
related = models.ManyToManyField('DocAlias', through=RelatedDocument, blank=True, related_name="reversely_related_document_set")
6362
def __unicode__(self):
6463
return self.name
6564
def values(self):
@@ -90,6 +89,7 @@ def save_with_history(self, force_insert=False, force_update=False):
9089
snap = DocHistory(**fields)
9190
snap.save()
9291
for m in many2many:
92+
# FIXME: check that this works with related
9393
#print "m2m:", m, many2many[m]
9494
rel = getattr(snap, m)
9595
for item in many2many[m]:
@@ -102,8 +102,16 @@ def save_with_history(self, force_insert=False, force_update=False):
102102
print "Deleted list:", snap
103103
super(Document, self).save(force_insert, force_update)
104104

105+
class RelatedDocHistory(models.Model):
106+
document = models.ForeignKey('DocHistory')
107+
doc_alias = models.ForeignKey('DocAlias', related_name="reversely_related_document_history_set")
108+
relationship = models.ForeignKey(DocRelationshipName)
109+
def __unicode__(self):
110+
return u"%s %s %s" % (self.document.name, self.relationship.name.lower(), self.doc_alias.name)
111+
105112
class DocHistory(DocumentInfo):
106113
doc = models.ForeignKey(Document) # ID of the Document this relates to
114+
related = models.ManyToManyField('DocAlias', through=RelatedDocHistory, blank=True)
107115
def __unicode__(self):
108116
return unicode(self.doc.name)
109117

redesign/doc/proxy.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -133,20 +133,18 @@ def last_modified_date(self):
133133
#replaced_by = models.ForeignKey('self', db_column='replaced_by', blank=True, null=True, related_name='replaces_set')
134134
@property
135135
def replaced_by(self):
136-
r = InternetDraft.objects.filter(docalias__relateddoc__relationship="replaces", docalias__relateddoc__related_document_set=self)
136+
r = InternetDraft.objects.filter(related__document=self, related__relateddocument__relationship="replaces")
137137
return r[0] if r else None
138138

139139
#replaces = FKAsOneToOne('replaces', reverse=True)
140140
@property
141141
def replaces(self):
142-
r = InternetDraft.objects.filter(related__doc_alias__document=self, related__relationship="replaces")
143-
return r[0] if r else Non
142+
r = self.replaces_set()
143+
return r[0] if r else None
144144

145-
146145
@property
147146
def replaces_set(self):
148-
# this is replaced_by
149-
return InternetDraft.objects.filter(docalias__relateddoc__relationship="replaces", docalias__relateddoc__related_document_set=self)
147+
return InternetDraft.objects.filter(docalias__relateddocument__relationship="replaces", docalias__relateddocument__document=self)
150148

151149
#review_by_rfc_editor = models.BooleanField()
152150
@property

redesign/import-document-state.py

Lines changed: 75 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ def name(name_class, slug, name, desc=""):
4646
type_draft = name(DocTypeName, "draft", "Draft")
4747
stream_ietf = name(DocStreamName, "ietf", "IETF")
4848

49+
relationship_replaces = name(DocRelationshipName, "replaces", "Replaces")
50+
4951
intended_status_mapping = {
5052
"BCP": name(IntendedStatusName, "bcp", "Best Current Practice"),
5153
"Draft Standard": name(IntendedStatusName, "ds", name="Draft Standard"),
@@ -145,7 +147,7 @@ def iesg_login_to_email(l):
145147
def date_in_match(match):
146148
return datetime.date(int(match.group('year')), int(match.group('month')), int(match.group('day')))
147149

148-
re_telechat_agenda = re.compile(r"(Placed on|Removed from) agenda for telechat - %s by" % date_re_str)
150+
re_telechat_agenda = re.compile(r"(Placed on|Removed from) agenda for telechat(| - %s) by" % date_re_str)
149151
re_ballot_position = re.compile(r"\[Ballot Position Update\] (New position, (?P<position>.*), has been recorded (|for (?P<for>.*) )|Position (|for (?P<for2>.*) )has been changed to (?P<position2>.*) from .*)by (?P<by>.*)")
150152
re_ballot_issued = re.compile(r"Ballot has been issued(| by)")
151153
re_state_changed = re.compile(r"(State (has been changed|changed|Changes) to <b>(?P<to>.*)</b> from <b>(?P<from>.*)</b> by|Sub state has been changed to (?P<tosub>.*) from (?P<fromsub>.*))")
@@ -191,14 +193,18 @@ def date_in_match(match):
191193
# d.std_level =
192194
# d.authors =
193195
# d.related =
194-
d.ad = iesg_login_to_email(o.idinternal.job_owner)
196+
d.ad = iesg_login_to_email(o.idinternal.job_owner) if o.idinternal else None
195197
d.shepherd = None
196198
d.notify = o.idinternal.state_change_notice_to or "" if o.idinternal else ""
197199
d.external_url = ""
198200
d.note = o.idinternal.note or "" if o.idinternal else ""
199201
d.internal_comments = o.comments or "" # FIXME: maybe put these somewhere else
200202
d.save()
201203

204+
# make sure our alias is updated
205+
DocAlias.objects.filter(name=d.name).exclude(document=d).delete()
206+
d_alias, _ = DocAlias.objects.get_or_create(name=d.name, document=d)
207+
202208
# clear already imported events
203209
d.event_set.all().delete()
204210

@@ -382,21 +388,60 @@ def date_in_match(match):
382388
save_event(d, e, c)
383389

384390
# stop typical comments from being output
385-
typical_comments = ["Who is the Document Shepherd for this document",
386-
"We understand that this document doesn't require any IANA actions",
391+
typical_comments = [
392+
"Document Shepherd Write-up for %s" % d.name,
393+
"Who is the Document Shepherd for this document",
394+
"We understand that this document doesn't require any IANA actions",
387395
]
388396
for t in typical_comments:
389397
if t in c.comment_text:
390398
handled = True
391399
break
392400

393401
if not handled:
394-
print "couldn't handle %s '%s'" % (c.id, c.comment_text.replace("\n", "").replace("\r", ""))
402+
print "couldn't handle %s '%s'" % (c.id, c.comment_text.replace("\n", "").replace("\r", "")[0:80])
395403

396404

397-
# import events that might be missing, we can't be sure where
398-
# to place them but if we don't generate them, we'll be
399-
# missing the information completely
405+
# import missing revision changes from DraftVersions
406+
known_revisions = set(e.newrevision.rev for e in d.event_set.filter(type="new_revision").select_related('newrevision'))
407+
for v in DraftVersions.objects.filter(filename=d.name).order_by("revision"):
408+
if v.revision not in known_revisions:
409+
e = NewRevision(type="new_revision")
410+
e.rev = v.revision
411+
# we don't have time information in this source, so
412+
# hack the seconds to include the revision to ensure
413+
# they're ordered correctly
414+
e.time = datetime.datetime.combine(v.revision_date, datetime.time(0, 0, int(v.revision)))
415+
e.by = system_email
416+
e.doc = d
417+
e.desc = "New version available"
418+
e.save()
419+
known_revisions.add(v.revision)
420+
421+
# import events that might be missing, we can't be sure where
422+
# to place them but if we don't generate them, we'll be
423+
# missing the information completely
424+
e = d.latest_event(Event, type="iesg_approved")
425+
approved_date = e.time.date() if e else None
426+
if o.b_approve_date != approved_date:
427+
e = Event(type="iesg_approved")
428+
e.time = o.idinternal.b_approve_date
429+
e.by = system_email
430+
e.doc = d
431+
e.desc = "IESG has approved"
432+
e.save()
433+
434+
if o.lc_expiration_date:
435+
e = Expiration(type="sent_last_call", expires=o.lc_expiration_date)
436+
e.time = o.lc_sent_date
437+
# let's try to figure out who did it
438+
events = d.event_set.filter(type="changed_document", desc__contains=" to <b>In Last Call</b>").order_by('-time')[:1]
439+
e.by = events[0].by if events else system_email
440+
e.doc = d
441+
e.desc = "Last call sent"
442+
e.save()
443+
444+
if o.idinternal:
400445
e = d.latest_event(Status, type="changed_status_date")
401446
status_date = e.date if e else None
402447
if o.idinternal.status_date != status_date:
@@ -407,65 +452,36 @@ def date_in_match(match):
407452
e.desc = "Status date has been changed to <b>%s</b> from <b>%s</b>" % (o.idinternal.status_date, status_date)
408453
e.save()
409454

410-
e = d.latest_event(Event, type="iesg_approved")
411-
approved_date = e.time.date() if e else None
412-
if o.b_approve_date != approved_date:
413-
e = Event(type="iesg_approved")
414-
e.time = o.idinternal.b_approve_date
415-
e.by = system_email
416-
e.doc = d
417-
e.desc = "IESG has approved"
418-
e.save()
455+
e = d.latest_event(Telechat, type="scheduled_for_telechat")
456+
telechat_date = e.telechat_date if e else None
457+
if not o.idinternal.agenda:
458+
o.idinternal.telechat_date = None # normalize
419459

420-
if o.lc_expiration_date:
421-
e = Expiration(type="sent_last_call", expires=o.lc_expiration_date)
422-
e.time = o.lc_sent_date
423-
# let's try to figure out who did it
424-
events = d.event_set.filter(type="changed_document", desc__contains=" to <b>In Last Call</b>").order_by('-time')[:1]
425-
e.by = events[0].by if events else system_email
460+
if telechat_date != o.idinternal.telechat_date:
461+
e = Telechat(type="scheduled_for_telechat",
462+
telechat_date=o.idinternal.telechat_date,
463+
returning_item=bool(o.idinternal.returning_item))
464+
e.time = made_up_date # FIXME: this isn't good, will override new values, estimate one instead
465+
e.by = system_email
466+
args = ("Placed on", o.idinternal.telechat_date) if o.idinternal.telechat_date else ("Removed from", telechat_date)
426467
e.doc = d
427-
e.desc = "Last call sent"
468+
e.desc = "%s agenda for telechat - %s by system" % args
428469
e.save()
429-
430-
if o.idinternal:
431-
e = d.latest_event(Telechat, type="scheduled_for_telechat")
432-
telechat_date = e.telechat_date if e else None
433-
if not o.idinternal.agenda:
434-
o.idinternal.telechat_date = None # normalize
435-
436-
if telechat_date != o.idinternal.telechat_date:
437-
e = Telechat(type="scheduled_for_telechat",
438-
telechat_date=o.idinternal.telechat_date,
439-
returning_item=bool(o.idinternal.returning_item))
440-
e.time = made_up_date
441-
e.by = system_email
442-
args = ("Placed on", o.idinternal.telechat_date) if o.idinternal.telechat_date else ("Removed from", telechat_date)
443-
e.doc = d
444-
e.desc = "%s agenda for telechat - %s by system" % args
445-
e.save()
446470

447471
# FIXME: import writeups
448472

473+
# import other attributes
474+
449475
# RFC alias
450476
if o.rfc_number:
451477
rfc_name = "rfc%s" % o.rfc_number
452478
DocAlias.objects.get_or_create(document=d, name=rfc_name)
453-
454-
# import missing revision changes from DraftVersions
455-
known_revisions = set(e.newrevision.rev for e in d.event_set.filter(type="new_revision").select_related('newrevision'))
456-
for v in DraftVersions.objects.filter(filename=d.name).order_by("revision"):
457-
if v.revision not in known_revisions:
458-
e = NewRevision(type="new_revision")
459-
e.rev = v.revision
460-
# we don't have time information in this source, so
461-
# hack the seconds to include the revision to ensure
462-
# they're ordered correctly
463-
e.time = datetime.datetime.combine(v.revision_date, datetime.time(0, 0, int(v.revision)))
464-
e.by = system_email
465-
e.doc = d
466-
e.desc = "New version available"
467-
e.save()
468-
known_revisions.add(v.revision)
479+
# FIXME: some RFCs seem to be called rfc1234bis?
480+
481+
if o.replaced_by:
482+
replacement, _ = Document.objects.get_or_create(name=o.replaced_by.filename)
483+
RelatedDocument.objects.get_or_create(document=replacement, doc_alias=d_alias, relationship=relationship_replaces)
484+
469485

470486
print "imported", d.name, " - ", d.iesg_state
471487

@@ -503,8 +519,8 @@ class CheckListInternetDraft(models.Model):
503519
# rfc_number = models.IntegerField(null=True, blank=True, db_index=True)
504520
# comments = models.TextField(blank=True,null=True)
505521
# last_modified_date = models.DateField()
506-
replaced_by = BrokenForeignKey('self', db_column='replaced_by', blank=True, null=True, related_name='replaces_set')
507-
replaces = FKAsOneToOne('replaces', reverse=True)
522+
# replaced_by = BrokenForeignKey('self', db_column='replaced_by', blank=True, null=True, related_name='replaces_set')
523+
# replaces = FKAsOneToOne('replaces', reverse=True)
508524
review_by_rfc_editor = models.BooleanField()
509525
expired_tombstone = models.BooleanField()
510526
# idinternal = FKAsOneToOne('idinternal', reverse=True, query=models.Q(rfc_flag = 0))

0 commit comments

Comments
 (0)