Import announcements, port NomCom views

- Legacy-Id: 3077
This commit is contained in:
Ole Laursen 2011-05-02 15:58:36 +00:00
parent 53a2370b20
commit 7d3bef3db4
15 changed files with 338 additions and 48 deletions

View file

@ -3,12 +3,14 @@
from django.conf.urls.defaults import patterns
from ietf.announcements.models import Announcement
from django.conf import settings
nomcom_dict = {
'queryset': Announcement.objects.all().filter(nomcom=True)
}
}
urlpatterns = patterns('',
# (r'^nomcom/$', 'django.views.generic.simple.redirect_to', {'url': 'http://www.ietf.org/nomcom/index.html'} ),
(r'^nomcom/$', 'ietf.announcements.views.nomcom'),
(r'^nomcom/(?P<object_id>\d+)/$', 'django.views.generic.list_detail.object_detail', nomcom_dict)
(r'^nomcom/(?P<object_id>\d+)/$', 'ietf.announcements.views.message_detail' if settings.USE_DB_REDESIGN_PROXY_CLASSES else 'django.views.generic.list_detail.object_detail', nomcom_dict)
)

View file

@ -1,6 +1,11 @@
# Copyright The IETF Trust 2007, All Rights Reserved
from django.views.generic.simple import direct_to_template
from django.shortcuts import get_object_or_404
from django.conf import settings
from django.db.models import Q
import re
from ietf.idtracker.models import ChairsHistory
from ietf.idtracker.models import Role
@ -29,3 +34,58 @@ def nomcom(request):
{ 'curr_chair' : curr_chair,
'regimes' : regimes })
def nomcomREDESIGN(request):
from person.models import Email
from group.models import Group
from redesign.announcements.models import Message
address_re = re.compile("<.*>")
nomcoms = list(Group.objects.filter(acronym__startswith="nomcom").exclude(name="nomcom"))
regimes = []
for n in nomcoms:
e = n.latest_event(type="started")
n.start_year = e.time.year if e else 0
if n.start_year <= 2003:
continue
e = n.latest_event(type="concluded")
n.end_year = e.time.year if e else ""
chair = n.role_set.get(name="chair").email
announcements = Message.objects.filter(related_groups=n).order_by('-time')
for a in announcements:
a.to_name = address_re.sub("", a.to)
regimes.append(dict(chair=chair,
announcements=announcements,
group=n))
regimes.sort(key=lambda x: x["group"].start_year, reverse=True)
return direct_to_template(request,
"announcements/nomcomREDESIGN.html",
{ 'curr_chair' : regimes[0]["chair"],
'regimes' : regimes })
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
nomcom = nomcomREDESIGN
def message_detail(request, object_id, queryset):
from person.models import Email
from group.models import Group
from redesign.announcements.models import Message
# restrict to nomcom announcements for the time being
nomcoms = Group.objects.filter(acronym__startswith="nomcom").exclude(acronym="nomcom")
m = get_object_or_404(Message, id=object_id,
related_groups__in=nomcoms)
return direct_to_template(request,
"announcements/message_detail.html",
dict(message=m))

View file

