Skip to content

Commit 67e317d

Browse files
committed
Merged in changes from conversion branch fixing a couple of problems
- Legacy-Id: 3285
2 parents 47e8f76 + df73e8b commit 67e317d

137 files changed

Lines changed: 11770 additions & 389 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

ietf/announcements/admin.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#coding: utf-8
22
from django.contrib import admin
3+
from django.conf import settings
34
from ietf.announcements.models import *
45

56
class AnnouncedFromAdmin(admin.ModelAdmin):
@@ -21,3 +22,22 @@ class ScheduledAnnouncementAdmin(admin.ModelAdmin):
2122
pass
2223
admin.site.register(ScheduledAnnouncement, ScheduledAnnouncementAdmin)
2324

25+
26+
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
27+
class MessageAdmin(admin.ModelAdmin):
28+
list_display = ["time", "by", "subject", "groups"]
29+
search_fields = ["body"]
30+
raw_id_fields = ["by"]
31+
32+
def groups(self, instance):
33+
return ", ".join(g.acronym for g in related_groups.all())
34+
35+
admin.site.register(Message, MessageAdmin)
36+
37+
class SendQueueAdmin(admin.ModelAdmin):
38+
list_display = ["time", "by", "message", "send_at", "sent_at"]
39+
list_filter = ["time", "send_at", "sent_at"]
40+
search_fields = ["message__body"]
41+
raw_id_fields = ["by"]
42+
43+
admin.site.register(SendQueue, SendQueueAdmin)

ietf/announcements/models.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Copyright The IETF Trust 2007, All Rights Reserved
22

33
from django.db import models
4+
from django.conf import settings
45
from ietf.idtracker.models import PersonOrOrgInfo, ChairsHistory
56
#from django.contrib.auth.models import Permission
67

@@ -87,3 +88,43 @@ class Meta:
8788
db_table = 'scheduled_announcements'
8889

8990

91+
if settings.USE_DB_REDESIGN_PROXY_CLASSES or hasattr(settings, "IMPORTING_ANNOUNCEMENTS"):
92+
import datetime
93+
94+
from person.models import Email, Person
95+
from group.models import Group
96+
97+
class Message(models.Model):
98+
time = models.DateTimeField(default=datetime.datetime.now)
99+
by = models.ForeignKey(Person)
100+
101+
subject = models.CharField(max_length=255)
102+
frm = models.CharField(max_length=255)
103+
to = models.CharField(max_length=1024)
104+
cc = models.CharField(max_length=1024, blank=True)
105+
bcc = models.CharField(max_length=255, blank=True)
106+
reply_to = models.CharField(max_length=255, blank=True)
107+
body = models.TextField()
108+
content_type = models.CharField(max_length=255, blank=True)
109+
110+
related_groups = models.ManyToManyField(Group, blank=True)
111+
112+
class Meta:
113+
ordering = ['time']
114+
115+
def __unicode__(self):
116+
return "'%s' %s -> %s" % (self.subject, self.frm, self.to)
117+
118+
class SendQueue(models.Model):
119+
time = models.DateTimeField(default=datetime.datetime.now)
120+
by = models.ForeignKey(Person)
121+
122+
message = models.ForeignKey(Message)
123+
124+
send_at = models.DateTimeField(blank=True, null=True)
125+
sent_at = models.DateTimeField(blank=True, null=True)
126+
127+
note = models.TextField(blank=True)
128+
129+
class Meta:
130+
ordering = ['time']

ietf/announcements/send_scheduled.py

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import re, datetime, email
22

3+
from django.conf import settings
4+
35
from ietf.utils.mail import send_mail_text, send_mail_mime
46

57
first_dot_on_line_re = re.compile(r'^\.', re.MULTILINE)
@@ -8,7 +10,6 @@ def send_scheduled_announcement(announcement):
810
# for some reason, the old Perl code base substituted away . on line starts
911
body = first_dot_on_line_re.sub("", announcement.body)
1012

