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:
parent
c2c08c9edc
commit
e73f7dbf5f
|
@ -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'
|
||||
|
||||
|
|
|
@ -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('',
|
||||
|
|
|
@ -94,7 +94,6 @@ INSTALLED_APPS = (
|
|||
'ietf.my',
|
||||
'ietf.proceedings',
|
||||
'ietf.redirects',
|
||||
'ietf.rfcs',
|
||||
)
|
||||
|
||||
INTERNAL_IPS = (
|
||||
|
|
290
ietf/templates/idtracker/idinternal_detail.html
Normal file
290
ietf/templates/idtracker/idinternal_detail.html
Normal 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 <{{ object.document.group_acronym }}> 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 " " %}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr bgcolor="white">
|
||||
<td>
|
||||
<div class="largefont3">
|
||||
Note:
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<div class="largefont3">
|
||||
{% firstof object.note|unformat_textarea %}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr bgcolor="white">
|
||||
<td width="20%"> </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&cat=bugs">Let us
|
||||
know</a>.</p>
|
||||
|
||||
<p><a href=
|
||||
"pidtracker.cgi?command=send_email&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>
|
||||
|
|
@ -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>
|
||||
|
Loading…
Reference in a new issue