@ -125,6 +125,7 @@ INSTALLED_APPS = (
'redesign.name',
'redesign.group',
'redesign.doc',
'redesign.announcements',
'redesign.issue',
'ietf.announcements',
'ietf.idindex',

View file

@ -0,0 +1,18 @@
{% extends "base.html" %}
{% load ietf_filters %}
{% block title %}Announcement: {{ message.time|date:"F j, Y" }} -- {{ message.subject|escape }}{% endblock %}
{% block content %}
<h1>NomCom Message</h1>
<p>
From: {{ message.frm|escape }}<br/>
To: {{ message.to|escape }}<br/>
Date: {{ message.time|date:"F j, Y" }}<br/>
Subject: {{ message.subject|escape }}
</p>
<hr width="400" align="left" />
<pre>
{{ message.text|escape }}
</pre>
{% endblock %}

View file

@ -0,0 +1,76 @@
{% extends "base.html" %}
{% load ietf_filters %}
{% block title %}IAB/IESG Nominating Committee{% endblock %}
{% block content %}
<h1>IAB/IESG Nominating Committee</h1>
<h3>Current Committee Chair: <a href="mailto:{{ curr_chair.address }}">{{ curr_chair.get_name }}</a></h3>
{% for regime in regimes %}
<hr>
<h1>Messages from {{ regime.group.start_year }} - {{ regime.group.end_year }}</h1>
<h4>Committee Chair: <a href="mailto:{{ regime.chair.address }}">{{ regime.chair.get_name }}</a></h4>
<table class="ietf-table">
<tr>
<th width="10%">Date</th>
<th width="60%">Subject</th>
<th width="30%">Sent To</th>
</tr>
{% for ann in regime.announcements %}
<tr>
<td>{{ ann.time|date:"Y-M-d" }}</td>
<td style="max-width:50%"><a href="/ann/nomcom/{{ ann.id }}/">{{ ann.subject|escape }}</a></td>
<td>{{ ann.to_name }}</td>
<tr>
{% endfor %}
</table>
{% endfor %}
<hr>
{# somebody ought to import these announcements in the DB instead of this mess #}
<h3>Messages from 2003-2004 NomCom</h3>
Committee Chair: <A HREF="mailto:richdr@microsoft.com">Rich Draves</A>
<br><br><li><a href="http://www.ietf.org/old/2009/nomcom/msg08-25-2003.txt">IETF Nominations Committee Chair Announcement</a> August 25, 2003
<LI><a href="http://www.ietf.org/old/2009/nomcom/msg09.22.txt">NomCom call for volunteers</a> September 22, 2003
<LI><A HREF="http://www.ietf.org/old/2009/nomcom/select-announce_03.txt">Selection of the Nominations Committee</A>
<LI><A HREF="http://www.ietf.org/old/2009/nomcom/msg10.06.txt">NomCom Volunteer List</a> October 06, 2004
<LI><A HREF="http://www.ietf.org/old/2009/nomcom/msg1010.txt">NomCom Selection</a> October 10, 2003
<LI><A HREF="http://www.ietf.org/old/2009/nomcom/msg10.17.txt">Call for Nominees</a> October 17, 2003
<LI><A HREF="http://www.ietf.org/old/2009/nomcom/msg10.24.txt">NomCom members</a> October 24, 2003
<LI><A HREF="http://www.ietf.org/old/2009/nomcom/msg11.07.txt">NomCom at IETF</a> November 07, 2003
<LI><A HREF="http://www.ietf.org/old/2009/nomcom/msg11.14.txt">NomCom News</a> November 14, 2003
<LI><A HREF="http://www.ietf.org/old/2009/nomcom/msg11.26.txt">Reminder - nominations to replace Randy Bush</a> November 26, 2003
<LI><A HREF="http://www.ietf.org/old/2009/nomcom/msg12.01.txt">Randy Bush replacement schedule</a> December 01, 2003
<LI><A HREF="http://www.ietf.org/old/2009/nomcom/msg01.14.txt">Randy Bush replacement</a> January 14, 2004
<LI><A HREF="http://www.ietf.org/old/2009/nomcom/msg02.13.txt">NomCom results</a> February 13, 2004
<LI><A HREF="http://www.ietf.org/old/2009/nomcom/msg09.28.txt">Call for Security AD nominations</a> September 28, 2004
<LI><A HREF="http://www.ietf.org/old/2009/nomcom/msg11.07.04.txt">Steve Bellovin replacement</a> November 07, 2004
<h3>Messages from 2002-2003 NomCom</h3>
Committee Chair: <A HREF="mailto:PRoberts@MEGISTO.com">Phil Roberts</A>
<br><br>
<LI><A HREF="http://www.ietf.org/old/2009/nomcom/msg19765.html">First Call for Volunteers</A> July 30, 2002
<LI><A HREF="http://www.ietf.org/old/2009/nomcom/select-announce.txt">Selection of the Nominations Committee</A>
<LI><A HREF="http://www.ietf.org/old/2009/nomcom/msg0918.txt">Announcement of the Nominations Committee</A> September 18, 2002
<LI><A HREF="http://www.ietf.org/old/2009/nomcom/msg10.21.txt">Announcement of IESG and IAB Nominations Requests</A> October 21, 2002
<LI><A HREF="http://www.ietf.org/old/2009/nomcom/msg11.05.txt">Announcement of IESG and IAB Nominations Requests</A> November 5, 2002
<LI><A HREF="http://www.ietf.org/old/2009/nomcom/msg11.12.txt">Announcement of IESG and IAB Nominations Requests</A> November 12, 2002
<LI><a href="http://www.ietf.org/old/2009/nomcom/msg02.27.txt">IETF Nomcom Announcement</a> February 27, 2003
<LI><a href="http://www.ietf.org/old/2009/nomcom/msg06.11.txt">Announcement of IESG and IAB Nominations Request</a> June 11, 2003
<LI><a href="http://www.ietf.org/old/2009/nomcom/msg07.15.txt">Nomcom result announcement</a> July 15, 2003
<h3>Historical Information</h3>
<li><a href="http://www.ietf.org/nomcom/committee.html">IAB/IESG Nominating Committee Members (by year)</a>
<h3>References</h3>
<LI><A HREF="http://www.ietf.org/rfc/rfc2026.txt">The Internet Standards Process (RFC 2026)</A>
<LI><A HREF="http://www.ietf.org/rfc/rfc3777.txt">IAB and IESG Selection, Confirmation, and Recall Process: Operation of the Nominating and Recall Committees (RFC 3777) (Also BCP10)</A>
<LI><A HREF="http://www.ietf.org/rfc/rfc3797.txt">Publicly Verifiable Nominations Committee (NomCom) Random Selection (RFC 3797)</A>
{% endblock %}

View file

View file

@ -0,0 +1,20 @@
from django.contrib import admin
from models import *
class MessageAdmin(admin.ModelAdmin):
list_display = ["time", "by", "subject", "groups"]
search_fields = ["text"]
raw_id_fields = ["by"]
def groups(self, instance):
return ", ".join(g.acronym for g in related_groups.all())
admin.site.register(Message, MessageAdmin)
class SendQueueAdmin(admin.ModelAdmin):
list_display = ["time", "by", "message", "send_at", "sent_at"]
list_filter = ["time", "send_at", "sent_at"]
search_fields = ["message__text"]
raw_id_fields = ["by"]
admin.site.register(SendQueue, SendQueueAdmin)

View file

@ -0,0 +1,37 @@
from django.db import models
import datetime
from person.models import Email
from group.models import Group
class Message(models.Model):
time = models.DateTimeField(default=datetime.datetime.now)
by = models.ForeignKey(Email)
subject = models.CharField(max_length=255)
frm = models.CharField(max_length=255)
to = models.CharField(max_length=255)
cc = models.CharField(max_length=255, blank=True)
bcc = models.CharField(max_length=255, blank=True)
reply_to = models.CharField(max_length=255, blank=True)
text = models.TextField()
related_groups = models.ManyToManyField(Group, blank=True)
class Meta:
ordering = ['time']
def __unicode__(self):
return "'%s' %s -> %s" % (self.subject, self.frm, self.to)
class SendQueue(models.Model):
time = models.DateTimeField(default=datetime.datetime.now)
by = models.ForeignKey(Email)
comment = models.TextField()
message = models.ForeignKey(Message)
send_at = models.DateTimeField(blank=True, null=True)
sent_at = models.DateTimeField(blank=True, null=True)
class Meta:
ordering = ['time']

View file

@ -21,10 +21,6 @@ class DocAliasAdmin(admin.ModelAdmin):
raw_id_fields = ['document']
admin.site.register(DocAlias, DocAliasAdmin)
class SendQueueAdmin(admin.ModelAdmin):
pass
admin.site.register(SendQueue, SendQueueAdmin)
# events
@ -38,7 +34,6 @@ class EventAdmin(admin.ModelAdmin):
admin.site.register(Event, EventAdmin)
admin.site.register(Message, EventAdmin)
admin.site.register(NewRevisionEvent, EventAdmin)
admin.site.register(WriteupEvent, EventAdmin)
admin.site.register(StatusDateEvent, EventAdmin)

View file

@ -169,15 +169,6 @@ class DocAlias(models.Model):
verbose_name = "document alias"
verbose_name_plural = "document aliases"
class SendQueue(models.Model):
time = models.DateTimeField() # Scheduled at this time
agent = models.ForeignKey(Email) # Scheduled by this person
comment = models.TextField()
#
msg = models.ForeignKey('Message')
to = models.ForeignKey(Email, related_name='to_messages')
cc = models.ManyToManyField(Email, related_name='cc_messages')
send = models.DateTimeField() # Send message at this time
# class Ballot(models.Model): # A collection of ballot positions
# """A collection of ballot positions, and the actions taken during the
@ -243,10 +234,6 @@ class Event(models.Model):
class Meta:
ordering = ['-time', 'id']
class Message(Event):
subj = models.CharField(max_length=255)
body = models.TextField()
class NewRevisionEvent(Event):
rev = models.CharField(max_length=16)

View file

@ -0,0 +1,86 @@
#!/usr/bin/python
import sys, os, re, datetime
basedir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
sys.path = [ basedir ] + sys.path
from ietf import settings
settings.USE_DB_REDESIGN_PROXY_CLASSES = False
from django.core import management
management.setup_environ(settings)
from redesign.person.models import *
from redesign.group.models import *
from redesign.announcements.models import *
from ietf.announcements.models import Announcement, PersonOrOrgInfo, AnnouncedTo, AnnouncedFrom
from importing.utils import *
# assumptions:
# - nomcom groups have been imported
# - persons have been imported
# imports Announcements
# FIXME: should import ScheduledAnnouncements
system_email, _ = Email.objects.get_or_create(address="(System)")
# Announcement
for o in Announcement.objects.all().select_related('announced_to', 'announced_from').order_by('announcement_id').iterator():
try:
message = Message.objects.get(id=o.announcement_id)
except Message.DoesNotExist:
message = Message(id=o.announcement_id)
message.time = datetime.datetime.combine(o.announced_date,
datetime.time(*(int(x) for x in o.announced_time.split(":"))))
try:
x = o.announced_by
except PersonOrOrgInfo.DoesNotExist:
message.by = system_email
else:
if not o.announced_by.first_name and o.announced_by.last_name == 'None':
message.by = system_email
else:
message.by = Email.objects.get(address=person_email(o.announced_by))
message.subject = o.subject.strip()
if o.announced_from_id == 99:
message.frm = o.other_val or ""
elif o.announced_from_id == 18 and o.nomcom_chair_id != 0:
message.frm = u"%s <%s>" % o.nomcom_chair.person.email()
else:
if '<' in o.announced_from.announced_from:
message.frm = o.announced_from.announced_from
else:
message.frm = u"%s <%s>" % (o.announced_from.announced_from, o.announced_from.email)
if o.announced_to_id == 99:
message.to = o.other_val or ""
else:
try:
message.to = u"%s <%s>" % (o.announced_to.announced_to, o.announced_to.email)
except AnnouncedTo.DoesNotExist:
message.to = ""
message.cc = o.cc or ""
for l in (o.extra or "").strip().replace("^", "\n").replace("\r", "").split("\n"):
l = l.strip()
if l.lower().startswith("bcc:"):
message.bcc = l[len("bcc:"):].strip()
elif l.lower().startswith("reply-to:"):
message.reply_to = l[len("reply-to:"):].strip()
message.text = o.text
message.save()
message.related_groups.clear()
if o.nomcom:
nomcom = Group.objects.filter(role__name="chair",
role__email__person__id=o.nomcom_chair.person.pk,
acronym__startswith="nomcom").exclude(acronym="nomcom").get()
message.related_groups.add(nomcom)

View file

@ -17,6 +17,8 @@ from redesign.name.models import *
from ietf.idtracker.models import InternetDraft, IDInternal, IESGLogin, DocumentComment, PersonOrOrgInfo, Rfc, IESGComment, IESGDiscuss, BallotInfo, Position
from ietf.idrfc.models import RfcIndex, DraftVersions
from importing.utils import *
import sys
document_name_to_import = None
@ -43,15 +45,6 @@ connection.queries = DummyQueries()
# IESGComment, IESGDiscuss, DocumentComment, IDAuthor, idrfc.RfcIndex,
# idrfc.DraftVersions
def name(name_class, slug, name, desc="", order=0):
# create if it doesn't exist, set name and desc
obj, _ = name_class.objects.get_or_create(slug=slug)
obj.name = name
obj.desc = desc
obj.order = order
obj.save()
return obj
def alias_doc(name, doc):
DocAlias.objects.filter(name=name).exclude(document=doc).delete()
alias, _ = DocAlias.objects.get_or_create(name=name, document=doc)
@ -208,7 +201,7 @@ def iesg_login_to_email(l):
l = buggy_iesg_logins_cache[l.id]
try:
return Email.objects.get(address=l.person.email()[1])
return Email.objects.get(address=person_email(l.person))
except Email.DoesNotExist:
try:
return Email.objects.get(person__name="%s %s" % (l.person.first_name, l.person.last_name))

View file

@ -17,27 +17,22 @@ from redesign.group.models import *
from redesign.name.models import *
from ietf.idtracker.models import IESGLogin, AreaDirector, IDAuthor, PersonOrOrgInfo, WGChair, WGEditor, WGSecretary, WGTechAdvisor, ChairsHistory, Role as OldRole, Acronym, IRTFChair
from importing.utils import *
# assumptions:
# - groups have been imported
# PersonOrOrgInfo/PostalAddress/EmailAddress/PhoneNumber are not
# imported, although some information is retrieved from those
# imports IESGLogin, AreaDirector, WGEditor, persons from IDAuthor,
# NomCom chairs from ChairsHistory, WGChair, IRTFChair, WGSecretary,
# WGTechAdvisor
# imports IESGLogin, AreaDirector, WGEditor, WGChair, IRTFChair,
# WGSecretary, WGTechAdvisor, NomCom chairs from ChairsHistory,
#
# also imports persons from IDAuthor, announcement originators from
# Announcements
# FIXME: should probably import Role
# make sure names exist
def name(name_class, slug, name, desc=""):
# create if it doesn't exist, set name
obj, _ = name_class.objects.get_or_create(slug=slug)
obj.name = name
obj.desc = desc
obj.save()
return obj
area_director_role = name(RoleName, "ad", "Area Director")
inactive_area_director_role = name(RoleName, "ex-ad", "Ex-Area Director", desc="Inactive Area Director")
chair_role = name(RoleName, "chair", "Chair")
@ -47,18 +42,16 @@ techadvisor_role = name(RoleName, "techadv", "Tech Advisor")
# helpers for creating the objects
def get_or_create_email(o, create_fake):
hardcoded_emails = { 'Dinara Suleymanova': "dinaras@ietf.org" }
email = o.person.email()[1] or hardcoded_emails.get("%s %s" % (o.person.first_name, o.person.last_name))
email = person_email(o.person)
if not email:
if create_fake:
email = u"unknown-email-%s-%s" % (o.person.first_name, o.person.last_name)
print ("USING FAKE EMAIL %s for %s %s %s" % (email, o.person.pk, o.person.first_name, o.person.last_name)).encode('utf-8')
else:
print ("NO EMAIL FOR %s %s %s %s %s" % (o.__class__, o.id, o.person.pk, o.person.first_name, o.person.last_name)).encode('utf-8')
print ("NO EMAIL FOR %s %s %s %s %s" % (o.__class__, o.pk, o.person.pk, o.person.first_name, o.person.last_name)).encode('utf-8')
return None
e, _ = Email.objects.get_or_create(address=email)
e, _ = Email.objects.select_related("person").get_or_create(address=email)
if not e.person:
n = u"%s %s" % (o.person.first_name, o.person.last_name)
asciified = unaccent.asciify(n)
@ -66,7 +59,7 @@ def get_or_create_email(o, create_fake):
if aliases:
p = aliases[0].person
else:
p = Person.objects.create(name=n, ascii=asciified)
p = Person.objects.create(id=o.person.pk, name=n, ascii=asciified)
# FIXME: fill in address?
Alias.objects.create(name=n, person=p)
if asciified != n:
@ -203,6 +196,14 @@ for o in AreaDirector.objects.all():
Role.objects.get_or_create(name=role_type, group=area, email=email)
# Announcement persons
for o in PersonOrOrgInfo.objects.filter(announcement__announcement_id__gte=1).distinct():
print "importing Announcement originator", o.person_or_org_tag, o.first_name.encode('utf-8'), o.last_name.encode('utf-8')
o.person = o # satisfy the get_or_create_email interface
email = get_or_create_email(o, create_fake=False)
# IDAuthor persons
for o in IDAuthor.objects.all().order_by('id').select_related('person'):
print "importing IDAuthor", o.id, o.person_id, o.person.first_name.encode('utf-8'), o.person.last_name.encode('utf-8')

View file

View file

@ -0,0 +1,14 @@
def name(name_class, slug, name, desc="", order=0):
# create if it doesn't exist, set name and desc
obj, _ = name_class.objects.get_or_create(slug=slug)
obj.name = name
obj.desc = desc
obj.order = order
obj.save()
return obj
def person_email(person):
hardcoded_emails = { 'Dinara Suleymanova': "dinaras@ietf.org" }
return person.email()[1] or hardcoded_emails.get("%s %s" % (person.first_name, person.last_name))