Skip to content

Commit bc8e744

Browse files
committed
add view views.upcoming
- Legacy-Id: 10860
1 parent 8b87125 commit bc8e744

6 files changed

Lines changed: 289 additions & 1 deletion

File tree

ietf/meeting/test_data.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,32 @@ def make_meeting_test_data():
7777
doc.set_state(State.objects.get(type='reuse_policy',slug='single'))
7878
mars_session.sessionpresentation_set.add(SessionPresentation(session=mars_session,document=doc,rev=doc.rev))
7979

80+
# Future Interim Meetings
81+
date = datetime.date.today() + datetime.timedelta(days=365)
82+
mars_meeting = Meeting.objects.create(
83+
number="interim-%s-mars-1" % date.year,
84+
type_id='interim',
85+
date=date,
86+
city="New York",
87+
country="US",
88+
)
89+
mars_session = Session.objects.create(meeting=mars_meeting, group=mars,
90+
attendees=10, requested_by=system_person,
91+
requested_duration=20, status_id="sched",
92+
scheduled=datetime.datetime.now(),type_id="session")
93+
ames = Group.objects.get(acronym="ames")
94+
ames_meeting = Meeting.objects.create(
95+
number="interim-%s-ames-1" % date.year,
96+
type_id='interim',
97+
date=date,
98+
city="New York",
99+
country="US",
100+
)
101+
ames_session = Session.objects.create(meeting=ames_meeting, group=ames,
102+
attendees=10, requested_by=system_person,
103+
requested_duration=20, status_id="canceled",
104+
scheduled=datetime.datetime.now(),type_id="session")
105+
80106
return meeting
81107

82108

ietf/meeting/tests_views.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from pyquery import PyQuery
1010

1111
from ietf.doc.models import Document
12-
from ietf.meeting.models import Session, TimeSlot
12+
from ietf.meeting.models import Session, TimeSlot, Meeting
1313
from ietf.meeting.test_data import make_meeting_test_data
1414
from ietf.utils.test_utils import TestCase, login_testing_unauthorized, unicontent
1515

@@ -330,3 +330,24 @@ def test_slot_to_the_right(self):
330330
ames_slot_qs.update(time=mars_ends + datetime.timedelta(seconds=10 * 60))
331331
self.assertTrue(mars_slot.slot_to_the_right)
332332
self.assertTrue(mars_scheduled.slot_to_the_right)
333+
334+
class InterimTests(TestCase):
335+
def test_upcoming(self):
336+
make_meeting_test_data()
337+
r = self.client.get("/meeting/upcoming/")
338+
self.assertEqual(r.status_code, 200)
339+
today = datetime.date.today()
340+
mars_interim = Meeting.objects.filter(date__gt=today,type='interim',number__contains='mars').first()
341+
ames_interim = Meeting.objects.filter(date__gt=today,type='interim',number__contains='ames').first()
342+
self.assertTrue(mars_interim.number in r.content)
343+
self.assertTrue(ames_interim.number in r.content)
344+
# cancelled session
345+
q = PyQuery(r.content)
346+
self.assertTrue('CANCELLED' in q('[id*="-ames"]').text())
347+
348+
def test_upcoming_ics(self):
349+
make_meeting_test_data()
350+
r = self.client.get("/meeting/upcoming.ics/")
351+
self.assertEqual(r.status_code, 200)
352+
self.assertEqual(r.get('Content-Type'),"text/calendar")
353+

ietf/meeting/urls.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@
6565
# The optionals have to go first, otherwise the agenda/(owner)/(name)/ patterns match things they shouldn't
6666
url(r'^(?:(?P<num>\d+)/)?', include(type_ietf_only_patterns_id_optional)),
6767
url(r'^(?P<num>\d+)/', include(type_ietf_only_patterns)),
68+
url(r'^upcoming/$', views.upcoming),
69+
url(r'^upcoming.ics/$', views.ical_upcoming),
6870
url(r'^$', views.current_materials),
6971
]
7072