11-
announcement.content_type
1213
extra = {}
1314
if announcement.replyto:
1415
extra['Reply-To'] = announcement.replyto
@@ -33,3 +34,35 @@ def send_scheduled_announcement(announcement):
3334
announcement.actual_sent_time = str(now.time())
3435
announcement.mail_sent = True
3536
announcement.save()
37+
38+
39+
def send_scheduled_announcementREDESIGN(send_queue):
40+
message = send_queue.message
41+
42+
# for some reason, the old Perl code base substituted away . on line starts
43+
body = first_dot_on_line_re.sub("", message.body)
44+
45+
extra = {}
46+
if message.reply_to:
47+
extra['Reply-To'] = message.reply_to
48+
49+
# announcement.content_type can contain a case-sensitive parts separator,
50+
# so we need to keep it as is, not lowercased, but we want a lowercased
51+
# version for the coming comparisons.
52+
content_type_lowercase = message.content_type.lower()
53+
if not content_type_lowercase or 'text/plain' in content_type_lowercase:
54+
send_mail_text(None, message.to, message.frm, message.subject,
55+
body, cc=message.cc, bcc=message.bcc)
56+
elif 'multipart' in content_type_lowercase:
57+
# make body a real message so we can parse it
58+
body = ("MIME-Version: 1.0\r\nContent-Type: %s\r\n" % message.content_type) + body
59+
60+
msg = email.message_from_string(body.encode("utf-8"))
61+
send_mail_mime(None, message.to, message.frm, message.subject,
62+
msg, cc=message.cc, bcc=message.bcc)
63+
64+
send_queue.sent_at = datetime.datetime.now()
65+
send_queue.save()
66+
67+
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
68+
send_scheduled_announcement = send_scheduled_announcementREDESIGN

ietf/announcements/tests.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
import datetime
2+
3+
from django.conf import settings
14
import django.test
25

36
from ietf.utils.test_utils import SimpleUrlTestCase, canonicalize_sitemap
47
from ietf.utils.test_runner import mail_outbox
8+
from ietf.utils.test_data import make_test_data
59

610
from ietf.announcements.models import ScheduledAnnouncement
711

@@ -57,3 +61,73 @@ def test_send_mime_announcement(self):
5761
self.assertTrue("This is a test" in mail_outbox[-1]["Subject"])
5862
self.assertTrue("--NextPart" in mail_outbox[-1].as_string())
5963
self.assertTrue(ScheduledAnnouncement.objects.get(id=a.id).mail_sent)
64+
65+
66+
class SendScheduledAnnouncementsTestCaseREDESIGN(django.test.TestCase):
67+
def test_send_plain_announcement(self):
68+
from ietf.announcements.models import Message, SendQueue
69+
from redesign.person.models import Person
70+
71+
make_test_data()
72+
73+
msg = Message.objects.create(
74+
by=Person.objects.get(name="(System)"),
75+
subject="This is a test",
76+
to="test@example.com",
77+
frm="testmonkey@example.com",
78+
cc="cc.a@example.com, cc.b@example.com",
79+
bcc="bcc@example.com",
80+
body="Hello World!",
81+
content_type="",
82+
)
83+
84+
q = SendQueue.objects.create(
85+
by=Person.objects.get(name="(System)"),
86+
message=msg,
87+
send_at=datetime.datetime.now() + datetime.timedelta(hours=12)
88+
)
89+
90+
mailbox_before = len(mail_outbox)
91+
92+
from ietf.announcements.send_scheduled import send_scheduled_announcement
93+
send_scheduled_announcement(q)
94+
95+
self.assertEquals(len(mail_outbox), mailbox_before + 1)
96+
self.assertTrue("This is a test" in mail_outbox[-1]["Subject"])
97+
self.assertTrue(SendQueue.objects.get(id=q.id).sent_at)
98+
99+
def test_send_mime_announcement(self):
100+
from ietf.announcements.models import Message, SendQueue
101+
from redesign.person.models import Person
102+
103+
make_test_data()
104+
105+
msg = Message.objects.create(
106+
by=Person.objects.get(name="(System)"),
107+
subject="This is a test",
108+
to="test@example.com",
109+
frm="testmonkey@example.com",
110+
cc="cc.a@example.com, cc.b@example.com",
111+
bcc="bcc@example.com",
112+
body='--NextPart\r\n\r\nA New Internet-Draft is available from the on-line Internet-Drafts directories.\r\n--NextPart\r\nContent-Type: Message/External-body;\r\n\tname="draft-huang-behave-bih-01.txt";\r\n\tsite="ftp.ietf.org";\r\n\taccess-type="anon-ftp";\r\n\tdirectory="internet-drafts"\r\n\r\nContent-Type: text/plain\r\nContent-ID: <2010-07-30001541.I-D@ietf.org>\r\n\r\n--NextPart--',
113+
content_type='Multipart/Mixed; Boundary="NextPart"',
114+
)
115+
116+
q = SendQueue.objects.create(
117+
by=Person.objects.get(name="(System)"),
118+
message=msg,
119+
send_at=datetime.datetime.now() + datetime.timedelta(hours=12)
120+
)
121+
122+
mailbox_before = len(mail_outbox)
123+
124+
from ietf.announcements.send_scheduled import send_scheduled_announcement
125+
send_scheduled_announcement(q)
126+
127+
self.assertEquals(len(mail_outbox), mailbox_before + 1)
128+
self.assertTrue("This is a test" in mail_outbox[-1]["Subject"])
129+
self.assertTrue("--NextPart" in mail_outbox[-1].as_string())
130+
self.assertTrue(SendQueue.objects.get(id=q.id).sent_at)
131+
132+
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
133+
SendScheduledAnnouncementsTestCase = SendScheduledAnnouncementsTestCaseREDESIGN

