Implement most of view_id.

* Moved RFCs model into idtracker
 * Switched idtracker querys to use idinternal
 * Created idinternal.document which returns either an InternetDraft or
   an Rfc depending on the value of rfc_flag
 * Create compatability methods in InternetDraft and Rfc models
   to be able to use certain attributes in the template without
   worring about where they come from.

Ticket #59 has a list of remaining bits.
 - Legacy-Id: 98
This commit is contained in:
Bill Fenner 2007-05-04 21:33:56 +00:00
parent c2c08c9edc
commit e73f7dbf5f
5 changed files with 432 additions and 27 deletions

View file

@ -140,6 +140,12 @@ class InternetDraft(models.Model):
def save(self):
self.id_document_key = self.id_document_name.upper()
super(InternetDraft, self).save()
def displayname(self):
return "%s-%s.txt" % ( self.filename, self.revision )
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):
@ -233,12 +239,114 @@ class AreaDirectors(models.Model):
class Meta:
db_table = 'area_directors'
###
# 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)
rfc_name = models.CharField(maxlength=200)
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.rfc_name.upper()
super(Rfc, self).save()
def displayname(self):
return "rfc%d.txt" % ( self.rfc_number )
def doclink(self):
return "http://www.ietf.org/rfc/%s" % ( self.displayname() )
class Meta:
db_table = 'rfcs'
verbose_name = 'RFC'
verbose_name_plural = 'RFCs'
class Admin:
search_fields = ['rfc_name', 'group', 'area']
list_display = ['rfc_number', 'rfc_name']
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 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.
"""
draft = models.ForeignKey(InternetDraft, primary_key=True, unique=True, db_column='id_document_tag')
# the above ignores the possibility that it's an RFC.
rfc_flag = models.IntegerField(null=True)
ballot_id = models.IntegerField()
primary_flag = models.IntegerField(null=True, blank=True)
primary_flag = models.IntegerField()
group_flag = models.IntegerField(blank=True)
token_name = models.CharField(blank=True, maxlength=25)
token_email = models.CharField(blank=True, maxlength=255)
@ -266,9 +374,27 @@ class IDInternal(models.Model):
approved_in_minute = models.IntegerField(null=True, blank=True)
def __str__(self):
if self.rfc_flag:
return "RFC%04d" % ( self.id_document_tag )
return "RFC%04d" % ( self.draft_id )
else:
return self.id_document_tag.filename
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 comments(self):
return self.documentcomment_set.all().filter(rfc_flag=self.rfc_flag).order_by('-comment_date','-comment_time')
def ballot_set(self):
# can't access manager via self; use the class name
return IDInternal.objects.filter(ballot_id=self.ballot_id)
class Meta:
db_table = 'id_internal'
verbose_name = 'IDTracker Draft'
@ -301,6 +427,11 @@ class DocumentComment(models.Model):
return self.created_by.__str__()
else:
return "system"
def get_username(self):
if self.created_by:
return self.created_by.login_name
else:
return "system"
class Meta:
db_table = 'document_comments'

View file

@ -1,9 +1,12 @@
from django.conf.urls.defaults import *
from ietf.idtracker.models import InternetDraft, IDState, IDSubState, DocumentComment
from ietf.idtracker.models import IDInternal, IDState, IDSubState, DocumentComment
from ietf.idtracker import views
id_dict = {
'queryset': InternetDraft.objects.all(),
'queryset': IDInternal.objects.all().filter(rfc_flag=0),
}
rfc_dict = {
'queryset': IDInternal.objects.all().filter(rfc_flag=1),
}
comment_dict = {
'queryset': DocumentComment.objects.all().filter(public_flag=1),
@ -13,8 +16,9 @@ urlpatterns = patterns('django.views.generic.simple',
(r'^states/$', 'direct_to_template', { 'template': 'idtracker/states.html', 'extra_context': { 'states': IDState.objects.all(), 'substates': IDSubState.objects.all() } }),
)
urlpatterns += patterns('django.views.generic.list_detail',
(r'^rfc(?P<object_id>\d+)/$', 'object_detail', rfc_dict),
(r'^(?P<object_id>\d+)/$', 'object_detail', id_dict),
(r'^(?P<slug>[^/]+)/$', 'object_detail', dict(id_dict, slug_field='filename')),
(r'^(?P<slug>[^/]+)/$', 'object_detail', dict(id_dict, slug_field='draft__filename')),
(r'^comment/(?P<object_id>\d+)/$', 'object_detail', comment_dict),
)
urlpatterns += patterns('',

View file

@ -94,7 +94,6 @@ INSTALLED_APPS = (
'ietf.my',
'ietf.proceedings',
'ietf.redirects',
'ietf.rfcs',
)
INTERNAL_IPS = (

View file

@ -0,0 +1,290 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
{% load ietf_filters %}
<html>
<head>
<title>IETF I-D Tracker v1.0 -- WCF</title>
<style type="text/css">
<!--
TD {text-decoration: none; color: #000000; font: 9pt arial;}
A:Link {color: #0000ff; text-decoration:underline}
A:Hover {color: #ff0000; text-decoration:underline}
A:visited {color: #0000ff; text-decoration:underline}
.largefont {font-weight: bold; color: #000000; font: 18pt arial}
.largefont2 {color: #000000; font: 14pt verdana}
.largefont3 {color: #000000; font: 13pt verdana}
.largefont_red {font-weight: bold; color: #ff0000; font: 16pt arial}
-->
</style>
</head>
<body link="blue" vlink="blue">
<table width="90%" cellpading="1" cellspacing="0">
<tr>
<td bgcolor="000000">
<table width="100%" cellspacing="0" cellpading="5">
<tr bgcolor="BEBEBE" align="center">
<th colspan="2">
<div class="largefont">
Detail Info
</div>
{% if object.ballot_set|length_is:"1" %}
{% else %}
<div align="right">
<a href="#action">Action List</a>
</div>
{% endif %}
</th>
</tr>
<tr bgcolor="white">
<td>
<div class="largefont3">
Draft Name:
</div>
</td>
<td>
<div class="largefont3">
<a href="{{ object.document.doclink }}">
{{ object.document.displayname }}</a>
<font color="red">
{% if object.via_rfc_editor %}
Independent submission via RFC Editor
{% else %}
{% ifequal object.document.group_acronym "none" %}
Individual submission
{% else %}
WG &lt;{{ object.document.group_acronym }}&gt; submission
{% endifequal %}
{% endif %}
</font>
</div>
</td>
</tr>
<tr bgcolor="white">
<td>
<div class="largefont3">
IESG Discussion:
</div>
</td>
<td>
{# what's the "if" here #}
<div class="largefont3">
<a href="ballot/">IESG evaluation record</a>
[<a href="/idtracker/view_evaluation_desc/">What
they mean</a>]
[<a href="/idtracker/view_key/">How they are
recorded</a>]
</div>
</td>
</tr>
<tr bgcolor="white">
<td>
<div class="largefont3">
Version:
</div>
</td>
<td>
<div class="largefont3">
{{ object.document.revision }}
</div>
</td>
</tr>
<tr bgcolor="white">
<td>
<div class="largefont3">
Intended Status:
</div>
</td>
<td>
<div class="largefont3">
{{ object.document.intended_status }}
</div>
</td>
</tr>
<tr bgcolor="white">
<td>
<div class="largefont3">
On Next Agenda?
</div>
</td>
<td>
<div class="largefont3">
{{ object.agenda|yesno:"Yes,No" }}
</div>
</td>
</tr>
<tr bgcolor="white">
<td>
<div class="largefont3">
Current State:
</div>
</td>
<td>
<div class="largefont3">
<a href="/idtracker/states/{{ object.cur_state.document_state_id }}/">
{{ object.cur_state }}</a>
{% if object.cur_sub_state %}
::
<a href="/idtracker/states/sub_state/{{ object.cur_substate.sub_state_id }}/">
{{ object.cur_sub_state }}
</a>
{% endif %}
{% if object.rfc_flag %}
{% else %}
{% ifequal object.cur_state.state "RFC Ed Queue" %}
<a href="http://www.rfc-editor.org/queue.html#{{ object.draft.filename }}">
[RFC Editor State]</a>
{% endifequal %}
{% endif %}
</div>
<a href="/idtracker/states/">
[Show States Table]</a>
</td>
</tr>
<tr bgcolor="white">
<td>
<div class="largefont3">
Responsible AD:
</div>
</td>
<td>
<div class="largefont3">
{{ object.job_owner }}
</div>
</td>
</tr>
<tr bgcolor="white">
<td>
<div class="largefont3">
Status Date:
</div>
</td>
<td bgcolor="white">
<div class="largefont3">
{% firstof object.status_date "&nbsp;" %}
</div>
</td>
</tr>
<tr bgcolor="white">
<td>
<div class="largefont3">
Note:
</div>
</td>
<td>
<div class="largefont3">
{% firstof object.note|unformat_textarea &nbsp; %}
</div>
</td>
</tr>
<tr bgcolor="white">
<td width="20%">&nbsp;</td>
<td>
<table cellpadding="1" cellspacing="1" border="0">
<tr>
<td>
<form action="/idtracker/" method="GET">
<input type="submit" value=
"Main Menu">
</form>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
{% if object.ballot_set|length_is:"1" %}
{% else %}
<a name="action"></a>
<table border="1" bgcolor="black">
<tr><td><font color="white"><h3>Actions</h3></font>
</td>
</tr>
</table>
{% endif %}
<h3>Comment Log</h3>
<table cellpadding="1" cellspacing="1" border="0">
<tr bgcolor="#7DC189">
<th>Date</th>
<th>Version</th>
<th>Comment</th>
</tr>
{% for comment in object.comments %}
<tr bgcolor="{% cycle #CFE1CC,#7DC189 %}">
<td>{{ comment.date }}</td>
<td align="center">{{ comment.version }}</td>
<td><font color="blue">[{{ comment.get_username }}]</font>
{% if comment.ballot %}
<font color="red">[IN IESG DISCUSSION
<b>*{{ comment.get_ballot_display }}*</b>]</font>
{% endif %} {{ comment.comment_text|format_textarea|truncatewords_html:"25" }}</td>
<td>
<form action="comment/{{ comment.id }}" method="GET">
<input type="submit" value="View Detail">
</form>
</td>
</tr>
{% endfor %}
</table>
<br>
<form action="/idtracker/" method="GET">
<input type="submit" value="Main Menu">
<input type="button" name="back_button" value="BACK"
onclick="history.go(-1);return true">
</form>
<!-- begin new footer -->
<hr>
<p>Did you find a bug? <a href=
"pidtracker.cgi?command=send_email&amp;cat=bugs">Let us
know</a>.</p>
<p><a href=
"pidtracker.cgi?command=send_email&amp;cat=discuss">Any
question or suggestion</a>?</p>
<p><i>This page produced by the <a href=
"mailto:iesg-secretary@ietf.org">IETF Secretariat</a> for
the <a href="mailto:iesg@ietf.org">IESG</a></i></p>
{% include "debug.html" %}
</body>
</html>

View file

@ -1,19 +0,0 @@
<h1>I-D Detail</h1>
<h2>{{ object.filename }}-{{ object.revision }}</h2>
{{ object.status }}
||
{{ object.idstate }}
||
{{ object.idinternal.cur_state }} ::
{{ object.idinternal.cur_sub_state }}
||
{{ object.idinternal.prev_state }} ::
{{ object.idinternal.prev_sub_state }}
<br>
Authors:
<ul>
{% for author in object.authors.all %}
<li>{{ author.person }} - {{ author.email }}
{% endfor %}
</ul>