datatracker/ietf/idtracker/models.py
Henrik Levkowetz cd030d3b43 Adding copyright notices to all python files
- Legacy-Id: 716
2007-06-27 21:16:34 +00:00

908 lines
36 KiB
Python

# Copyright The IETF Trust 2007, All Rights Reserved
from django.db import models
from ietf.utils import FKAsOneToOne
class Acronym(models.Model):
acronym_id = models.AutoField(primary_key=True)
acronym = models.CharField(maxlength=12)
name = models.CharField(maxlength=100)
name_key = models.CharField(maxlength=50, editable=False)
def save(self):
self.name_key = self.name.upper()
super(Acronym, self).save()
def __str__(self):
return self.acronym
class Meta:
db_table = "acronym"
class Admin:
list_display = ('acronym', 'name')
pass
class AreaStatus(models.Model):
status_id = models.AutoField(primary_key=True)
status = models.CharField(maxlength=25, db_column='status_value')
def __str__(self):
return self.status
class Meta:
db_table = 'area_status'
class Admin:
pass
# I think equiv_group_flag is historical.
class IDState(models.Model):
document_state_id = models.AutoField(primary_key=True)
state = models.CharField(maxlength=50, db_column='document_state_val')
equiv_group_flag = models.IntegerField(null=True, blank=True)
description = models.TextField(blank=True, db_column='document_desc')
def __str__(self):
return self.state
def choices():
return [(state.document_state_id, state.state) for state in IDState.objects.all()]
choices = staticmethod(choices)
class Meta:
db_table = 'ref_doc_states_new'
ordering = ['document_state_id']
class Admin:
pass
class IDNextState(models.Model):
cur_state = models.ForeignKey(IDState, related_name='nextstate')
next_state = models.ForeignKey(IDState, related_name='prevstate', core=True)
condition = models.CharField(blank=True, maxlength=255)
def __str__(self):
return "%s -> %s" % (self.cur_state.state, self.next_state.state )
class Meta:
db_table = 'ref_next_states_new'
class Admin:
pass
class IDSubState(models.Model):
sub_state_id = models.AutoField(primary_key=True)
sub_state = models.CharField(maxlength=55, db_column='sub_state_val')
description = models.TextField(blank=True, db_column='sub_state_desc')
def __str__(self):
return self.sub_state
class Meta:
db_table = 'sub_state'
ordering = ['sub_state_id']
class Admin:
pass
class Area(models.Model):
ACTIVE=1
area_acronym = models.ForeignKey(Acronym, primary_key=True, unique=True)
start_date = models.DateField(auto_now_add=True)
concluded_date = models.DateField(null=True, blank=True)
status = models.ForeignKey(AreaStatus)
comments = models.TextField(blank=True)
last_modified_date = models.DateField(auto_now=True)
extra_email_addresses = models.TextField(blank=True)
def __str__(self):
return self.area_acronym.acronym
def active_area_choices():
return [(area.area_acronym_id, area.area_acronym.acronym) for area in Area.objects.filter(status=1).select_related().order_by('acronym.acronym')]
active_area_choices = staticmethod(active_area_choices)
class Meta:
db_table = 'areas'
verbose_name="area"
class Admin:
list_display = ('area_acronym', 'status')
pass
class IDStatus(models.Model):
status_id = models.AutoField(primary_key=True)
status = models.CharField(maxlength=25, db_column='status_value')
def __str__(self):
return self.status
class Meta:
db_table = "id_status"
verbose_name="I-D Status"
verbose_name_plural="I-D Statuses"
class Admin:
pass
class IDIntendedStatus(models.Model):
intended_status_id = models.AutoField(primary_key=True)
intended_status = models.CharField(maxlength=25, db_column='status_value')
def __str__(self):
return self.intended_status
class Meta:
db_table = "id_intended_status"
verbose_name="I-D Intended Publication Status"
verbose_name_plural="I-D Intended Publication Statuses"
class Admin:
pass
class InternetDraft(models.Model):
id_document_tag = models.AutoField(primary_key=True)
title = models.CharField(maxlength=255, db_column='id_document_name')
id_document_key = models.CharField(maxlength=255, editable=False)
group = models.ForeignKey(Acronym, db_column='group_acronym_id')
filename = models.CharField(maxlength=255, unique=True)
revision = models.CharField(maxlength=2)
revision_date = models.DateField()
file_type = models.CharField(maxlength=20)
txt_page_count = models.IntegerField()
local_path = models.CharField(maxlength=255, blank=True)
start_date = models.DateField()
expiration_date = models.DateField()
abstract = models.TextField()
dunn_sent_date = models.DateField()
extension_date = models.DateField(null=True, blank=True)
status = models.ForeignKey(IDStatus)
intended_status = models.ForeignKey(IDIntendedStatus)
lc_sent_date = models.DateField(null=True, blank=True)
lc_changes = models.CharField(maxlength=3)
lc_expiration_date = models.DateField(null=True, blank=True)
b_sent_date = models.DateField(null=True, blank=True)
b_discussion_date = models.DateField(null=True, blank=True)
b_approve_date = models.DateField(null=True, blank=True)
wgreturn_date = models.DateField(null=True, blank=True)
rfc_number = models.IntegerField(null=True, blank=True)
comments = models.TextField(blank=True)
last_modified_date = models.DateField()
replaced_by = models.ForeignKey('self', db_column='replaced_by', raw_id_admin=True, 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))
def save(self):
self.id_document_key = self.title.upper()
super(InternetDraft, self).save()
def displayname(self):
return "%s-%s.txt" % ( self.filename, self.revision_display() )
def doclink(self):
return "http://www.ietf.org/internet-drafts/%s" % ( self.displayname() )
def group_acronym(self):
return self.group.acronym
def __str__(self):
return self.filename
def idstate(self):
idinternal = self.idinternal
if idinternal:
return idinternal.docstate()
else:
return "I-D Exists"
def revision_display(self):
r = int(self.revision)
if self.status.status != 'Active' and not self.expired_tombstone:
r = max(r - 1, 0)
return "%02d" % r
def doctype(self):
return "Draft"
def filename_with_link(self, text=None):
if text is None:
text=self.filename
if self.status.status != 'Active':
return text
else:
return '<a href="%s">%s</a>' % ( self.doclink(), text )
def displayname_with_link(self):
return self.filename_with_link(self.displayname())
class Meta:
db_table = "internet_drafts"
class Admin:
search_fields = ['filename']
list_display = ('filename', 'revision', 'status')
list_filter = ['status']
pass
#date_hierarchy = 'revision_date'
#list_filter = ['revision_date']
class PersonOrOrgInfo(models.Model):
person_or_org_tag = models.AutoField(primary_key=True)
record_type = models.CharField(blank=True, maxlength=8)
name_prefix = models.CharField(blank=True, maxlength=10)
first_name = models.CharField(blank=True, maxlength=20)
first_name_key = models.CharField(blank=True, maxlength=20, editable=False)
middle_initial = models.CharField(blank=True, maxlength=4)
middle_initial_key = models.CharField(blank=True, maxlength=4, editable=False)
last_name = models.CharField(blank=True, maxlength=50)
last_name_key = models.CharField(blank=True, maxlength=50, editable=False)
name_suffix = models.CharField(blank=True, maxlength=10)
date_modified = models.DateField(null=True, blank=True, auto_now=True)
modified_by = models.CharField(blank=True, maxlength=8)
date_created = models.DateField(auto_now_add=True)
created_by = models.CharField(blank=True, maxlength=8)
address_type = models.CharField(blank=True, maxlength=4)
def save(self):
self.first_name_key = self.first_name.upper()
self.middle_initial_key = self.middle_initial.upper()
self.last_name_key = self.last_name.upper()
super(PersonOrOrgInfo, self).save()
def __str__(self):
if self.first_name == '' and self.last_name == '':
return self.affiliation()
return "%s %s" % ( self.first_name or "<nofirst>", self.last_name or "<nolast>")
def email(self, priority=1, type='INET'):
name = str(self)
try:
email = self.emailaddress_set.get(priority=priority, type=type).address
except EmailAddress.DoesNotExist:
email = ''
return (name, email)
# Added by Sunny Lee to display person's affiliation - 5/26/2007
def affiliation(self, priority=1):
try:
postal = self.postaladdress_set.get(address_priority=priority)
except PostalAddress.DoesNotExist:
return "PersonOrOrgInfo with no postal address!"
except AssertionError:
return "PersonOrOrgInfo with multiple priority-%d addresses!" % priority
return "%s" % ( postal.affiliated_company or postal.department or "???" )
class Meta:
db_table = 'person_or_org_info'
ordering = ['last_name']
verbose_name="Rolodex Entry"
verbose_name_plural="Rolodex"
class Admin:
search_fields = ['first_name','last_name']
pass
# could use a mapping for user_level
class IESGLogin(models.Model):
USER_LEVEL_CHOICES = (
('0', 'Secretariat'),
('1', 'IESG'),
('2', 'ex-IESG'),
('3', 'Level 3'),
('4', 'Comment Only(?)'),
)
id = models.AutoField(primary_key=True)
login_name = models.CharField(blank=True, maxlength=255)
password = models.CharField(maxlength=25)
user_level = models.IntegerField(choices=USER_LEVEL_CHOICES)
first_name = models.CharField(blank=True, maxlength=25)
last_name = models.CharField(blank=True, maxlength=25)
person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag', raw_id_admin=True, unique=True)
pgp_id = models.CharField(blank=True, maxlength=20)
default_search = models.IntegerField(null=True)
def __str__(self):
#return "%s, %s" % ( self.last_name, self.first_name)
return "%s %s" % ( self.first_name, self.last_name)
def is_current_ad(self):
return self.user_level == 1
def active_iesg():
return IESGLogin.objects.filter(user_level=1,id__gt=1).order_by('last_name') #XXX hardcoded
active_iesg = staticmethod(active_iesg)
class Meta:
db_table = 'iesg_login'
class Admin:
list_display = ('login_name', 'first_name', 'last_name', 'user_level')
ordering = ['user_level','last_name']
pass
class AreaDirector(models.Model):
area = models.ForeignKey(Area, db_column='area_acronym_id', edit_inline=models.STACKED, num_in_admin=2, null=True)
person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag', raw_id_admin=True, core=True)
def __str__(self):
return "%s (%s)" % ( self.person, self.role() )
def role(self):
try:
return "%s AD" % self.area
except Area.DoesNotExist:
return "?%d? AD" % self.area_id
class Meta:
db_table = 'area_directors'
class Admin:
pass
###
# RFC tables
class RfcIntendedStatus(models.Model):
intended_status_id = models.AutoField(primary_key=True)
status = models.CharField(maxlength=25, db_column='status_value')
def __str__(self):
return self.status
class Meta:
db_table = 'rfc_intend_status'
verbose_name = 'RFC Intended Status Field'
class Admin:
pass
class RfcStatus(models.Model):
status_id = models.AutoField(primary_key=True)
status = models.CharField(maxlength=25, db_column='status_value')
def __str__(self):
return self.status
class Meta:
db_table = 'rfc_status'
verbose_name = 'RFC Status'
verbose_name_plural = 'RFC Statuses'
class Admin:
pass
class Rfc(models.Model):
rfc_number = models.IntegerField(primary_key=True)
title = models.CharField(maxlength=200, db_column='rfc_name')
rfc_name_key = models.CharField(maxlength=200, editable=False)
group_acronym = models.CharField(blank=True, maxlength=8)
area_acronym = models.CharField(blank=True, maxlength=8)
status = models.ForeignKey(RfcStatus, db_column="status_id")
intended_status = models.ForeignKey(RfcIntendedStatus, db_column="intended_status_id")
fyi_number = models.CharField(blank=True, maxlength=20)
std_number = models.CharField(blank=True, maxlength=20)
txt_page_count = models.IntegerField(null=True, blank=True)
online_version = models.CharField(blank=True, maxlength=3)
rfc_published_date = models.DateField(null=True, blank=True)
proposed_date = models.DateField(null=True, blank=True)
draft_date = models.DateField(null=True, blank=True)
standard_date = models.DateField(null=True, blank=True)
historic_date = models.DateField(null=True, blank=True)
lc_sent_date = models.DateField(null=True, blank=True)
lc_expiration_date = models.DateField(null=True, blank=True)
b_sent_date = models.DateField(null=True, blank=True)
b_approve_date = models.DateField(null=True, blank=True)
comments = models.TextField(blank=True)
last_modified_date = models.DateField()
def __str__(self):
return "RFC%04d" % ( self.rfc_number )
def save(self):
self.rfc_name_key = self.title.upper()
super(Rfc, self).save()
def displayname(self):
return "%s.txt" % ( self.filename() )
def filename(self):
return "rfc%d" % ( self.rfc_number )
def revision(self):
return "RFC"
def revision_display(self):
return "RFC"
def doclink(self):
return "http://www.ietf.org/rfc/%s" % ( self.displayname() )
def doctype(self):
return "RFC"
def filename_with_link(self):
return '<a href="%s">%s</a>' % ( self.doclink(), self.displayname() )
def displayname_with_link(self):
return self.filename_with_link()
_idinternal_cache = None
_idinternal_cached = False
def idinternal(self):
if self._idinternal_cached:
return self._idinternal_cache
try:
self._idinternal_cache = IDInternal.objects.get(draft=self.rfc_number, rfc_flag=1)
except IDInternal.DoesNotExist:
self._idinternal_cache = None
self._idinternal_cached = True
return self._idinternal_cache
class Meta:
db_table = 'rfcs'
verbose_name = 'RFC'
verbose_name_plural = 'RFCs'
class Admin:
search_fields = ['title', 'group', 'area']
list_display = ['rfc_number', 'title']
pass
class RfcAuthor(models.Model):
rfc = models.ForeignKey(Rfc, unique=True, db_column='rfc_number', related_name='authors', edit_inline=models.TABULAR)
person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag', raw_id_admin=True, core=True)
def __str__(self):
return "%s, %s" % ( self.person.last_name, self.person.first_name)
class Meta:
db_table = 'rfc_authors'
verbose_name = 'RFC Author'
class RfcObsolete(models.Model):
rfc = models.ForeignKey(Rfc, db_column='rfc_number', raw_id_admin=True, related_name='updates_or_obsoletes')
action = models.CharField(maxlength=20, core=True)
rfc_acted_on = models.ForeignKey(Rfc, db_column='rfc_acted_on', raw_id_admin=True, related_name='updated_or_obsoleted_by')
def __str__(self):
return "RFC%04d %s RFC%04d" % (self.rfc_id, self.action, self.rfc_acted_on_id)
class Meta:
db_table = 'rfcs_obsolete'
verbose_name = 'RFC updates or obsoletes'
verbose_name_plural = verbose_name
class Admin:
pass
## End RFC Tables
class BallotInfo(models.Model): # Added by Michael Lee
ballot = models.AutoField(primary_key=True, db_column='ballot_id')
active = models.BooleanField()
an_sent = models.BooleanField()
an_sent_date = models.DateField(null=True, blank=True)
an_sent_by = models.ForeignKey(IESGLogin, db_column='an_sent_by', related_name='ansent')
defer = models.BooleanField(null=True, blank=True)
defer_by = models.ForeignKey(IESGLogin, db_column='defer_by', related_name='deferred')
defer_date = models.DateField(null=True, blank=True)
approval_text = models.TextField(blank=True)
last_call_text = models.TextField(blank=True)
ballot_writeup = models.TextField(blank=True)
ballot_issued = models.IntegerField(null=True, blank=True)
def __str__(self):
try:
return "Ballot for %s" % self.drafts.filter(primary_flag=1)
except IDInternal.DoesNotExist:
return "Ballot ID %d (no I-D?)" % (self.ballot)
def remarks(self):
remarks = list(self.discusses.all()) + list(self.comments.all())
return remarks
def active_positions(self):
'''Returns a list of dicts, with AD and Position tuples'''
active_iesg = IESGLogin.active_iesg()
ads = [ad.id for ad in active_iesg]
positions = {}
for position in self.positions.filter(ad__in=ads):
positions[position.ad_id] = position
ret = []
for ad in active_iesg:
ret.append({'ad': ad, 'pos': positions.get(ad.id, None)})
return ret
class Meta:
db_table = 'ballot_info'
class Admin:
pass
class IDInternal(models.Model):
"""
An IDInternal represents a document that has been added to the
I-D tracker. It can be either an Internet Draft or an RFC.
The table has only a single primary key field, meaning that
there is the danger of RFC number collision with low-numbered
Internet Drafts.
Since it's most common to be an Internet Draft, the draft
field is defined as a FK to InternetDrafts. One side effect
of this is that select_related() will only work with
rfc_flag=0.
When searching where matches may be either I-Ds or RFCs,
you cannot use draft__ as that will cause an INNER JOIN
which will limit the responses to I-Ds.
"""
draft = models.ForeignKey(InternetDraft, primary_key=True, unique=True, db_column='id_document_tag')
rfc_flag = models.IntegerField(null=True)
ballot = models.ForeignKey(BallotInfo, related_name='drafts', db_column="ballot_id")
primary_flag = models.IntegerField(blank=True, null=True)
group_flag = models.IntegerField(blank=True)
token_name = models.CharField(blank=True, maxlength=25)
token_email = models.CharField(blank=True, maxlength=255)
note = models.TextField(blank=True)
status_date = models.DateField(null=True)
email_display = models.CharField(blank=True, maxlength=50)
agenda = models.IntegerField(null=True, blank=True)
cur_state = models.ForeignKey(IDState, db_column='cur_state', related_name='docs')
prev_state = models.ForeignKey(IDState, db_column='prev_state', related_name='docs_prev')
assigned_to = models.CharField(blank=True, maxlength=25)
mark_by = models.ForeignKey(IESGLogin, db_column='mark_by', related_name='marked')
job_owner = models.ForeignKey(IESGLogin, db_column='job_owner', related_name='documents')
event_date = models.DateField(null=True)
area_acronym = models.ForeignKey(Area)
cur_sub_state = models.ForeignKey(IDSubState, related_name='docs', null=True, blank=True)
prev_sub_state = models.ForeignKey(IDSubState, related_name='docs_prev', null=True, blank=True)
returning_item = models.IntegerField(null=True, blank=True)
telechat_date = models.DateField(null=True, blank=True)
via_rfc_editor = models.IntegerField(null=True, blank=True)
state_change_notice_to = models.CharField(blank=True, maxlength=255)
dnp = models.IntegerField(null=True, blank=True)
dnp_date = models.DateField(null=True, blank=True)
noproblem = models.IntegerField(null=True, blank=True)
resurrect_requested_by = models.ForeignKey(IESGLogin, db_column='resurrect_requested_by', related_name='docsresurrected', null=True, blank=True)
approved_in_minute = models.IntegerField(null=True, blank=True)
def __str__(self):
if self.rfc_flag:
return "RFC%04d" % ( self.draft_id )
else:
return self.draft.filename
def get_absolute_url(self):
if self.rfc_flag:
return "/idtracker/rfc%d/" % ( self.draft_id )
else:
return "/idtracker/%s/" % ( self.draft.filename )
_cached_rfc = None
def document(self):
if self.rfc_flag:
if self._cached_rfc is None:
self._cached_rfc = Rfc.objects.get(rfc_number=self.draft_id)
return self._cached_rfc
else:
return self.draft
def public_comments(self):
return self.comments().filter(public_flag=1)
def comments(self):
# would filter by rfc_flag but the database is broken. (see
# trac ticket #96) so this risks collisions.
return self.documentcomment_set.all().order_by('-comment_date','-comment_time','-id')
def ballot_set(self):
return IDInternal.objects.filter(ballot=self.ballot_id).order_by('-primary_flag')
def ballot_primary(self):
return IDInternal.objects.filter(ballot=self.ballot_id,primary_flag=1)
def ballot_others(self):
return IDInternal.objects.filter(models.Q(primary_flag=0)|models.Q(primary_flag__isnull=True), ballot=self.ballot_id)
def docstate(self):
if self.cur_sub_state_id > 0:
return "%s :: %s" % ( self.cur_state, self.cur_sub_state )
else:
return self.cur_state
class Meta:
db_table = 'id_internal'
verbose_name = 'IDTracker Draft'
class Admin:
pass
class DocumentComment(models.Model):
BALLOT_CHOICES = (
(1, 'discuss'),
(2, 'comment'),
)
document = models.ForeignKey(IDInternal)
rfc_flag = models.IntegerField(null=True, blank=True)
public_flag = models.IntegerField()
date = models.DateField(db_column='comment_date')
time = models.CharField(db_column='comment_time', maxlength=20)
version = models.CharField(blank=True, maxlength=3)
comment_text = models.TextField(blank=True)
created_by = models.ForeignKey(IESGLogin, db_column='created_by', null=True)
result_state = models.ForeignKey(IDState, db_column='result_state', null=True, related_name="comments_leading_to_state")
origin_state = models.ForeignKey(IDState, db_column='origin_state', null=True, related_name="comments_coming_from_state")
ballot = models.IntegerField(null=True, choices=BALLOT_CHOICES)
def get_absolute_url(self):
if self.rfc_flag:
return "/idtracker/rfc%d/comment/%d/" % (self.document_id, self.id)
else:
return "/idtracker/%s/comment/%d/" % (self.document.draft.filename, self.id)
def get_author(self):
if self.created_by_id and self.created_by_id != 999:
return self.created_by.__str__()
else:
return "system"
def get_username(self):
if self.created_by_id and self.created_by_id != 999:
return self.created_by.login_name
else:
return "system"
class Meta:
db_table = 'document_comments'
class Position(models.Model):
ballot = models.ForeignKey(BallotInfo, raw_id_admin=True, related_name='positions')
ad = models.ForeignKey(IESGLogin, raw_id_admin=True)
yes = models.IntegerField(db_column='yes_col')
noobj = models.IntegerField(db_column='no_col')
abstain = models.IntegerField()
approve = models.IntegerField()
discuss = models.IntegerField()
recuse = models.IntegerField()
def __str__(self):
return "Position for %s on %s" % ( self.ad, self.ballot )
def abstain_ind(self):
if self.recuse:
return 'R'
if self.abstain:
return 'X'
else:
return ' '
class Meta:
db_table = 'ballots'
unique_together = (('ballot', 'ad'), )
verbose_name = "IESG Ballot Position"
class Admin:
pass
class IESGComment(models.Model):
ballot = models.ForeignKey(BallotInfo, raw_id_admin=True, related_name="comments")
ad = models.ForeignKey(IESGLogin, raw_id_admin=True)
date = models.DateField(db_column="comment_date")
revision = models.CharField(maxlength=2)
active = models.IntegerField()
text = models.TextField(blank=True, db_column="comment_text")
def __str__(self):
return "Comment text by %s on %s" % ( self.ad, self.ballot )
def is_comment(self):
return True
class Meta:
db_table = 'ballots_comment'
unique_together = (('ballot', 'ad'), )
verbose_name = 'IESG Comment Text'
verbose_name_plural = 'IESG Comments'
class Admin:
pass
class IESGDiscuss(models.Model):
ballot = models.ForeignKey(BallotInfo, raw_id_admin=True, related_name="discusses")
ad = models.ForeignKey(IESGLogin, raw_id_admin=True)
date = models.DateField(db_column="discuss_date")
revision = models.CharField(maxlength=2)
active = models.IntegerField()
text = models.TextField(blank=True, db_column="discuss_text")
def __str__(self):
return "Discuss text by %s on %s" % ( self.ad, self.ballot )
def is_discuss(self):
return True
class Meta:
db_table = 'ballots_discuss'
unique_together = (('ballot', 'ad'), )
verbose_name = 'IESG Discuss Text'
verbose_name_plural = 'IESG Discusses'
class Admin:
pass
class IDAuthor(models.Model):
document = models.ForeignKey(InternetDraft, db_column='id_document_tag', related_name='authors', edit_inline=models.TABULAR, raw_id_admin=True)
person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag', raw_id_admin=True, core=True)
author_order = models.IntegerField(null=True, blank=True)
def __str__(self):
return "%s authors %s" % ( self.person, self.document.filename )
def email(self):
try:
return self.person.emailaddress_set.filter(type='I-D').get(priority=self.document_id).address
except EmailAddress.DoesNotExist:
return None
class Meta:
db_table = 'id_authors'
verbose_name = "I-D Author"
ordering = ['document','author_order']
# PostalAddress, EmailAddress and PhoneNumber are edited in
# the admin for the Rolodex.
# The unique_together constraint is commented out for now, because
# of a bug in oldforms and AutomaticManipulator which fails to
# create the isUniquefoo_bar method properly. Since django is
# moving away from oldforms, I have to assume that this is going
# to be fixed by moving admin to newforms.
# A table without a unique primary key!
# must decide which field is/are core.
class PostalAddress(models.Model):
address_type = models.CharField(maxlength=4)
address_priority = models.IntegerField(null=True)
person_or_org = models.ForeignKey(PersonOrOrgInfo, primary_key=True, db_column='person_or_org_tag', edit_inline=models.STACKED)
person_title = models.CharField(maxlength=50, blank=True)
affiliated_company = models.CharField(maxlength=70, blank=True)
aff_company_key = models.CharField(maxlength=70, blank=True, editable=False)
department = models.CharField(maxlength=100, blank=True)
staddr1 = models.CharField(maxlength=40, core=True)
staddr2 = models.CharField(maxlength=40, blank=True)
mail_stop = models.CharField(maxlength=20, blank=True)
city = models.CharField(maxlength=20, blank=True)
state_or_prov = models.CharField(maxlength=20, blank=True)
postal_code = models.CharField(maxlength=20, blank=True)
country = models.CharField(maxlength=20, blank=True)
def save(self):
self.aff_company_key = self.affiliated_company.upper()
super(PostalAddress, self).save()
class Meta:
db_table = 'postal_addresses'
#unique_together = (('address_type', 'person_or_org'), )
verbose_name_plural = 'Postal Addresses'
class EmailAddress(models.Model):
person_or_org = models.ForeignKey(PersonOrOrgInfo, primary_key=True, db_column='person_or_org_tag', edit_inline=models.TABULAR)
type = models.CharField(maxlength=12, db_column='email_type')
priority = models.IntegerField(db_column='email_priority')
address = models.CharField(maxlength=255, core=True, db_column='email_address')
comment = models.CharField(blank=True, maxlength=255, db_column='email_comment')
def __str__(self):
return self.address
class Meta:
db_table = 'email_addresses'
#unique_together = (('email_priority', 'person_or_org'), )
# with this, I get 'ChangeManipulator' object has no attribute 'isUniqueemail_priority_person_or_org'
class PhoneNumber(models.Model):
person_or_org = models.ForeignKey(PersonOrOrgInfo, primary_key=True, db_column='person_or_org_tag', edit_inline=models.TABULAR)
phone_type = models.CharField(maxlength=3)
phone_priority = models.IntegerField()
phone_number = models.CharField(blank=True, maxlength=255, core=True)
phone_comment = models.CharField(blank=True, maxlength=255)
class Meta:
db_table = 'phone_numbers'
#unique_together = (('phone_priority', 'person_or_org'), )
### Working Groups
class WGType(models.Model):
group_type_id = models.AutoField(primary_key=True)
type = models.CharField(maxlength=25, db_column='group_type')
def __str__(self):
return self.type
class Meta:
db_table = 'g_type'
class Admin:
pass
class WGStatus(models.Model):
status_id = models.AutoField(primary_key=True)
status = models.CharField(maxlength=25, db_column='status_value')
def __str__(self):
return self.status
class Meta:
db_table = 'g_status'
class Admin:
pass
class IETFWG(models.Model):
ACTIVE = 1
group_acronym = models.ForeignKey(Acronym, primary_key=True, unique=True, editable=False)
group_type = models.ForeignKey(WGType)
proposed_date = models.DateField(null=True, blank=True)
start_date = models.DateField(null=True, blank=True)
dormant_date = models.DateField(null=True, blank=True)
concluded_date = models.DateField(null=True, blank=True)
status = models.ForeignKey(WGStatus)
area_director = models.ForeignKey(AreaDirector, null=True)
meeting_scheduled = models.CharField(blank=True, maxlength=3)
email_address = models.CharField(blank=True, maxlength=60)
email_subscribe = models.CharField(blank=True, maxlength=120)
email_keyword = models.CharField(blank=True, maxlength=50)
email_archive = models.CharField(blank=True, maxlength=95)
comments = models.TextField(blank=True)
last_modified_date = models.DateField()
meeting_scheduled_old = models.CharField(blank=True, maxlength=3)
area = FKAsOneToOne('areagroup', reverse=True)
def __str__(self):
return self.group_acronym.acronym
def active_drafts(self):
return self.group_acronym.internetdraft_set.all().filter(status__status="Active")
def choices():
return [(wg.group_acronym_id, wg.group_acronym.acronym) for wg in IETFWG.objects.all().filter(group_type__type='WG').select_related().order_by('acronym.acronym')]
choices = staticmethod(choices)
def area_acronym(self):
return AreaGroup.objects.filter(group_acronym_id=self.group_acronym_id).area
class Meta:
db_table = 'groups_ietf'
ordering = ['?'] # workaround django wanting to sort by acronym but not joining with it
verbose_name = 'IETF Working Group'
class Admin:
search_fields = ['group_acronym__acronym', 'group_acronym__name']
list_display = ('group_acronym', 'group_type', 'status', 'area_director')
list_filter = ['status', 'group_type', 'area_director']
pass
class WGChair(models.Model):
person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag', raw_id_admin=True, unique=True, core=True)
group_acronym = models.ForeignKey(IETFWG, edit_inline=models.TABULAR)
def __str__(self):
return "%s (%s)" % ( self.person, self.role() )
def role(self):
return "%s %s Chair" % ( self.group_acronym.acronym, self.group_acronym.group_type )
class Meta:
db_table = 'g_chairs'
verbose_name = "WG Chair"
class WGEditor(models.Model):
group_acronym = models.ForeignKey(IETFWG, edit_inline=models.TABULAR)
person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag', raw_id_admin=True, unique=True, core=True)
class Meta:
db_table = 'g_editors'
verbose_name = "WG Editor"
# Note: there is an empty table 'g_secretary'.
# This uses the 'g_secretaries' table but is called 'GSecretary' to
# match the model naming scheme.
class WGSecretary(models.Model):
group_acronym = models.ForeignKey(IETFWG, edit_inline=models.TABULAR)
person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag', raw_id_admin=True, unique=True, core=True)
def __str__(self):
return "%s (%s)" % ( self.person, self.role() )
def role(self):
return "%s %s Secretary" % ( self.group_acronym.acronym, self.group_acronym.group_type )
class Meta:
db_table = 'g_secretaries'
verbose_name = "WG Secretary"
verbose_name_plural = "WG Secretaries"
class WGTechAdvisor(models.Model):
group_acronym = models.ForeignKey(IETFWG, edit_inline=models.TABULAR)
person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag', raw_id_admin=True, core=True)
def __str__(self):
return "%s (%s)" % ( self.person, self.role() )
def role(self):
return "%s Technical Advisor" % self.group_acronym.acronym
class Meta:
db_table = 'g_tech_advisors'
verbose_name = "WG Technical Advisor"
class AreaGroup(models.Model):
area = models.ForeignKey(Area, db_column='area_acronym_id', related_name='areagroup', core=True)
group = models.ForeignKey(IETFWG, db_column='group_acronym_id', edit_inline=models.TABULAR, num_in_admin=1, max_num_in_admin=1, unique=True)
def __str__(self):
return "%s is in %s" % ( self.group, self.area )
class Meta:
db_table = 'area_group'
verbose_name = 'Area this group is in'
verbose_name_plural = 'Area to Group mappings'
class GoalMilestone(models.Model):
DONE_CHOICES = (
('Done', 'Done'),
('No', 'Not Done'),
)
gm_id = models.AutoField(primary_key=True)
group_acronym = models.ForeignKey(IETFWG, raw_id_admin=True)
description = models.TextField()
expected_due_date = models.DateField()
done_date = models.DateField(null=True, blank=True)
done = models.CharField(blank=True, choices=DONE_CHOICES, maxlength=4)
last_modified_date = models.DateField()
def __str__(self):
return self.description
class Meta:
db_table = 'goals_milestones'
verbose_name = 'IETF WG Goal or Milestone'
verbose_name_plural = 'IETF WG Goals or Milestones'
ordering = ['expected_due_date']
class Admin:
list_display = ('group_acronym', 'description', 'expected_due_date', 'done')
date_hierarchy = 'expected_due_date'
list_filter = ['done']
pass
#### end wg stuff
class Role(models.Model):
'''This table is named 'chairs' in the database, as its original
role was to store "who are IETF, IAB and IRTF chairs?". It has
since expanded to store roles, such as "IAB Exec Dir" and "IAD",
so the model is renamed.
'''
person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag', raw_id_admin=True)
role_name = models.CharField(maxlength=25, db_column='chair_name')
def __str__(self):
return "%s (%s)" % (self.person, self.role())
def role(self):
if self.role_name in ('IETF', 'IAB', 'IRTF', 'NomCom'):
return "%s Chair" % self.role_name
else:
return self.role_name
class Meta:
db_table = 'chairs'
class Admin:
pass
class ChairsHistory(models.Model):
CHAIR_CHOICES = (
( '1', 'IETF' ),
( '2', 'IAB' ),
( '3', 'NOMCOM' ),
)
chair_type_id = models.IntegerField(choices=CHAIR_CHOICES)
present_chair = models.BooleanField()
person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag', raw_id_admin=True)
start_year = models.IntegerField()
end_year = models.IntegerField(null=True, blank=True)
class Meta:
db_table = 'chairs_history'
#
# IRTF RG info
class IRTF(models.Model):
irtf_id = models.AutoField(primary_key=True)
acronym = models.CharField(blank=True, maxlength=25, db_column='irtf_acronym')
name = models.CharField(blank=True, maxlength=255, db_column='irtf_name')
charter_text = models.TextField(blank=True)
meeting_scheduled = models.BooleanField(null=True, blank=True)
class Meta:
db_table = 'irtf'
class Admin:
pass
class IRTFChair(models.Model):
irtf = models.ForeignKey(IRTF)
person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag', raw_id_admin=True)
class Meta:
db_table = 'irtf_chairs'
class Admin:
pass
# Not a model, but it's related.
# This is used in the view to represent documents
# in "I-D Exists".
#
class DocumentWrapper(object):
'''A wrapper for a document, used to synthesize I-D Exists.'''
document = None
synthetic = True
job_owner = "Not Assigned Yet"
docstate = "I-D Exists"
cur_state = "I-D Exists"
cur_state_id = 100
primary_flag = 1
def __init__(self, document):
self.document = document