ietf/announcements/urls.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
from django.conf.urls.defaults import patterns
44
from ietf.announcements.models import Announcement
55

6+
from django.conf import settings
7+
68
nomcom_dict = {
79
'queryset': Announcement.objects.all().filter(nomcom=True)
8-
}
10+
}
911

1012
urlpatterns = patterns('',
1113
# (r'^nomcom/$', 'django.views.generic.simple.redirect_to', {'url': 'http://www.ietf.org/nomcom/index.html'} ),
1214
(r'^nomcom/$', 'ietf.announcements.views.nomcom'),
13-
(r'^nomcom/(?P<object_id>\d+)/$', 'django.views.generic.list_detail.object_detail', nomcom_dict)
15+
(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)
1416
)

ietf/announcements/views.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
# Copyright The IETF Trust 2007, All Rights Reserved
22

33
from django.views.generic.simple import direct_to_template
4+
from django.shortcuts import get_object_or_404
5+
from django.conf import settings
6+
from django.db.models import Q
7+
8+
import re
49

510
from ietf.idtracker.models import ChairsHistory
611
from ietf.idtracker.models import Role
@@ -29,3 +34,56 @@ def nomcom(request):
2934
{ 'curr_chair' : curr_chair,
3035
'regimes' : regimes })
3136

37+
def nomcomREDESIGN(request):
38+
from group.models import Group
39+
from ietf.announcements.models import Message
40+
41+
address_re = re.compile("<.*>")
42+
43+
nomcoms = list(Group.objects.filter(acronym__startswith="nomcom").exclude(name="nomcom"))
44+
45+
regimes = []
46+
47+
for n in nomcoms:
48+
e = n.latest_event(type="started")
49+
n.start_year = e.time.year if e else 0
50+
if n.start_year <= 2003:
51+
continue
52+
e = n.latest_event(type="concluded")
53+
n.end_year = e.time.year if e else ""
54+
55+
chair = n.role_set.get(name="chair").email
56+
announcements = Message.objects.filter(related_groups=n).order_by('-time')
57+
for a in announcements:
58+
a.to_name = address_re.sub("", a.to)
59+
60+
regimes.append(dict(chair=chair,
61+
announcements=announcements,
62+
group=n))
63+
64+
regimes.sort(key=lambda x: x["group"].start_year, reverse=True)
65+
66+
return direct_to_template(request,
67+
"announcements/nomcomREDESIGN.html",
68+
{ 'curr_chair' : regimes[0]["chair"],
69+
'regimes' : regimes })
70+
71+
72+
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
73+
nomcom = nomcomREDESIGN
74+
75+
76+
def message_detail(request, object_id, queryset):
77+
from group.models import Group
78+
from ietf.announcements.models import Message
79+
80+
# restrict to nomcom announcements for the time being
81+
nomcoms = Group.objects.filter(acronym__startswith="nomcom").exclude(acronym="nomcom")
82+
m = get_object_or_404(Message, id=object_id,
83+
related_groups__in=nomcoms)
84+
85+
return direct_to_template(request,
86+
"announcements/message_detail.html",
87+
dict(message=m))
88+
89+

