Skip to content

Commit aeaf67a

Browse files
committed
Merged in [15125] from rjsparks@nostrum.com:
Added a view that generates the \'send minutes\' email for the secretariat. Fixes ietf-tools#2493. - Legacy-Id: 15134 Note: SVN reference [15125] has been migrated to Git commit 345bff8
2 parents c4f9fac + 345bff8 commit aeaf67a

7 files changed

Lines changed: 130 additions & 10 deletions

File tree

ietf/meeting/forms.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from ietf.meeting.helpers import is_meeting_approved, get_next_agenda_name
1919
from ietf.message.models import Message
2020
from ietf.person.models import Person
21-
from ietf.utils.fields import DatepickerDateField, DurationField
21+
from ietf.utils.fields import DatepickerDateField, DurationField, MultiEmailField
2222
from ietf.utils.validators import ( validate_file_size, validate_mime_type,
2323
validate_file_extension, validate_no_html_frame)
2424

@@ -345,4 +345,8 @@ def clean_file(self):
345345
validate_no_html_frame(file)
346346
return file
347347

348-
348+
class RequestMinutesForm(forms.Form):
349+
to = MultiEmailField()
350+
cc = MultiEmailField(required=False)
351+
subject = forms.CharField()
352+
body = forms.CharField(widget=forms.Textarea,strip=False)

ietf/meeting/tests_views.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@
2424
from ietf.meeting.helpers import send_interim_approval_request
2525
from ietf.meeting.helpers import send_interim_cancellation_notice
2626
from ietf.meeting.helpers import send_interim_minutes_reminder, populate_important_dates
27-
from ietf.meeting.models import Session, TimeSlot, Meeting, SchedTimeSessAssignment, Schedule
27+
from ietf.meeting.models import Session, TimeSlot, Meeting, SchedTimeSessAssignment, Schedule, SessionPresentation
2828
from ietf.meeting.test_data import make_meeting_test_data, make_interim_meeting
2929
from ietf.meeting.utils import finalize
3030
from ietf.name.models import SessionStatusName
3131
from ietf.utils.test_utils import TestCase, login_testing_unauthorized, unicontent
32-
from ietf.utils.mail import outbox
32+
from ietf.utils.mail import outbox, empty_outbox
3333
from ietf.utils.text import xslugify
3434

3535
from ietf.person.factories import PersonFactory
@@ -1997,3 +1997,24 @@ def test_meeting_requests(self):
19971997
self.assertEqual(r.status_code,200)
19981998
self.assertTrue(requested_session.group.acronym in unicontent(r))
19991999
self.assertTrue(not_meeting.group.acronym in unicontent(r))
2000+
2001+
def test_request_minutes(self):
2002+
meeting = MeetingFactory(type_id='ietf')
2003+
area = GroupFactory(type_id='area')
2004+
has_minutes = SessionFactory(meeting=meeting,group__parent=area)
2005+
has_no_minutes = SessionFactory(meeting=meeting,group__parent=area)
2006+
SessionPresentation.objects.create(session=has_minutes,document=DocumentFactory(type_id='minutes'))
2007+
2008+
empty_outbox()
2009+
url = urlreverse('ietf.meeting.views.request_minutes',kwargs={'num':meeting.number})
2010+
login_testing_unauthorized(self,"secretary",url)
2011+
r = self.client.get(url)
2012+
self.assertNotIn(has_minutes.group.acronym, unicontent(r).lower())
2013+
self.assertIn(has_no_minutes.group.acronym, unicontent(r).lower())
2014+
r = self.client.post(url,{'to':'wgchairs@ietf.org',
2015+
'cc': 'irsg@irtf.org',
2016+
'subject': 'I changed the subject',
2017+
'body': 'corpus',
2018+
})
2019+
self.assertEqual(r.status_code,302)
2020+
self.assertEqual(len(outbox),1)