ietf/meeting/views.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -874,3 +874,36 @@ def sort_key(session):
874874
'can_manage_materials' : can_manage,
875875
'type_counter': type_counter,
876876
})
877+
878+
def ical_upcoming(request):
879+
'''ICAL upcoming meetings'''
880+
return HttpResponse()
881+
882+
def upcoming(request):
883+
'''List of upcoming meetings'''
884+
today = datetime.datetime.today()
885+
meetings = Meeting.objects.filter(date__gt=today)
886+
887+
# extract groups hierarchy
888+
seen = set()
889+
groups = [ m.session_set.first().group for m in meetings.filter(type='interim') ]
890+
group_parents = []
891+
for g in groups:
892+
if g.parent.acronym not in seen:
893+
group_parents.append(g.parent)
894+
seen.add(g.parent.acronym)
895+
896+
seen = set()
897+
for p in group_parents:
898+
p.group_list = []
899+
for g in groups:
900+
if g.acronym not in seen and g.parent == p:
901+
p.group_list.append(g)
902+
seen.add(g.acronym)
903+
904+
p.group_list.sort(key=lambda g: g.acronym)
905+
906+
return render(request, "meeting/upcoming.html",
907+
{ 'meetings':meetings,
908+
'group_parents':group_parents,
909+
})
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
2+
function toggle_visibility() {
3+
var h = window.location.hash;
4+
h = h.replace(/^#?,?/, '');
5+
6+
// reset UI elements to default state
7+
$(".pickview").removeClass("active disabled");
8+
$(".pickviewneg").addClass("active");
9+
10+
if (h) {
11+
// if there are items in the hash, hide all rows that are
12+
// hidden by default, show all rows that are shown by default
13+
$('[id^="row-"]').hide();
14+
//$.each($(".pickviewneg").text().trim().split(/ +/), function (i, v) {
15+
// v = v.trim().toLowerCase();
16+
// $('[id^="row-"]').filter('[id*="-' + v + '"]').show();
17+
//});
18+
19+
// show the customizer
20+
$("#customize").collapse("show");
21+
22+
// loop through the has items and change the UI element and row visibilities accordingly
23+
$.each(h.split(","), function (i, v) {
24+
if (v.indexOf("-") == 0) {
25+
// this is a "negative" item: when present, hide these rows
26+
v = v.replace(/^-/, '');
27+
$('[id^="row-"]').filter('[id*="-' + v + '"]').hide();
28+
$(".view." + v).find("button").removeClass("active disabled");
29+
$("button.pickviewneg." + v).removeClass("active");
30+
} else {
31+
// this is a regular item: when present, show these rows
32+
$('[id^="row-"]').filter('[id*="-' + v + '"]').show();
33+
$(".view." + v).find("button").addClass("active disabled");
34+
$("button.pickview." + v).addClass("active");
35+
}
36+
});
37+
38+
// show the week view
39+
//$("#weekview").attr("src", "week-view.html" + window.location.hash).removeClass("hidden");
40+
41+
// show the custom .ics link
42+
//$("#ical-link").attr("href",$("#ical-link").attr("href").split("?")[0]+"?"+h);
43+
//$("#ical-link").removeClass("hidden");
44+
45+
} else {
46+
// if the hash is empty, show all and hide weekview
47+
$('[id^="row-"]').show();
48+
//$("#ical-link, #weekview").addClass("hidden");
49+
}
50+
}
51+
52+
$(".pickview, .pickviewneg").click(function () {
53+
var h = window.location.hash;
54+
var item = $(this).text().trim().toLowerCase();
55+
if ($(this).hasClass("pickviewneg")) {
56+
item = "-" + item;
57+
}
58+
59+
re = new RegExp('(^|#|,)' + item + "(,|$)");
60+
if (h.match(re) == null) {
61+
if (h.replace("#", "").length == 0) {
62+
h = item;
63+
} else {
64+
h += "," + item;
65+
}
66+
h = h.replace(/^#?,/, '');
67+
} else {
68+
h = h.replace(re, "$2").replace(/^#?,/, '');
69+
}
70+
window.location.hash = h.replace(/^#$/, '');
71+
toggle_visibility();
72+
});
73+
74+
$(document).ready(function () {
75+
toggle_visibility();
76+
});
77+
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
{% extends "base.html" %}
2+
{# Copyright The IETF Trust 2015, All Rights Reserved #}
3+
{% load origin %}
4+
5+
{% load ietf_filters staticfiles %}
6+
7+
{% block pagehead %}
8+
<link rel="stylesheet" href="{% static "jquery.tablesorter/css/theme.bootstrap.min.css" %}">
9+
{% endblock %}
10+
11+
{% block bodyAttrs %}data-spy="scroll" data-target="#affix"{% endblock %}
12+
13+
{% block title %}IETF Upcoming Meetings{% endblock %}
14+
15+
{% block content %}
16+
{% origin %}
17+
<div class="row">
18+
<div class="col-md-10">
19+
20+
<h1>IETF Upcoming Meetings</h1>
21+
22+
<div class="panel-group" id="accordion">
23+
<div class="panel panel-default">
24+
<div class="panel-heading">
25+
<h4 class="panel-title">
26+
<a data-toggle="collapse" data-parent="#accordion" href="#customize">
27+
<span class="fa fa-caret-down"></span> Customize the meeting list...
28+
</a>
29+
</h4>
30+
</div> <!-- panel-heading -->
31+
32+
<div id="customize" class="panel-collapse collapse">
33+
<div class="panel-body">
34+
<p>
35+
You can customize the list to show only selected groups
36+
by clicking on groups and areas in the table below.
37+
To be able to return to the customized view later, bookmark the resulting URL.
38+
</p>
39+
40+
{% if group_parents|length %}
41+
<p>Groups displayed in <b><i>italics</i></b> are BOFs.</p>
42+
43+
<table class="table table-condensed">
44+
<thead>
45+
<tr>
46+
{% for p in group_parents %}
47+
<th style="width:{% widthratio 1 group_parents|length 100 %}%">
48+
<button class="btn btn-default btn-block pickview {{p.acronym|lower}}">{{p.acronym|upper}}</button>
49+
</th>
50+
{% endfor %}
51+
</tr>
52+
</thead>
53+
<tbody>
54+
<tr>
55+
{% for p in group_parents %}
56+
<td class="view {{p.acronym|lower}}">
57+
<div class="btn-group-vertical btn-block">
58+
{% for group in p.group_list %}
59+
<div class="btn-group btn-group-xs btn-group-justified">
60+
<button class="btn btn-default pickview {{group.acronym}}">
61+
{% if group.is_bof %}
62+
<i>{{group.acronym}}</i>
63+
{% else %}
64+
{{group.acronym}}
65+
{% endif %}
66+
</button>
67+
</div> <!-- button-group -->
68+
{% endfor %}
69+
</div> <!-- button-group-vertical -->
70+
</td>
71+
{% endfor %}
72+
</tr>
73+
</tbody>
74+
</table>
75+
{% else %}
76+
<blockquote><i>No meetings have been scheduled yet.</i></blockquote>
77+
{% endif %}
78+
79+
</div> <!-- panel-body -->
80+
</div> <!-- panel-collapse -->
81+
</div> <!-- panel -->
82+
</div> <!-- panel-group -->
83+
84+
{% if meetings %}
85+
<h3></h3>
86+
<table class="table table-condensed table-striped tablesorter">
87+
<thead>
88+
<tr>
89+
<th>Date</th>
90+
<th>Group</th>
91+
<th>Name</th>
92+
</tr>
93+
</thead>
94+
<tbody>
95+
{% for meeting in meetings %}
96+
{% if meeting.type.slug == 'interim' %}
97+
<tr id="row-{{ forloop.counter }}-{{ meeting.session_set.all.0.group.acronym }}">
98+
{% else %}
99+
<tr id="row-{{ forloop.counter }}-ietf">
100+
{% endif %}
101+
<td>{{ meeting.date }}</td>
102+
{% if meeting.type.slug == 'interim' %}
103+
<td>{{ meeting.session_set.all.0.group.acronym }}</td>
104+
{% else %}
105+
<td>ietf</td>
106+
{% endif %}
107+
<td>
108+
{% if meeting.type.slug == "interim" %}
109+
<a href="{% url 'ietf.meeting.views.session_details' num=meeting.number acronym=meeting.session_set.all.0.group.acronym %}">{{ meeting.number }}{% if meeting.session_set.all.0.status.slug == "canceled" %} -- CANCELLED --{% endif %}</a>
110+
{% else %}
111+
<a href="{% url 'ietf.meeting.views.agenda' num=meeting.number %}">IETF - {{ meeting.number }}</a>
112+
{% endif %}
113+
</td>
114+
</tr>
115+
{% endfor %}
116+
</tbody>
117+
</table>
118+
{% else %}
119+
<h3>No upcoming meetings</h3>
120+
{% endif %}
121+
122+
</div>
123+
</div>
124+
{% endblock %}
125+
126+
{% block js %}
127+
<script src="{% static "jquery.tablesorter/js/jquery.tablesorter.combined.min.js" %}"></script>
128+
<script src="{% static 'ietf/js/toggle-visibility.js' %}"></script>
129+
{% endblock %}

0 commit comments

Comments
 (0)