source: osmose-frontend/errors.py @ 184d4e1

Last change on this file since 184d4e1 was 184d4e1, checked in by Frédéric Rodrigo <frodrigo@…>, 7 years ago

Fix deal with empty source param on /errors/

  • Property mode set to 100644
File size: 8.3 KB
Line 
1#! /usr/bin/env python
2#-*- coding: utf-8 -*-
3
4###########################################################################
5##                                                                       ##
6## Copyrights Etienne Chové <chove@crans.org> 2009                       ##
7##                                                                       ##
8## This program is free software: you can redistribute it and/or modify  ##
9## it under the terms of the GNU General Public License as published by  ##
10## the Free Software Foundation, either version 3 of the License, or     ##
11## (at your option) any later version.                                   ##
12##                                                                       ##
13## This program is distributed in the hope that it will be useful,       ##
14## but WITHOUT ANY WARRANTY; without even the implied warranty of        ##
15## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         ##
16## GNU General Public License for more details.                          ##
17##                                                                       ##
18## You should have received a copy of the GNU General Public License     ##
19## along with this program.  If not, see <http://www.gnu.org/licenses/>. ##
20##                                                                       ##
21###########################################################################
22
23from bottle import route, request, template, response, abort, redirect
24from tools import utils
25import StringIO, re
26
27import errors_graph
28
29
30def int_list(s):
31    return map(lambda x: int(x), filter(lambda x: x and x!='',s).split(','))
32
33@route('/errors/graph.png')
34def graph(db):
35    class options:
36        sources = request.params.get('sources', type=int_list, default=[])
37        classes = request.params.get('class', type=int_list, default=[])
38        items   = request.params.get('item', type=int_list, default=[])
39        country = request.params.get('country')
40        if country <> None and not re.match(r"^([a-z_]+)$", country):
41            country = None
42
43    try:
44        data = errors_graph.make_plt(db, options)
45        response.content_type = "image/png"
46        return data
47    except Exception, e:
48        response.content_type = "text/plain"
49        import traceback
50        out = StringIO.StringIO()
51        traceback.print_exc(file=out)
52        return out.getvalue() + "\n"
53
54
55@route('/errors')
56def index_redirect():
57    redirect("errors/")
58
59
60@route('/errors/')
61@route('/errors/done')
62@route('/errors/false-positive')
63def index(db, lang):
64    source  = request.params.get('source', type=int)
65    class_  = request.params.get('class', type=int)
66    item    = request.params.get('item', type=int)
67    country = request.params.get('country')
68    num_points = request.params.get('points', type=int)
69    show_all = request.params.get('all')
70
71    if country == '':
72        country = None
73    if country and not re.match(r"^([a-z_]+)$", country):
74        country = None
75
76    if num_points <= 0:
77        num_points = None
78    elif num_points > 10000:
79        num_points = 10000
80
81    if request.path.endswith("false-positive"):
82        title = _("False positives")
83        gen = "false-positive"
84        default_show_all = False
85    elif request.path.endswith("done"):
86        title = _("Fixed errors")
87        gen = "done"
88        default_show_all = False
89    else:
90        title = _("Informations")
91        gen = "info"
92        default_show_all = True
93
94    if show_all == None:
95        show_all = default_show_all
96    elif int(show_all) == 0:
97        show_all = False
98    else:
99        show_all = True
100
101    sql = """
102    SELECT DISTINCT
103        (string_to_array(comment,'-'))[array_upper(string_to_array(comment,'-'), 1)] AS country
104    FROM
105        dynpoi_source
106    ORDER BY
107        country
108    """
109    db.execute(sql)
110    countries = db.fetchall()
111
112    sql = """
113    SELECT
114        item,
115        menu
116    FROM
117        dynpoi_item
118    ORDER BY
119        item
120    """
121    db.execute(sql)
122    items = db.fetchall()
123
124    sql = """
125    SELECT
126        dynpoi_class.source AS source,
127        dynpoi_class.class AS class,
128        dynpoi_class.item AS item,
129        first(dynpoi_item.menu) AS menu,
130        first(dynpoi_class.title) AS title,
131        %s AS count,
132        dynpoi_source.comment AS source_comment
133    FROM
134        dynpoi_class
135        LEFT JOIN dynpoi_item ON
136            dynpoi_class.item = dynpoi_item.item
137        LEFT JOIN dynpoi_source ON
138            dynpoi_class.source = dynpoi_source.source
139        %s %s
140    WHERE 1=1
141        %s
142    GROUP BY
143        dynpoi_class.source,
144        dynpoi_class.class,
145        dynpoi_class.item,
146        dynpoi_source.comment
147    ORDER BY
148        dynpoi_class.item,
149        dynpoi_class.source
150    """
151
152    if show_all:
153        opt_left_join = "LEFT"
154    else:
155        opt_left_join = ""
156
157    if gen == "info":
158        opt_count = "count(marker.source)"
159        opt_join = """
160        JOIN marker ON
161            dynpoi_class.source = marker.source AND
162            dynpoi_class.class = marker.class
163        """
164    elif gen == "false-positive":
165        opt_count = "count(dynpoi_status.source)"
166        opt_join = """
167        JOIN dynpoi_status ON
168            dynpoi_class.source = dynpoi_status.source AND
169            dynpoi_class.class = dynpoi_status.class AND
170            dynpoi_status.status = 'false'
171        """
172    elif gen == "done":
173        opt_count = "count(dynpoi_status.source)"
174        opt_join = """
175        JOIN dynpoi_status ON
176            dynpoi_class.source = dynpoi_status.source AND
177            dynpoi_class.class = dynpoi_status.class AND
178            dynpoi_status.status = 'done'
179        """
180
181    opt_where = ""
182
183    if source <> None:
184        opt_where += " AND dynpoi_class.source = %s" % source
185    if class_ <> None:
186        opt_where += " AND dynpoi_class.class = %s" % class_
187    if item <> None:
188        opt_where += " AND dynpoi_class.item = %s" % item
189    if country <> None:
190        opt_where += " AND dynpoi_source.comment LIKE '%%%s'" % ("-" + country)
191
192    if source == None and item == None and country == None:
193        if show_all:
194            opt_count = "-1"
195            if gen == "info":
196                opt_left_join = ""
197                opt_join = ""
198
199    sql = sql % (opt_count, opt_left_join, opt_join, opt_where)
200
201    db.execute(sql)
202    errors_groups = db.fetchall()
203    total = 0
204    for res in errors_groups:
205        if res["count"] != -1:
206            total += res["count"]
207
208    if (total > 0 and total < 1000) or num_points:
209        if gen == "info":
210            opt_count = "count(marker.source)"
211            opt_join = """
212            JOIN marker ON
213                dynpoi_class.source = marker.source AND
214                dynpoi_class.class = marker.class
215            """
216
217        sql = """
218        SELECT
219            %s
220            dynpoi_class.source AS source,
221            dynpoi_class.class AS class,
222            dynpoi_class.item AS item,
223            dynpoi_class.level AS level,
224            dynpoi_item.menu,
225            dynpoi_class.title,
226            subtitle,
227            dynpoi_source.comment AS source_comment,
228            subclass,
229            lat,
230            lon,
231            elems AS elems,
232            %s AS date
233        FROM
234            dynpoi_class
235            LEFT JOIN dynpoi_item ON
236                dynpoi_class.item = dynpoi_item.item
237            LEFT JOIN dynpoi_source ON
238                dynpoi_class.source = dynpoi_source.source
239            %s
240        WHERE 1=1
241            %s
242        ORDER BY
243            %s
244            dynpoi_class.item,
245            dynpoi_class.source
246        """
247
248        if gen == "info":
249            marker_id = "marker.id AS marker_id,"
250            opt_date = "-1"
251            opt_order = "subtitle->'en',"
252        elif gen in ("false-positive", "done"):
253            marker_id = ""
254            opt_date = "date"
255            opt_order = "dynpoi_status.date DESC,"
256        if num_points:
257            sql += "LIMIT %d" % num_points
258
259        sql = sql % ((marker_id, ) + (opt_date, opt_join, opt_where, opt_order))
260        db.execute(sql)
261        errors = db.fetchall()
262    else:
263        opt_date = None
264        errors = None
265
266    return template('errors/index', countries=countries, items=items, errors_groups=errors_groups, total=total, errors=errors, query=request.query_string, country=country, item=item, translate=utils.translator(lang), gen=gen, opt_date=opt_date, title=title)
Note: See TracBrowser for help on using the repository browser.