source: osmose-frontend/errors_graph.py @ 7f3b062

Last change on this file since 7f3b062 was 7f3b062, checked in by Jocelyn Jaubert <jocelyn.jaubert@…>, 7 years ago

Fix graph generation

  • Property mode set to 100644
File size: 6.7 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
23import time, sys, datetime, os, commands
24
25
26def get_data(db, options):
27    sql =  "SELECT dynpoi_stats.source, dynpoi_stats.class, dynpoi_stats.timestamp, dynpoi_stats.count "
28    sql += "FROM dynpoi_stats %s "
29    sql += "WHERE 1=1 %s "
30    sql += "ORDER BY timestamp"
31
32    join_item = ""
33    where_sql = ""
34
35    if len(options.items)==1:
36       join_item += "JOIN dynpoi_class ON dynpoi_stats.source = dynpoi_class.source AND dynpoi_stats.class = dynpoi_class.class "
37       where_sql += "AND dynpoi_class.item=%d " % options.items[0]
38    elif len(options.items)>=1:
39       join_item += "JOIN dynpoi_class ON dynpoi_stats.source = dynpoi_class.source AND dynpoi_stats.class = dynpoi_class.class "
40       where_sql += "AND dynpoi_class.item in (%s) " % convIntsToStr(options.items)
41
42    if len(options.classes)==1:
43       where_sql += "AND dynpoi_stats.class=%d " % options.classes[0]
44    elif len(options.classes)>=1:
45       where_sql += "AND dynpoi_stats.class in (%s) " % convIntsToStr(options.classes)
46
47    if len(options.sources)==1:
48       where_sql += "AND dynpoi_stats.source=%d " % options.sources[0]
49    elif len(options.sources)>=1:
50       where_sql += "AND dynpoi_stats.source in (%s) " % convIntsToStr(options.sources)
51
52    if options.country:
53       join_item += "JOIN dynpoi_source ON dynpoi_stats.source = dynpoi_source.source "
54       where_sql += "AND dynpoi_source.comment LIKE '%%-%s%%' " % options.country
55
56    sql = sql % (join_item, where_sql)
57
58    if len(sys.argv)>1:
59      print sql
60
61    db.execute(sql)
62
63    if len(options.sources)!=1:
64        delay = datetime.timedelta(days=1)
65    else:
66        delay = datetime.timedelta(seconds=1)
67
68    result = []
69    last = {}
70    timestamp = 0
71    prev_timestamp = 0
72    for res in db.fetchall():
73        timestamp = res['timestamp']
74        if prev_timestamp == 0:
75            prev_timestamp = timestamp
76
77        last[(res["source"],res["class"])] = res['count']
78        if (timestamp - prev_timestamp) > delay:
79            result.append((timestamp.strftime('%d/%m/%Y'), sum(last.itervalues())))
80            prev_timestamp = timestamp
81
82    if last:
83        result.append((timestamp.strftime('%d/%m/%Y'), sum(last.itervalues())))
84    return result
85
86def get_text(db, options):
87    if len(options.sources)==1 and len(options.classes)==1:
88        db.execute("SELECT title->'en' FROM dynpoi_class WHERE source=%s AND class=%s;", (options.sources[0], options.classes[0]))
89
90    elif len(options.items)==1 and len(options.classes)==1:
91        db.execute("SELECT title->'en' FROM dynpoi_class WHERE class=%s AND item=%s LIMIT 1;", (options.classes[0], options.items[0]))
92
93    else:
94        return ""
95
96    res = db.fetchone()
97    if res:
98        return res[0]
99    else:
100        return ""
101
102def get_src(db, options):
103    if len(options.sources) != 1:
104        return "All"
105    else:
106        db.execute("SELECT comment FROM dynpoi_source WHERE source=%s;", (options.sources[0], ))
107        return db.fetchone()[0]
108
109def make_plt(db, options):
110
111    data = get_data(db, options)
112    text = get_text(db, options)
113
114    if not data or len(data) < 2:
115         raise SystemError("no data available")
116
117    gnuplotFilename = "/tmp/data_%i.plt"%os.getpid()
118    dataFilename = "/tmp/data_%i.dat"%os.getpid()
119
120    f_plt = open(gnuplotFilename, 'w')
121    f_plt.write("set terminal png\n")
122    f_plt.write("set title \"Source : %s\"\n"%get_src(db, options))
123#    f_plt.write("set style data fsteps\n")
124    f_plt.write("set style data line\n")
125    f_plt.write("set timefmt \"%d/%m/%Y\"\n")
126    f_plt.write("set xdata time\n")
127    f_plt.write("set xrange [ \"%s\":\"%s\" ]\n"%(data[0][0], data[-1][0]))
128    f_plt.write("set format x \"%d/%m\\n%Y\"\n")
129    #f_plt.write("set xlabel \"Date\nTime\"\n")
130    f_plt.write("set yrange [ %d : %d ]\n"%(0,100*(max([x[1] for x in data])/100+2)))
131    #f_plt.write("set ylabel "Concentration\nmg/l"\n")
132    f_plt.write("set grid\n")
133    f_plt.write("set key left\n")
134    f_plt.write("plot '%s' using 1:2 t '%s'\n"%(dataFilename, text))
135    f_plt.close()
136
137    f_dat = open(dataFilename, 'w')
138    for x in data:
139        f_dat.write("%s %d\n"%(x[0], x[1]))
140    f_dat.close()
141
142    s, o = commands.getstatusoutput("gnuplot "+gnuplotFilename)
143
144    if s:
145        raise SystemError("error in gnuplot generation")
146
147    os.remove(gnuplotFilename)
148    os.remove(dataFilename)
149
150    return o
151
152
153def convStrToInts(string):
154    """
155    Convertie une chaine en liste d'entier
156    """
157    if not string:
158        return []
159
160    string = string.replace(" ", "")
161    if string=="":
162        return []
163
164    return [int(elt) for elt in string.split(",")]
165
166def convIntsToStr(values):
167    """
168    Convertie une liste d'entier en chaine
169    """
170    return ", ".join([str(elt) for elt in values])
171
172
173if __name__ == "__main__":
174    from optparse import OptionParser, SUPPRESS_HELP
175    start = time.clock()
176
177    parser = OptionParser()
178
179    parser.add_option("--source", dest="sources", type="int", action="append", default=[])
180    parser.add_option("--class", dest="classes", type="int", action="append", default=[])
181    parser.add_option("--item", dest="items", type="int", action="append", default=[])
182    parser.add_option("--country", dest="country", type="string", default=None)
183    (options, args) = parser.parse_args()
184
185    data = make_plt(None, options)
186    f = open("graph.png", "w")
187    f.write(data)
188    f.close()
189    end = time.clock()
190    print "graph.png generated in %ims"%((end-start)*1000)
191    sys.exit(0)
Note: See TracBrowser for help on using the repository browser.