Import document replaces, revamp document relationships a little bit to remove a model, fix bugs

- Legacy-Id: 2730
This commit is contained in:
Ole Laursen 2010-12-23 18:09:59 +00:00
parent 7deeb609a1
commit 0ada0780fa
4 changed files with 101 additions and 85 deletions

View file

@ -2,12 +2,6 @@ from django.contrib import admin
from models import *
from person.models import *
class RelatedDocAdmin(admin.ModelAdmin):
list_display = ["source", "relationship", "target"]
search_fields = ["doc_alias__name", "related_document_set__name", ]
list_display_links = ["relationship", ]
admin.site.register(RelatedDoc, RelatedDocAdmin)
class DocumentAdmin(admin.ModelAdmin):
list_display = ['name', 'rev', 'state', 'group', 'pages', 'intended_std_level', 'author_list', 'time']
search_fields = ['name']

View file

@ -8,14 +8,6 @@ from redesign.util import admin_link
import datetime
class RelatedDoc(models.Model):
relationship = models.ForeignKey(DocRelationshipName)
doc_alias = models.ForeignKey('DocAlias')
def __unicode__(self):
return "%s %s" % (self.relationship.name, self.doc_alias.name)
source = admin_link("related_document_set")
target = admin_link("doc_alias__document")
class DocumentInfo(models.Model):
"""Any kind of document. Draft, RFC, Charter, IPR Statement, Liaison Statement"""
time = models.DateTimeField() # should probably have auto_now=True
@ -38,7 +30,6 @@ class DocumentInfo(models.Model):
intended_std_level = models.ForeignKey(IntendedStatusName, blank=True, null=True)
std_level = models.ForeignKey(StdStatusName, blank=True, null=True)
authors = models.ManyToManyField(Email, blank=True, null=True)
related = models.ManyToManyField(RelatedDoc, related_name='related_%(class)s_set', blank=True)
ad = models.ForeignKey(Email, related_name='ad_%(class)s_set', blank=True, null=True)
shepherd = models.ForeignKey(Email, related_name='shepherd_%(class)s_set', blank=True, null=True)
notify = models.CharField(max_length=255, blank=True)
@ -58,8 +49,16 @@ class DocumentInfo(models.Model):
e = model.objects.filter(doc=self).filter(**filter_args).order_by('-time')[:1]
return e[0] if e else None
class RelatedDocument(models.Model):
document = models.ForeignKey('Document') # source
doc_alias = models.ForeignKey('DocAlias') # target
relationship = models.ForeignKey(DocRelationshipName)
def __unicode__(self):
return u"%s %s %s" % (self.document.name, self.relationship.name.lower(), self.doc_alias.name)
class Document(DocumentInfo):
name = models.CharField(max_length=255, primary_key=True) # immutable
related = models.ManyToManyField('DocAlias', through=RelatedDocument, blank=True, related_name="reversely_related_document_set")
def __unicode__(self):
return self.name
def values(self):
@ -90,6 +89,7 @@ class Document(DocumentInfo):
snap = DocHistory(**fields)
snap.save()
for m in many2many:
# FIXME: check that this works with related
#print "m2m:", m, many2many[m]
rel = getattr(snap, m)
for item in many2many[m]:
@ -102,8 +102,16 @@ class Document(DocumentInfo):
print "Deleted list:", snap
super(Document, self).save(force_insert, force_update)
class RelatedDocHistory(models.Model):
document = models.ForeignKey('DocHistory')
doc_alias = models.ForeignKey('DocAlias', related_name="reversely_related_document_history_set")
relationship = models.ForeignKey(DocRelationshipName)
def __unicode__(self):
return u"%s %s %s" % (self.document.name, self.relationship.name.lower(), self.doc_alias.name)
class DocHistory(DocumentInfo):
doc = models.ForeignKey(Document) # ID of the Document this relates to
related = models.ManyToManyField('DocAlias', through=RelatedDocHistory, blank=True)
def __unicode__(self):
return unicode(self.doc.name)

View file

