Moving ietf to trunk/ietf

[[Split portion of a mixed commit.]]
 - Legacy-Id: 96.1
This commit is contained in:
Henrik Levkowetz 2007-05-04 12:37:28 +00:00
commit 5872696834
149 changed files with 9599 additions and 0 deletions

17
.gitignore vendored Normal file
View 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
View file

@ -0,0 +1,2 @@
/*.pyc
/settings_local.py

0
ietf/__init__.py Normal file
View file

2
ietf/agenda/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/*.pyc
/settings_local.py

0
ietf/agenda/__init__.py Normal file
View file

3
ietf/agenda/models.py Normal file
View file

@ -0,0 +1,3 @@
from django.db import models
# Create your models here.

1
ietf/agenda/views.py Normal file
View file

@ -0,0 +1 @@
# Create your views here.

2
ietf/announcements/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/*.pyc
/settings_local.py

View file

View 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

View 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)
)

View file

@ -0,0 +1 @@
# Create your views here.

2
ietf/bin/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/*.pyc
/settings_local.py

17
ietf/bin/graphall Executable file
View 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
View file

@ -0,0 +1,2 @@
#!/bin/sh
python manage.py dumpdata --format=xml redirects | xmllint --format -

2
ietf/database-notes/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/*.pyc
/settings_local.py

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View 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
View file

@ -0,0 +1,2 @@
/*.pyc
/settings_local.py

0
ietf/idindex/__init__.py Normal file
View file

17
ietf/idindex/forms.py Normal file
View 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
View 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
View 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
View 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
View file

@ -0,0 +1,2 @@
/*.pyc
/settings_local.py

56
ietf/idtracker/README Normal file
View 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

View file

View 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
View 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
View 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

View file

@ -0,0 +1,2 @@
/*.pyc
/settings_local.py

View file

View 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 &nbsp; and one space so that
HTML output doesn't collapse them."""
return value.replace(' ', '&nbsp; ')
@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('&lt;b&gt;','<b>').replace('&lt;/b&gt;','</b>').replace('&lt;br&gt;','<br>')))

26
ietf/idtracker/urls.py Normal file
View 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
View 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
View file

@ -0,0 +1,2 @@
/*.pyc
/settings_local.py

0
ietf/iesg/__init__.py Normal file
View file

21
ietf/iesg/feeds.py Normal file
View 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
View 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
View 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
View file

@ -0,0 +1 @@
# Create your views here.

2
ietf/ipr/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/*.pyc
/settings_local.py

0
ietf/ipr/__init__.py Normal file
View file

167
ietf/ipr/models.py Normal file
View 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
View 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
View 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
View file

@ -0,0 +1,2 @@
/*.pyc
/settings_local.py

View file

154
ietf/liaisons/models.py Normal file
View 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
View 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
View file

@ -0,0 +1 @@
# Create your views here.

2
ietf/mailinglists/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/*.pyc
/settings_local.py

View file

View 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

View 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) }),
)

View file

@ -0,0 +1 @@
# Create your views here.

11
ietf/manage.py Normal file
View 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
View file

@ -0,0 +1,2 @@
/*.pyc
/settings_local.py

0
ietf/my/__init__.py Normal file
View file

3
ietf/my/models.py Normal file
View file

@ -0,0 +1,3 @@
from django.db import models
# Create your models here.

8
ietf/my/urls.py Normal file
View 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
View 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
View file

@ -0,0 +1,2 @@
/*.pyc
/settings_local.py

View file

250
ietf/proceedings/models.py Normal file
View 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

View file

@ -0,0 +1 @@
# Create your views here.

2
ietf/redirects/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/*.pyc
/settings_local.py

View file

2
ietf/redirects/fixtures/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/*.pyc
/settings_local.py

View 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
View 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
View 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
View 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
View file

@ -0,0 +1,2 @@
/*.pyc
/settings_local.py

0
ietf/rfcs/__init__.py Normal file
View file

85
ietf/rfcs/models.py Normal file
View 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
View file

@ -0,0 +1 @@
# Create your views here.

109
ietf/settings.py Normal file
View 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
View file

@ -0,0 +1,2 @@
/*.pyc
/settings_local.py

View file

@ -0,0 +1,2 @@
/*.pyc
/settings_local.py

View 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
View 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 %}

View 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
View 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
View 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
View file

@ -0,0 +1,2 @@
/*.pyc
/settings_local.py

View file

@ -0,0 +1,2 @@
{% load ietf_filters %}
{{ obj.comment_text|format_textarea|truncatewords_html:"40" }}

View file

@ -0,0 +1 @@
{% if obj.ballot %}IESG Evaluation {{ obj.get_ballot_display.upper }}{% else %}Comment{% endif %} from {{ obj.get_author }}

View file

@ -0,0 +1,2 @@
{% load ietf_filters %}
{{ obj.telechat_minute|escape|linebreaks|truncatewords_html:"40" }}

View file

@ -0,0 +1 @@
{{ obj.telechat_date|date:"F j, Y" }}

2
ietf/templates/idindex/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/*.pyc
/settings_local.py

View 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>

View 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>

View 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 &nbsp; <a href="/idindex/showdocs/all/date/">(sorted by submission date)</a> &nbsp; <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 &nbsp; <a href="/idindex/showdocs/current/date/">(sorted by submission date)</a> &nbsp; <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 &nbsp; <a href="/idindex/showdocs/rfc/date/">(sorted by submission date)</a> &nbsp; <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 &nbsp; <a href="/idindex/showdocs/dead/date/">(sorted by submission date)</a> &nbsp; <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 %}

View 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 %}
&nbsp;
{% 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>

View 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 %}

View 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 %}

View 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 %}

View 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 }} &nbsp; <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 }}&nbsp;
<b>{{ form.other_group.label_tag }}</b> {{ form.other_group }}&nbsp;
<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 }} &nbsp;
{{ 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