ietf/meeting/urls.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
url(r'^week-view(?:.html)?/?$', views.week_view),
8484
url(r'^room-view(?:.html)?/?$', views.room_view),
8585
url(r'^materials(?:.html)?/?$', views.materials),
86+
url(r'^request_minutes/?$', views.request_minutes),
8687
url(r'^materials/%(document)s((?P<ext>\.[a-z0-9]+)|/)?$' % settings.URL_REGEXPS, views.materials_document),
8788
url(r'^session/?$', views.materials_editable_groups),
8889
url(r'^proceedings(?:.html)?/?$', views.proceedings),

ietf/meeting/views.py

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,14 @@
6363
from ietf.secr.proceedings.proc_utils import (get_progress_stats, post_process, import_audio_files,
6464
import_youtube_video_urls, create_recording)
6565
from ietf.utils.decorators import require_api_key
66-
from ietf.utils.mail import send_mail_message
66+
from ietf.utils.mail import send_mail_message, send_mail_text
6767
from ietf.utils.pipe import pipe
6868
from ietf.utils.pdf import pdf_pages
6969
from ietf.utils.text import xslugify
7070
from ietf.utils.validators import get_mime_type
7171

7272
from .forms import (InterimMeetingModelForm, InterimAnnounceForm, InterimSessionModelForm,
73-
InterimCancelForm, InterimSessionInlineFormSet, FileUploadForm)
73+
InterimCancelForm, InterimSessionInlineFormSet, FileUploadForm, RequestMinutesForm,)
7474

7575

7676
def get_menu_entries(request):
@@ -139,7 +139,7 @@ def materials(request, num=None):
139139
if date_list: setattr(event, 'last_update', sorted(date_list, reverse=True)[0])
140140