@ -133,20 +133,18 @@ class InternetDraft(Document):
#replaced_by = models.ForeignKey('self', db_column='replaced_by', blank=True, null=True, related_name='replaces_set')
@property
def replaced_by(self):
r = InternetDraft.objects.filter(docalias__relateddoc__relationship="replaces", docalias__relateddoc__related_document_set=self)
r = InternetDraft.objects.filter(related__document=self, related__relateddocument__relationship="replaces")
return r[0] if r else None
#replaces = FKAsOneToOne('replaces', reverse=True)
@property
def replaces(self):
r = InternetDraft.objects.filter(related__doc_alias__document=self, related__relationship="replaces")
return r[0] if r else Non
r = self.replaces_set()
return r[0] if r else None
@property
def replaces_set(self):
# this is replaced_by
return InternetDraft.objects.filter(docalias__relateddoc__relationship="replaces", docalias__relateddoc__related_document_set=self)
return InternetDraft.objects.filter(docalias__relateddocument__relationship="replaces", docalias__relateddocument__document=self)
#review_by_rfc_editor = models.BooleanField()
@property

View file

@ -46,6 +46,8 @@ def name(name_class, slug, name, desc=""):
type_draft = name(DocTypeName, "draft", "Draft")
stream_ietf = name(DocStreamName, "ietf", "IETF")
relationship_replaces = name(DocRelationshipName, "replaces", "Replaces")
intended_status_mapping = {
"BCP": name(IntendedStatusName, "bcp", "Best Current Practice"),
"Draft Standard": name(IntendedStatusName, "ds", name="Draft Standard"),
@ -145,7 +147,7 @@ date_re_str = "(?P<year>[0-9][0-9][0-9][0-9])-(?P<month>[0-9][0-9])-(?P<day>[0-9
def date_in_match(match):
return datetime.date(int(match.group('year')), int(match.group('month')), int(match.group('day')))
re_telechat_agenda = re.compile(r"(Placed on|Removed from) agenda for telechat - %s by" % date_re_str)
re_telechat_agenda = re.compile(r"(Placed on|Removed from) agenda for telechat(| - %s) by" % date_re_str)
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>.*)")
re_ballot_issued = re.compile(r"Ballot has been issued(| by)")
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,7 +193,7 @@ for o in all_drafts:
# d.std_level =
# d.authors =
# d.related =
d.ad = iesg_login_to_email(o.idinternal.job_owner)
d.ad = iesg_login_to_email(o.idinternal.job_owner) if o.idinternal else None
d.shepherd = None
d.notify = o.idinternal.state_change_notice_to or "" if o.idinternal else ""
d.external_url = ""
@ -199,6 +201,10 @@ for o in all_drafts:
d.internal_comments = o.comments or "" # FIXME: maybe put these somewhere else
d.save()
# make sure our alias is updated
DocAlias.objects.filter(name=d.name).exclude(document=d).delete()
d_alias, _ = DocAlias.objects.get_or_create(name=d.name, document=d)
# clear already imported events
d.event_set.all().delete()
@ -382,8 +388,10 @@ for o in all_drafts:
save_event(d, e, c)
# stop typical comments from being output
typical_comments = ["Who is the Document Shepherd for this document",
"We understand that this document doesn't require any IANA actions",
typical_comments = [
"Document Shepherd Write-up for %s" % d.name,
"Who is the Document Shepherd for this document",
"We understand that this document doesn't require any IANA actions",
]
for t in typical_comments:
if t in c.comment_text:
@ -391,66 +399,9 @@ for o in all_drafts:
break
if not handled:
print "couldn't handle %s '%s'" % (c.id, c.comment_text.replace("\n", "").replace("\r", ""))
print "couldn't handle %s '%s'" % (c.id, c.comment_text.replace("\n", "").replace("\r", "")[0:80])
# import events that might be missing, we can't be sure where
# to place them but if we don't generate them, we'll be
# missing the information completely
e = d.latest_event(Status, type="changed_status_date")
status_date = e.date if e else None
if o.idinternal.status_date != status_date:
e = Status(type="changed_status_date", date=o.idinternal.status_date)
e.time = made_up_date
e.by = system_email
e.doc = d
e.desc = "Status date has been changed to <b>%s</b> from <b>%s</b>" % (o.idinternal.status_date, status_date)
e.save()
e = d.latest_event(Event, type="iesg_approved")
approved_date = e.time.date() if e else None
if o.b_approve_date != approved_date:
e = Event(type="iesg_approved")
e.time = o.idinternal.b_approve_date
e.by = system_email
e.doc = d
e.desc = "IESG has approved"
e.save()
if o.lc_expiration_date:
e = Expiration(type="sent_last_call", expires=o.lc_expiration_date)
e.time = o.lc_sent_date
# let's try to figure out who did it
events = d.event_set.filter(type="changed_document", desc__contains=" to <b>In Last Call</b>").order_by('-time')[:1]
e.by = events[0].by if events else system_email
e.doc = d
e.desc = "Last call sent"
e.save()
if o.idinternal:
e = d.latest_event(Telechat, type="scheduled_for_telechat")
telechat_date = e.telechat_date if e else None
if not o.idinternal.agenda:
o.idinternal.telechat_date = None # normalize
if telechat_date != o.idinternal.telechat_date:
e = Telechat(type="scheduled_for_telechat",
telechat_date=o.idinternal.telechat_date,
returning_item=bool(o.idinternal.returning_item))
e.time = made_up_date
e.by = system_email
args = ("Placed on", o.idinternal.telechat_date) if o.idinternal.telechat_date else ("Removed from", telechat_date)
e.doc = d
e.desc = "%s agenda for telechat - %s by system" % args
e.save()
# FIXME: import writeups
# RFC alias
if o.rfc_number:
rfc_name = "rfc%s" % o.rfc_number
DocAlias.objects.get_or_create(document=d, name=rfc_name)
# import missing revision changes from DraftVersions
known_revisions = set(e.newrevision.rev for e in d.event_set.filter(type="new_revision").select_related('newrevision'))
for v in DraftVersions.objects.filter(filename=d.name).order_by("revision"):
@ -466,6 +417,71 @@ for o in all_drafts:
e.desc = "New version available"
e.save()
known_revisions.add(v.revision)
# import events that might be missing, we can't be sure where
# to place them but if we don't generate them, we'll be
# missing the information completely
e = d.latest_event(Event, type="iesg_approved")
approved_date = e.time.date() if e else None
if o.b_approve_date != approved_date:
e = Event(type="iesg_approved")
e.time = o.idinternal.b_approve_date
e.by = system_email
e.doc = d
e.desc = "IESG has approved"
e.save()
if o.lc_expiration_date:
e = Expiration(type="sent_last_call", expires=o.lc_expiration_date)
e.time = o.lc_sent_date
# let's try to figure out who did it
events = d.event_set.filter(type="changed_document", desc__contains=" to <b>In Last Call</b>").order_by('-time')[:1]
e.by = events[0].by if events else system_email
e.doc = d
e.desc = "Last call sent"
e.save()
if o.idinternal:
e = d.latest_event(Status, type="changed_status_date")
status_date = e.date if e else None
if o.idinternal.status_date != status_date:
e = Status(type="changed_status_date", date=o.idinternal.status_date)
e.time = made_up_date
e.by = system_email
e.doc = d
e.desc = "Status date has been changed to <b>%s</b> from <b>%s</b>" % (o.idinternal.status_date, status_date)
e.save()
e = d.latest_event(Telechat, type="scheduled_for_telechat")
telechat_date = e.telechat_date if e else None
if not o.idinternal.agenda:
o.idinternal.telechat_date = None # normalize
if telechat_date != o.idinternal.telechat_date:
e = Telechat(type="scheduled_for_telechat",
telechat_date=o.idinternal.telechat_date,
returning_item=bool(o.idinternal.returning_item))
e.time = made_up_date # FIXME: this isn't good, will override new values, estimate one instead
e.by = system_email
args = ("Placed on", o.idinternal.telechat_date) if o.idinternal.telechat_date else ("Removed from", telechat_date)
e.doc = d
e.desc = "%s agenda for telechat - %s by system" % args
e.save()
# FIXME: import writeups
# import other attributes
# RFC alias
if o.rfc_number:
rfc_name = "rfc%s" % o.rfc_number
DocAlias.objects.get_or_create(document=d, name=rfc_name)
# FIXME: some RFCs seem to be called rfc1234bis?
if o.replaced_by:
replacement, _ = Document.objects.get_or_create(name=o.replaced_by.filename)
RelatedDocument.objects.get_or_create(document=replacement, doc_alias=d_alias, relationship=relationship_replaces)
print "imported", d.name, " - ", d.iesg_state
@ -503,8 +519,8 @@ class CheckListInternetDraft(models.Model):
# rfc_number = models.IntegerField(null=True, blank=True, db_index=True)
# comments = models.TextField(blank=True,null=True)
# last_modified_date = models.DateField()
replaced_by = BrokenForeignKey('self', db_column='replaced_by', blank=True, null=True, related_name='replaces_set')
replaces = FKAsOneToOne('replaces', reverse=True)
# replaced_by = BrokenForeignKey('self', db_column='replaced_by', blank=True, null=True, related_name='replaces_set')
# replaces = FKAsOneToOne('replaces', reverse=True)
review_by_rfc_editor = models.BooleanField()
expired_tombstone = models.BooleanField()
# idinternal = FKAsOneToOne('idinternal', reverse=True, query=models.Q(rfc_flag = 0))