Add the poi detail and poi list table
[infos-pratiques:etalage.git] / poiscasse / controllers.py
1 # -*- coding: utf-8 -*-
2
3
4 # PoisCasse -- Open Data POIs portal
5 # By: Emmanuel Raviart <eraviart@easter-eggs.com>
6 #     Romain Soufflet <rsoufflet@easter-eggs.com>
7 #
8 # Copyright (C) 2011 Easter-eggs
9 # http://gitorious.org/infos-pratiques/poiscasse
10 #
11 # This file is part of PoisCasse.
12 #
13 # PoisCasse is free software; you can redistribute it and/or modify
14 # it under the terms of the GNU Affero General Public License as
15 # published by the Free Software Foundation, either version 3 of the
16 # License, or (at your option) any later version.
17 #
18 # PoisCasse is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 # GNU Affero General Public License for more details.
22 #
23 # You should have received a copy of the GNU Affero General Public License
24 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
25
26
27 """Controllers for territories"""
28
29
30 import itertools
31 import logging
32
33 from biryani import strings
34 from territoria2 import territories
35
36 from . import contexts, conf, conv, model, pois, ramdb, templates, urls, wsgihelpers
37
38
39 log = logging.getLogger(__name__)
40
41
42 @wsgihelpers.wsgify
43 def about(req):
44     ctx = contexts.Ctx(req)
45     return templates.render(ctx, '/about.mako')
46
47
48 @wsgihelpers.wsgify
49 @ramdb.ramdb_based
50 def index(req):
51     ctx = contexts.Ctx(req)
52
53     params = req.GET
54     params = dict(
55         category = params.get('category'),
56         page = params.get('page'),
57         term = params.get('term'),
58         territory = params.get('territory'),
59         )
60
61     category, error = conv.str_to_slug(params['category'], state = ctx)
62     if error is not None:
63         raise wsgihelpers.not_found(ctx, explanation = ctx._('Category Error: {0}').format(error))
64
65     page_number, error = conv.pipe(
66         conv.str_to_int,
67         conv.make_greater_or_equal(1),
68         conv.default(1),
69         )(params['page'], state = ctx)
70     if error is not None:
71         raise wsgihelpers.not_found(ctx, explanation = ctx._('Page Number Error: {0}').format(error))
72
73     term, error = conv.str_to_slug(params['term'], state = ctx)
74     if error is not None:
75         raise wsgihelpers.not_found(ctx, explanation = ctx._('Research Terms Error: {0}').format(error))
76
77     ctx.postal_distribution, error = conv.str_to_postal_distribution(params['territory'], state = ctx)
78     if error is not None:
79         raise wsgihelpers.not_found(ctx, explanation = ctx._('Territory Error: {0}').format(error))
80     elif ctx.postal_distribution:
81         found_territories = list(territories.Territory.find({
82             'main_postal_distribution.postal_code': ctx.postal_distribution[0],
83             'main_postal_distribution.postal_routing': ctx.postal_distribution[1],
84             }).limit(2))
85         if not found_territories:
86             error = u'Territoire inconnu'
87             raise wsgihelpers.not_found(ctx, explanation = ctx._('Territory Error: {0}').format(error))
88         elif len(found_territories) > 1:
89             error = u'Territoire ambigu'
90             raise wsgihelpers.not_found(ctx, explanation = ctx._('Territory Error: {0}').format(error))
91         else:
92             territory_dict = found_territories[0].new_kind_code()
93             territory_kind_code = (territory_dict['kind'], territory_dict['code'])
94     else:
95         territory_kind_code = None
96
97     page_size = 20
98     pois_infos = []
99     for poi_id in itertools.islice(
100             ramdb.iter_pois_id(category_slug = category, term = term, territory_kind_code = territory_kind_code),
101             (page_number - 1) * page_size,
102             page_number * page_size,
103             ):
104         poi = ramdb.ram_pois_by_id[poi_id]
105         pois_infos.append(dict(
106             _id = poi._id,
107             geo = poi.geo,
108             name = poi.name,
109             ))
110
111     return templates.render(ctx, '/index.mako',
112         category = category,
113         page_number = page_number,
114         page_size = page_size,
115         pois_count = len(ramdb.ram_pois_by_id),
116         term = params['term'],
117         pois_infos = pois_infos,
118         )
119
120
121 def make_router():
122     """Return a WSGI application that dispatches requests to controllers """
123     return urls.make_router(
124         ('GET', '^/?$', index),
125         ('GET', '^/a-propos/?$', about),
126         ('GET', '^/poi/(?P<poi_id>[a-z0-9]{24})/?$', poi),
127         )
128
129
130 @wsgihelpers.wsgify
131 @ramdb.ramdb_based
132 def poi(req):
133     ctx = contexts.Ctx(req)
134
135     params = req.params
136     params = dict(
137         poi_id = req.urlvars.get('poi_id'),
138         )
139
140     poi_id, error = conv.str_to_object_id(params['poi_id'], ctx)
141     if error is not None:
142         raise wsgihelpers.not_found(ctx, explanation = ctx._('Poi ID Error: {0}').format(error))
143
144     poi = pois.Poi.find_one({"_id": poi_id})
145     return templates.render(ctx, '/poi.mako', poi = poi)
146
147
148 @wsgihelpers.wsgify
149 @ramdb.ramdb_based
150 def territory(req):
151     ctx = contexts.Ctx(req)
152
153     params = req.GET
154     params = dict(
155         postal_distribution = req.urlvars.get('postal_distribution'),
156         type = req.urlvars.get('type'),
157         )
158
159     territory_kind, error = conv.pipe(
160         conv.str_to_slug,
161         conv.slug_plural_fr_to_territory_kind,
162         conv.exists,
163         )(params['type'], state = ctx)
164     if error is not None:
165         raise wsgihelpers.not_found(ctx, explanation = ctx._('Territory Type Error: {0}').format(error))
166
167     territory, error = conv.pipe(
168         conv.str_to_postal_distribution,
169         conv.make_postal_distribution_to_territory_id(guess = True, kinds = [territory_kind]),
170         conv.id_to_territory,
171         conv.exists,
172         )(params['postal_distribution'], state = ctx)
173     if error is not None:
174         raise wsgihelpers.not_found(ctx, explanation = ctx._('Territory Error: {0}').format(error))
175
176     territory_full_url = urls.get_full_url(ctx, territory.ref)
177     if req.url != territory_full_url:
178         raise wsgihelpers.redirect(ctx, location = territory_full_url)
179
180     return templates.render(ctx, '/territory.mako', territory = territory)
181