Skip to content
This repository was archived by the owner on Sep 5, 2019. It is now read-only.

Commit 9631940

Browse files
author
Marc Sommerhalder
committed
Adds location filters for events
1 parent 66ac353 commit 9631940

File tree

11 files changed

+123
-46
lines changed

11 files changed

+123
-46
lines changed

HISTORY.rst

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
Changelog
22
---------
33

4+
- Adds location filters for events.
5+
[msom]
6+
47
0.45.0 (2018-12-07)
58
~~~~~~~~~~~~~~~~~~~
69

onegov/org/forms/settings.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from lxml import etree
44
from onegov.form import Form
55
from onegov.form import with_options
6-
from onegov.form.fields import MultiCheckboxField
6+
from onegov.form.fields import MultiCheckboxField, TagsField
77
from onegov.form.validators import Stdnum
88
from onegov.gis import CoordinatesField
99
from onegov.org import _
@@ -194,6 +194,11 @@ class SettingsForm(Form):
194194
],
195195
)
196196

197+
event_locations = TagsField(
198+
label=_("Values of the location filter"),
199+
fieldset=_("Events"),
200+
)
201+
197202
default_map_view = CoordinatesField(
198203
label=_("The default map view. This should show the whole town"),
199204
render_kw={
@@ -224,6 +229,9 @@ class SettingsForm(Form):
224229
# common.js for more information (search for footer)
225230
footer_height = HiddenField()
226231

232+
def on_request(self):
233+
self.request.include('tags-input')
234+
227235
def validate_homepage_structure(self, field):
228236
if field.data:
229237
try:

onegov/org/locale/de_CH/LC_MESSAGES/onegov.org.po

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
msgid ""
22
msgstr ""
33
"Project-Id-Version: PACKAGE 1.0\n"
4-
"POT-Creation-Date: 2018-12-06 14:53+0100\n"
5-
"PO-Revision-Date: 2018-12-06 14:53+0100\n"
4+
"POT-Creation-Date: 2018-12-08 11:01+0100\n"
5+
"PO-Revision-Date: 2018-12-08 11:01+0100\n"
66
"Last-Translator: Marc Sommerhalder <[email protected]>\n"
77
"Language-Team: German\n"
88
"Language: de_CH\n"
@@ -1045,6 +1045,9 @@ msgstr "Startseiten Weiterleitung"
10451045
msgid "Hide these fields for non-logged-in users"
10461046
msgstr "Diese Felder für nicht angemeldete Benutzer ausblenden"
10471047

1048+
msgid "Values of the location filter"
1049+
msgstr "Werte des Ortfilters"
1050+
10481051
msgid "The default map view. This should show the whole town"
10491052
msgstr "Die Standard Kartenansicht. Diese sollte die ganze Gemeinde zeigen."
10501053

@@ -2212,6 +2215,9 @@ msgstr ""
22122215
"die Anfrage zu übermitteln. Wenn Sie Änderungen vornehmen möchten, klicken "
22132216
"Sie auf \"Bearbeiten\" um zum Formular zurückzukehren."
22142217

2218+
msgid "Tag"
2219+
msgstr "Schlagwort"
2220+
22152221
msgid "Export these events"
22162222
msgstr "Diese Termine exportieren"
22172223

onegov/org/locale/fr_CH/LC_MESSAGES/onegov.org.po

+8-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
msgid ""
33
msgstr ""
44
"Project-Id-Version: PACKAGE 1.0\n"
5-
"POT-Creation-Date: 2018-12-06 14:53+0100\n"
6-
"PO-Revision-Date: 2018-12-06 14:53+0100\n"
5+
"POT-Creation-Date: 2018-12-08 11:01+0100\n"
6+
"PO-Revision-Date: 2018-12-08 11:02+0100\n"
77
"Last-Translator: Marc Sommerhalder <[email protected]>\n"
88
"Language-Team: French\n"
99
"Language: fr_CH\n"
@@ -1047,6 +1047,9 @@ msgstr "Redirection vers la page d'accueil"
10471047
msgid "Hide these fields for non-logged-in users"
10481048
msgstr "Masquer ces champs pour les utilisateurs non connectés"
10491049

1050+
msgid "Values of the location filter"
1051+
msgstr "Valeurs du filtre de localisation"
1052+
10501053
msgid "The default map view. This should show the whole town"
10511054
msgstr "La vue par défaut de la carte. Cela devrait montrer la ville entière"
10521055

@@ -2218,6 +2221,9 @@ msgstr ""
22182221
"processus. S'il y a quelque chose que vous souhaitez modifier, cliquez sur « "
22192222
"Modifier » pour retourner sur le formulaire complété."
22202223

2224+
msgid "Tag"
2225+
msgstr "Étiquette"
2226+
22212227
msgid "Export these events"
22222228
msgstr "Exporter ces événements"
22232229

onegov/org/models/organisation.py

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class Organisation(Base, TimestampMixin):
5757
locales = meta_property()
5858
redirect_homepage_to = meta_property()
5959
hidden_people_fields = meta_property(default=list)
60+
event_locations = meta_property(default=list)
6061
geo_provider = meta_property(default='geo-mapbox')
6162

6263
@contact.setter

onegov/org/path.py

+19-5
Original file line numberDiff line numberDiff line change
@@ -352,12 +352,26 @@ def get_resource_move(app, key, subject, direction, target):
352352
session, resource, subject, target, direction)
353353

354354

355-
@OrgApp.path(model=OccurrenceCollection, path='/events',
356-
converters=dict(start=extended_date_converter,
357-
end=extended_date_converter, tags=[]))
358-
def get_occurrences(app, page=0, range=None, start=None, end=None, tags=None):
355+
@OrgApp.path(
356+
model=OccurrenceCollection, path='/events',
357+
converters=dict(
358+
start=extended_date_converter,
359+
end=extended_date_converter,
360+
tags=[],
361+
locations=[]
362+
)
363+
)
364+
def get_occurrences(
365+
app, page=0, range=None, start=None, end=None, tags=None, locations=None
366+
):
359367
return OccurrenceCollection(
360-
app.session(), page=page, range=range, start=start, end=end, tags=tags
368+
app.session(),
369+
page=page,
370+
range=range,
371+
start=start,
372+
end=end,
373+
tags=tags,
374+
locations=locations
361375
)
362376

363377

onegov/org/templates/macros.pt

+1-1
Original file line numberDiff line numberDiff line change
@@ -788,7 +788,7 @@
788788
<div class="occurrence-time" tal:define="time layout.format_time_range(occurrence.localized_start, occurrence.localized_end)">
789789
${time[0].upper()}${time[1:]}
790790
</div>
791-
<div><span tal:repeat="tag occurrence.tags" class="blank-label" i18n:translate>${tag}</span></div>
791+
<div class="occurrence-tags"><span tal:repeat="tag occurrence.tags" class="blank-label" i18n:translate>${tag}</span></div>
792792
</div>
793793
<div class="clearfix"></div>
794794
</div>

onegov/org/templates/occurrences.pt

+17-2
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020

2121
<div class="large-4 medium-4 columns">
2222

23-
<div class="tag-filters borderless-side-panel">
24-
<h2 i18n:translate>Tags</h2>
23+
<div class="tag-filters borderless-side-panel" tal:condition="tags">
24+
<h2 i18n:translate>Tag</h2>
2525
<div class="occurrences-filter-tags">
2626
<tal:b tal:repeat="tag tags">
2727
<span class="blank-label ${tag.active and 'active' or ''}">
@@ -31,6 +31,21 @@
3131
</div>
3232
</div>
3333

34+
<div class="location-filters borderless-side-panel" tal:condition="locations">
35+
<h2 i18n:translate>Location</h2>
36+
<div class="occurrences-filter-locations">
37+
<div class="filter-panel">
38+
<ul class="tags">
39+
<li tal:repeat="location locations">
40+
<span class="blank-label ${location.active and 'active' or ''}">
41+
<tal:b replace="structure location(request)"></tal:b>
42+
</span>
43+
</li>
44+
</ul>
45+
</div>
46+
</div>
47+
</div>
48+
3449
<div class="date-filters borderless-side-panel">
3550
<h2 i18n:translate>Date</h2>
3651
<div class="occurrences-filter-ranges">

onegov/org/tests/test_views.py

+41-14
Original file line numberDiff line numberDiff line change
@@ -2181,57 +2181,70 @@ def test_cleanup_allocations(client):
21812181

21822182

21832183
def test_view_occurrences(client):
2184+
client.login_admin()
2185+
settings = client.get('/settings')
2186+
settings.form['event_locations'] = [
2187+
"Gemeindesaal", "Sportanlage", "Turnhalle"
2188+
]
2189+
settings.form.submit()
2190+
client.logout()
21842191

21852192
def events(query=''):
21862193
page = client.get(f'/events/?{query}')
21872194
return [event.text for event in page.pyquery('h3 a')]
21882195

21892196
def dates(query=''):
21902197
page = client.get(f'/events/?{query}')
2191-
return [datetime.strptime(div.text, '%d.%m.%Y').date() for div
2192-
in page.pyquery('.occurrence-date')]
2198+
return [
2199+
datetime.strptime(div.text, '%d.%m.%Y').date()
2200+
for div in page.pyquery('.occurrence-date')
2201+
]
21932202

21942203
def tags(query=''):
21952204
page = client.get(f'/events/?{query}')
2196-
tags = [tag.text.strip() for tag in page.pyquery('.blank-label')]
2197-
return list(set([tag for tag in tags if tag]))
2205+
tags = [s.text.strip() for s in page.pyquery('.occurrence-tags span')]
2206+
return list(set(tags))
21982207

21992208
def as_json(query=''):
22002209
return client.get(f'/events/json?{query}').json
22012210

22022211
assert len(events()) == 10
22032212
assert len(events('page=1')) == 2
22042213
assert dates() == sorted(dates())
2205-
assert len(as_json()) == 12
2206-
assert len(as_json('max=3')) == 3
22072214

2215+
# Test tags
22082216
query = 'tags=Party'
22092217
assert tags(query) == ["Party"]
22102218
assert events(query) == ["150 Jahre Govikon"]
2211-
assert len(as_json('cat1=Party')) == 1
2212-
assert len(as_json('cat1=Party&cat2=Sportanlage')) == 1
22132219

22142220
query = 'tags=Politics'
22152221
assert tags(query) == ["Politik"]
22162222
assert events(query) == ["Generalversammlung"]
2217-
assert len(as_json('cat1=Politics')) == 1
2218-
assert len(as_json('cat2=Saal')) == 1
22192223

22202224
query = 'tags=Sports'
22212225
assert tags(query) == ["Sport"]
22222226
assert len(events(query)) == 10
22232227
assert set(events(query)) == set(["Gemeinsames Turnen", "Fussballturnier"])
2224-
assert len(as_json('cat1=Sports')) == 10
2225-
assert len(as_json('cat2=Turnhalle&cat2=Sportanlage')) == 11
22262228

22272229
query = 'tags=Politics&tags=Party'
22282230
assert sorted(tags(query)) == ["Party", "Politik"]
22292231
assert len(events(query)) == 2
22302232
assert set(events(query)) == set(["150 Jahre Govikon",
22312233
"Generalversammlung"])
2232-
assert len(as_json('cat1=Politics&cat1=Party')) == 2
2233-
assert len(as_json('max=1&cat1=Politics&cat1=Party')) == 1
22342234

2235+
# Test locations
2236+
query = 'locations=Sportanlage'
2237+
assert sorted(events(query)) == ["150 Jahre Govikon", "Fussballturnier"]
2238+
2239+
query = 'locations=Gemeindesaal&locations=Turnhalle'
2240+
assert sorted(set(events(query))) == [
2241+
"Gemeinsames Turnen", "Generalversammlung"
2242+
]
2243+
2244+
query = 'locations=halle'
2245+
assert events(query) == []
2246+
2247+
# Test dates
22352248
unique_dates = sorted(set(dates()))
22362249

22372250
query = 'start={}'.format(unique_dates[1].isoformat())
@@ -2265,6 +2278,20 @@ def as_json(query=''):
22652278
query = 'range=weekend&start={}'.format(unique_dates[-2].isoformat())
22662279
assert len(events(query)) == 1
22672280

2281+
# Test JSON
2282+
assert len(as_json()) == 12
2283+
assert len(as_json('max=3')) == 3
2284+
assert len(as_json('cat1=Party')) == 1
2285+
assert len(as_json('cat1=Party&cat2=Sportanlage')) == 1
2286+
assert len(as_json('cat1=Politics')) == 1
2287+
assert len(as_json('cat2=Gemeindesaal')) == 1
2288+
assert len(as_json('cat2=saal')) == 0
2289+
assert len(as_json('cat1=Sports')) == 10
2290+
assert len(as_json('cat2=Turnhalle&cat2=Sportanlage')) == 11
2291+
assert len(as_json('cat1=Politics&cat1=Party')) == 2
2292+
assert len(as_json('max=1&cat1=Politics&cat1=Party')) == 1
2293+
2294+
# Test iCal
22682295
assert client.get('/events/').click('Diese Termine exportieren').\
22692296
text.startswith('BEGIN:VCALENDAR')
22702297

onegov/org/views/occurrence.py

+15-18
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
from onegov.org.layout import OccurrenceLayout, OccurrencesLayout
1313
from onegov.ticket import TicketCollection
1414
from sedate import as_datetime, replace_timezone
15-
from sqlalchemy import or_
16-
from sqlalchemy.dialects.postgresql import array
1715
from sqlalchemy.orm import joinedload
1816

1917

@@ -29,13 +27,21 @@ def view_occurrences(self, request):
2927
]
3028
translated_tags.sort(key=lambda i: i[1])
3129

