Moving ietf to trunk/ietf
[[Split portion of a mixed commit.]] - Legacy-Id: 96.1
This commit is contained in:
commit
5872696834
17
.gitignore
vendored
Normal file
17
.gitignore
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# A simulation of Subversion default ignores, generated by reposurgeon.
|
||||||
|
*.o
|
||||||
|
*.lo
|
||||||
|
*.la
|
||||||
|
*.al
|
||||||
|
*.libs
|
||||||
|
*.so
|
||||||
|
*.so.[0-9]*
|
||||||
|
*.a
|
||||||
|
*.pyc
|
||||||
|
*.pyo
|
||||||
|
*.rej
|
||||||
|
*~
|
||||||
|
*.#*
|
||||||
|
.*.swp
|
||||||
|
.DS_store
|
||||||
|
# Simulated Subversion default ignores end here
|
2
ietf/.gitignore
vendored
Normal file
2
ietf/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/*.pyc
|
||||||
|
/settings_local.py
|
0
ietf/__init__.py
Normal file
0
ietf/__init__.py
Normal file
2
ietf/agenda/.gitignore
vendored
Normal file
2
ietf/agenda/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/*.pyc
|
||||||
|
/settings_local.py
|
0
ietf/agenda/__init__.py
Normal file
0
ietf/agenda/__init__.py
Normal file
3
ietf/agenda/models.py
Normal file
3
ietf/agenda/models.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
# Create your models here.
|
1
ietf/agenda/views.py
Normal file
1
ietf/agenda/views.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# Create your views here.
|
2
ietf/announcements/.gitignore
vendored
Normal file
2
ietf/announcements/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/*.pyc
|
||||||
|
/settings_local.py
|
0
ietf/announcements/__init__.py
Normal file
0
ietf/announcements/__init__.py
Normal file
83
ietf/announcements/models.py
Normal file
83
ietf/announcements/models.py
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
from django.db import models
|
||||||
|
from ietf.idtracker.models import PersonOrOrgInfo, ChairsHistory
|
||||||
|
|
||||||
|
# I don't know why the IETF database mostly stores times
|
||||||
|
# as char(N) instead of TIME. Until it's important, let's
|
||||||
|
# keep them as char here too.
|
||||||
|
|
||||||
|
class AnnouncedFrom(models.Model):
|
||||||
|
announced_from_id = models.AutoField(primary_key=True)
|
||||||
|
announced_from_value = models.CharField(blank=True, maxlength=255)
|
||||||
|
announced_from_email = models.CharField(blank=True, maxlength=255)
|
||||||
|
def __str__(self):
|
||||||
|
return self.announced_from_value
|
||||||
|
class Meta:
|
||||||
|
db_table = 'announced_from'
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class AnnouncedTo(models.Model):
|
||||||
|
announced_to_id = models.AutoField(primary_key=True)
|
||||||
|
announced_to_value = models.CharField(blank=True, maxlength=255)
|
||||||
|
announced_to_email = models.CharField(blank=True, maxlength=255)
|
||||||
|
def __str__(self):
|
||||||
|
return self.announced_to_value
|
||||||
|
class Meta:
|
||||||
|
db_table = 'announced_to'
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Announcement(models.Model):
|
||||||
|
announcement_id = models.AutoField(primary_key=True)
|
||||||
|
announced_by = models.ForeignKey(PersonOrOrgInfo, raw_id_admin=True, db_column='announced_by')
|
||||||
|
announced_date = models.DateField(null=True, blank=True)
|
||||||
|
announced_time = models.CharField(blank=True, maxlength=20)
|
||||||
|
text = models.TextField(blank=True, db_column='announcement_text')
|
||||||
|
announced_from = models.ForeignKey(AnnouncedFrom)
|
||||||
|
cc = models.CharField(blank=True, maxlength=255)
|
||||||
|
subject = models.CharField(blank=True, maxlength=255)
|
||||||
|
extra = models.TextField(blank=True)
|
||||||
|
announced_to = models.ForeignKey(AnnouncedTo)
|
||||||
|
nomcom = models.BooleanField()
|
||||||
|
nomcom_chair_id = models.IntegerField(null=True, blank=True) # ForeignKey to nomcom chairs
|
||||||
|
manually_added = models.BooleanField(db_column='manualy_added')
|
||||||
|
other_val = models.CharField(blank=True, maxlength=255)
|
||||||
|
def __str__(self):
|
||||||
|
return "Announcement from %s to %s on %s %s" % (self.announced_from, self.announced_to, self.announced_date, self.announced_time)
|
||||||
|
def from_name(self):
|
||||||
|
if self.announced_from_id == 99:
|
||||||
|
return self.other_val
|
||||||
|
if self.announced_from_id == 14: # sigh hardcoding
|
||||||
|
return ChairsHistory.objects.all().get(id=self.nomcom_chair_id).person
|
||||||
|
return self.announced_from
|
||||||
|
class Meta:
|
||||||
|
db_table = 'announcements'
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class ScheduledAnnouncement(models.Model):
|
||||||
|
mail_sent = models.BooleanField()
|
||||||
|
to_be_sent_date = models.DateField(null=True, blank=True)
|
||||||
|
to_be_sent_time = models.CharField(blank=True, maxlength=50)
|
||||||
|
scheduled_by = models.CharField(blank=True, maxlength=100)
|
||||||
|
scheduled_date = models.DateField(null=True, blank=True)
|
||||||
|
scheduled_time = models.CharField(blank=True, maxlength=50)
|
||||||
|
subject = models.CharField(blank=True, maxlength=255)
|
||||||
|
to_val = models.CharField(blank=True, maxlength=255)
|
||||||
|
from_val = models.CharField(blank=True, maxlength=255)
|
||||||
|
cc_val = models.TextField(blank=True)
|
||||||
|
body = models.TextField(blank=True)
|
||||||
|
actual_sent_date = models.DateField(null=True, blank=True)
|
||||||
|
actual_sent_time = models.CharField(blank=True, maxlength=50)
|
||||||
|
first_q = models.IntegerField(null=True, blank=True)
|
||||||
|
second_q = models.IntegerField(null=True, blank=True)
|
||||||
|
note = models.TextField(blank=True)
|
||||||
|
content_type = models.CharField(blank=True, maxlength=255)
|
||||||
|
replyto = models.CharField(blank=True, maxlength=255)
|
||||||
|
bcc_val = models.CharField(blank=True, maxlength=255)
|
||||||
|
def __str__(self):
|
||||||
|
return "Scheduled Announcement from %s to %s on %s %s" % (self.from_val, self.to_val, self.to_be_sent_date, self.to_be_sent_time)
|
||||||
|
class Meta:
|
||||||
|
db_table = 'scheduled_announcements'
|
||||||
|
class Admin:
|
||||||
|
pass
|
10
ietf/announcements/urls.py
Normal file
10
ietf/announcements/urls.py
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
from django.conf.urls.defaults import *
|
||||||
|
from ietf.announcements.models import Announcement
|
||||||
|
|
||||||
|
nomcom_dict = {
|
||||||
|
'queryset': Announcement.objects.all().filter(nomcom=True)
|
||||||
|
}
|
||||||
|
|
||||||
|
urlpatterns = patterns('',
|
||||||
|
(r'^nomcom/(?P<object_id>\d+)/$', 'django.views.generic.list_detail.object_detail', nomcom_dict)
|
||||||
|
)
|
1
ietf/announcements/views.py
Normal file
1
ietf/announcements/views.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# Create your views here.
|
2
ietf/bin/.gitignore
vendored
Normal file
2
ietf/bin/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/*.pyc
|
||||||
|
/settings_local.py
|
17
ietf/bin/graphall
Executable file
17
ietf/bin/graphall
Executable file
|
@ -0,0 +1,17 @@
|
||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Requires modelviz.py from
|
||||||
|
# http://code.djangoproject.com/wiki/DjangoGraphviz
|
||||||
|
#
|
||||||
|
PYTHONPATH=`dirname $PWD`
|
||||||
|
export PYTHONPATH
|
||||||
|
DJANGO_SETTINGS_MODULE=ietf/settings
|
||||||
|
export DJANGO_SETTINGS_MODULE
|
||||||
|
for d in *
|
||||||
|
do
|
||||||
|
if grep models.Model $d/models.py > /dev/null 2>&1
|
||||||
|
then
|
||||||
|
python modelviz.py $d
|
||||||
|
fi
|
||||||
|
done > models.dot
|
||||||
|
unflatten -f -l 10 models.dot | dot -Tps -Gsize=10.5,8.0 -Gmargin=0.25 -Gratio=auto -Grotate=90 | sed -e 's/ Bold/-Bold/' > models.ps
|
2
ietf/bin/redirect-dump
Executable file
2
ietf/bin/redirect-dump
Executable file
|
@ -0,0 +1,2 @@
|
||||||
|
#!/bin/sh
|
||||||
|
python manage.py dumpdata --format=xml redirects | xmllint --format -
|
2
ietf/database-notes/.gitignore
vendored
Normal file
2
ietf/database-notes/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/*.pyc
|
||||||
|
/settings_local.py
|
1440
ietf/database-notes/generated-model
Normal file
1440
ietf/database-notes/generated-model
Normal file
File diff suppressed because it is too large
Load diff
2161
ietf/database-notes/idtracker.dump
Normal file
2161
ietf/database-notes/idtracker.dump
Normal file
File diff suppressed because it is too large
Load diff
207
ietf/database-notes/pub-table-list.txt
Normal file
207
ietf/database-notes/pub-table-list.txt
Normal file
|
@ -0,0 +1,207 @@
|
||||||
|
all_id.cgi:id_internal
|
||||||
|
all_id.cgi:internet_drafts
|
||||||
|
all_id_html.cgi:id_internal
|
||||||
|
all_id_html.cgi:internet_drafts
|
||||||
|
area_mailing_list.cgi:acronym
|
||||||
|
area_mailing_list.cgi:general_info
|
||||||
|
idindex.cgi:acronym
|
||||||
|
idindex.cgi:g_status
|
||||||
|
idindex.cgi:general_info
|
||||||
|
idindex.cgi:groups_ietf
|
||||||
|
idindex.cgi:id_authors
|
||||||
|
idindex.cgi:id_internal
|
||||||
|
idindex.cgi:id_status
|
||||||
|
idindex.cgi:internet_drafts
|
||||||
|
idindex.cgi:ref_doc_states_new
|
||||||
|
idindex.cgi:rfcs
|
||||||
|
idindex.cgi:rfcs_obsolete
|
||||||
|
idindex.cgi:temp_id
|
||||||
|
imported_mailing_list
|
||||||
|
ipr.cgi:>
|
||||||
|
ipr.cgi:and
|
||||||
|
ipr.cgi:internet_drafts
|
||||||
|
ipr.cgi:ipr_contacts
|
||||||
|
ipr.cgi:ipr_detail
|
||||||
|
ipr.cgi:ipr_ids
|
||||||
|
ipr.cgi:ipr_rfcs
|
||||||
|
ipr.cgi:ipr_updates
|
||||||
|
ipr.cgi:rfcs
|
||||||
|
ipr.cgi:temp_txt
|
||||||
|
ipr.cgi:the
|
||||||
|
ipr.cgi:this
|
||||||
|
ipr_detail.cgi:internet_drafts
|
||||||
|
ipr_detail.cgi:ipr_contacts
|
||||||
|
ipr_detail.cgi:ipr_detail
|
||||||
|
ipr_detail.cgi:ipr_licensing
|
||||||
|
ipr_detail.cgi:ipr_selecttype
|
||||||
|
ipr_detail_show.cgi:internet_drafts
|
||||||
|
ipr_detail_show.cgi:ipr_contacts
|
||||||
|
ipr_detail_show.cgi:ipr_detail
|
||||||
|
ipr_detail_show.cgi:ipr_ids
|
||||||
|
ipr_detail_show.cgi:ipr_rfcs
|
||||||
|
ipr_detail_show.cgi:ipr_updates
|
||||||
|
ipr_detail_show.cgi:rfcs
|
||||||
|
ipr_detail_show.cgi:this
|
||||||
|
ipr_generic.cgi:>
|
||||||
|
ipr_generic.cgi:and
|
||||||
|
ipr_generic.cgi:ipr_contacts
|
||||||
|
ipr_generic.cgi:ipr_detail
|
||||||
|
ipr_generic.cgi:ipr_updates
|
||||||
|
ipr_generic.cgi:temp_txt
|
||||||
|
ipr_generic.cgi:the
|
||||||
|
ipr_generic.cgi:this
|
||||||
|
ipr_list.cgi:ipr_detail
|
||||||
|
ipr_list.cgi:ipr_updates
|
||||||
|
ipr_notify.cgi:>
|
||||||
|
ipr_notify.cgi:and
|
||||||
|
ipr_notify.cgi:internet_drafts
|
||||||
|
ipr_notify.cgi:ipr_contacts
|
||||||
|
ipr_notify.cgi:ipr_detail
|
||||||
|
ipr_notify.cgi:ipr_ids
|
||||||
|
ipr_notify.cgi:ipr_rfcs
|
||||||
|
ipr_notify.cgi:ipr_updates
|
||||||
|
ipr_notify.cgi:rfcs
|
||||||
|
ipr_notify.cgi:temp_txt
|
||||||
|
ipr_notify.cgi:the
|
||||||
|
ipr_notify.cgi:this
|
||||||
|
ipr_search.cgi:acronym
|
||||||
|
ipr_search.cgi:groups_ietf
|
||||||
|
ipr_search.cgi:internet_drafts
|
||||||
|
ipr_search.cgi:ipr_detail
|
||||||
|
ipr_search.cgi:ipr_ids
|
||||||
|
ipr_search.cgi:ipr_rfcs
|
||||||
|
ipr_search.cgi:ipr_updates
|
||||||
|
ipr_search.cgi:rfcs
|
||||||
|
ipr_search.cgi:rfcs_obsolete
|
||||||
|
ipr_update_list.cgi:ipr_detail
|
||||||
|
ipr_update_list.cgi:ipr_updates
|
||||||
|
lastcall.cgi:hit_counter
|
||||||
|
lastcall.cgi:id_internal
|
||||||
|
lastcall.cgi:internet_drafts
|
||||||
|
lastcall.cgi:rfcs
|
||||||
|
liaison_detail.cgi:from_bodies
|
||||||
|
liaison_detail.cgi:liaison_detail
|
||||||
|
liaison_detail.cgi:liaison_purpose
|
||||||
|
liaison_detail.cgi:uploads
|
||||||
|
liaison_field_help.cgi:general_info
|
||||||
|
liaison_guide_from_ietf.cgi:general_info
|
||||||
|
liaison_guide_to_ietf.cgi:general_info
|
||||||
|
liaison_managers_list.cgi:email_addresses
|
||||||
|
liaison_managers_list.cgi:general_info
|
||||||
|
liaison_managers_list.cgi:liaison_managers
|
||||||
|
liaisons.cgi:liaison_detail
|
||||||
|
liaisons.cgi:uploads
|
||||||
|
mailing_list
|
||||||
|
meeting_agenda_html.cgi:acronym
|
||||||
|
meeting_agenda_html.cgi:area_directors
|
||||||
|
meeting_agenda_html.cgi:areas
|
||||||
|
meeting_agenda_html.cgi:groups_ietf
|
||||||
|
meeting_agenda_html.cgi:irtf
|
||||||
|
meeting_agenda_html.cgi:meeting_agenda_count
|
||||||
|
meeting_agenda_html.cgi:meeting_venues
|
||||||
|
meeting_agenda_html.cgi:meetings
|
||||||
|
meeting_agenda_html.cgi:non_session
|
||||||
|
meeting_agenda_html.cgi:non_session_ref
|
||||||
|
meeting_agenda_html.cgi:proceedings
|
||||||
|
meeting_agenda_html.cgi:session_names
|
||||||
|
meeting_agenda_html.cgi:switches
|
||||||
|
meeting_agenda_html.cgi:temp_agenda$table_id
|
||||||
|
meeting_agenda_html.cgi:wg_agenda
|
||||||
|
meeting_agenda_html.cgi:wg_meeting_sessions
|
||||||
|
meeting_agenda_text.cgi:acronym
|
||||||
|
meeting_agenda_text.cgi:area_directors
|
||||||
|
meeting_agenda_text.cgi:areas
|
||||||
|
meeting_agenda_text.cgi:groups_ietf
|
||||||
|
meeting_agenda_text.cgi:irtf
|
||||||
|
meeting_agenda_text.cgi:meeting_agenda_count
|
||||||
|
meeting_agenda_text.cgi:meeting_venues
|
||||||
|
meeting_agenda_text.cgi:meetings
|
||||||
|
meeting_agenda_text.cgi:non_session
|
||||||
|
meeting_agenda_text.cgi:proceedings
|
||||||
|
meeting_agenda_text.cgi:session_names
|
||||||
|
meeting_agenda_text.cgi:temp_agenda$table_id
|
||||||
|
meeting_agenda_text.cgi:wg_agenda
|
||||||
|
meeting_agenda_text.cgi:wg_meeting_sessions
|
||||||
|
meeting_materials.cgi:acronym
|
||||||
|
meeting_materials.cgi:agenda
|
||||||
|
meeting_materials.cgi:groups_ietf
|
||||||
|
meeting_materials.cgi:irtf
|
||||||
|
meeting_materials.cgi:meetings
|
||||||
|
meeting_materials.cgi:minutes
|
||||||
|
meeting_materials.cgi:proceedings
|
||||||
|
meeting_materials.cgi:slides
|
||||||
|
meeting_materials.cgi:wg_agenda
|
||||||
|
meeting_materials.cgi:wg_meeting_sessions
|
||||||
|
nwg_list.cgi:acronym
|
||||||
|
nwg_list.cgi:none_wg_mailing_list
|
||||||
|
nwg_list.cgi:or
|
||||||
|
nwg_list_submit.cgi:acronym
|
||||||
|
nwg_list_submit.cgi:area_directors
|
||||||
|
nwg_list_submit.cgi:none_wg_mailing_list
|
||||||
|
nwg_list_submit.cgi:the
|
||||||
|
pidtracker.cgi:$table_name
|
||||||
|
pidtracker.cgi:a
|
||||||
|
pidtracker.cgi:acronym
|
||||||
|
pidtracker.cgi:any
|
||||||
|
pidtracker.cgi:area_group
|
||||||
|
pidtracker.cgi:ballot_info
|
||||||
|
pidtracker.cgi:discuss
|
||||||
|
pidtracker.cgi:document_comments
|
||||||
|
pidtracker.cgi:hit_counter
|
||||||
|
pidtracker.cgi:id_internal
|
||||||
|
pidtracker.cgi:id_status
|
||||||
|
pidtracker.cgi:iesg_login
|
||||||
|
pidtracker.cgi:internet_drafts
|
||||||
|
pidtracker.cgi:its
|
||||||
|
pidtracker.cgi:ref_doc_states_new
|
||||||
|
pidtracker.cgi:rfcs
|
||||||
|
pidtracker.cgi:sub_state
|
||||||
|
pidtracker.cgi:the
|
||||||
|
previous_announcement.cgi:ballot_info
|
||||||
|
previous_announcement.cgi:id_internal
|
||||||
|
previous_announcement.cgi:internet_drafts
|
||||||
|
recent_announcement.cgi:ballot_info
|
||||||
|
recent_announcement.cgi:id_internal
|
||||||
|
recent_announcement.cgi:internet_drafts
|
||||||
|
request_approve_mail.cgi:=
|
||||||
|
request_approve_mail.cgi:a
|
||||||
|
request_approve_mail.cgi:acronym
|
||||||
|
request_approve_mail.cgi:iesg_login
|
||||||
|
request_approve_mail.cgi:mailing_list
|
||||||
|
request_approve_mail.cgi:none_wg_mailing_list
|
||||||
|
request_area_confirm.cgi:a
|
||||||
|
request_area_confirm.cgi:mailing_list
|
||||||
|
request_area_confirm.cgi:person_or_org_info
|
||||||
|
request_confirm.cgi:a
|
||||||
|
request_confirm.cgi:ad_address
|
||||||
|
request_confirm.cgi:area_directors
|
||||||
|
request_confirm.cgi:chairs
|
||||||
|
request_confirm.cgi:email_addresses
|
||||||
|
request_confirm.cgi:g_chairs
|
||||||
|
request_confirm.cgi:imported_mailing_list
|
||||||
|
request_confirm.cgi:mailing_list
|
||||||
|
request_list.cgi:acronym
|
||||||
|
request_list.cgi:areas,acronym
|
||||||
|
request_list.cgi:imported_mailing_list
|
||||||
|
request_list.cgi:none_wg_mailing_list
|
||||||
|
request_mail.cgi:email_addresses
|
||||||
|
request_mail.cgi:iesg_login
|
||||||
|
request_mail.cgi:mailing_list
|
||||||
|
rfc_editor_announcement.cgi:ballot_info
|
||||||
|
rfc_editor_announcement.cgi:id_internal
|
||||||
|
rfc_editor_announcement.cgi:internet_drafts
|
||||||
|
show_nomcom_message.cgi:announced_from
|
||||||
|
show_nomcom_message.cgi:announcements
|
||||||
|
show_nomcom_message.cgi:chairs_history
|
||||||
|
states_table.cgi:ref_doc_states_new
|
||||||
|
states_table.cgi:sub_state
|
||||||
|
status_of_item.cgi:hit_counter
|
||||||
|
status_of_item.cgi:id_internal
|
||||||
|
status_of_item.cgi:internet_drafts
|
||||||
|
status_of_item.cgi:ref_doc_states_new
|
||||||
|
status_of_item.cgi:rfcs
|
||||||
|
upload.cgi:($sqlStr);
|
||||||
|
upload.cgi:uploads
|
||||||
|
view_meeting_agenda_html.cgi:meetings
|
||||||
|
view_meeting_agenda_text.cgi:meetings
|
||||||
|
view_telechat_minute.cgi:telechat_minutes
|
2
ietf/idindex/.gitignore
vendored
Normal file
2
ietf/idindex/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/*.pyc
|
||||||
|
/settings_local.py
|
0
ietf/idindex/__init__.py
Normal file
0
ietf/idindex/__init__.py
Normal file
17
ietf/idindex/forms.py
Normal file
17
ietf/idindex/forms.py
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
from django import newforms as forms
|
||||||
|
from itertools import chain
|
||||||
|
from ietf.idtracker.models import IDState, IDStatus, GroupIETF
|
||||||
|
from ietf.idindex.models import orgs
|
||||||
|
|
||||||
|
class IDIndexSearchForm(forms.Form):
|
||||||
|
filename = forms.CharField(max_length=100, label='Filename (Full or Partial):', widget=forms.TextInput(attrs={'size': 30}))
|
||||||
|
id_tracker_state_id = forms.ChoiceField(choices=chain((('', 'All/Any'),),
|
||||||
|
[(state.document_state_id, state.state) for state in IDState.objects.all()]), label='I-D Tracker State:')
|
||||||
|
wg_id = forms.ChoiceField(choices=chain((('', 'All/Any'),),
|
||||||
|
[(wg.group_acronym_id, wg.group_acronym.acronym) for wg in GroupIETF.objects.all().select_related().order_by('acronym.acronym')]), label='Working Group:')
|
||||||
|
other_group = forms.ChoiceField(choices=chain((('', 'All/Any'),),
|
||||||
|
[(org['key'], org['name']) for org in orgs]), label='Other Group:')
|
||||||
|
status_id = forms.ChoiceField(choices=chain((('', 'All/Any'),),
|
||||||
|
[(status.status_id, status.status) for status in IDStatus.objects.all()]), label='I-D Status:')
|
||||||
|
last_name = forms.CharField(max_length=50)
|
||||||
|
first_name = forms.CharField(max_length=50)
|
19
ietf/idindex/models.py
Normal file
19
ietf/idindex/models.py
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
alphabet = [chr(65 + i) for i in range(0, 26)]
|
||||||
|
orgs_dict = {
|
||||||
|
'iab': { 'name': 'IAB' },
|
||||||
|
'iana': { 'name': 'IANA' },
|
||||||
|
'iasa': { 'name': 'IASA' },
|
||||||
|
'iesg': { 'name': 'IESG' },
|
||||||
|
'irtf': { 'name': 'IRTF' },
|
||||||
|
'proto': { 'name': 'PROTO' },
|
||||||
|
'rfc-editor': { 'name': 'RFC Editor', 'prefixes': [ 'rfc-editor', 'rfced' ] },
|
||||||
|
'tools': { 'name': 'Tools' },
|
||||||
|
}
|
||||||
|
orgs_keys = orgs_dict.keys()
|
||||||
|
for o in orgs_keys:
|
||||||
|
orgs_dict[o]['key'] = o
|
||||||
|
orgs_keys.sort()
|
||||||
|
orgs = [orgs_dict[o] for o in orgs_keys]
|
||||||
|
|
28
ietf/idindex/urls.py
Normal file
28
ietf/idindex/urls.py
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
from django.conf.urls.defaults import *
|
||||||
|
from ietf.idtracker.models import InternetDraft
|
||||||
|
from ietf.idindex import views
|
||||||
|
from ietf.idindex import forms
|
||||||
|
from ietf.idindex.views import alphabet, orgs
|
||||||
|
|
||||||
|
info_dict = {
|
||||||
|
'queryset': InternetDraft.objects.all(),
|
||||||
|
'template_name': 'idindex/internetdraft_detail.html',
|
||||||
|
'extra_context': {
|
||||||
|
'alphabet': alphabet,
|
||||||
|
'orgs': orgs,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
urlpatterns = patterns('',
|
||||||
|
(r'^wgdocs/(?P<id>\d+)/$', views.wgdocs),
|
||||||
|
(r'^wgdocs/(?P<slug>[^/]+)/$', views.wgdocs),
|
||||||
|
(r'^wglist/(?P<wg>[^/]+)/$', views.wglist),
|
||||||
|
(r'^inddocs/(?P<filter>[^/]+)/$', views.inddocs),
|
||||||
|
(r'^otherdocs/(?P<cat>[^/]+)/$', views.otherdocs),
|
||||||
|
(r'^showdocs/(?P<cat>[^/]+)/((?P<sortby>[^/]+)/)?$', views.showdocs),
|
||||||
|
(r'^(?P<object_id>\d+)/$', 'django.views.generic.list_detail.object_detail', info_dict),
|
||||||
|
(r'^(?P<slug>[^/]+)/$', 'django.views.generic.list_detail.object_detail', dict(info_dict, slug_field='filename')),
|
||||||
|
(r'^all_id_txt.html$', views.all_id, { 'template_name': 'idindex/all_id_txt.html' }),
|
||||||
|
(r'^all_id.html$', views.all_id, { 'template_name': 'idindex/all_id.html' }),
|
||||||
|
(r'^$', views.search),
|
||||||
|
)
|
152
ietf/idindex/views.py
Normal file
152
ietf/idindex/views.py
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
from django.http import HttpResponse,HttpResponseRedirect
|
||||||
|
from django.views.generic.list_detail import object_list
|
||||||
|
from django.db.models import Q
|
||||||
|
from django.http import Http404
|
||||||
|
from django.template import RequestContext, Context, loader
|
||||||
|
from django.shortcuts import render_to_response
|
||||||
|
from ietf.idtracker.models import Acronym, GroupIETF, InternetDraft
|
||||||
|
from ietf.idindex.forms import IDIndexSearchForm
|
||||||
|
from ietf.idindex.models import alphabet, orgs, orgs_dict
|
||||||
|
from ietf.utils import orl, flattenl
|
||||||
|
|
||||||
|
base_extra = { 'alphabet': alphabet, 'orgs': orgs }
|
||||||
|
|
||||||
|
def wglist(request, wg=None):
|
||||||
|
if wg == 'other':
|
||||||
|
queryset = GroupIETF.objects.filter(
|
||||||
|
orl([Q(group_acronym__acronym__istartswith="%d" % i) for i in range(0,10)])
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
queryset = GroupIETF.objects.filter(group_acronym__acronym__istartswith=wg)
|
||||||
|
queryset = queryset.filter(group_type__type='WG').select_related().order_by('g_status.status', 'acronym.acronym')
|
||||||
|
return object_list(request, queryset=queryset, template_name='idindex/wglist.html', allow_empty=True, extra_context=base_extra)
|
||||||
|
|
||||||
|
def wgdocs(request, **kwargs):
|
||||||
|
if kwargs.has_key('id'):
|
||||||
|
queryset = InternetDraft.objects.filter(group=kwargs['id'])
|
||||||
|
group = Acronym.objects.get(acronym_id=kwargs['id'])
|
||||||
|
else:
|
||||||
|
queryset = InternetDraft.objects.filter(group__acronym=kwargs['slug'])
|
||||||
|
group = Acronym.objects.get(acronym=kwargs['slug'])
|
||||||
|
queryset = queryset.order_by('status_id', 'filename')
|
||||||
|
extra = base_extra
|
||||||
|
extra['group'] = group
|
||||||
|
return object_list(request, queryset=queryset, template_name='idindex/wgdocs.html', allow_empty=True, extra_context=extra)
|
||||||
|
|
||||||
|
def inddocs(request, filter=None):
|
||||||
|
ind_exception = orl(
|
||||||
|
[Q(filename__istartswith='draft-%s-' % e) for e in
|
||||||
|
flattenl([org.get('prefixes', [ org['key'] ]) for org in orgs]) + ['ietf']])
|
||||||
|
if filter == 'other':
|
||||||
|
queryset = InternetDraft.objects.filter(
|
||||||
|
orl([Q(filename__istartswith="draft-%d" % i) for i in range(0,10)])
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
queryset = InternetDraft.objects.filter(filename__istartswith='draft-' + filter)
|
||||||
|
queryset = queryset.exclude(ind_exception).filter(group__acronym='none').order_by('filename')
|
||||||
|
extra = base_extra
|
||||||
|
extra['filter'] = filter
|
||||||
|
return object_list(request, queryset=queryset, template_name='idindex/inddocs.html', allow_empty=True, extra_context=extra)
|
||||||
|
|
||||||
|
def otherdocs(request, cat=None):
|
||||||
|
try:
|
||||||
|
org = orgs_dict[cat]
|
||||||
|
except KeyError:
|
||||||
|
raise Http404
|
||||||
|
queryset = InternetDraft.objects.filter(
|
||||||
|
orl([Q(filename__istartswith="draft-%s-" % p)|
|
||||||
|
Q(filename__istartswith="draft-ietf-%s-" % p)
|
||||||
|
for p in org.get('prefixes', [ org['key'] ])]))
|
||||||
|
queryset = queryset.order_by('filename')
|
||||||
|
extra = base_extra
|
||||||
|
extra['category'] = cat
|
||||||
|
return object_list(request, queryset=queryset, template_name='idindex/otherdocs.html', allow_empty=True, extra_context=extra)
|
||||||
|
|
||||||
|
def showdocs(request, cat=None, sortby=None):
|
||||||
|
catmap = {
|
||||||
|
'all': { 'extra': { 'header': 'All' } },
|
||||||
|
'current': { 'extra': { 'header': 'Current', 'norfc': 1 },
|
||||||
|
'query': Q(status__status="Active") },
|
||||||
|
'rfc': { 'extra': { 'header': 'Published' },
|
||||||
|
'query': Q(status__status="RFC") },
|
||||||
|
'dead': { 'extra': { 'header': "Expired/Withdrawn/Replaced", 'norfc': 1 },
|
||||||
|
'query': Q(status__in=[2,4,5,6]) }, # Using the words seems fragile here for some reason
|
||||||
|
}
|
||||||
|
if not(catmap.has_key(cat)):
|
||||||
|
raise Http404
|
||||||
|
sortmap = { 'date': { 'header': "Submission Date",
|
||||||
|
'fields': ['revision_date','filename'] },
|
||||||
|
'name': { 'header': "Filename",
|
||||||
|
'fields': ['filename'] },
|
||||||
|
'': { 'header': "WHA?",
|
||||||
|
'fields': ['filename'] },
|
||||||
|
}
|
||||||
|
if sortby is None:
|
||||||
|
sortby = 'name'
|
||||||
|
queryset = InternetDraft.objects.all()
|
||||||
|
if catmap[cat].has_key('query'):
|
||||||
|
queryset = queryset.filter(catmap[cat]['query'])
|
||||||
|
queryset = queryset.order_by(*list(['status_id'] + sortmap[sortby]['fields']))
|
||||||
|
extra = catmap[cat]['extra']
|
||||||
|
extra['sort_header'] = sortmap[sortby]['header']
|
||||||
|
extra.update(base_extra)
|
||||||
|
return object_list(request, queryset=queryset, template_name='idindex/showdocs.html', allow_empty=True, extra_context=extra)
|
||||||
|
|
||||||
|
|
||||||
|
def search(request):
|
||||||
|
form = IDIndexSearchForm()
|
||||||
|
t = loader.get_template('idindex/search.html')
|
||||||
|
# if there's a post, do the search and supply results to the template
|
||||||
|
# XXX should handle GET too
|
||||||
|
if request.method == 'POST':
|
||||||
|
qdict = { 'filename': 'filename__icontains',
|
||||||
|
'id_tracker_state_id': 'idinternal__cur_state',
|
||||||
|
'wg_id': 'group',
|
||||||
|
'status_id': 'status',
|
||||||
|
'last_name': 'authors__person__last_name__icontains',
|
||||||
|
'first_name': 'authors__person__first_name__icontains',
|
||||||
|
}
|
||||||
|
q_objs = [Q(**{qdict[k]: request.POST[k]})
|
||||||
|
for k in qdict.keys()
|
||||||
|
if request.POST[k] != '']
|
||||||
|
try:
|
||||||
|
other = orgs_dict[request.POST['other_group']]
|
||||||
|
q_objs += [orl(
|
||||||
|
[Q(filename__istartswith="draft-%s-" % p)|
|
||||||
|
Q(filename__istartswith="draft-ietf-%s-" % p)
|
||||||
|
for p in other.get('prefixes', [ other['key'] ])])]
|
||||||
|
except KeyError:
|
||||||
|
pass # either no other_group arg or no orgs_dict entry
|
||||||
|
matches = InternetDraft.objects.all().filter(*q_objs)
|
||||||
|
matches = matches.order_by('filename')
|
||||||
|
searched = True
|
||||||
|
else:
|
||||||
|
matches = None
|
||||||
|
searched = False
|
||||||
|
|
||||||
|
c = RequestContext(request, {
|
||||||
|
'form': form,
|
||||||
|
'object_list': matches,
|
||||||
|
'didsearch': searched,
|
||||||
|
'alphabet': alphabet,
|
||||||
|
'orgs': orgs,
|
||||||
|
})
|
||||||
|
return HttpResponse(t.render(c))
|
||||||
|
|
||||||
|
def all_id(request, template_name):
|
||||||
|
from django.db import connection
|
||||||
|
from ietf.utils import flattenl
|
||||||
|
cursor = connection.cursor()
|
||||||
|
# 99 = Dead
|
||||||
|
# 32 = RFC Published
|
||||||
|
cursor.execute("SELECT id_document_tag FROM id_internal WHERE rfc_flag=0 AND cur_state NOT IN (99,32)")
|
||||||
|
in_tracker = flattenl(cursor.fetchall())
|
||||||
|
tracker_list = InternetDraft.objects.all().filter(id_document_tag__in=in_tracker).order_by('status_id','filename').select_related(depth=1)
|
||||||
|
object_list = []
|
||||||
|
for o in tracker_list:
|
||||||
|
object_list.append({'tracker': True, 'id': o})
|
||||||
|
notracker_list = InternetDraft.objects.all().exclude(id_document_tag__in=in_tracker).order_by('status_id','filename').select_related(depth=1)
|
||||||
|
for o in notracker_list:
|
||||||
|
object_list.append({'tracker': False, 'id': o})
|
||||||
|
return render_to_response(template_name, {'object_list': object_list},
|
||||||
|
context_instance=RequestContext(request))
|
2
ietf/idtracker/.gitignore
vendored
Normal file
2
ietf/idtracker/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/*.pyc
|
||||||
|
/settings_local.py
|
56
ietf/idtracker/README
Normal file
56
ietf/idtracker/README
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
form_for_model(IDInternal) will autogenerate form elemnts to edit the model
|
||||||
|
|
||||||
|
class ImageAddForm(BaseForm):
|
||||||
|
|
||||||
|
def __init__(self, *args, name=None, **kwargs):
|
||||||
|
super(ImageAddForm, self).__init__(*args, **kwargs)
|
||||||
|
self.fields['category'].choices=(('a','a'),)
|
||||||
|
# create filter based on name=
|
||||||
|
|
||||||
|
ImageForm = form_for_model(Image, form=ImageAddForm)
|
||||||
|
foo = ImageForm(name='foo')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
To get from draft to author list:
|
||||||
|
|
||||||
|
>>> d = a[5]
|
||||||
|
>>> print d
|
||||||
|
draft-fenner-zinin-rtg-standard-reqts
|
||||||
|
>>> print d.authors.all()
|
||||||
|
[<IDAuthors: IDAuthors object>, <IDAuthors: IDAuthors object>]
|
||||||
|
>>> l=d.authors.all()
|
||||||
|
>>> print l[0].person
|
||||||
|
Bill Fenner
|
||||||
|
>>> print l[0].person.emailaddresses_set.filter(priority=d.id_document_tag)
|
||||||
|
[<EmailAddresses: EmailAddresses object>]
|
||||||
|
>>> print l[0].person.emailaddresses_set.filter(priority=d.id_document_tag)[0].ail_address
|
||||||
|
fenner@research.att.com
|
||||||
|
|
||||||
|
IDAuthors should have an auxilliary function for this.
|
||||||
|
It's the one that has the person linkage and knows the document.
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
we should use a variant of django-registration.
|
||||||
|
http://www.stonemind.net/blog/2007/04/13/django-registration-for-newbies/
|
||||||
|
|
||||||
|
1. verify email address with round trip
|
||||||
|
2. if there's a row in iesg_login, use that username
|
||||||
|
(? liaison tool logins ?)
|
||||||
|
otherwise, force the email address
|
||||||
|
3. get a password and create the user
|
||||||
|
(this is almost the same as resetting the password)
|
||||||
|
4. find the person_or_org_info row, associate that with
|
||||||
|
the user row
|
||||||
|
|
||||||
|
--
|
||||||
|
|
||||||
|
<ubernostrum> Both the regular and date-base object_detail can take either an
|
||||||
|
+object_id, or a slug/slug_field combo.
|
||||||
|
<ubernostrum> So use the username as the "slug" and specify 'username' as the
|
||||||
|
+'slug_field' argument.
|
||||||
|
|
||||||
|
http://www.b-list.org/weblog/2006/11/16/django-tips-get-most-out-generic-views
|
||||||
|
|
||||||
|
newly learned: 'slug_field' just gets passed so can be otherdb__username
|
0
ietf/idtracker/__init__.py
Normal file
0
ietf/idtracker/__init__.py
Normal file
10
ietf/idtracker/change-schema
Normal file
10
ietf/idtracker/change-schema
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
ALTER TABLE `id_internal` CHANGE `cur_sub_state_id` `cur_sub_state_id` INT( 11 ) NULL DEFAULT NULL ,
|
||||||
|
CHANGE `prev_sub_state_id` `prev_sub_state_id` INT( 11 ) NULL DEFAULT NULL ;
|
||||||
|
|
||||||
|
update id_internal set cur_sub_state_id=NULL where cur_sub_state_id < 1;
|
||||||
|
update id_internal set prev_sub_state_id=NULL where prev_sub_state_id < 1;
|
||||||
|
|
||||||
|
ALTER TABLE `email_addresses` ADD `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST ;
|
||||||
|
ALTER TABLE `postal_addresses` ADD `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST ;
|
||||||
|
ALTER TABLE `phone_numbers` ADD `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST ;
|
||||||
|
|
31
ietf/idtracker/feeds.py
Normal file
31
ietf/idtracker/feeds.py
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
from django.contrib.syndication.feeds import Feed
|
||||||
|
from django.utils.feedgenerator import Atom1Feed
|
||||||
|
from ietf.idtracker.models import InternetDraft, DocumentComment
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
class DocumentComments(Feed):
|
||||||
|
feed_type = Atom1Feed
|
||||||
|
def get_object(self, bits):
|
||||||
|
if len(bits) != 1:
|
||||||
|
raise ObjectDoesNotExist
|
||||||
|
return InternetDraft.objects.get(filename=bits[0])
|
||||||
|
|
||||||
|
def title(self, obj):
|
||||||
|
return "I-D Tracker comments for %s" % obj.filename
|
||||||
|
|
||||||
|
def link(self, obj):
|
||||||
|
return "/idtracker/%s" % obj.filename
|
||||||
|
# obj.get_absolute_url() ?
|
||||||
|
|
||||||
|
def description(self, obj):
|
||||||
|
self.title(obj)
|
||||||
|
|
||||||
|
def items(self, obj):
|
||||||
|
return DocumentComment.objects.filter(document=obj.id_document_tag).order_by("-date")[:15]
|
||||||
|
|
||||||
|
def item_pubdate(self, item):
|
||||||
|
time = datetime.time(*[int(t) for t in item.time.split(":")])
|
||||||
|
return datetime.datetime.combine(item.date, time)
|
||||||
|
|
||||||
|
def item_author_name(self, item):
|
||||||
|
return item.get_author()
|
518
ietf/idtracker/models.py
Normal file
518
ietf/idtracker/models.py
Normal file
|
@ -0,0 +1,518 @@
|
||||||
|
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
|
||||||
|
class Meta:
|
||||||
|
db_table = 'ref_doc_states_new'
|
||||||
|
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'
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Areas(models.Model):
|
||||||
|
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
|
||||||
|
class Meta:
|
||||||
|
db_table = 'areas'
|
||||||
|
#ordering = ['area_acronym_id']
|
||||||
|
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)
|
||||||
|
id_document_name = models.CharField(maxlength=255)
|
||||||
|
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.id_document_name.upper()
|
||||||
|
super(InternetDraft, self).save()
|
||||||
|
def __str__(self):
|
||||||
|
return self.filename
|
||||||
|
def idstate(self):
|
||||||
|
idinternal = self.idinternal
|
||||||
|
if idinternal:
|
||||||
|
if idinternal.cur_sub_state:
|
||||||
|
return "%s :: %s" % ( idinternal.cur_state, idinternal.cur_sub_state )
|
||||||
|
else:
|
||||||
|
return idinternal.cur_state
|
||||||
|
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
|
||||||
|
class Meta:
|
||||||
|
db_table = "internet_drafts"
|
||||||
|
class Admin:
|
||||||
|
search_fields = ['filename']
|
||||||
|
pass
|
||||||
|
#list_display = ('filename', 'revision', 'status')
|
||||||
|
#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):
|
||||||
|
return "%s %s" % ( self.first_name or "<nofirst>", self.last_name or "<nolast>")
|
||||||
|
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)
|
||||||
|
class Meta:
|
||||||
|
db_table = 'iesg_login'
|
||||||
|
class Admin:
|
||||||
|
list_display = ('login_name', 'first_name', 'last_name', 'user_level')
|
||||||
|
ordering = ['user_level','last_name']
|
||||||
|
pass
|
||||||
|
|
||||||
|
# No admin panel needed; this is edited in Areas.
|
||||||
|
class AreaDirectors(models.Model):
|
||||||
|
area = models.ForeignKey(Areas, db_column='area_acronym_id', edit_inline=models.STACKED, num_in_admin=2)
|
||||||
|
person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag', raw_id_admin=True, core=True)
|
||||||
|
def __str__(self):
|
||||||
|
return "(%s) %s" % ( self.area, self.person )
|
||||||
|
class Meta:
|
||||||
|
db_table = 'area_directors'
|
||||||
|
|
||||||
|
class IDInternal(models.Model):
|
||||||
|
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)
|
||||||
|
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=None)
|
||||||
|
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(Areas)
|
||||||
|
cur_sub_state = models.ForeignKey(IDSubState, related_name='docs', null=True, blank=True)
|
||||||
|
prev_sub_state = models.ForeignKey(IDSubState, related_name=None, 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.id_document_tag )
|
||||||
|
else:
|
||||||
|
return self.id_document_tag.filename
|
||||||
|
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=None)
|
||||||
|
origin_state = models.ForeignKey(IDState, db_column='origin_state', null=True, related_name=None)
|
||||||
|
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:
|
||||||
|
return self.created_by.__str__()
|
||||||
|
else:
|
||||||
|
return "system"
|
||||||
|
class Meta:
|
||||||
|
db_table = 'document_comments'
|
||||||
|
|
||||||
|
|
||||||
|
class IDAuthors(models.Model):
|
||||||
|
document = models.ForeignKey(InternetDraft, db_column='id_document_tag', related_name='authors', edit_inline=models.TABULAR)
|
||||||
|
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']
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# 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)
|
||||||
|
# always uppercase(affiliated_company)
|
||||||
|
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 GType(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 GStatus(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 GroupIETF(models.Model):
|
||||||
|
group_acronym = models.ForeignKey(Acronym, primary_key=True, unique=True, editable=False)
|
||||||
|
group_type = models.ForeignKey(GType)
|
||||||
|
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(GStatus)
|
||||||
|
area_director = models.ForeignKey(AreaDirectors, raw_id_admin=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)
|
||||||
|
def __str__(self):
|
||||||
|
return self.group_acronym.acronym
|
||||||
|
def active_drafts(self):
|
||||||
|
return self.group_acronym.internetdraft_set.all().filter(status__status="Active")
|
||||||
|
class Meta:
|
||||||
|
db_table = 'groups_ietf'
|
||||||
|
ordering = ['?'] # workaround django wanting to sort by acronym but not joining with it
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class GChairs(models.Model):
|
||||||
|
person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag', raw_id_admin=True, unique=True, core=True)
|
||||||
|
group_acronym = models.ForeignKey(GroupIETF, edit_inline=models.TABULAR)
|
||||||
|
class Meta:
|
||||||
|
db_table = 'g_chairs'
|
||||||
|
|
||||||
|
class GEditors(models.Model):
|
||||||
|
group_acronym = models.ForeignKey(GroupIETF, 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'
|
||||||
|
|
||||||
|
# Which is right? Secretaries or Secretary?
|
||||||
|
class GSecretaries(models.Model):
|
||||||
|
group_acronym = models.ForeignKey(GroupIETF, 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_secretaries'
|
||||||
|
|
||||||
|
#class GSecretary(models.Model):
|
||||||
|
# group_acronym = models.ForeignKey(GroupIETF, 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_secretary'
|
||||||
|
|
||||||
|
class GTechAdvisors(models.Model):
|
||||||
|
group_acronym = models.ForeignKey(GroupIETF, edit_inline=models.TABULAR)
|
||||||
|
person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag', raw_id_admin=True, core=True)
|
||||||
|
class Meta:
|
||||||
|
db_table = 'g_tech_advisors'
|
||||||
|
|
||||||
|
class AreaGroup(models.Model):
|
||||||
|
area = models.ForeignKey(Areas, db_column='area_acronym_id', related_name='areagroup', core=True)
|
||||||
|
group = models.ForeignKey(GroupIETF, db_column='group_acronym_id', edit_inline=models.TABULAR, num_in_admin=1, unique=True)
|
||||||
|
class Meta:
|
||||||
|
db_table = 'area_group'
|
||||||
|
|
||||||
|
class GoalsMilestones(models.Model):
|
||||||
|
gm_id = models.AutoField(primary_key=True)
|
||||||
|
group_acronym = models.ForeignKey(GroupIETF, 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, maxlength=4)
|
||||||
|
last_modified_date = models.DateField()
|
||||||
|
def __str__(self):
|
||||||
|
return self.description
|
||||||
|
class Meta:
|
||||||
|
db_table = 'goals_milestones'
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
#### end wg stuff
|
||||||
|
|
||||||
|
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 IRTFChairs(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
|
2
ietf/idtracker/templatetags/.gitignore
vendored
Normal file
2
ietf/idtracker/templatetags/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/*.pyc
|
||||||
|
/settings_local.py
|
0
ietf/idtracker/templatetags/__init__.py
Normal file
0
ietf/idtracker/templatetags/__init__.py
Normal file
89
ietf/idtracker/templatetags/ietf_filters.py
Normal file
89
ietf/idtracker/templatetags/ietf_filters.py
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
from django import template
|
||||||
|
from django.utils.html import escape, fix_ampersands, linebreaks
|
||||||
|
from django.template.defaultfilters import linebreaksbr
|
||||||
|
try:
|
||||||
|
from email import utils as emailutils
|
||||||
|
except ImportError:
|
||||||
|
from email import Utils as emailutils
|
||||||
|
import re
|
||||||
|
|
||||||
|
register = template.Library()
|
||||||
|
|
||||||
|
@register.filter(name='expand_comma')
|
||||||
|
def expand_comma(value):
|
||||||
|
"""
|
||||||
|
Adds a space after each comma, to allow word-wrapping of
|
||||||
|
long comma-separated lists."""
|
||||||
|
return value.replace(",", ", ")
|
||||||
|
|
||||||
|
@register.filter(name='parse_email_list')
|
||||||
|
def parse_email_list(value):
|
||||||
|
"""
|
||||||
|
Parse a list of comma-seperated email addresses into
|
||||||
|
a list of mailto: links."""
|
||||||
|
addrs = re.split(", ?", value)
|
||||||
|
ret = []
|
||||||
|
for addr in addrs:
|
||||||
|
(name, email) = emailutils.parseaddr(addr)
|
||||||
|
if not(name):
|
||||||
|
name = email
|
||||||
|
ret.append('<a href="mailto:%s">%s</a>' % ( fix_ampersands(email), escape(name) ))
|
||||||
|
return ", ".join(ret)
|
||||||
|
|
||||||
|
# there's an "ahref -> a href" in GEN_UTIL
|
||||||
|
# but let's wait until we understand what that's for.
|
||||||
|
@register.filter(name='make_one_per_line')
|
||||||
|
def make_one_per_line(value):
|
||||||
|
"""
|
||||||
|
Turn a comma-separated list into a carraige-return-seperated list."""
|
||||||
|
return re.sub(", ?", "\n", value)
|
||||||
|
|
||||||
|
@register.filter(name='link_if_url')
|
||||||
|
def link_if_url(value):
|
||||||
|
"""
|
||||||
|
If the argument looks like a url, return a link; otherwise, just
|
||||||
|
return the argument."""
|
||||||
|
if (re.match('(https?|mailto):', value)):
|
||||||
|
return "<a href=\"%s\">%s</a>" % ( fix_ampersands(value), escape(value) )
|
||||||
|
else:
|
||||||
|
return escape(value)
|
||||||
|
|
||||||
|
# This replicates the nwg_list.cgi method.
|
||||||
|
# It'd probably be better to check for the presence of
|
||||||
|
# a scheme with a better RE.
|
||||||
|
@register.filter(name='add_scheme')
|
||||||
|
def add_scheme(value):
|
||||||
|
if (re.match('www', value)):
|
||||||
|
return "http://" + value
|
||||||
|
else:
|
||||||
|
return value
|
||||||
|
|
||||||
|
@register.filter(name='timesum')
|
||||||
|
def timesum(value):
|
||||||
|
"""
|
||||||
|
Sum the times in a list of dicts; used for sql query debugging info"""
|
||||||
|
sum = 0.0
|
||||||
|
for v in value:
|
||||||
|
sum += float(v['time'])
|
||||||
|
return sum
|
||||||
|
|
||||||
|
@register.filter(name='text_to_html')
|
||||||
|
def text_to_html(value):
|
||||||
|
return keep_spacing(linebreaks(escape(value)))
|
||||||
|
|
||||||
|
@register.filter(name='keep_spacing')
|
||||||
|
def keep_spacing(value):
|
||||||
|
"""
|
||||||
|
Replace any two spaces with one and one space so that
|
||||||
|
HTML output doesn't collapse them."""
|
||||||
|
return value.replace(' ', ' ')
|
||||||
|
|
||||||
|
@register.filter(name='format_textarea')
|
||||||
|
def format_textarea(value):
|
||||||
|
"""
|
||||||
|
Escapes HTML, except for <b>, </b>, <br>.
|
||||||
|
|
||||||
|
Adds <br> at the end like the builtin linebreaksbr.
|
||||||
|
|
||||||
|
Also calls keep_spacing."""
|
||||||
|
return keep_spacing(linebreaksbr(escape(value).replace('<b>','<b>').replace('</b>','</b>').replace('<br>','<br>')))
|
26
ietf/idtracker/urls.py
Normal file
26
ietf/idtracker/urls.py
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
from django.conf.urls.defaults import *
|
||||||
|
from ietf.idtracker.models import InternetDraft, IDState, IDSubState, DocumentComment
|
||||||
|
from ietf.idtracker import views
|
||||||
|
|
||||||
|
id_dict = {
|
||||||
|
'queryset': InternetDraft.objects.all(),
|
||||||
|
}
|
||||||
|
comment_dict = {
|
||||||
|
'queryset': DocumentComment.objects.all().filter(public_flag=1),
|
||||||
|
}
|
||||||
|
|
||||||
|
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'^(?P<object_id>\d+)/$', 'object_detail', id_dict),
|
||||||
|
(r'^(?P<slug>[^/]+)/$', 'object_detail', dict(id_dict, slug_field='filename')),
|
||||||
|
(r'^comment/(?P<object_id>\d+)/$', 'object_detail', comment_dict),
|
||||||
|
)
|
||||||
|
urlpatterns += patterns('',
|
||||||
|
(r'^(?P<slug>[^/]+)/comment/(?P<object_id>\d+)/$', views.comment, comment_dict),
|
||||||
|
(r'^states/(?P<state>\d+)/$', views.state_desc),
|
||||||
|
(r'^states/substate/(?P<state>\d+)/$', views.state_desc, { 'is_substate': 1 }),
|
||||||
|
(r'^(?P<id>\d+)/edit/$', views.edit_idinternal),
|
||||||
|
(r'^$', views.search),
|
||||||
|
)
|
120
ietf/idtracker/views.py
Normal file
120
ietf/idtracker/views.py
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
# Create your views here.
|
||||||
|
from django.http import HttpResponse,HttpResponseRedirect
|
||||||
|
from django import newforms as forms
|
||||||
|
from django.template import RequestContext, Context, loader
|
||||||
|
from django.shortcuts import get_object_or_404, render_to_response
|
||||||
|
from django.db.models import Q
|
||||||
|
from django.views.generic.list_detail import object_detail
|
||||||
|
from ietf.idtracker.models import InternetDraft, IDInternal, IDState, IDSubState
|
||||||
|
|
||||||
|
# Override default form field mappings
|
||||||
|
# group_acronym: CharField(max_length=10)
|
||||||
|
# note: CharField(max_length=100)
|
||||||
|
def myfields(f):
|
||||||
|
if f.name == "group":
|
||||||
|
return forms.CharField(max_length=10,
|
||||||
|
widget=forms.TextInput(attrs={'size': 5}))
|
||||||
|
if f.name == "note":
|
||||||
|
return forms.CharField(max_length=100,
|
||||||
|
widget=forms.TextInput(attrs={'size': 100}))
|
||||||
|
return f.formfield()
|
||||||
|
|
||||||
|
def search(request):
|
||||||
|
InternetDraftForm = forms.models.form_for_model(InternetDraft, formfield_callback=myfields)
|
||||||
|
idform = InternetDraftForm(request.POST)
|
||||||
|
InternalForm = forms.models.form_for_model(IDInternal, formfield_callback=myfields)
|
||||||
|
form = InternalForm(request.POST)
|
||||||
|
t = loader.get_template('idtracker/idtracker_search.html')
|
||||||
|
# if there's a post, do the search and supply results to the template
|
||||||
|
if request.method == 'POST':
|
||||||
|
qdict = { 'filename': 'draft__filename__contains',
|
||||||
|
'job_owner': 'job_owner',
|
||||||
|
'group': 'draft__group__acronym',
|
||||||
|
'cur_state': 'cur_state',
|
||||||
|
'cur_sub_state': 'cur_sub_state',
|
||||||
|
'rfc_number': 'draft__rfc_number',
|
||||||
|
'area_acronym': 'area_acronym',
|
||||||
|
'note': 'note__contains',
|
||||||
|
}
|
||||||
|
q_objs = [Q(**{qdict[k]: request.POST[k]})
|
||||||
|
for k in qdict.keys()
|
||||||
|
if request.POST[k] != '']
|
||||||
|
matches = IDInternal.objects.all().filter(*q_objs)
|
||||||
|
# matches = IDInternal.objects.all()
|
||||||
|
# if request.POST['filename']:
|
||||||
|
# matches = matches.filter(draft__filename__contains=request.POST["filename"])
|
||||||
|
# if request.POST['job_owner']:
|
||||||
|
# matches = matches.filter(job_owner=request.POST['job_owner'])
|
||||||
|
# if request.POST['group']:
|
||||||
|
# matches = matches.filter(draft__group__acronym=request.POST['group_acronym'])
|
||||||
|
# if request.POST['cur_state']:
|
||||||
|
# matches = matches.filter(cur_state=request.POST['cur_state'])
|
||||||
|
# if request.POST['cur_sub_state']:
|
||||||
|
# matches = matches.filter(cur_sub_state=request.POST['cur_sub_state'])
|
||||||
|
# if request.POST['rfc_number']:
|
||||||
|
# matches = matches.filter(draft__rfc_number=request.POST['rfc_number'])
|
||||||
|
# if request.POST['area_acronym']:
|
||||||
|
# matches = matches.filter(area_acronym=request.POST['area_acronym'])
|
||||||
|
# if request.POST['note']:
|
||||||
|
# matches = matches.filter(note__contains=request.POST['note'])
|
||||||
|
matches = matches.order_by('cur_state', 'cur_sub_state_id')
|
||||||
|
else:
|
||||||
|
matches = None
|
||||||
|
|
||||||
|
c = RequestContext(request, {
|
||||||
|
'form': form,
|
||||||
|
'idform': idform,
|
||||||
|
'matches': matches,
|
||||||
|
})
|
||||||
|
return HttpResponse(t.render(c))
|
||||||
|
|
||||||
|
def edit_idinternal(request, id=None):
|
||||||
|
#draft = InternetDraft.objects.get(pk=id)
|
||||||
|
draft = get_object_or_404(InternetDraft.objects, pk=id)
|
||||||
|
IDEntryForm = forms.models.form_for_instance(draft)
|
||||||
|
# todo: POST handling for idform
|
||||||
|
idform = IDEntryForm()
|
||||||
|
idinternal = draft.idinternal()
|
||||||
|
if idinternal:
|
||||||
|
EntryForm = forms.models.form_for_instance(idinternal)
|
||||||
|
if request.method == 'POST':
|
||||||
|
form = EntryForm(request.POST)
|
||||||
|
if form.is_valid():
|
||||||
|
form.save()
|
||||||
|
return HttpResponseRedirect("/") # really want here
|
||||||
|
else:
|
||||||
|
form = EntryForm()
|
||||||
|
else:
|
||||||
|
form = None
|
||||||
|
|
||||||
|
t = loader.get_template('idtracker/idtracker_edit.html')
|
||||||
|
|
||||||
|
c = RequestContext(request, {
|
||||||
|
'form': form,
|
||||||
|
'idform': idform,
|
||||||
|
'draft': draft,
|
||||||
|
})
|
||||||
|
return HttpResponse(t.render(c))
|
||||||
|
|
||||||
|
def state_desc(request, state, is_substate=0):
|
||||||
|
if int(state) == 100:
|
||||||
|
object = {
|
||||||
|
'state': 'I-D Exists',
|
||||||
|
'description': """
|
||||||
|
Initial (default) state for all internet drafts. Such documents are
|
||||||
|
not being tracked by the IESG as no request has been made of the
|
||||||
|
IESG to do anything with the document.
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
elif is_substate:
|
||||||
|
sub = get_object_or_404(IDSubState, pk=state)
|
||||||
|
object = { 'state': sub.sub_state, 'description': sub.description }
|
||||||
|
else:
|
||||||
|
object = get_object_or_404(IDState, pk=state)
|
||||||
|
return render_to_response('idtracker/state_desc.html', {'state': object},
|
||||||
|
context_instance=RequestContext(request))
|
||||||
|
|
||||||
|
def comment(request, slug, object_id, queryset):
|
||||||
|
draft = get_object_or_404(InternetDraft, filename=slug)
|
||||||
|
queryset = queryset.filter(document=draft.id_document_tag)
|
||||||
|
return object_detail(request, queryset=queryset, object_id=object_id)
|
2
ietf/iesg/.gitignore
vendored
Normal file
2
ietf/iesg/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/*.pyc
|
||||||
|
/settings_local.py
|
0
ietf/iesg/__init__.py
Normal file
0
ietf/iesg/__init__.py
Normal file
21
ietf/iesg/feeds.py
Normal file
21
ietf/iesg/feeds.py
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
from django.contrib.syndication.feeds import Feed
|
||||||
|
from django.utils.feedgenerator import Atom1Feed
|
||||||
|
from ietf.iesg.models import TelechatMinutes
|
||||||
|
|
||||||
|
class IESGMinutes(Feed):
|
||||||
|
title = "IESG Telechat Minutes"
|
||||||
|
link = "/iesg/telechat/"
|
||||||
|
subtitle = "Minutes from IESG Telechats."
|
||||||
|
feed_type = Atom1Feed
|
||||||
|
|
||||||
|
def items(self):
|
||||||
|
return TelechatMinutes.objects.order_by('-telechat_date')[:10]
|
||||||
|
|
||||||
|
def item_link(self, item):
|
||||||
|
return "/iesg/telechat/detail/%d/" % (item.id)
|
||||||
|
|
||||||
|
# The approval date isn't stored, so let's just say they're
|
||||||
|
# published on the date of the telechat.
|
||||||
|
def item_pubdate(self, item):
|
||||||
|
# (slightly better would be 0900 Eastern on this date)
|
||||||
|
return item.telechat_date
|
9
ietf/iesg/models.py
Normal file
9
ietf/iesg/models.py
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
class TelechatMinutes(models.Model):
|
||||||
|
telechat_date = models.DateField(null=True, blank=True)
|
||||||
|
telechat_minute = models.TextField(blank=True)
|
||||||
|
exported = models.IntegerField(null=True, blank=True)
|
||||||
|
class Meta:
|
||||||
|
db_table = 'telechat_minutes'
|
||||||
|
|
25
ietf/iesg/urls.py
Normal file
25
ietf/iesg/urls.py
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
from django.conf.urls.defaults import *
|
||||||
|
from ietf.iesg.models import TelechatMinutes
|
||||||
|
|
||||||
|
|
||||||
|
#urlpatterns = patterns('django.views.generic.list_detail',
|
||||||
|
# (r'^lastcall/$', 'object_list', {
|
||||||
|
# 'queryset': InternetDraft.objects.all() }),
|
||||||
|
#)
|
||||||
|
|
||||||
|
queryset = TelechatMinutes.objects.all()
|
||||||
|
telechat_detail = {
|
||||||
|
'queryset': queryset,
|
||||||
|
'date_field': 'telechat_date',
|
||||||
|
}
|
||||||
|
telechat_archive = dict(telechat_detail, allow_empty=True)
|
||||||
|
|
||||||
|
urlpatterns = patterns('django.views.generic.date_based',
|
||||||
|
(r'^telechat/$', 'archive_index', telechat_archive),
|
||||||
|
(r'^telechat/(?P<year>\d{4})/$', 'archive_year', telechat_archive),
|
||||||
|
(r'^telechat/(?P<year>\d{4})/(?P<month>[a-z]{3})/$', 'archive_month', telechat_archive),
|
||||||
|
)
|
||||||
|
|
||||||
|
urlpatterns += patterns('django.views.generic.list_detail',
|
||||||
|
(r'^telechat/detail/(?P<object_id>\d+)/$', 'object_detail', { 'queryset': queryset }),
|
||||||
|
)
|
1
ietf/iesg/views.py
Normal file
1
ietf/iesg/views.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# Create your views here.
|
2
ietf/ipr/.gitignore
vendored
Normal file
2
ietf/ipr/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/*.pyc
|
||||||
|
/settings_local.py
|
0
ietf/ipr/__init__.py
Normal file
0
ietf/ipr/__init__.py
Normal file
167
ietf/ipr/models.py
Normal file
167
ietf/ipr/models.py
Normal file
|
@ -0,0 +1,167 @@
|
||||||
|
from django.db import models
|
||||||
|
from ietf.idtracker.views import InternetDraft
|
||||||
|
from ietf.rfcs.models import Rfc
|
||||||
|
|
||||||
|
LICENSE_CHOICES = (
|
||||||
|
(1, 'No License Required for Implementers.'),
|
||||||
|
(2, 'Royalty-Free, Reasonable and Non-Discriminatory License to All Implementers.'),
|
||||||
|
(3, 'Reasonable and Non-Discriminatory License to All Implementers with Possible Royalty/Fee.'),
|
||||||
|
(4, 'Licensing Declaration to be Provided Later.'),
|
||||||
|
(5, 'Unwilling to Commit to the Provisions.'),
|
||||||
|
(6, 'See Text Below for Licensing Declaration.'),
|
||||||
|
)
|
||||||
|
STDONLY_CHOICES = (
|
||||||
|
(0, ""),
|
||||||
|
(1, "The licensing declaration is limited solely to standards-track IETF documents."),
|
||||||
|
)
|
||||||
|
SELECT_CHOICES = (
|
||||||
|
("0", 'NO'),
|
||||||
|
("1", 'YES'),
|
||||||
|
("2", 'NO'),
|
||||||
|
)
|
||||||
|
|
||||||
|
# not clear why this has both an ID and selecttype
|
||||||
|
# Also not clear why a table for "YES" and "NO".
|
||||||
|
class IprSelecttype(models.Model):
|
||||||
|
type_id = models.AutoField(primary_key=True)
|
||||||
|
selecttype = models.IntegerField(unique=True)
|
||||||
|
type_display = models.CharField(blank=True, maxlength=15)
|
||||||
|
def __str__(self):
|
||||||
|
return self.type_display
|
||||||
|
class Meta:
|
||||||
|
db_table = 'ipr_selecttype'
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class IprLicensing(models.Model):
|
||||||
|
licensing_option = models.AutoField(primary_key=True)
|
||||||
|
value = models.CharField(maxlength=255, db_column='licensing_option_value')
|
||||||
|
def __str__(self):
|
||||||
|
return self.value;
|
||||||
|
class Meta:
|
||||||
|
db_table = 'ipr_licensing'
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class IprDetail(models.Model):
|
||||||
|
ipr_id = models.AutoField(primary_key=True)
|
||||||
|
p_h_legal_name = models.CharField("Patent Holder's Legal Name", blank=True, maxlength=255)
|
||||||
|
document_title = models.CharField(blank=True, maxlength=255)
|
||||||
|
rfc_number = models.IntegerField(null=True, blank=True) # always NULL
|
||||||
|
id_document_tag = models.IntegerField(null=True, blank=True) # always NULL
|
||||||
|
other_designations = models.CharField(blank=True, maxlength=255)
|
||||||
|
p_applications = models.TextField(blank=True, maxlength=255)
|
||||||
|
date_applied = models.CharField(blank=True, maxlength=255)
|
||||||
|
#selecttype = models.ForeignKey(IprSelecttype, to_field='selecttype', db_column='selecttype')
|
||||||
|
selecttype = models.IntegerField(null=True, choices=SELECT_CHOICES)
|
||||||
|
discloser_identify = models.TextField(blank=True, maxlength=255, db_column='disclouser_identify')
|
||||||
|
#licensing_option = models.ForeignKey(IprLicensing, db_column='licensing_option')
|
||||||
|
licensing_option = models.IntegerField(null=True, blank=True, choices=LICENSE_CHOICES)
|
||||||
|
other_notes = models.TextField(blank=True)
|
||||||
|
submitted_date = models.DateField(null=True, blank=True)
|
||||||
|
status = models.IntegerField(null=True, blank=True)
|
||||||
|
comments = models.TextField(blank=True)
|
||||||
|
old_ipr_url = models.CharField(blank=True, maxlength=255)
|
||||||
|
additional_old_title1 = models.CharField(blank=True, maxlength=255)
|
||||||
|
additional_old_url1 = models.CharField(blank=True, maxlength=255)
|
||||||
|
additional_old_title2 = models.CharField(blank=True, maxlength=255)
|
||||||
|
additional_old_url2 = models.CharField(blank=True, maxlength=255)
|
||||||
|
country = models.CharField(blank=True, maxlength=100)
|
||||||
|
p_notes = models.TextField(blank=True)
|
||||||
|
third_party = models.BooleanField()
|
||||||
|
lic_opt_a_sub = models.IntegerField(choices=STDONLY_CHOICES)
|
||||||
|
lic_opt_b_sub = models.IntegerField(choices=STDONLY_CHOICES)
|
||||||
|
lic_opt_c_sub = models.IntegerField(choices=STDONLY_CHOICES)
|
||||||
|
generic = models.BooleanField()
|
||||||
|
# I don't understand selectowned, it looks like it should be a boolean field.
|
||||||
|
selectowned = models.IntegerField(null=True, blank=True, choices=SELECT_CHOICES)
|
||||||
|
comply = models.BooleanField()
|
||||||
|
lic_checkbox = models.BooleanField()
|
||||||
|
update_notified_date = models.DateField(null=True, blank=True)
|
||||||
|
def __str__(self):
|
||||||
|
return self.document_title
|
||||||
|
def selecttypetext(self):
|
||||||
|
if self.selecttype == "1":
|
||||||
|
return "YES"
|
||||||
|
else:
|
||||||
|
return "NO"
|
||||||
|
def selectownedtext(self):
|
||||||
|
if self.selectowned == "1":
|
||||||
|
return "YES"
|
||||||
|
else:
|
||||||
|
return "NO"
|
||||||
|
class Meta:
|
||||||
|
db_table = 'ipr_detail'
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class IprContact(models.Model):
|
||||||
|
TYPE_CHOICES = (
|
||||||
|
('1', 'Patent Holder Contact'),
|
||||||
|
('2', 'IETF Participant Contact'),
|
||||||
|
('3', 'Submitter Contact'),
|
||||||
|
)
|
||||||
|
contact_id = models.AutoField(primary_key=True)
|
||||||
|
ipr = models.ForeignKey(IprDetail, raw_id_admin=True, related_name="contact")
|
||||||
|
contact_type = models.IntegerField(choices=TYPE_CHOICES)
|
||||||
|
name = models.CharField(maxlength=255)
|
||||||
|
title = models.CharField(blank=True, maxlength=255)
|
||||||
|
department = models.CharField(blank=True, maxlength=255)
|
||||||
|
telephone = models.CharField(maxlength=25)
|
||||||
|
fax = models.CharField(blank=True, maxlength=25)
|
||||||
|
email = models.CharField(maxlength=255)
|
||||||
|
address1 = models.CharField(blank=True, maxlength=255)
|
||||||
|
address2 = models.CharField(blank=True, maxlength=255)
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
class Meta:
|
||||||
|
db_table = 'ipr_contacts'
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class IprDraft(models.Model):
|
||||||
|
document = models.ForeignKey(InternetDraft, db_column='id_document_tag', raw_id_admin=True)
|
||||||
|
ipr = models.ForeignKey(IprDetail, raw_id_admin=True, related_name='drafts')
|
||||||
|
revision = models.CharField(maxlength=2)
|
||||||
|
def __str__(self):
|
||||||
|
return "%s applies to %s-%s" % ( self.ipr, self.document, self.revision )
|
||||||
|
class Meta:
|
||||||
|
db_table = 'ipr_ids'
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class IprNotification(models.Model):
|
||||||
|
ipr = models.ForeignKey(IprDetail, raw_id_admin=True)
|
||||||
|
notification = models.TextField(blank=True)
|
||||||
|
date_sent = models.DateField(null=True, blank=True)
|
||||||
|
time_sent = models.CharField(blank=True, maxlength=25)
|
||||||
|
def __str__(self):
|
||||||
|
return "IPR notification for %s sent %s %s" % (self.ipr, self.date_sent, self.time_sent)
|
||||||
|
class Meta:
|
||||||
|
db_table = 'ipr_notifications'
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class IprRfc(models.Model):
|
||||||
|
ipr = models.ForeignKey(IprDetail, raw_id_admin=True, related_name='rfcs')
|
||||||
|
rfc_number = models.ForeignKey(Rfc, db_column='rfc_number', raw_id_admin=True)
|
||||||
|
def __str__(self):
|
||||||
|
return "%s applies to RFC%04d" % ( self.ipr, self.rfc_number )
|
||||||
|
class Meta:
|
||||||
|
db_table = 'ipr_rfcs'
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class IprUpdate(models.Model):
|
||||||
|
id = models.IntegerField(primary_key=True)
|
||||||
|
ipr = models.ForeignKey(IprDetail, raw_id_admin=True, related_name='updates')
|
||||||
|
updated = models.ForeignKey(IprDetail, db_column='updated', raw_id_admin=True, related_name='updated_by')
|
||||||
|
status_to_be = models.IntegerField(null=True, blank=True)
|
||||||
|
processed = models.IntegerField(null=True, blank=True)
|
||||||
|
class Meta:
|
||||||
|
db_table = 'ipr_updates'
|
||||||
|
class Admin:
|
||||||
|
pass
|
21
ietf/ipr/urls.py
Normal file
21
ietf/ipr/urls.py
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
from django.conf.urls.defaults import *
|
||||||
|
from ietf.ipr import models, views
|
||||||
|
|
||||||
|
urlpatterns = patterns('',
|
||||||
|
(r'^$', views.showlist),
|
||||||
|
(r'^about/?$', views.default),
|
||||||
|
(r'^ipr-(?P<ipr_id>\d+)/$', views.show),
|
||||||
|
(r'^update/$', views.updatelist),
|
||||||
|
(r'^update/(?P<ipr_id>\d+)/$', views.update),
|
||||||
|
(r'^new-(?P<type>(specific|generic|thirdpty))/$', views.new),
|
||||||
|
)
|
||||||
|
|
||||||
|
queryset = models.IprDetail.objects.all()
|
||||||
|
archive = {'queryset':queryset, 'date_field': 'submitted_date', 'allow_empty':True }
|
||||||
|
|
||||||
|
urlpatterns += patterns('django.views.generic.date_based',
|
||||||
|
(r'^(?P<year>\d{4})/$', 'archive_year', archive),
|
||||||
|
(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$', 'archive_month', archive),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
112
ietf/ipr/views.py
Normal file
112
ietf/ipr/views.py
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
import models
|
||||||
|
from django.shortcuts import render_to_response as render
|
||||||
|
import django.newforms as forms
|
||||||
|
|
||||||
|
def default(request):
|
||||||
|
"""Default page, with links to sub-pages"""
|
||||||
|
return render("ipr/disclosure.html", {})
|
||||||
|
|
||||||
|
def showlist(request):
|
||||||
|
"""Display a list of existing disclosures"""
|
||||||
|
return list(request, 'ipr/list.html')
|
||||||
|
|
||||||
|
def updatelist(request):
|
||||||
|
"""Display a list of existing disclosures, with links to update forms"""
|
||||||
|
return list(request, 'ipr/update_list.html')
|
||||||
|
|
||||||
|
def list(request, template):
|
||||||
|
"""Display a list of existing disclosures, using the provided template"""
|
||||||
|
disclosures = models.IprDetail.objects.all()
|
||||||
|
generic_disclosures = disclosures.filter(status__in=[1,3], generic=1)
|
||||||
|
specific_disclosures = disclosures.filter(status__in=[1,3], generic=0, third_party=0)
|
||||||
|
thirdpty_disclosures = disclosures.filter(status__in=[1,3], generic=0, third_party=1)
|
||||||
|
|
||||||
|
return render(template,
|
||||||
|
{
|
||||||
|
'generic_disclosures' : generic_disclosures.order_by(* ['-submitted_date', ] ),
|
||||||
|
'specific_disclosures': specific_disclosures.order_by(* ['-submitted_date', ] ),
|
||||||
|
'thirdpty_disclosures': thirdpty_disclosures.order_by(* ['-submitted_date', ] ),
|
||||||
|
} )
|
||||||
|
|
||||||
|
def show(request, ipr_id=None):
|
||||||
|
"""Show a specific IPR disclosure"""
|
||||||
|
assert ipr_id != None
|
||||||
|
ipr = models.IprDetail.objects.filter(ipr_id=ipr_id)[0]
|
||||||
|
ipr.disclosure_type = get_disclosure_type(ipr)
|
||||||
|
try:
|
||||||
|
ipr.holder_contact = ipr.contact.filter(contact_type=1)[0]
|
||||||
|
except IndexError:
|
||||||
|
ipr.holder_contact = ""
|
||||||
|
try:
|
||||||
|
ipr.ietf_contact = ipr.contact.filter(contact_type=2)[0]
|
||||||
|
except IndexError:
|
||||||
|
ipr.ietf_contact = ""
|
||||||
|
try:
|
||||||
|
ipr.submitter = ipr.contact.filter(contact_type=3)[0]
|
||||||
|
except IndexError:
|
||||||
|
ipr.submitter = ""
|
||||||
|
|
||||||
|
if ipr.generic:
|
||||||
|
return render("ipr/details_generic.html", {"ipr": ipr})
|
||||||
|
if ipr.third_party:
|
||||||
|
return render("ipr/details_thirdpty.html", {"ipr": ipr})
|
||||||
|
else:
|
||||||
|
return render("ipr/details_specific.html", {"ipr": ipr})
|
||||||
|
|
||||||
|
|
||||||
|
def update(request, ipr_id=None):
|
||||||
|
"""Update a specific IPR disclosure"""
|
||||||
|
# TODO: replace the placeholder code with the appropriate update code
|
||||||
|
return show(request, ipr_id)
|
||||||
|
|
||||||
|
def new(request, type):
|
||||||
|
"""Form to make a new IPR disclosure"""
|
||||||
|
debug = ""
|
||||||
|
|
||||||
|
IprForm = forms.form_for_model(models.IprDetail, formfield_callback=detail_field_fixup)
|
||||||
|
# Some extra fields which will get post-processing to generate the IprRfcs
|
||||||
|
# and IprDrafts entries which go into the database:
|
||||||
|
IprForm.base_fields["rfclist"] = forms.CharField(required=False)
|
||||||
|
IprForm.base_fields["draftlist"] = forms.CharField(required=False)
|
||||||
|
IprForm.base_fields["stdonly_license"] = forms.BooleanField(required=False)
|
||||||
|
|
||||||
|
ContactForm = forms.form_for_model(models.IprContact)
|
||||||
|
|
||||||
|
if request.method == 'POST':
|
||||||
|
form = IprForm(request.POST)
|
||||||
|
|
||||||
|
form.holder_contact = ContactForm(request.POST, prefix="ph")
|
||||||
|
form.ietf_contact = ContactForm(request.POST, prefix="ietf")
|
||||||
|
form.submitter = ContactForm(request.POST, prefix="sub")
|
||||||
|
|
||||||
|
if form.is_valid():
|
||||||
|
form.save()
|
||||||
|
return HttpResponseRedirect("/ipr/")
|
||||||
|
else:
|
||||||
|
form = IprForm()
|
||||||
|
form.holder_contact = ContactForm(prefix="ph")
|
||||||
|
form.ietf_contact = ContactForm(prefix="ietf")
|
||||||
|
form.submitter = ContactForm(prefix="sub")
|
||||||
|
|
||||||
|
form.unbound_form = not form.is_bound
|
||||||
|
form.disclosure_type = type.capitalize()
|
||||||
|
return render("ipr/new_%s.html" % type, {"ipr": form, "debug": debug, })
|
||||||
|
|
||||||
|
def detail_field_fixup(field):
|
||||||
|
if field.name == "licensing_option":
|
||||||
|
return forms.IntegerField(widget=forms.RadioSelect(choices=models.LICENSE_CHOICES))
|
||||||
|
if field.name in ["selecttype", "selectowned"]:
|
||||||
|
return forms.IntegerField(widget=forms.RadioSelect(choices=((1, "YES"), (2, "NO"))))
|
||||||
|
return field.formfield()
|
||||||
|
|
||||||
|
|
||||||
|
# ---- Helper functions ------------------------------------------------------
|
||||||
|
|
||||||
|
def get_disclosure_type(ipr):
|
||||||
|
if ipr.generic:
|
||||||
|
assert not ipr.third_party
|
||||||
|
return "Generic"
|
||||||
|
if ipr.third_party:
|
||||||
|
return "Third Party"
|
||||||
|
else:
|
||||||
|
return "Specific"
|
2
ietf/liaisons/.gitignore
vendored
Normal file
2
ietf/liaisons/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/*.pyc
|
||||||
|
/settings_local.py
|
0
ietf/liaisons/__init__.py
Normal file
0
ietf/liaisons/__init__.py
Normal file
154
ietf/liaisons/models.py
Normal file
154
ietf/liaisons/models.py
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
from django.db import models
|
||||||
|
from ietf.idtracker.models import Acronym,PersonOrOrgInfo
|
||||||
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
|
|
||||||
|
class LiaisonPurpose(models.Model):
|
||||||
|
purpose_id = models.AutoField(primary_key=True)
|
||||||
|
purpose_text = models.CharField(blank=True, maxlength=50)
|
||||||
|
def __str__(self):
|
||||||
|
return self.purpose_text
|
||||||
|
class Meta:
|
||||||
|
db_table = 'liaison_purpose'
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class FromBodies(models.Model):
|
||||||
|
from_id = models.AutoField(primary_key=True)
|
||||||
|
body_name = models.CharField(blank=True, maxlength=35)
|
||||||
|
poc = models.ForeignKey(PersonOrOrgInfo, db_column='poc', raw_id_admin=True, null=True)
|
||||||
|
is_liaison_manager = models.BooleanField()
|
||||||
|
other_sdo = models.BooleanField()
|
||||||
|
email_priority = models.IntegerField(null=True, blank=True)
|
||||||
|
def __str__(self):
|
||||||
|
return self.body_name
|
||||||
|
class Meta:
|
||||||
|
db_table = 'from_bodies'
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class LiaisonDetail(models.Model):
|
||||||
|
detail_id = models.AutoField(primary_key=True)
|
||||||
|
person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag', raw_id_admin=True)
|
||||||
|
submitted_date = models.DateField(null=True, blank=True)
|
||||||
|
last_modified_date = models.DateField(null=True, blank=True)
|
||||||
|
from_id = models.IntegerField(null=True, blank=True)
|
||||||
|
to_body = models.CharField(blank=True, maxlength=255)
|
||||||
|
title = models.CharField(blank=True, maxlength=255)
|
||||||
|
response_contact = models.CharField(blank=True, maxlength=255)
|
||||||
|
technical_contact = models.CharField(blank=True, maxlength=255)
|
||||||
|
purpose_text = models.TextField(blank=True, db_column='purpose')
|
||||||
|
body = models.TextField(blank=True)
|
||||||
|
deadline_date = models.DateField(null=True, blank=True)
|
||||||
|
cc1 = models.TextField(blank=True)
|
||||||
|
# unclear why cc2 is a CharField, but it's always
|
||||||
|
# either NULL or blank.
|
||||||
|
cc2 = models.CharField(blank=True, maxlength=50)
|
||||||
|
submitter_name = models.CharField(blank=True, maxlength=255)
|
||||||
|
submitter_email = models.CharField(blank=True, maxlength=255)
|
||||||
|
by_secretariat = models.IntegerField(null=True, blank=True)
|
||||||
|
to_poc = models.CharField(blank=True, maxlength=255)
|
||||||
|
to_email = models.CharField(blank=True, maxlength=255)
|
||||||
|
purpose = models.ForeignKey(LiaisonPurpose)
|
||||||
|
replyto = models.CharField(blank=True, maxlength=255)
|
||||||
|
def __str__(self):
|
||||||
|
return self.title or "<no title>"
|
||||||
|
def from_body(self):
|
||||||
|
"""The from_id field is a foreign key for either
|
||||||
|
FromBodies or Acronyms, depending on whether it's
|
||||||
|
the IETF or not. There is no flag field saying
|
||||||
|
which, so we just try it. If the index values
|
||||||
|
overlap, then this function will be ambiguous
|
||||||
|
and will return the value from FromBodies. Current
|
||||||
|
acronym IDs start at 925 so the day of reckoning
|
||||||
|
is not nigh."""
|
||||||
|
try:
|
||||||
|
from_body = FromBodies.objects.get(pk=self.from_id)
|
||||||
|
return from_body.body_name
|
||||||
|
except ObjectDoesNotExist:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
acronym = Acronym.objects.get(pk=self.from_id)
|
||||||
|
if acronym.areas_set.count():
|
||||||
|
type = "AREA"
|
||||||
|
else:
|
||||||
|
type = "WG"
|
||||||
|
return "IETF %s %s" % ( acronym.acronym.upper(), type )
|
||||||
|
except ObjectDoesNotExist:
|
||||||
|
pass
|
||||||
|
return "<unknown body %d>" % self.from_id
|
||||||
|
def from_email(self):
|
||||||
|
"""If there is an entry in from_bodies, it has
|
||||||
|
the desired email priority. However, if it's from
|
||||||
|
an IETF WG, there is no entry in from_bodies, so
|
||||||
|
default to 1."""
|
||||||
|
try:
|
||||||
|
from_body = FromBodies.objects.get(pk=self.from_id)
|
||||||
|
email_priority = from_body.email_priority
|
||||||
|
except FromBodies.DoesNotExist:
|
||||||
|
email_priority = 1
|
||||||
|
return self.person.emailaddress_set.all().get(priority=email_priority)
|
||||||
|
class Meta:
|
||||||
|
db_table = 'liaison_detail'
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class SDOs(models.Model):
|
||||||
|
sdo_id = models.AutoField(primary_key=True)
|
||||||
|
sdo_name = models.CharField(blank=True, maxlength=255)
|
||||||
|
def __str__(self):
|
||||||
|
return self.sdo_name
|
||||||
|
def liaisonmanager(self):
|
||||||
|
try:
|
||||||
|
return self.liaisonmanagers_set.all()[0]
|
||||||
|
except:
|
||||||
|
return None
|
||||||
|
class Meta:
|
||||||
|
db_table = 'sdos'
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class LiaisonManagers(models.Model):
|
||||||
|
person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag', raw_id_admin=True)
|
||||||
|
email_priority = models.IntegerField(null=True, blank=True, core=True)
|
||||||
|
sdo = models.ForeignKey(SDOs, edit_inline=models.TABULAR, num_in_admin=1)
|
||||||
|
def email(self):
|
||||||
|
try:
|
||||||
|
return self.person.emailaddress_set.get(priority=self.email_priority)
|
||||||
|
except ObjectDoesNotExist:
|
||||||
|
return None
|
||||||
|
class Meta:
|
||||||
|
db_table = 'liaison_managers'
|
||||||
|
|
||||||
|
class LiaisonsInterim(models.Model):
|
||||||
|
title = models.CharField(blank=True, maxlength=255)
|
||||||
|
submitter_name = models.CharField(blank=True, maxlength=255)
|
||||||
|
submitter_email = models.CharField(blank=True, maxlength=255)
|
||||||
|
submitted_date = models.DateField(null=True, blank=True)
|
||||||
|
from_id = models.IntegerField(null=True, blank=True)
|
||||||
|
def __str__(self):
|
||||||
|
return self.title
|
||||||
|
class Meta:
|
||||||
|
db_table = 'liaisons_interim'
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Uploads(models.Model):
|
||||||
|
file_id = models.AutoField(primary_key=True)
|
||||||
|
file_title = models.CharField(blank=True, maxlength=255, core=True)
|
||||||
|
person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag', raw_id_admin=True)
|
||||||
|
file_extension = models.CharField(blank=True, maxlength=10)
|
||||||
|
detail = models.ForeignKey(LiaisonDetail, raw_id_admin=True, edit_inline=models.TABULAR, num_in_admin=1)
|
||||||
|
def __str__(self):
|
||||||
|
return self.file_title
|
||||||
|
class Meta:
|
||||||
|
db_table = 'uploads'
|
||||||
|
|
||||||
|
# empty table
|
||||||
|
#class SdoChairs(models.Model):
|
||||||
|
# sdo = models.ForeignKey(SDOs)
|
||||||
|
# person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag', raw_id_admin=True)
|
||||||
|
# email_priority = models.IntegerField(null=True, blank=True)
|
||||||
|
# class Meta:
|
||||||
|
# db_table = 'sdo_chairs'
|
||||||
|
# class Admin:
|
||||||
|
# pass
|
20
ietf/liaisons/urls.py
Normal file
20
ietf/liaisons/urls.py
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
from django.conf.urls.defaults import *
|
||||||
|
from ietf.liaisons.models import LiaisonDetail, LiaisonManagers
|
||||||
|
|
||||||
|
info_dict = {
|
||||||
|
'queryset': LiaisonDetail.objects.all().order_by("-submitted_date"),
|
||||||
|
}
|
||||||
|
|
||||||
|
# there's an opportunity for date-based filtering.
|
||||||
|
urlpatterns = patterns('django.views.generic.list_detail',
|
||||||
|
(r'^$', 'object_list', info_dict),
|
||||||
|
(r'^(?P<object_id>\d+)/$', 'object_detail', info_dict),
|
||||||
|
(r'^managers/$', 'object_list', { 'queryset': LiaisonManagers.objects.all().select_related().order_by('sdos.sdo_name') }), #XXX order_by relies on select_related()
|
||||||
|
)
|
||||||
|
|
||||||
|
urlpatterns += patterns('django.views.generic.simple',
|
||||||
|
(r'^help/$', 'direct_to_template', {'template': 'liaisons/help.html'}),
|
||||||
|
(r'^help/fields/', 'direct_to_template', {'template': 'liaisons/field_help.html'}),
|
||||||
|
(r'^help/from_ietf/', 'direct_to_template', {'template': 'liaisons/guide_from_ietf.html'}),
|
||||||
|
(r'^help/to_ietf/', 'direct_to_template', {'template': 'liaisons/guide_to_ietf.html'}),
|
||||||
|
)
|
1
ietf/liaisons/views.py
Normal file
1
ietf/liaisons/views.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# Create your views here.
|
2
ietf/mailinglists/.gitignore
vendored
Normal file
2
ietf/mailinglists/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/*.pyc
|
||||||
|
/settings_local.py
|
0
ietf/mailinglists/__init__.py
Normal file
0
ietf/mailinglists/__init__.py
Normal file
96
ietf/mailinglists/models.py
Normal file
96
ietf/mailinglists/models.py
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
from django.db import models
|
||||||
|
from ietf.idtracker.models import Acronym, Areas, PersonOrOrgInfo
|
||||||
|
|
||||||
|
class ImportedMailingList(models.Model):
|
||||||
|
group_acronym = models.ForeignKey(Acronym)
|
||||||
|
list_acronym = models.CharField(blank=True, maxlength=255)
|
||||||
|
list_name = models.CharField(blank=True, maxlength=255)
|
||||||
|
list_domain = models.CharField(blank=True, maxlength=25)
|
||||||
|
def __str__(self):
|
||||||
|
return self.list_name or self.group_acronym
|
||||||
|
class Meta:
|
||||||
|
db_table = 'imported_mailing_list'
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class MailingList(models.Model):
|
||||||
|
SUBSCRIPTION_CHOICES = (
|
||||||
|
('1', 'Confirm'),
|
||||||
|
('2', 'Approval'),
|
||||||
|
('3', 'Confirm+Approval'),
|
||||||
|
)
|
||||||
|
MAILTYPE_CHOICES = (
|
||||||
|
('1', 'Create new WG email list at ietf.org'),
|
||||||
|
('2', 'Move existing WG email list to ietf.org'),
|
||||||
|
('3', 'Move existing non-WG email list to selected domain'),
|
||||||
|
('4', 'Create new non-WG email list at selected domain'),
|
||||||
|
('5', 'Close existing WG email list at ietf.org'),
|
||||||
|
('6', 'Close existing non-WG email list at selected domain'),
|
||||||
|
)
|
||||||
|
# I don't understand the reasoning behind 2 vs 3.
|
||||||
|
# this is set in the javascript and not editable,
|
||||||
|
# so I think there's a 1:1 mapping from mail_type -> mail_cat.
|
||||||
|
# The existing database doesn't help much since many
|
||||||
|
# mail_cat values are NULL.
|
||||||
|
MAILCAT_CHOICES = (
|
||||||
|
('1', 'WG Mailing List'),
|
||||||
|
('2', 'Non-WG Mailing List'),
|
||||||
|
('3', 'Close Non-WG Mailing List'),
|
||||||
|
)
|
||||||
|
mailing_list_id = models.CharField('Unique ID', primary_key=True, maxlength=25)
|
||||||
|
request_date = models.DateField()
|
||||||
|
mlist_name = models.CharField('Mailing list name', maxlength=250)
|
||||||
|
short_desc = models.CharField(maxlength=250)
|
||||||
|
long_desc = models.TextField(blank=True)
|
||||||
|
requestor = models.CharField(maxlength=250)
|
||||||
|
requestor_email = models.CharField(maxlength=250)
|
||||||
|
# admins is a VARCHAR but can have multiple lines
|
||||||
|
admins = models.TextField(blank=True, maxlength=250)
|
||||||
|
archive_remote = models.TextField(blank=True)
|
||||||
|
archive_private = models.BooleanField()
|
||||||
|
initial = models.TextField('Initial members',blank=True)
|
||||||
|
welcome_message = models.TextField(blank=True)
|
||||||
|
subscription = models.IntegerField(choices=SUBSCRIPTION_CHOICES)
|
||||||
|
post_who = models.BooleanField('Only members can post')
|
||||||
|
post_admin = models.BooleanField('Administrator approval required for posts')
|
||||||
|
add_comment = models.TextField(blank=True)
|
||||||
|
mail_type = models.IntegerField(choices=MAILTYPE_CHOICES)
|
||||||
|
mail_cat = models.IntegerField(choices=MAILCAT_CHOICES)
|
||||||
|
auth_person = models.ForeignKey(PersonOrOrgInfo, db_column='auth_person_or_org_tag', raw_id_admin=True)
|
||||||
|
welcome_new = models.TextField(blank=True)
|
||||||
|
approved = models.BooleanField()
|
||||||
|
approved_date = models.DateField(null=True, blank=True)
|
||||||
|
reason_to_delete = models.TextField(blank=True)
|
||||||
|
domain_name = models.CharField(blank=True, maxlength=10)
|
||||||
|
def __str__(self):
|
||||||
|
return self.mlist_name
|
||||||
|
class Meta:
|
||||||
|
db_table = 'mailing_list'
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class NonWgMailingList(models.Model):
|
||||||
|
id = models.CharField(primary_key=True, maxlength=35)
|
||||||
|
purpose = models.TextField(blank=True)
|
||||||
|
area_acronym = models.ForeignKey(Areas)
|
||||||
|
admin = models.TextField(blank=True)
|
||||||
|
list_url = models.CharField(maxlength=255)
|
||||||
|
s_name = models.CharField(blank=True, maxlength=255)
|
||||||
|
s_email = models.CharField(blank=True, maxlength=255)
|
||||||
|
# Can be 0, 1, -1, or what looks like a person_or_org_tag, positive or neg.
|
||||||
|
# The values less than 1 don't get displayed on the list of lists.
|
||||||
|
status = models.IntegerField()
|
||||||
|
list_name = models.CharField(blank=True, maxlength=255)
|
||||||
|
subscribe_url = models.CharField(blank=True, maxlength=255)
|
||||||
|
subscribe_other = models.TextField(blank=True)
|
||||||
|
ds_name = models.CharField(blank=True, maxlength=255)
|
||||||
|
ds_email = models.CharField(blank=True, maxlength=255)
|
||||||
|
msg_to_ad = models.TextField(blank=True)
|
||||||
|
def __str__(self):
|
||||||
|
return self.list_name
|
||||||
|
class Meta:
|
||||||
|
db_table = 'none_wg_mailing_list'
|
||||||
|
ordering = ['list_name']
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
8
ietf/mailinglists/urls.py
Normal file
8
ietf/mailinglists/urls.py
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
from django.conf.urls.defaults import *
|
||||||
|
from ietf.idtracker.models import Areas
|
||||||
|
from ietf.mailinglists.models import NonWgMailingList
|
||||||
|
|
||||||
|
urlpatterns = patterns('django.views.generic.list_detail',
|
||||||
|
(r'^area_lists/$', 'object_list', { 'queryset': Areas.objects.filter(status=1).select_related().order_by('acronym.acronym'), 'template_name': 'mailinglists/areas_list.html' }),
|
||||||
|
(r'^nonwg_lists/$', 'object_list', { 'queryset': NonWgMailingList.objects.filter(status__gt=0) }),
|
||||||
|
)
|
1
ietf/mailinglists/views.py
Normal file
1
ietf/mailinglists/views.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# Create your views here.
|
11
ietf/manage.py
Normal file
11
ietf/manage.py
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
from django.core.management import execute_manager
|
||||||
|
try:
|
||||||
|
import settings # Assumed to be in the same directory.
|
||||||
|
except ImportError:
|
||||||
|
import sys
|
||||||
|
sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
execute_manager(settings)
|
2
ietf/my/.gitignore
vendored
Normal file
2
ietf/my/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/*.pyc
|
||||||
|
/settings_local.py
|
0
ietf/my/__init__.py
Normal file
0
ietf/my/__init__.py
Normal file
3
ietf/my/models.py
Normal file
3
ietf/my/models.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
# Create your models here.
|
8
ietf/my/urls.py
Normal file
8
ietf/my/urls.py
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
from django.conf.urls.defaults import *
|
||||||
|
from ietf.my import views
|
||||||
|
|
||||||
|
urlpatterns = patterns('',
|
||||||
|
# this is for testing
|
||||||
|
(r'^(?P<addr>.+)/$', views.my),
|
||||||
|
(r'^$', views.my),
|
||||||
|
)
|
21
ietf/my/views.py
Normal file
21
ietf/my/views.py
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
from django.http import HttpResponse,HttpResponseRedirect
|
||||||
|
from django import newforms as forms
|
||||||
|
from django.template import RequestContext, Context, loader
|
||||||
|
from django.shortcuts import get_object_or_404
|
||||||
|
from ietf.idtracker.models import PersonOrOrgInfo, EmailAddress
|
||||||
|
|
||||||
|
def my(request, addr=None):
|
||||||
|
if addr is None:
|
||||||
|
# get email address from logged in user
|
||||||
|
return
|
||||||
|
person = PersonOrOrgInfo.objects.filter(emailaddresses__email_address=addr).distinct()
|
||||||
|
if len(person) != 1:
|
||||||
|
if len(person) == 0:
|
||||||
|
raise Http404
|
||||||
|
# multiple people matched!
|
||||||
|
return "Oops"
|
||||||
|
t = loader.get_template('my/my.html')
|
||||||
|
c = RequestContext(request, {
|
||||||
|
'me': person[0],
|
||||||
|
})
|
||||||
|
return HttpResponse(t.render(c))
|
2
ietf/proceedings/.gitignore
vendored
Normal file
2
ietf/proceedings/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/*.pyc
|
||||||
|
/settings_local.py
|
0
ietf/proceedings/__init__.py
Normal file
0
ietf/proceedings/__init__.py
Normal file
250
ietf/proceedings/models.py
Normal file
250
ietf/proceedings/models.py
Normal file
|
@ -0,0 +1,250 @@
|
||||||
|
from django.db import models
|
||||||
|
from ietf.idtracker.models import Acronym, PersonOrOrgInfo, IRTF
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
# group_acronym is either an IETF Acronym
|
||||||
|
# or an IRTF one, depending on the value of irtf.
|
||||||
|
# Multiple inheritance to the rescue.
|
||||||
|
#
|
||||||
|
# interim = i prefix (complicated because you have to check if self has
|
||||||
|
# an interim attribute first)
|
||||||
|
class ResolveAcronym(object):
|
||||||
|
def acronym(self):
|
||||||
|
try:
|
||||||
|
interim = self.interim
|
||||||
|
except AttributeError:
|
||||||
|
interim = False
|
||||||
|
if self.irtf:
|
||||||
|
acronym = IRTF.objects.get(pk=self.group_acronym_id).acronym
|
||||||
|
else:
|
||||||
|
acronym = Acronym.objects.get(pk=self.group_acronym_id).acronym
|
||||||
|
if interim:
|
||||||
|
return "i" + acronym
|
||||||
|
return acronym
|
||||||
|
|
||||||
|
class Meeting(models.Model):
|
||||||
|
meeting_num = models.IntegerField(primary_key=True)
|
||||||
|
start_date = models.DateField()
|
||||||
|
end_date = models.DateField()
|
||||||
|
city = models.CharField(blank=True, maxlength=255)
|
||||||
|
state = models.CharField(blank=True, maxlength=255)
|
||||||
|
country = models.CharField(blank=True, maxlength=255)
|
||||||
|
ack = models.TextField(blank=True)
|
||||||
|
agenda_html = models.TextField(blank=True)
|
||||||
|
agenda_text = models.TextField(blank=True)
|
||||||
|
future_meeting = models.TextField(blank=True)
|
||||||
|
overview1 = models.TextField(blank=True)
|
||||||
|
overview2 = models.TextField(blank=True)
|
||||||
|
def __str__(self):
|
||||||
|
return "IETF %d" % (self.meeting_num)
|
||||||
|
class Meta:
|
||||||
|
db_table = 'meetings'
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class MeetingVenue(models.Model):
|
||||||
|
meeting_num = models.ForeignKey(Meeting, db_column='meeting_num', unique=True)
|
||||||
|
break_area_name = models.CharField(maxlength=255)
|
||||||
|
reg_area_name = models.CharField(maxlength=255)
|
||||||
|
def __str__(self):
|
||||||
|
return "IETF %d" % (self.meeting_num_id)
|
||||||
|
class Meta:
|
||||||
|
db_table = 'meeting_venues'
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class NonSessionRef(models.Model):
|
||||||
|
name = models.CharField(maxlength=255)
|
||||||
|
class Meta:
|
||||||
|
db_table = 'non_session_ref'
|
||||||
|
|
||||||
|
class NonSession(models.Model):
|
||||||
|
day_id = models.IntegerField()
|
||||||
|
non_session_ref = models.ForeignKey(NonSessionRef)
|
||||||
|
meeting_num = models.ForeignKey(Meeting, db_column='meeting_num', unique=True)
|
||||||
|
time_desc = models.CharField(blank=True, maxlength=75)
|
||||||
|
class Meta:
|
||||||
|
db_table = 'non_session'
|
||||||
|
|
||||||
|
class Proceeding(models.Model):
|
||||||
|
meeting_num = models.ForeignKey(Meeting, db_column='meeting_num', unique=True, primary_key=True)
|
||||||
|
dir_name = models.CharField(blank=True, maxlength=25)
|
||||||
|
sub_begin_date = models.DateField(null=True, blank=True)
|
||||||
|
sub_cut_off_date = models.DateField(null=True, blank=True)
|
||||||
|
frozen = models.IntegerField(null=True, blank=True)
|
||||||
|
c_sub_cut_off_date = models.DateField(null=True, blank=True)
|
||||||
|
pr_from_date = models.DateField(null=True, blank=True)
|
||||||
|
pr_to_date = models.DateField(null=True, blank=True)
|
||||||
|
def __str__(self):
|
||||||
|
return "IETF %d" % (self.meeting_num_id)
|
||||||
|
class Meta:
|
||||||
|
db_table = 'proceedings'
|
||||||
|
ordering = ['?'] # workaround for FK primary key
|
||||||
|
#class Admin:
|
||||||
|
# pass # admin site doesn't like something about meeting_num
|
||||||
|
|
||||||
|
class SessionConflict(models.Model):
|
||||||
|
group_acronym = models.ForeignKey(Acronym, raw_id_admin=True, related_name='conflicts_set')
|
||||||
|
conflict_gid = models.ForeignKey(Acronym, raw_id_admin=True, related_name='conflicts_with_set', db_column='conflict_gid')
|
||||||
|
meeting_num = models.ForeignKey(Meeting, db_column='meeting_num')
|
||||||
|
def __str__(self):
|
||||||
|
return "At IETF %d, %s conflicts with %s" % ( self.meeting_num_id, self.group_acronym.acronym, self.conflict_gid.acronym)
|
||||||
|
class Meta:
|
||||||
|
db_table = 'session_conflicts'
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class SessionName(models.Model):
|
||||||
|
session_name_id = models.AutoField(primary_key=True)
|
||||||
|
session_name = models.CharField(blank=True, maxlength=255)
|
||||||
|
def __str__(self):
|
||||||
|
return self.session_name
|
||||||
|
class Meta:
|
||||||
|
db_table = 'session_names'
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class MeetingTime(models.Model):
|
||||||
|
time_id = models.AutoField(primary_key=True)
|
||||||
|
time_desc = models.CharField(maxlength=100)
|
||||||
|
meeting = models.ForeignKey(Meeting, db_column='meeting_num', unique=True)
|
||||||
|
day_id = models.IntegerField()
|
||||||
|
session_name = models.ForeignKey(SessionName)
|
||||||
|
def __str__(self):
|
||||||
|
return "[%d] |%s| %s" % (self.meeting_id, (self.meeting.start_date + datetime.timedelta(self.day_id)).strftime('%A'), self.time_desc)
|
||||||
|
class Meta:
|
||||||
|
db_table = 'meeting_times'
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class MeetingRoom(models.Model):
|
||||||
|
room_id = models.AutoField(primary_key=True)
|
||||||
|
meeting = models.ForeignKey(Meeting, db_column='meeting_num')
|
||||||
|
room_name = models.CharField(maxlength=255)
|
||||||
|
def __str__(self):
|
||||||
|
return "[%d] %s" % (self.meeting_id, self.room_name)
|
||||||
|
class Meta:
|
||||||
|
db_table = 'meeting_rooms'
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class WgMeetingSession(models.Model, ResolveAcronym):
|
||||||
|
session_id = models.AutoField(primary_key=True)
|
||||||
|
meeting = models.ForeignKey(Meeting, db_column='meeting_num')
|
||||||
|
group_acronym_id = models.IntegerField()
|
||||||
|
irtf = models.BooleanField()
|
||||||
|
num_session = models.IntegerField()
|
||||||
|
length_session1 = models.CharField(blank=True, maxlength=100)
|
||||||
|
length_session2 = models.CharField(blank=True, maxlength=100)
|
||||||
|
length_session3 = models.CharField(blank=True, maxlength=100)
|
||||||
|
conflict1 = models.CharField(blank=True, maxlength=255)
|
||||||
|
conflict2 = models.CharField(blank=True, maxlength=255)
|
||||||
|
conflict3 = models.CharField(blank=True, maxlength=255)
|
||||||
|
conflict_other = models.TextField(blank=True)
|
||||||
|
special_req = models.TextField(blank=True)
|
||||||
|
number_attendee = models.IntegerField(null=True, blank=True)
|
||||||
|
approval_ad = models.IntegerField(null=True, blank=True)
|
||||||
|
status_id = models.IntegerField(null=True, blank=True)
|
||||||
|
ts_status_id = models.IntegerField(null=True, blank=True)
|
||||||
|
requested_date = models.DateField(null=True, blank=True)
|
||||||
|
approved_date = models.DateField(null=True, blank=True)
|
||||||
|
requested_by = models.ForeignKey(PersonOrOrgInfo, raw_id_admin=True, db_column='requested_by')
|
||||||
|
scheduled_date = models.DateField(null=True, blank=True)
|
||||||
|
last_modified_date = models.DateField(null=True, blank=True)
|
||||||
|
ad_comments = models.TextField(blank=True)
|
||||||
|
sched_room_id1 = models.ForeignKey(MeetingRoom, db_column='sched_room_id1', null=True, blank=True, related_name='here1')
|
||||||
|
sched_time_id1 = models.ForeignKey(MeetingTime, db_column='sched_time_id1', null=True, blank=True, related_name='now1')
|
||||||
|
sched_date1 = models.DateField(null=True, blank=True)
|
||||||
|
sched_room_id2 = models.ForeignKey(MeetingRoom, db_column='sched_room_id2', null=True, blank=True, related_name='here2')
|
||||||
|
sched_time_id2 = models.ForeignKey(MeetingTime, db_column='sched_time_id2', null=True, blank=True, related_name='now2')
|
||||||
|
sched_date2 = models.DateField(null=True, blank=True)
|
||||||
|
sched_room_id3 = models.ForeignKey(MeetingRoom, db_column='sched_room_id3', null=True, blank=True, related_name='here3')
|
||||||
|
sched_time_id3 = models.ForeignKey(MeetingTime, db_column='sched_time_id3', null=True, blank=True, related_name='now3')
|
||||||
|
sched_date3 = models.DateField(null=True, blank=True)
|
||||||
|
special_agenda_note = models.CharField(blank=True, maxlength=255)
|
||||||
|
combined_room_id1 = models.ForeignKey(MeetingRoom, db_column='combined_room_id1', null=True, blank=True, related_name='here4')
|
||||||
|
combined_time_id1 = models.ForeignKey(MeetingTime, db_column='combined_time_id1', null=True, blank=True, related_name='now4')
|
||||||
|
combined_room_id2 = models.ForeignKey(MeetingRoom, db_column='combined_room_id2', null=True, blank=True, related_name='here5')
|
||||||
|
combined_time_id2 = models.ForeignKey(MeetingTime, db_column='combined_time_id2', null=True, blank=True, related_name='now5')
|
||||||
|
def __str__(self):
|
||||||
|
return "%s at %s" % (self.acronym(), self.meeting)
|
||||||
|
class Meta:
|
||||||
|
db_table = 'wg_meeting_sessions'
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class WgAgenda(models.Model, ResolveAcronym):
|
||||||
|
meeting = models.ForeignKey(Meeting, db_column='meeting_num')
|
||||||
|
group_acronym_id = models.IntegerField()
|
||||||
|
filename = models.CharField(maxlength=255)
|
||||||
|
irtf = models.BooleanField()
|
||||||
|
interim = models.BooleanField()
|
||||||
|
def __str__(self):
|
||||||
|
return "Agenda for %s at IETF %d" % (self.acronym(), self.meeting_id)
|
||||||
|
class Meta:
|
||||||
|
db_table = 'wg_agenda'
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Minute(models.Model, ResolveAcronym):
|
||||||
|
meeting = models.ForeignKey(Meeting, db_column='meeting_num')
|
||||||
|
group_acronym = models.ForeignKey(Acronym, raw_id_admin=True)
|
||||||
|
filename = models.CharField(blank=True, maxlength=255)
|
||||||
|
irtf = models.BooleanField()
|
||||||
|
interim = models.BooleanField()
|
||||||
|
def __str__(self):
|
||||||
|
return "Minutes for %s at IETF %d" % (self.acronym(), self.meeting_id)
|
||||||
|
class Meta:
|
||||||
|
db_table = 'minutes'
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# It looks like Switches was meant for something bigger, but
|
||||||
|
# is only used for the agenda generation right now so we'll
|
||||||
|
# put it here.
|
||||||
|
class Switches(models.Model):
|
||||||
|
name = models.CharField(maxlength=100)
|
||||||
|
val = models.IntegerField(null=True, blank=True)
|
||||||
|
updated_date = models.DateField(null=True, blank=True)
|
||||||
|
updated_time = models.TimeField(null=True, blank=True)
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
class Meta:
|
||||||
|
db_table = 'switches'
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Empty table, don't pretend that it exists.
|
||||||
|
#class SlideTypes(models.Model):
|
||||||
|
# type_id = models.AutoField(primary_key=True)
|
||||||
|
# type = models.CharField(maxlength=255, db_column='type_name')
|
||||||
|
# def __str__(self):
|
||||||
|
# return self.type
|
||||||
|
# class Meta:
|
||||||
|
# db_table = 'slide_types'
|
||||||
|
# class Admin:
|
||||||
|
# pass
|
||||||
|
|
||||||
|
class Slide(models.Model, ResolveAcronym):
|
||||||
|
SLIDE_TYPE_CHOICES=(
|
||||||
|
('1', '(converted) HTML'),
|
||||||
|
('2', 'PDF'),
|
||||||
|
('3', 'Text'),
|
||||||
|
('4', 'PowerPoint'),
|
||||||
|
('5', 'Microsoft Word'),
|
||||||
|
)
|
||||||
|
meeting = models.ForeignKey(Meeting, db_column='meeting_num')
|
||||||
|
group_acronym_id = models.IntegerField(null=True, blank=True)
|
||||||
|
slide_num = models.IntegerField(null=True, blank=True)
|
||||||
|
slide_type_id = models.IntegerField(choices=SLIDE_TYPE_CHOICES)
|
||||||
|
slide_name = models.CharField(blank=True, maxlength=255)
|
||||||
|
irtf = models.BooleanField()
|
||||||
|
interim = models.BooleanField()
|
||||||
|
order_num = models.IntegerField(null=True, blank=True)
|
||||||
|
in_q = models.IntegerField(null=True, blank=True)
|
||||||
|
def __str__(self):
|
||||||
|
return "IETF%d: %s slides (%s)" % (self.meeting_id, self.acronym(), self.slide_name)
|
||||||
|
class Meta:
|
||||||
|
db_table = 'slides'
|
||||||
|
class Admin:
|
||||||
|
pass
|
1
ietf/proceedings/views.py
Normal file
1
ietf/proceedings/views.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# Create your views here.
|
2
ietf/redirects/.gitignore
vendored
Normal file
2
ietf/redirects/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/*.pyc
|
||||||
|
/settings_local.py
|
0
ietf/redirects/__init__.py
Normal file
0
ietf/redirects/__init__.py
Normal file
2
ietf/redirects/fixtures/.gitignore
vendored
Normal file
2
ietf/redirects/fixtures/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/*.pyc
|
||||||
|
/settings_local.py
|
71
ietf/redirects/fixtures/initial_data.xml
Normal file
71
ietf/redirects/fixtures/initial_data.xml
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<django-objects version="1.0">
|
||||||
|
<object pk="1" model="redirects.redirect">
|
||||||
|
<field type="CharField" name="cgi">public/liaisons.cgi</field>
|
||||||
|
<field type="CharField" name="url">/liaisons</field>
|
||||||
|
<field type="CharField" name="rest"/>
|
||||||
|
<field type="CharField" name="remove"/>
|
||||||
|
</object>
|
||||||
|
<object pk="2" model="redirects.redirect">
|
||||||
|
<field type="CharField" name="cgi">public/liaison_detail.cgi</field>
|
||||||
|
<field type="CharField" name="url">/liaisons</field>
|
||||||
|
<field type="CharField" name="rest">%(detail_id)s/</field>
|
||||||
|
<field type="CharField" name="remove"/>
|
||||||
|
</object>
|
||||||
|
<object pk="3" model="redirects.redirect">
|
||||||
|
<field type="CharField" name="cgi">public/liaison_managers_list.cgi</field>
|
||||||
|
<field type="CharField" name="url">/liaisons/managers</field>
|
||||||
|
<field type="CharField" name="rest"/>
|
||||||
|
<field type="CharField" name="remove"/>
|
||||||
|
</object>
|
||||||
|
<object pk="4" model="redirects.redirect">
|
||||||
|
<field type="CharField" name="cgi">public/liaison_guide_to_ietf.cgi</field>
|
||||||
|
<field type="CharField" name="url">/liaisons/help/to_ietf</field>
|
||||||
|
<field type="CharField" name="rest"/>
|
||||||
|
<field type="CharField" name="remove"/>
|
||||||
|
</object>
|
||||||
|
<object pk="5" model="redirects.redirect">
|
||||||
|
<field type="CharField" name="cgi">public/liaison_guide_from_ietf.cgi</field>
|
||||||
|
<field type="CharField" name="url">/liaisons/help/from_ietf</field>
|
||||||
|
<field type="CharField" name="rest"/>
|
||||||
|
<field type="CharField" name="remove"/>
|
||||||
|
</object>
|
||||||
|
<object pk="6" model="redirects.redirect">
|
||||||
|
<field type="CharField" name="cgi">public/liaison_field_help.cgi</field>
|
||||||
|
<field type="CharField" name="url">/liaisons/help/field_help</field>
|
||||||
|
<field type="CharField" name="rest"/>
|
||||||
|
<field type="CharField" name="remove"/>
|
||||||
|
</object>
|
||||||
|
<object pk="7" model="redirects.redirect">
|
||||||
|
<field type="CharField" name="cgi">public/idindex.cgi</field>
|
||||||
|
<field type="CharField" name="url">/idindex</field>
|
||||||
|
<field type="CharField" name="rest">%(id)s/%(command)s</field>
|
||||||
|
<field type="CharField" name="remove">id_detail</field>
|
||||||
|
</object>
|
||||||
|
<object pk="4" model="redirects.command">
|
||||||
|
<field type="CharField" name="command">show_ind_id</field>
|
||||||
|
<field type="CharField" name="url">inddocs</field>
|
||||||
|
<field to="redirects.redirect" name="script" rel="ManyToOneRel">7</field>
|
||||||
|
<field to="redirects.suffix" name="suffix" rel="ManyToOneRel">2</field>
|
||||||
|
</object>
|
||||||
|
<object pk="3" model="redirects.command">
|
||||||
|
<field type="CharField" name="command">show_wg</field>
|
||||||
|
<field type="CharField" name="url">wglist</field>
|
||||||
|
<field to="redirects.redirect" name="script" rel="ManyToOneRel">7</field>
|
||||||
|
<field to="redirects.suffix" name="suffix" rel="ManyToOneRel">2</field>
|
||||||
|
</object>
|
||||||
|
<object pk="5" model="redirects.command">
|
||||||
|
<field type="CharField" name="command">show_list</field>
|
||||||
|
<field type="CharField" name="url">showdocs</field>
|
||||||
|
<field to="redirects.redirect" name="script" rel="ManyToOneRel">7</field>
|
||||||
|
<field to="redirects.suffix" name="suffix" rel="ManyToOneRel">3</field>
|
||||||
|
</object>
|
||||||
|
<object pk="2" model="redirects.suffix">
|
||||||
|
<field type="CharField" name="rest">%(fl)s</field>
|
||||||
|
<field type="CharField" name="remove"/>
|
||||||
|
</object>
|
||||||
|
<object pk="3" model="redirects.suffix">
|
||||||
|
<field type="CharField" name="rest">%(cat)s/%(sort)s</field>
|
||||||
|
<field type="CharField" name="remove"/>
|
||||||
|
</object>
|
||||||
|
</django-objects>
|
50
ietf/redirects/models.py
Normal file
50
ietf/redirects/models.py
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
class Redirect(models.Model):
|
||||||
|
"""Mapping of CGI script to url. The "rest" is a
|
||||||
|
sprintf-style string with %(param)s entries to insert
|
||||||
|
parameters from the request, and is appended to the
|
||||||
|
url. An exception in formatting "rest" results in
|
||||||
|
just the bare url being used. "remove" is removed
|
||||||
|
from the end of the resulting url before redirecting,
|
||||||
|
in case some values of "rest" add too much.
|
||||||
|
|
||||||
|
If there is a "command" parameter, a matching row is
|
||||||
|
searched for in the Command table to see if there
|
||||||
|
is a different value of rest= and remove=.
|
||||||
|
"""
|
||||||
|
cgi = models.CharField(maxlength=50, unique=True)
|
||||||
|
url = models.CharField(maxlength=255)
|
||||||
|
rest = models.CharField(maxlength=100, blank=True)
|
||||||
|
remove = models.CharField(maxlength=50, blank=True)
|
||||||
|
def __str__(self):
|
||||||
|
return "%s -> %s/%s" % (self.cgi, self.url, self.rest)
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Suffix(models.Model):
|
||||||
|
"""This is a "rest" and "remove" (see Redirect class)
|
||||||
|
for requests with command=.
|
||||||
|
"""
|
||||||
|
rest = models.CharField(maxlength=100, blank=True)
|
||||||
|
remove = models.CharField(maxlength=50, blank=True)
|
||||||
|
def __str__(self):
|
||||||
|
return "-> %s - %s" % (self.rest, self.remove)
|
||||||
|
class Admin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Command(models.Model):
|
||||||
|
"""When a request comes in with a command= argument,
|
||||||
|
the command is looked up in this table to see if there
|
||||||
|
are more specific "rest" and "remove" arguments to
|
||||||
|
use than those specified in the Redirect class that
|
||||||
|
matched. The optional "url" is prepended to the "rest".
|
||||||
|
"""
|
||||||
|
command = models.CharField(maxlength=50, core=True)
|
||||||
|
url = models.CharField(maxlength=50, blank=True)
|
||||||
|
script = models.ForeignKey(Redirect, edit_inline=models.TABULAR, related_name='commands')
|
||||||
|
suffix = models.ForeignKey(Suffix)
|
||||||
|
def __str__(self):
|
||||||
|
return "%s?command=%s %s" % (self.script.cgi, self.command, self.suffix)
|
||||||
|
class Admin:
|
||||||
|
pass
|
5
ietf/redirects/urls.py
Normal file
5
ietf/redirects/urls.py
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
from django.conf.urls.defaults import *
|
||||||
|
|
||||||
|
urlpatterns = patterns('',
|
||||||
|
(r'^(?P<script>.*.cgi)$', 'ietf.redirects.views.redirect'),
|
||||||
|
)
|
34
ietf/redirects/views.py
Normal file
34
ietf/redirects/views.py
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
from django.http import HttpResponseRedirect,Http404
|
||||||
|
import re
|
||||||
|
|
||||||
|
from ietf.redirects.models import Redirect, Command
|
||||||
|
|
||||||
|
def redirect(request, path="", script=""):
|
||||||
|
if path:
|
||||||
|
script = path + "/" + script
|
||||||
|
try:
|
||||||
|
redir = Redirect.objects.get(cgi=script)
|
||||||
|
except Redirect.DoesNotExist:
|
||||||
|
raise Http404
|
||||||
|
url = redir.url + "/"
|
||||||
|
(rest, remove) = (redir.rest, redir.remove)
|
||||||
|
try:
|
||||||
|
cmd = redir.commands.all().get(command=request.REQUEST['command'])
|
||||||
|
if cmd.url:
|
||||||
|
rest = cmd.url + "/" + cmd.suffix.rest
|
||||||
|
else:
|
||||||
|
rest = cmd.suffix.rest
|
||||||
|
remove = cmd.suffix.remove
|
||||||
|
except Command.DoesNotExist:
|
||||||
|
pass # it's ok, there's no more-specific request.
|
||||||
|
except IndexError:
|
||||||
|
pass # it's ok, request didn't have 'command'.
|
||||||
|
try:
|
||||||
|
url += rest % request.REQUEST
|
||||||
|
except:
|
||||||
|
# rest had something in it that request didn't have, so just
|
||||||
|
# redirect to the root of the tool.
|
||||||
|
pass
|
||||||
|
if remove:
|
||||||
|
url = re.sub(re.escape(remove) + "/?$", "", url)
|
||||||
|
return HttpResponseRedirect(url)
|
2
ietf/rfcs/.gitignore
vendored
Normal file
2
ietf/rfcs/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/*.pyc
|
||||||
|
/settings_local.py
|
0
ietf/rfcs/__init__.py
Normal file
0
ietf/rfcs/__init__.py
Normal file
85
ietf/rfcs/models.py
Normal file
85
ietf/rfcs/models.py
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
from django.db import models
|
||||||
|
from ietf.idtracker.models import PersonOrOrgInfo
|
||||||
|
|
||||||
|
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()
|
||||||
|
class Meta:
|
||||||
|
db_table = 'rfcs'
|
||||||
|
verbose_name = 'RFC'
|
||||||
|
verbose_name_plural = 'RFCs'
|
||||||
|
class Admin:
|
||||||
|
search_fields = ['rfc_name', 'group_acronym', 'area_acronym']
|
||||||
|
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
|
||||||
|
|
1
ietf/rfcs/views.py
Normal file
1
ietf/rfcs/views.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# Create your views here.
|
109
ietf/settings.py
Normal file
109
ietf/settings.py
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
# Django settings for ietf project.
|
||||||
|
# BASE_DIR and "settings_local" are from
|
||||||
|
# http://code.djangoproject.com/wiki/SplitSettings
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
DEBUG = True
|
||||||
|
TEMPLATE_DEBUG = DEBUG
|
||||||
|
|
||||||
|
ADMINS = (
|
||||||
|
('Bill Fenner', 'fenner@research.att.com'),
|
||||||
|
)
|
||||||
|
|
||||||
|
MANAGERS = ADMINS
|
||||||
|
|
||||||
|
DATABASE_ENGINE = 'mysql' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'.
|
||||||
|
DATABASE_NAME = 'django_idtracker' # Or path to database file if using sqlite3.
|
||||||
|
DATABASE_USER = 'django' # Not used with sqlite3.
|
||||||
|
DATABASE_PASSWORD = 'playing' # Not used with sqlite3.
|
||||||
|
DATABASE_OPTIONS={'charset': 'Latin1',}
|
||||||
|
DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3.
|
||||||
|
DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3.
|
||||||
|
|
||||||
|
# Local time zone for this installation. Choices can be found here:
|
||||||
|
# http://www.postgresql.org/docs/8.1/static/datetime-keywords.html#DATETIME-TIMEZONE-SET-TABLE
|
||||||
|
# although not all variations may be possible on all operating systems.
|
||||||
|
# If running in a Windows environment this must be set to the same as your
|
||||||
|
# system time zone.
|
||||||
|
TIME_ZONE = 'America/Los_Angeles'
|
||||||
|
|
||||||
|
# Language code for this installation. All choices can be found here:
|
||||||
|
# http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes
|
||||||
|
# http://blogs.law.harvard.edu/tech/stories/storyReader$15
|
||||||
|
LANGUAGE_CODE = 'en-us'
|
||||||
|
|
||||||
|
SITE_ID = 1
|
||||||
|
|
||||||
|
# If you set this to False, Django will make some optimizations so as not
|
||||||
|
# to load the internationalization machinery.
|
||||||
|
USE_I18N = True
|
||||||
|
|
||||||
|
# Absolute path to the directory that holds media.
|
||||||
|
# Example: "/home/media/media.lawrence.com/"
|
||||||
|
MEDIA_ROOT = ''
|
||||||
|
|
||||||
|
# URL that handles the media served from MEDIA_ROOT.
|
||||||
|
# Example: "http://media.lawrence.com"
|
||||||
|
MEDIA_URL = ''
|
||||||
|
|
||||||
|
# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
|
||||||
|
# trailing slash.
|
||||||
|
# Examples: "http://foo.com/media/", "/media/".
|
||||||
|
ADMIN_MEDIA_PREFIX = '/media/'
|
||||||
|
|
||||||
|
# List of callables that know how to import templates from various sources.
|
||||||
|
TEMPLATE_LOADERS = (
|
||||||
|
'django.template.loaders.filesystem.load_template_source',
|
||||||
|
'django.template.loaders.app_directories.load_template_source',
|
||||||
|
# 'django.template.loaders.eggs.load_template_source',
|
||||||
|
)
|
||||||
|
|
||||||
|
MIDDLEWARE_CLASSES = (
|
||||||
|
'django.middleware.common.CommonMiddleware',
|
||||||
|
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||||
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||||
|
'django.middleware.doc.XViewMiddleware',
|
||||||
|
)
|
||||||
|
|
||||||
|
ROOT_URLCONF = 'ietf.urls'
|
||||||
|
|
||||||
|
TEMPLATE_DIRS = (
|
||||||
|
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
|
||||||
|
# Always use forward slashes, even on Windows.
|
||||||
|
# Don't forget to use absolute paths, not relative paths.
|
||||||
|
BASE_DIR + "/templates"
|
||||||
|
)
|
||||||
|
|
||||||
|
INSTALLED_APPS = (
|
||||||
|
'django.contrib.auth',
|
||||||
|
'django.contrib.contenttypes',
|
||||||
|
'django.contrib.sessions',
|
||||||
|
'django.contrib.sites',
|
||||||
|
'django.contrib.admin',
|
||||||
|
'ietf.agenda',
|
||||||
|
'ietf.announcements',
|
||||||
|
'ietf.idindex',
|
||||||
|
'ietf.idtracker',
|
||||||
|
'ietf.iesg',
|
||||||
|
'ietf.ipr',
|
||||||
|
'ietf.liaisons',
|
||||||
|
'ietf.mailinglists',
|
||||||
|
'ietf.my',
|
||||||
|
'ietf.proceedings',
|
||||||
|
'ietf.redirects',
|
||||||
|
'ietf.rfcs',
|
||||||
|
)
|
||||||
|
|
||||||
|
INTERNAL_IPS = (
|
||||||
|
# llama in san jose
|
||||||
|
'135.207.33.119',
|
||||||
|
# fenestro
|
||||||
|
'67.188.114.134',
|
||||||
|
)
|
||||||
|
|
||||||
|
# Put SECRET_KEY in here, or any other sensitive or site-specific
|
||||||
|
# changes. DO NOT commit settings_local.py to svn.
|
||||||
|
from settings_local import *
|
2
ietf/templates/.gitignore
vendored
Normal file
2
ietf/templates/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/*.pyc
|
||||||
|
/settings_local.py
|
2
ietf/templates/announcements/.gitignore
vendored
Normal file
2
ietf/templates/announcements/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/*.pyc
|
||||||
|
/settings_local.py
|
17
ietf/templates/announcements/announcement_detail.html
Normal file
17
ietf/templates/announcements/announcement_detail.html
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% load ietf_filters %}
|
||||||
|
|
||||||
|
{% block title %}NomCom Message{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>NomCom Message</h1>
|
||||||
|
<p>
|
||||||
|
From: {{ object.from_name|escape }}<br>
|
||||||
|
To: {{ object.announced_to|escape }}<br>
|
||||||
|
Date: {{ object.announced_date|date:"F j, Y" }}<br>
|
||||||
|
Subject: {{ object.subject|escape }}<br>
|
||||||
|
<hr width="400" align="left">
|
||||||
|
<pre>
|
||||||
|
{{ object.text|escape }}
|
||||||
|
</pre>
|
||||||
|
{% endblock %}
|
15
ietf/templates/apps.html
Normal file
15
ietf/templates/apps.html
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<blockquote>
|
||||||
|
<h3>Currently available applications:</h3>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
{% for app in apps %}
|
||||||
|
<li><a href="/{{ app }}">{{ app }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</blockquote>
|
||||||
|
{% endblock %}
|
115
ietf/templates/base-new.html
Normal file
115
ietf/templates/base-new.html
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>{% block title %}IETF Data{% endblock %} - WCF</title>
|
||||||
|
|
||||||
|
<style type="text/css">
|
||||||
|
@import "http://www1.tools.ietf.org/demo/www.ietf.org/v1.css";
|
||||||
|
</style>
|
||||||
|
</head><body>
|
||||||
|
|
||||||
|
<div id="leftmenu">
|
||||||
|
<div class="menulogo">
|
||||||
|
<img class="menulogo" src="http://www1.tools.ietf.org/images/ietflogo2i.png" alt="IETF logo" />
|
||||||
|
</div>
|
||||||
|
<ul>
|
||||||
|
<li><a title="About the Internet Engineering Task Force">About the IETF</a>
|
||||||
|
<ul> <!--sublist for about-->
|
||||||
|
<li><a title="What is the IETF?">Overview</a></li>
|
||||||
|
<li><a title="History of the IETF, from the Education Team">IETF history</a></li>
|
||||||
|
<!-- note: this link should be changed to reflect the new struct -->
|
||||||
|
<li><a title="How an IETF standard is adopted">IETF standards process</a></li>
|
||||||
|
<!-- same as "process? -->
|
||||||
|
<!-- <li><a href="#">IETF rules</a></li> -->
|
||||||
|
|
||||||
|
<!-- I don't know of a "who's who" -->
|
||||||
|
<!-- <li><a href="#">People</a></li> -->
|
||||||
|
|
||||||
|
</ul></li><!--end about sublist-->
|
||||||
|
<li><a title="What the IETF is doing">IETF activities</a>
|
||||||
|
<ul> <!--sublist for activities-->
|
||||||
|
<li><a title="Internet Engineering Steering Group">IESG</a></li>
|
||||||
|
<li><a title="Liasons with other standards bodies">IETF Liaison Activities</a></li>
|
||||||
|
<li><a title="The Secretariat, provided by NeuStar Secretariat Services">IETF administration</a> </li>
|
||||||
|
<li><a title="IESG and IAB Nominations Committee">The NomCom</a></li>
|
||||||
|
<li><a title="IETF Working Groups">Working Groups</a></li>
|
||||||
|
<li><a title="Meetings past, present, and future">Meetings</a></li>
|
||||||
|
<li><a href="http://tools.ietf.org" >More Tools</a></li>
|
||||||
|
</ul> </li><!--end activities sublist-->
|
||||||
|
|
||||||
|
<li><a title="Documents of the IETF">Documents</a>
|
||||||
|
<ul><!--sublist for documents-->
|
||||||
|
<li><a href="/demo/www.ietf.org/documents/rfc" title="Repository of RFC documents">RFCs</a></li>
|
||||||
|
<li><a title="Internet Draft pages">Internet-Drafts</a></li>
|
||||||
|
<li><a title="Proceedings of past meetings">Proceedings</a></li>
|
||||||
|
<li><a href="/demo/www.ietf.org/submit/" title="Submit Internet Drafts">Submission</a></li>
|
||||||
|
</ul> <!--end documents sublist-->
|
||||||
|
<li><a title="Other sites having to do with the IETF">Related sites</a>
|
||||||
|
<ul> <!--begin othersites sublist-->
|
||||||
|
<li><a href="http://www.iab.org">IAB</a></li>
|
||||||
|
<li><a href="http://koi.uoregon.edu/~iaoc/">IASA</a></li>
|
||||||
|
<li><a href="http://www.rfc-editor.org/">RFC Editor</a></li>
|
||||||
|
<li><a href="http://www.iana.org/">IANA</a></li>
|
||||||
|
<li><a href="http://www.irtf.org/">IRTF</a></li>
|
||||||
|
</ul> </li><!--end the othersites sublist-->
|
||||||
|
<li>Site search:</li>
|
||||||
|
<li><form method="get" action="http://www.google.com/u/ietf">
|
||||||
|
<input name="q" size="16" maxlength="255" value="" type="text" /><br />
|
||||||
|
<input name="sa" value="Go" type="submit" />
|
||||||
|
</form>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="maincontent">
|
||||||
|
{% block content %}{% endblock %}
|
||||||
|
{% block main_content %}{% endblock %}
|
||||||
|
{% if debug %}
|
||||||
|
<div id="debug">
|
||||||
|
<h2>Queries</h2>
|
||||||
|
<p>
|
||||||
|
{{ sql_queries|length }} Queries
|
||||||
|
{% ifnotequal sql_queries|length 0 %}
|
||||||
|
(<span style="cursor: pointer;" onclick="document.getElementById('debugQueryTable').style.display='';">Show</span>)
|
||||||
|
{% endifnotequal %}
|
||||||
|
</p>
|
||||||
|
<table id="debugQueryTable" style="display: none;">
|
||||||
|
<col width="1"></col>
|
||||||
|
<col></col>
|
||||||
|
<col width="1"></col>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">#</th>
|
||||||
|
<th scope="col">SQL</th>
|
||||||
|
<th scope="col">Time</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for query in sql_queries %}<tr class="{% cycle odd,even %}">
|
||||||
|
<td>{{ forloop.counter }}</td>
|
||||||
|
<td>{{ query.sql|escape }}</td>
|
||||||
|
<td>{{ query.time }}</td>
|
||||||
|
</tr>{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="footer">
|
||||||
|
|
||||||
|
The IETF is an organized activity of the <a href="http://www.isoc.org">Internet Society</a>
|
||||||
|
<!-- <img src="http://tools.ietf.org/demo/www.ietf.org/images/isoc-small.gif" alt="Internet Society"> -->
|
||||||
|
<br>Please send problem reports to <a href="mailto:ietf-web@ietf.org">ietf-web@ietf.org</a>.
|
||||||
|
<br>
|
||||||
|
<a href="http://www.djangoproject.com/"><img src="http://media.djangoproject.com/img/badges/djangomade124x25.gif" border="0" alt="Made with Django." title="Made with Django." /></a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
39
ietf/templates/base.html
Normal file
39
ietf/templates/base.html
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!DOCTYPE html
|
||||||
|
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US"><head><title>{% block title %}IETF Data{% endblock %} - WCF</title>
|
||||||
|
</head><body><center>
|
||||||
|
<table border=0 cellpadding=0 cellspacing=0>
|
||||||
|
<tr>
|
||||||
|
<td><a href="http://www.ietf.org/home.html"><img src="https://www1.ietf.org/images/header/ietflogo_sm.gif" border="0"></a></td>
|
||||||
|
<td><a href="http://www.ietf.org/home.html"><img src="https://www1.ietf.org/images/header/home11.gif" border="0"></a></td>
|
||||||
|
<td><img src="https://www1.ietf.org/images/header/separator.gif" border="0"></td>
|
||||||
|
<td><a href="http://www.ietf.org/html.charters/wg-dir.html"><img src="https://www1.ietf.org/images/header/wg11.gif" border="0"></a></td>
|
||||||
|
<td><img src="https://www1.ietf.org/images/header/separator.gif" border="0"></td>
|
||||||
|
<td><a href="http://www.ietf.org/meetings/meetings.html"><img src="https://www1.ietf.org/images/header/meetings11.gif" border="0"></a></td>
|
||||||
|
|
||||||
|
<td><img src="https://www1.ietf.org/images/header/separator.gif" border="0"></td>
|
||||||
|
<td><a href="http://www.ietf.org/proceedings_directory.html"><img src="https://www1.ietf.org/images/header/proceed11.gif" border="0"></a></td>
|
||||||
|
<td><img src="https://www1.ietf.org/images/header/separator.gif" border="0"></td>
|
||||||
|
<td><a href="https://datatracker.ietf.org/public/idindex.cgi"><img src="https://www1.ietf.org/images/header/id-index11.gif" border="0"></a></td>
|
||||||
|
<td><img src="https://www1.ietf.org/images/header/separator.gif" border="0"></td>
|
||||||
|
<td><a href="http://www.ietf.org/rfc.html"><img src="https://www1.ietf.org/images/header/rfc11.gif" border="0"></a></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</center>
|
||||||
|
<hr>
|
||||||
|
<!-- end new headers and layout -->
|
||||||
|
<div id="content">
|
||||||
|
{% block content %}{% endblock %}
|
||||||
|
{% block main_content %}{% endblock %}
|
||||||
|
</div>
|
||||||
|
<hr/>
|
||||||
|
<address>
|
||||||
|
This page provided by Bill Fenner's proof-of-concept IETF web page front
|
||||||
|
ends.
|
||||||
|
</address>
|
||||||
|
<a href="http://www.djangoproject.com/"><img src="http://media.djangoproject.com/img/badges/djangomade124x25.gif" border="0" alt="Made with Django." title="Made with Django." /></a>
|
||||||
|
{% include "debug.html" %}
|
||||||
|
</body>
|
||||||
|
</html>
|
33
ietf/templates/debug.html
Normal file
33
ietf/templates/debug.html
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
{% if debug %}
|
||||||
|
{% load ietf_filters %}
|
||||||
|
<div id="debug">
|
||||||
|
<h2>Queries</h2>
|
||||||
|
<p>
|
||||||
|
{{ sql_queries|length }} Queries ({{ sql_queries|timesum }}s)
|
||||||
|
{% ifnotequal sql_queries|length 0 %}
|
||||||
|
(<span style="cursor: pointer;" onclick="document.getElementById('debugQueryTable').style.display='';">Show</span>)
|
||||||
|
{% endifnotequal %}
|
||||||
|
</p>
|
||||||
|
<table id="debugQueryTable" style="display: none;">
|
||||||
|
<col width="1"></col>
|
||||||
|
<col></col>
|
||||||
|
<col width="1"></col>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">#</th>
|
||||||
|
<th scope="col">SQL</th>
|
||||||
|
<th scope="col">Time</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for query in sql_queries %}
|
||||||
|
<tr class="{% cycle odd,even %}">
|
||||||
|
<td>{{ forloop.counter }}</td>
|
||||||
|
<td>{{ query.sql|expand_comma|escape }}</td>
|
||||||
|
<td>{{ query.time }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
2
ietf/templates/feeds/.gitignore
vendored
Normal file
2
ietf/templates/feeds/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/*.pyc
|
||||||
|
/settings_local.py
|
2
ietf/templates/feeds/comments_description.html
Normal file
2
ietf/templates/feeds/comments_description.html
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
{% load ietf_filters %}
|
||||||
|
{{ obj.comment_text|format_textarea|truncatewords_html:"40" }}
|
1
ietf/templates/feeds/comments_title.html
Normal file
1
ietf/templates/feeds/comments_title.html
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{% if obj.ballot %}IESG Evaluation {{ obj.get_ballot_display.upper }}{% else %}Comment{% endif %} from {{ obj.get_author }}
|
2
ietf/templates/feeds/iesg_minutes_description.html
Normal file
2
ietf/templates/feeds/iesg_minutes_description.html
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
{% load ietf_filters %}
|
||||||
|
{{ obj.telechat_minute|escape|linebreaks|truncatewords_html:"40" }}
|
1
ietf/templates/feeds/iesg_minutes_title.html
Normal file
1
ietf/templates/feeds/iesg_minutes_title.html
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{{ obj.telechat_date|date:"F j, Y" }}
|
2
ietf/templates/idindex/.gitignore
vendored
Normal file
2
ietf/templates/idindex/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/*.pyc
|
||||||
|
/settings_local.py
|
61
ietf/templates/idindex/all_id.html
Normal file
61
ietf/templates/idindex/all_id.html
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
<html>
|
||||||
|
<HEAD><TITLE>All I-Ds List</title>
|
||||||
|
<STYLE TYPE="text/css">
|
||||||
|
<!--
|
||||||
|
TD {text-decoration: none; color: #000000; font: 10pt arial;}
|
||||||
|
body {
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
font-size: 1.1em;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
padding:6px 0px 10px 30px;
|
||||||
|
line-height:1em;
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
font-size: 1.0em;
|
||||||
|
color: #333;
|
||||||
|
|
||||||
|
}
|
||||||
|
/* Links
|
||||||
|
----------------------------------------------- */
|
||||||
|
a:link, a:visited {
|
||||||
|
border-bottom:1px dotted #69f;
|
||||||
|
color:#36c;
|
||||||
|
text-decoration:none;
|
||||||
|
}
|
||||||
|
a:visited {
|
||||||
|
border-bottom-color:#969;
|
||||||
|
color:#36c;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
border-bottom:1px solid #f00;
|
||||||
|
color:#f00;
|
||||||
|
}
|
||||||
|
a.noline:link, a.noline:visited, a.noline:hover {border-style:none;}
|
||||||
|
-->
|
||||||
|
</STYLE>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<center>All I-Ds List</center>
|
||||||
|
<br><br>
|
||||||
|
<a href="all_id_txt.html">TAB Delimited Format</a><br><br>
|
||||||
|
|
||||||
|
<table cellpadding="3" cellspacing="1" border="1">
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<th>I-D name and version</th>
|
||||||
|
<th>Last Updated Date</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>RFC Number</th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{% for object in object_list %}
|
||||||
|
<tr><td>{{ object.id.filename }}-{{ object.id.revision_display}}</td><td>{{ object.id.last_modified_date }}</td><td>{% if object.tracker %}In IESG processing - see tracker{% else %}{{ object.id.status }}{% ifequal object.id.status.status "Replaced" %} {{ object.id.comments }}{% endifequal %}{% endif %}</td><td>{% if object.id.rfc_number %}{{ object.id.rfc_number }}{% endif %}</td></tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
{% include "debug.html" %}
|
||||||
|
</body>
|
||||||
|
</html>
|
52
ietf/templates/idindex/all_id_txt.html
Normal file
52
ietf/templates/idindex/all_id_txt.html
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
<html>
|
||||||
|
<HEAD><TITLE>All I-Ds List</title>
|
||||||
|
<STYLE TYPE="text/css">
|
||||||
|
<!--
|
||||||
|
TD {text-decoration: none; color: #000000; font: 10pt arial;}
|
||||||
|
body {
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
font-size: 1.1em;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
padding:6px 0px 10px 30px;
|
||||||
|
line-height:1em;
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
font-size: 1.0em;
|
||||||
|
color: #333;
|
||||||
|
|
||||||
|
}
|
||||||
|
/* Links
|
||||||
|
----------------------------------------------- */
|
||||||
|
a:link, a:visited {
|
||||||
|
border-bottom:1px dotted #69f;
|
||||||
|
color:#36c;
|
||||||
|
text-decoration:none;
|
||||||
|
}
|
||||||
|
a:visited {
|
||||||
|
border-bottom-color:#969;
|
||||||
|
color:#36c;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
border-bottom:1px solid #f00;
|
||||||
|
color:#f00;
|
||||||
|
}
|
||||||
|
a.noline:link, a.noline:visited, a.noline:hover {border-style:none;}
|
||||||
|
-->
|
||||||
|
</STYLE>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<center>All I-Ds List</center>
|
||||||
|
<br><br>
|
||||||
|
<a href="all_id.html">HTML Format</a><br><br>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
{% for object in object_list %}{{ object.id.filename }}-{{ object.id.revision_display}} {{ object.id.last_modified_date }} {% if object.tracker %}In IESG processing - see tracker{% else %}{{ object.id.status }}{% ifequal object.id.status.status "Replaced" %} {{ object.id.comments }}{% endifequal %}{% endif %} {% if object.id.rfc_number %}{{ object.id.rfc_number }}{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</pre>
|
||||||
|
{% include "debug.html" %}
|
||||||
|
</body>
|
||||||
|
</html>
|
43
ietf/templates/idindex/base.html
Normal file
43
ietf/templates/idindex/base.html
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %}Internet Draft Database Index{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% block heading %}
|
||||||
|
<center><font size=+2>Internet-Drafts Database Interface</font></center>
|
||||||
|
<br>
|
||||||
|
<a href="ftp://ftp.ietf.org/internet-drafts/all_id.txt">TAB Delimited Format</a><br><br>
|
||||||
|
|
||||||
|
<img src="http://www.ietf.org/images/blue.gif" hspace="3" border="0"> All I-Ds <a href="/idindex/showdocs/all/date/">(sorted by submission date)</a> <a href="/idindex/showdocs/all/name/">(sorted by filename)</a><br>
|
||||||
|
|
||||||
|
<img src="http://www.ietf.org/images/blue.gif" hspace="3" border="0"> Active I-Ds <a href="/idindex/showdocs/current/date/">(sorted by submission date)</a> <a href="/idindex/showdocs/current/name/">(sorted by filename)</a><br>
|
||||||
|
|
||||||
|
<img src="http://www.ietf.org/images/blue.gif" hspace="3" border="0"> I-Ds Published as RFCs <a href="/idindex/showdocs/rfc/date/">(sorted by submission date)</a> <a href="/idindex/showdocs/rfc/name/">(sorted by filename)</a><br>
|
||||||
|
|
||||||
|
<img src="http://www.ietf.org/images/blue.gif" hspace="3" border="0"> Expired/Withdrawn/Replaced I-Ds <a href="/idindex/showdocs/dead/date/">(sorted by submission date)</a> <a href="/idindex/showdocs/dead/name/">(sorted by filename)</a><br><br>
|
||||||
|
|
||||||
|
<img src="http://www.ietf.org/images/blue.gif" hspace="3" border="0"> IETF Working Group Drafts
|
||||||
|
{% for letter in alphabet %}
|
||||||
|
<a href="/idindex/wglist/{{ letter }}/">{{ letter.upper }}</a>
|
||||||
|
{% endfor %}
|
||||||
|
<a href="/idindex/wglist/other/">other</a><br>
|
||||||
|
<img src="http://www.ietf.org/images/blue.gif" hspace="3" border="0"> Individual Drafts by Author Identifier
|
||||||
|
{% for letter in alphabet %}
|
||||||
|
<a href="/idindex/inddocs/{{ letter }}/">{{ letter.upper }}</a>
|
||||||
|
{% endfor %}
|
||||||
|
<a href="/idindex/inddocs/other/">other</a><br>
|
||||||
|
|
||||||
|
<img src="http://www.ietf.org/images/blue.gif" hspace="3" border="0"> Other Drafts
|
||||||
|
{% for org in orgs %}
|
||||||
|
<a href="/idindex/otherdocs/{{ org.key }}/">{{ org.name.upper }}</a>
|
||||||
|
{% endfor %}
|
||||||
|
<br><br>
|
||||||
|
|
||||||
|
<img src="http://www.ietf.org/images/blue.gif" hspace="3" border="0"> <a href="/idindex/">I-D Search</a>
|
||||||
|
<hr>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block iddbcontent %}
|
||||||
|
Please select one of the above items.
|
||||||
|
{% endblock %}
|
||||||
|
{% endblock %}
|
42
ietf/templates/idindex/doclist.html
Normal file
42
ietf/templates/idindex/doclist.html
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
{{ object_list|length }} result{{ object_list|length|pluralize }}.<br>
|
||||||
|
<b>Please click a document below to view detail information</b><br>
|
||||||
|
<table cellpadding="1" cellspacing="0" border="0">
|
||||||
|
<tr bgcolor="#dfdfff">
|
||||||
|
<td width="280"><b>I-D Filename and Version Number</td>
|
||||||
|
<td width="120"><b>Submission Date</td>
|
||||||
|
|
||||||
|
<td width="70"><b>Status</td>
|
||||||
|
{% if norfc %}
|
||||||
|
{% else %}
|
||||||
|
<td width="70"><b>RFC #</td>
|
||||||
|
{% endif %}
|
||||||
|
<td width="150"><a href="https://datatracker.ietf.org/"><b>I-D Tracker</a> State</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{% for draft in object_list %}
|
||||||
|
<tr bgcolor="{% cycle #efefff,#dfdfff %}">
|
||||||
|
{# use url here! #}
|
||||||
|
{# todo: check out decrease revision logic #}
|
||||||
|
<td><a href="/idindex/{{ draft.filename }}/">{{ draft.filename }}-{{ draft.revision }}</a></td>
|
||||||
|
<td>{{ draft.revision_date }}</td>
|
||||||
|
<td>{{ draft.status }}</td>
|
||||||
|
{% if norfc %}
|
||||||
|
{% else %}
|
||||||
|
<td>
|
||||||
|
{% if draft.rfc_number %}
|
||||||
|
<a href="http://www.ietf.org/rfc/rfc{{ draft.rfc_number|stringformat:"04d" }}.txt">{{ draft.rfc_number }}</a>
|
||||||
|
{% else %}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
{% endif %}
|
||||||
|
<td>
|
||||||
|
{% ifequal draft.idstate "I-D Exists" %}
|
||||||
|
{{ draft.idstate }}
|
||||||
|
{% else %}
|
||||||
|
<a href="/idtracker/{{ draft.filename }}/">{{ draft.idstate }}</a>
|
||||||
|
{% endifequal %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
6
ietf/templates/idindex/inddocs.html
Normal file
6
ietf/templates/idindex/inddocs.html
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{% extends "idindex/base.html" %}
|
||||||
|
|
||||||
|
{% block iddbcontent %}
|
||||||
|
<h2>I-Ds List, Author identifier starts with <i>draft-{{ filter }}</i></h2>
|
||||||
|
{% include "idindex/doclist.html" %}
|
||||||
|
{% endblock %}
|
49
ietf/templates/idindex/internetdraft_detail.html
Normal file
49
ietf/templates/idindex/internetdraft_detail.html
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
{% extends "idindex/base.html" %}
|
||||||
|
|
||||||
|
{% block title %}Internet Draft Database Index - {{ object.filename }}{% endblock %}
|
||||||
|
|
||||||
|
{% block iddbcontent %}
|
||||||
|
<h2>{{ object.filename }}-{{ object.revision_display }}</h2>
|
||||||
|
<blockquote>
|
||||||
|
{% ifequal object.status.status "Active" %}
|
||||||
|
<li> <b><a href="http://www.ietf.org/internet-drafts/{{ object.filename }}-{{ object.revision }}.txt">View Document</a></b></li>
|
||||||
|
{% endifequal %}
|
||||||
|
<li> <b><a href="view_related_docs/">View Related Documents</a></b> (e.g., documents that replaced or were replaced by the subject I-D, and their derivatives and precursors.)</li>
|
||||||
|
{% ifequal object.group.acronym "none" %}
|
||||||
|
{% else %}
|
||||||
|
<li> <b>IETF Working Group: <a href="http://www.ietf.org/html.charters/{{ object.group.acronym }}-charter.html">{{ object.group.name }}</a></li>
|
||||||
|
{% endifequal %}
|
||||||
|
<li> <b>I-D Title:</b> {{ object.id_document_name }}</li>
|
||||||
|
<li> <b>I-D Status:</b> {{ object.status }}
|
||||||
|
{% ifequal object.status.status "Replaced" %}
|
||||||
|
(by <a href="/idindex/{{object.replaced_by.filename}}/">{{ object.replaced_by.filename }}</a>)
|
||||||
|
{% endifequal %}
|
||||||
|
{% if object.replaces %}
|
||||||
|
(replaced <a href="/idindex/{{object.replaces.filename}}/">{{ object.replaces.filename }}</a>)
|
||||||
|
{% endif %}
|
||||||
|
</li>
|
||||||
|
<li> <b>I-D Intended Status at Publication:</b> {{ object.intended_status }}</li>
|
||||||
|
<li> <b>RFC Number:</b> {% if object.rfc_number %}<a href="http://www.ietf.org/rfc/rfc{{ object.rfc_number }}.txt">{{ object.rfc_number }}</a>{% endif %}</li>
|
||||||
|
<li> <b><a href="https://datatracker.ietf.org/">I-D Tracker</a> State:</b>
|
||||||
|
{% if object.idtracker %}
|
||||||
|
<a href="/idtracker/{{ object.filename }}/">{{ object.idstate }}</a>
|
||||||
|
{% else %}
|
||||||
|
{{ object.idstate }}
|
||||||
|
{% endif %}
|
||||||
|
</li>
|
||||||
|
<li> <b>Abstract: </b><br> {{ object.abstract|escape }}
|
||||||
|
</li>
|
||||||
|
<li> <b>Author(s):</b><br>The e-mail addresses provided for the authors of this Internet-Draft may no longer be valid. If you are an author of this Internet-Draft, and if your e-mail address is not correct, then please send your current e-mail address to <a href="mailto:ietf-action@ietf.org">ietf-action@ietf.org</a>.
|
||||||
|
<blockquote>
|
||||||
|
{% for author in object.authors.all %}
|
||||||
|
{% if author.email %}
|
||||||
|
<a href="mailto:{{ author.email }}">{{ author.person }}</a>
|
||||||
|
{% else %}
|
||||||
|
{{ author.person }}
|
||||||
|
{% endif %}
|
||||||
|
<br>
|
||||||
|
{% endfor %}
|
||||||
|
</blockquote></li>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
{% endblock %}
|
6
ietf/templates/idindex/otherdocs.html
Normal file
6
ietf/templates/idindex/otherdocs.html
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{% extends "idindex/base.html" %}
|
||||||
|
|
||||||
|
{% block iddbcontent %}
|
||||||
|
<hr><h2>I-Ds List, other drafts - <i>{{ category.upper }}</i></h2>
|
||||||
|
{% include "idindex/doclist.html" %}
|
||||||
|
{% endblock %}
|
41
ietf/templates/idindex/search.html
Normal file
41
ietf/templates/idindex/search.html
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
{% extends "idindex/base.html" %}
|
||||||
|
|
||||||
|
{% block title %}Internet Draft Database Index - Search{% endblock %}
|
||||||
|
|
||||||
|
{% block iddbcontent %}
|
||||||
|
{% if didsearch %}
|
||||||
|
{# existing page just displays header and no results. #}
|
||||||
|
{% if object_list %}
|
||||||
|
{% include "idindex/doclist.html" %}
|
||||||
|
{% else %}
|
||||||
|
<h2>No results to your search.</h2>
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
<center>
|
||||||
|
<h2>I-D Search</h2>
|
||||||
|
<form action="" method="POST">
|
||||||
|
<table cellpadding="1" cellspacing="1" border="0" bgcolor="#9999ff">
|
||||||
|
<tr><td>
|
||||||
|
<table cellpadding="2" cellspacing="1" border="0" bgcolor="#ffffff">
|
||||||
|
<tr>
|
||||||
|
<td><b>{{ form.filename.label_tag }}</b> </td>
|
||||||
|
<td>{{ form.filename }} <b>{{ form.id_tracker_state_id.label_tag }}</b> {{ form.id_tracker_state_id }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><b>{{ form.wg_id.label_tag }}</b> </td>
|
||||||
|
<td>{{ form.wg_id }}
|
||||||
|
<b>{{ form.other_group.label_tag }}</b> {{ form.other_group }}
|
||||||
|
<b>{{ form.status_id.label_tag }}</b> {{ form.status_id }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><b>Author:</b></td>
|
||||||
|
<td>{{ form.last_name.label_tag }} {{ form.last_name }}
|
||||||
|
{{ form.first_name.label_tag }} {{ form.first_name }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr><td colspan="2" align="center"><br><input type="submit" value=" Search "></td></tr>
|
||||||
|
</table>
|
||||||
|
</td></tr></table>
|
||||||
|
</center>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endblock %}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue