datatracker/redesign/doc/models.py
Ole Laursen c71f1d9f97 Added redesign work-in-progress
- Legacy-Id: 2686
2010-11-19 19:21:15 +00:00

212 lines
9.1 KiB
Python

# Copyright The IETF Trust 2007, All Rights Reserved
from django.db import models
from redesign.group.models import *
from redesign.name.models import *
from redesign.person.models import Email
from redesign.util import admin_link
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
# Document related
type = models.ForeignKey(DocTypeName, blank=True, null=True) # Draft, Agenda, Minutes, Charter, Discuss, Guideline, Email, Review, Issue, Wiki, External ...
title = models.CharField(max_length=255)
# State
state = models.ForeignKey(DocStateName, blank=True, null=True) # Active/Expired/RFC/Replaced/Withdrawn
tags = models.ManyToManyField(DocInfoTagName, blank=True, null=True) # Revised ID Needed, ExternalParty, AD Followup, ...
stream = models.ForeignKey(DocStreamName, blank=True, null=True) # IETF, IAB, IRTF, Independent Submission
group = models.ForeignKey(Group, blank=True, null=True) # WG, RG, IAB, IESG, Edu, Tools
wg_state = models.ForeignKey(WgDocStateName, blank=True, null=True) # Not/Candidate/Active/Parked/LastCall/WriteUp/Submitted/Dead
iesg_state = models.ForeignKey(IesgDocStateName, blank=True, null=True) #
iana_state = models.ForeignKey(IanaDocStateName, blank=True, null=True)
rfc_state = models.ForeignKey(RfcDocStateName, blank=True, null=True)
# Other
abstract = models.TextField()
rev = models.CharField(max_length=16)
pages = models.IntegerField(blank=True, null=True)
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)
external_url = models.URLField(blank=True) # Should be set for documents with type 'External'.
note = models.TextField(blank=True)
internal_comments = models.TextField(blank=True)
class Meta:
abstract = True
def author_list(self):
return ", ".join(email.address for email in self.authors.all())
def latest_event(self, **filter_args):
e = self.event_set.filter(**filter_args).order_by('-time')[:1]
if e:
return e[0]
else:
return None
class Document(DocumentInfo):
name = models.CharField(max_length=255, primary_key=True) # immutable
def __unicode__(self):
return self.name
def values(self):
try:
fields = dict([(field.name, getattr(self, field.name))
for field in self._meta.fields
if field is not self._meta.pk])
except:
for field in self._meta.fields:
print "* %24s"%field.name,
print getattr(self, field.name)
raise
many2many = dict([(field.name, getattr(self, field.name).all())
for field in self._meta.many_to_many ])
return fields, many2many
def save_with_history(self, force_insert=False, force_update=False):
fields, many2many = self.values()
fields["doc"] = self
try:
snap = DocHistory.objects.get(**dict((k,v) for k,v in fields.items() if k != 'time'))
# FIXME: what if there are two with the same set of values
# at different points in time?
if snap.time > fields["time"]:
snap.time = fields["time"]
snap.save()
except DocHistory.DoesNotExist:
snap = DocHistory(**fields)
snap.save()
for m in many2many:
#print "m2m:", m, many2many[m]
rel = getattr(snap, m)
for item in many2many[m]:
rel.add(item)
except DocHistory.MultipleObjectsReturned:
list = DocHistory.objects.filter(**dict((k,v) for k,v in fields.items() if k != 'time'))
list.delete()
snap = DocHistory(**fields)
snap.save()
print "Deleted list:", snap
super(Document, self).save(force_insert, force_update)
class DocHistory(DocumentInfo):
doc = models.ForeignKey(Document) # ID of the Document this relates to
def __unicode__(self):
return unicode(self.doc.name)
class DocAlias(models.Model):
"""This is used for documents that may appear under multiple names,
and in particular for RFCs, which for continuity still keep the
same immutable Document.name, in the tables, but will be referred
to by RFC number, primarily, after achieving RFC status.
"""
document = models.ForeignKey(Document)
name = models.CharField(max_length=255)
def __unicode__(self):
return "%s-->%s" % (self.name, self.document.name)
document_link = admin_link("document")
class Meta:
verbose_name_plural="Aliases"
class SendQueue(models.Model):
time = models.DateTimeField() # Scheduled at this time
agent = models.ForeignKey(Email) # Scheduled by this person
comment = models.TextField()
#
msg = models.ForeignKey('Message')
to = models.ForeignKey(Email, related_name='to_messages')
cc = models.ManyToManyField(Email, related_name='cc_messages')
send = models.DateTimeField() # Send message at this time
# class Ballot(models.Model): # A collection of ballot positions
# """A collection of ballot positions, and the actions taken during the
# lifetime of the ballot.
# The actual ballot positions are found by searching Messages for
# BallotPositions for this document between the dates indicated by
# self.initiated.time and (self.closed.time or now)
# """
# initiated = models.ForeignKey(Message, related_name="initiated_ballots")
# deferred = models.ForeignKey(Message, null=True, blank=True, related_name="deferred_ballots")
# last_call = models.ForeignKey(Message, null=True, blank=True, related_name="lastcalled_ballots")
# closed = models.ForeignKey(Message, null=True, blank=True, related_name="closed_ballots")
# announced = models.ForeignKey(Message, null=True, blank=True, related_name="announced_ballots")
EVENT_TYPES = [
# misc document events
("new_revision", "Added new revision"),
("document_changed", "Changed document"),
("tombstone_added", "Added tombstone"),
("requested_resurrect", "Requested resurrect"),
# IESG events
("sent_ballot_announcement", "Sent ballot announcement"),
("deferred_ballot", "Deferred ballot"),
("approved_ballot", "Approved ballot"),
("changed_ballot_position", "Changed ballot position"),
("changed_ballot_approval_text", "Changed ballot approval text"),
("changed_ballot_writeup_text", "Changed ballot writeup text"),
("changed_last_call_text", "Changed last call text"),
("sent_last_call", "Sent last call"),
("scheduled_for_telechat", "Scheduled for telechat"),
("resolved_to_do_not_publish", "Resolved to 'do not publish'"),
("resolved_to_no_problem", "Resolved to 'no problem'"),
("approved_in_minute", "Approved in minute"),
]
class Event(models.Model):
"""An occurrence in connection with a document."""
time = models.DateTimeField()
type = models.CharField(max_length=50, choices=EVENT_TYPES)
by = models.ForeignKey(Email, blank=True, null=True)
doc = models.ForeignKey('doc.Document')
desc = models.TextField()
def __unicode__(self):
return u"%s %s at %s" % (self.by.get_name(), self.get_type_display().lower(), self.time)
class Meta:
ordering = ['-time']
class Message(Event):
subj = models.CharField(max_length=255)
body = models.TextField()
class Text(Event):
content = models.TextField(blank=True)
# IESG events
class BallotPosition(Event):
ad = models.ForeignKey(Email)
pos = models.ForeignKey(BallotPositionName, verbose_name="position", default="norec")
discuss = models.TextField(help_text="Discuss text if position is discuss", blank=True)
discuss_time = models.DateTimeField(help_text="Time discuss text was written", blank=True, null=True)
comment = models.TextField(help_text="Optional comment", blank=True)
comment_time = models.DateTimeField(help_text="Time optional comment was written", blank=True, null=True)
class Expiration(Event):
expires = models.DateTimeField()
class Telechat(Event):
telechat_date = models.DateField()
returning_item = models.BooleanField(default=False)