141141
return render(request, "meeting/materials.html", {
142-
'meeting_num': meeting.number,
142+
'meeting': meeting,
143143
'plenaries': plenaries,
144144
'ietf': ietf,
145145
'training': training,
@@ -2284,3 +2284,39 @@ def edit_timeslot_type(request, num, slot_id):
22842284
return render(request, 'meeting/edit_timeslot_type.html', {'timeslot':timeslot,'form':form,'sessions':sessions})
22852285

22862286

2287+
@role_required('Secretariat')
2288+
def request_minutes(request, num=None):
2289+
meeting = get_ietf_meeting(num)
2290+
if request.method=='POST':
2291+
form = RequestMinutesForm(data=request.POST)
2292+
if form.is_valid():
2293+
send_mail_text(request,
2294+
to=form.cleaned_data.get('to'),
2295+
frm=request.user.person.email_address(),
2296+
subject=form.cleaned_data.get('subject'),
2297+
txt=form.cleaned_data.get('body'),
2298+
cc=form.cleaned_data.get('cc'),
2299+
)
2300+
return HttpResponseRedirect(reverse('ietf.meeting.views.materials',kwargs={'num':num}))
2301+
else:
2302+
needs_minutes = set()
2303+
for a in meeting.agenda.assignments.filter(session__group__type_id__in=('wg','rg')):
2304+
if not a.session.all_meeting_minutes():
2305+
group = a.session.group
2306+
if group.parent and group.parent.type_id in ('area','irtf'):
2307+
needs_minutes.add(a.session.group)
2308+
needs_minutes = list(needs_minutes)
2309+
needs_minutes.sort(key=lambda g: ('zzz' if g.parent.acronym == 'irtf' else g.parent.acronym)+":"+g.acronym)
2310+
body_context = {'meeting':meeting,
2311+
'needs_minutes':needs_minutes,
2312+
'settings':settings,
2313+
}
2314+
body = render_to_string('meeting/request_minutes.txt', body_context)
2315+
initial = {'to': 'wgchairs@ietf.org',
2316+
'cc': 'irsg@irtf.org',
2317+
'subject': 'Request for IETF WG and Bof Session Minutes',
2318+
'body': body,
2319+
}
2320+
form = RequestMinutesForm(initial=initial)
2321+
context = {'meeting':meeting, 'form': form}
2322+
return render(request, 'meeting/request_minutes.html', context)

ietf/templates/meeting/materials.html

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@
1010

1111
{% block bodyAttrs %}data-spy="scroll" data-target="#affix"{% endblock %}
1212

13-
{% block title %}IETF {{ meeting_num }} preliminary &amp; interim materials{% endblock %}
13+
{% block title %}IETF {{ meeting.number }} preliminary &amp; interim materials{% endblock %}
1414

1515
{% block content %}
1616
{% origin %}
1717
<div class="row">
1818
<div class="col-md-10">
1919

20-
<h1>IETF {{ meeting_num }} meeting materials</h1>
20+
<h1>IETF {{ meeting.number }} meeting materials</h1>
2121

2222
{% if submission_started %}
2323
<p class="alert alert-info">
@@ -29,8 +29,11 @@ <h1>IETF {{ meeting_num }} meeting materials</h1>
2929
<p>
3030
{% if user|has_role:"Secretariat" %}
3131
<a class="btn btn-default" href="{% url 'ietf.secr.proceedings.views.main' %}">Secretariat proceedings functions</a>
32+
{% if meeting.end_date.today > meeting.end_date %}
33+
<a class="btn btn-default" href="{% url 'ietf.meeting.views.request_minutes' num=meeting.number %}">Send request for minutes</a>
34+
{% endif %}
3235
{% endif %}
33-
<a class="btn btn-default" href="/meeting/{{meeting_num}}/requests">Meeting requests/conflicts</a>
36+
<a class="btn btn-default" href="/meeting/{{meeting.number}}/requests">Meeting requests/conflicts</a>
3437
</p>
3538

3639
{% with "True" as show_agenda %}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{% extends "base.html" %}
2+
{# Copyright The IETF Trust 2018, All Rights Reserved #}
3+
{% load origin %}
4+
5+
{% load ietf_filters staticfiles bootstrap3 %}
6+
7+
{% block morecss %}
8+
#id_body {height:700px;}
9+
{% endblock %}
10+
11+
{% block title %}IETF {{ meeting.number }}: Request Minutes{% endblock %}
12+
13+
{% block content %}
14+
{% origin %}
15+
<div class="row">
16+
<div class="col-md-10">
17+
18+
<h1 class="title">IETF {{ meeting.number }}: Request Minutes <br>
19+
<small>{{meeting.city}}, {{meeting.country}} -- {{meeting.venue_name}}</small>
20+
</h1>
21+
</div>
22+
</div>
23+
<div class="row">
24+
<form method="post">
25+
{% csrf_token %}
26+
{% bootstrap_form form %}
27+
{% buttons %}
28+
<button type="submit" class="btn btn-danger">Send</button>
29+
{% endbuttons %}
30+
</form>
31+
</div>
32+
33+
{% endblock %}
34+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{% autoescape off %} Dear WG Chairs and BOF Chairs,
2+
3+
The secretariat is in the process of compiling the proceedings for {{meeting }}
4+
and we are still missing meeting minutes from various sessions.
5+
6+
The cutoff for submissions is {{ meeting.get_submission_cut_off_date }}, and the correction submissions
7+
cutoff is {{ meeting.get_submission_correction_date }}.
8+
9+
Please upload meeting minutes, as well as any presentations from your
10+
sessions, at your earliest convenience using the Meeting Materials Manager
11+
found here: {{ settings.IDTRACKER_BASE_URL }}{% url 'ietf.meeting.views.materials' num=meeting.number %}
12+
13+
Alternatively, you are welcome to send them to iesg-secretary@ietf.org for
14+
manual posting.
15+
16+
Groups that are missing minutes:{% for group in needs_minutes %}{% ifchanged group.parent %}
17+
18+
{{group.parent.name}}:{% endifchanged %}
19+
{{ group.acronym | upper }}{% if group.state_id == 'bof' %} (BoF){% endif %}{% endfor %}
20+
21+
{% endautoescape %}

0 commit comments

Comments
 (0)