ietf/bin/expire-ids

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@ if not in_id_expire_freeze():
1515
for doc in get_expired_ids():
1616
send_expire_notice_for_id(doc)
1717
expire_id(doc)
18-
syslog.syslog("Expired %s (id=%s)%s" % (doc.file_tag(), doc.id_document_tag, " in the ID Tracker" if doc.idinternal else ""))
18+
syslog.syslog("Expired %s (id=%s)%s" % (doc.file_tag(), doc.pk, " in the ID Tracker" if doc.latest_event(type="started_iesg_process") else ""))
1919

2020
clean_up_id_files()

ietf/bin/expire-last-calls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@ from ietf.idrfc.lastcall import *
1414
drafts = get_expired_last_calls()
1515
for doc in drafts:
1616
expire_last_call(doc)
17-
syslog.syslog("Expired last call for %s (id=%s)" % (doc.file_tag(), doc.id_document_tag))
17+
syslog.syslog("Expired last call for %s (id=%s)" % (doc.file_tag(), doc.pk))

ietf/bin/notify-expirations

Lines changed: 5 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -6,56 +6,11 @@ from ietf import settings
66
from django.core import management
77
management.setup_environ(settings)
88

9-
from ietf.idtracker.models import InternetDraft,IDAuthor,WGChair
10-
from ietf.utils.mail import send_mail_subj
9+
from ietf.idrfc.expire import get_soon_to_expire_ids, send_expire_warning_for_id
1110

12-
notify_days = 14 # notify about documents that expire within the
13-
# next 2 weeks
1411

15-
start_date = datetime.date.today() - datetime.timedelta(InternetDraft.DAYS_TO_EXPIRE - 1)
16-
end_date = start_date + datetime.timedelta(notify_days - 1)
12+
# notify about documents that expire within the next 2 weeks
13+
notify_days = 14
1714

18-
19-
matches = InternetDraft.objects.filter(revision_date__gte=start_date,revision_date__lte=end_date,status__status='Active')
20-
21-
#For development - focus on one draft
22-
#matches = InternetDraft.objects.filter(filename__icontains='geopriv-http-location-delivery')
23-
24-
# Todo:
25-
#second_cutoff = IDDates.objects.get(date_id=2)
26-
#ietf_monday = IDDates.objects.get(date_id=3)
27-
#freeze_delta = ietf_monday - second_cutoff
28-
29-
for draft in matches:
30-
if not draft.can_expire():
31-
# debugging
32-
#print "%s can't expire, skipping" % draft
33-
continue
34-
expiration = draft.expiration()
35-
# # The I-D expiration job doesn't run while submissions are frozen.
36-
# if ietf_monday > expiration > second_cutoff:
37-
# expiration += freeze_delta
38-
authors = draft.authors.all()
39-
to_addrs = [author.email() for author in authors if author.email()]
40-
cc_addrs = None
41-
if draft.group.acronym != 'none':
42-
cc_addrs = [chair.person.email() for chair in WGChair.objects.filter(group_acronym=draft.group)]
43-
44-
#For development debugging
45-
"""
46-
print "filename: "+draft.filename
47-
print "to: ", to_addrs
48-
print "cc: ", cc_addrs
49-
print "expires: ", expiration
50-
print "status: ", draft.status.status, "/", draft.idstate()
51-
print
52-
continue
53-
"""
54-
55-
if to_addrs or cc_addrs:
56-
send_mail_subj(None, to_addrs, None, 'notify_expirations/subject.txt', 'notify_expirations/body.txt',
57-
{
58-
'draft':draft,
59-
'expiration':expiration,
60-
},
61-
cc_addrs)
15+
for doc in get_soon_to_expire_ids(notify_days):
16+
send_expire_warning_for_id(doc)

0 commit comments

Comments
 (0)