32-
tags = (
30+
tags = [
3331
Link(
3432
text=translation,
3533
url=request.link(self.for_filter(tag=tag)),
3634
active=tag in self.tags and 'active' or ''
3735
) for tag, translation in translated_tags
38-
)
36+
]
37+
38+
locations = [
39+
Link(
40+
text=location,
41+
url=request.link(self.for_filter(location=location)),
42+
active=location in self.locations and 'active' or ''
43+
) for location in request.app.org.event_locations
44+
]
3945

4046
ranges = [
4147
Link(
@@ -73,6 +79,7 @@ def view_occurrences(self, request):
7379
'start': self.start.isoformat() if self.start else '',
7480
'ranges': ranges,
7581
'tags': tags,
82+
'locations': locations,
7683
'title': _('Events'),
7784
}
7885

@@ -190,20 +197,10 @@ def json_export_occurences(self, request):
190197
def cors(response):
191198
response.headers.add('Access-Control-Allow-Origin', '*')
192199

193-
query = self.query()
194-
195-
tags = request.params.getall('cat1')
196-
if tags:
197-
query = query.filter(Occurrence._tags.has_any(array(tags)))
198-
199-
locations = request.params.getall('cat2')
200-
if locations:
201-
query = query.filter(
202-
or_(*[
203-
Occurrence.location.ilike(f'%{location}%')
204-
for location in locations
205-
])
206-
)
200+
query = self.for_filter(
201+
tags=request.params.getall('cat1'),
202+
locations=request.params.getall('cat2')
203+
).query()
207204

208205
limit = request.params.get('max')
209206
if limit and limit.isdigit():

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def get_long_description():
4040
'onegov.chat',
4141
'onegov.core>=0.41.0',
4242
'onegov.directory>=0.4.1',
43-
'onegov.event>=1.0.0',
43+
'onegov.event>=1.1.0',
4444
'onegov.file>=0.2.1',
4545
'onegov.form>=0.18.0',
4646
'onegov.foundation>=0.0.7',

0 commit comments

Comments
 (0)