1 /*
2 ** Modular Logfile Analyzer
3 ** Copyright 2000 Jan Kneschke <jan@kneschke.de>
4 **
5 ** Homepage: http://www.modlogan.org
6 **
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 2 of the License, or
11 (at your option) any later version, and provided that the above
12 copyright and permission notice is included with all distributed
13 copies of this or derived software.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
23
24 **
25 ** $Id: pictures_vd.c,v 1.18 2004/08/27 18:41:37 ostborn Exp $
26 */
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <math.h>
30 #include <string.h>
31
32 #include "config.h"
33
34 #ifdef HAVE_LIBGD
35 #ifdef HAVE_GD_GD_H
36 #include <gd/gd.h>
37 #include <gd/gdfonts.h>
38 #else
39 #include <gd.h>
40 #include <gdfonts.h>
41 #endif
42 #endif
43
44 #include "mconfig.h"
45 #include "mlist.h"
46 #include "mdatatypes.h"
47 #include "mlocale.h"
48 #include "misc.h"
49
50 #include "pictures.h"
51 #include "generate.h"
52
53 #define IM_FILENAME "visit_duration_"
54 #define IM_FILEEXT ".png"
55
56 #define GRAPH_CUTOFF 0.95
57 #define GRAPH_CUTOFF_TEXT "95%"
58
mplugin_modlogan_create_pic_vd(mconfig * ext_conf,mstate * state)59 char *mplugin_modlogan_create_pic_vd(mconfig *ext_conf, mstate *state) {
60 #ifdef HAVE_LIBGD
61 char filename[255];
62 config_output *conf = ext_conf->plugin_conf;
63 mstate_web *staweb = state->ext;
64 mhash *h = NULL;
65 mlist *l = NULL;
66 int i, max, ndx, max_names;
67 unsigned long visitpl_sum = 0;
68 unsigned long visitpl_cur = 0;
69 mdata **md;
70
71 static char href[255] = "";
72
73 mgraph * graph = malloc(sizeof(mgraph));
74 memset(graph, 0, sizeof(mgraph));
75
76 // FIXME: This code has Y10K error :-)
77 // -9 because -14 + 1 + 4
78 graph->name = malloc( strlen( get_month_string(state->month,0)) - 9 +
79 strlen( GRAPH_CUTOFF_TEXT ) +
80 strlen( _("Visit Duration for %1$s %2$04d (bottom %3$s, in min)")));
81 // %1$s - monthname
82 // %2$04d - year, padded w/ 0 in 4 digits
83 // %3$s - graph cutoff text (95%)
84 // You can alter the order of the arguments via
85 // changing the appearence order in the msgstr ..
86 sprintf(graph->name, _("Visit Duration for %1$s %2$04d (bottom %3$s, in min)"),
87 get_month_string(state->month,0),
88 state->year,
89 GRAPH_CUTOFF_TEXT
90 );
91
92 h = get_visit_duration(ext_conf, staweb->visits);
93
94 max = 0;
95
96 for (i = 0; i < h->size; i++) {
97 for( l = h->data[i]->list; l && l->data; l = l->next) {
98 mdata *data = l->data;
99
100 if (strtol(data->key, NULL, 10) > max)
101 max = strtol(data->key, NULL, 10);
102 }
103 }
104
105 /* minimum width */
106 if (max<45) max=45;
107
108 /* maximum width */
109 if (max>90) max=90;
110
111 graph->max_x = max + 1;
112 graph->max_z = 1;
113 graph->filename = NULL;
114 graph->height = 0;
115 graph->width = 0;
116
117 graph->pairs = malloc(sizeof(mgraph_array *) * graph->max_z);
118 for (i = 0; i < graph->max_z; i++) {
119 graph->pairs[i] = malloc(sizeof(mgraph_array));
120 graph->pairs[i]->values = malloc(sizeof(double) * graph->max_x);
121 memset(graph->pairs[i]->values, 0, sizeof(double) * graph->max_x);
122 }
123
124 graph->pair_names = malloc(sizeof(mgraph_array *) * graph->max_x);
125
126 md = mhash_sorted_to_marray(h, M_SORTBY_KEY, M_SORTDIR_ASC);
127 ndx = 0;
128 for (i = 0; i < graph->max_x; i++) {
129 mdata *data = md[ndx];
130
131 if (data && strtol(data->key, NULL, 10) == i) {
132 graph->pairs[0]->values[i] = mdata_get_count(data);
133 visitpl_sum += graph->pairs[0]->values[i];
134 ndx++;
135 } else {
136 graph->pairs[0]->values[i] = 0;
137 }
138
139 /* only print 10, 20, 30, ... */
140 if ((i == 0) || (i % 10)) {
141 graph->pair_names[i] = malloc(1);
142 *(graph->pair_names[i]) = '\0';
143 } else {
144 graph->pair_names[i] = malloc(log10(i) + 2);
145 sprintf(graph->pair_names[i], "%d", i);
146 }
147 }
148 free(md);
149
150 max_names = graph->max_x;
151
152 /* Now honor the cutoff ratio... */
153 visitpl_sum = ceil(visitpl_sum * GRAPH_CUTOFF);
154 for (i = 0; i < graph->max_x-1; i++) { /* this -1 is intentional */
155 visitpl_cur += graph->pairs[0]->values[i];
156 if (visitpl_cur > visitpl_sum) break;
157 }
158 /* minimum width */
159 if (i<45) i=45;
160
161 /* maximum width */
162 if (i>90) i=90;
163
164 graph->max_x = i+1;
165
166 mhash_free(h);
167
168 graph->pairs[0]->name = _("Count");
169 graph->pairs[0]->color = conf->col_hits;
170
171 sprintf(filename, "%s/%s%04d%02d%s",
172 conf->outputdir,
173 IM_FILENAME,
174 state->year, state->month,
175 IM_FILEEXT);
176
177 graph->filename = filename;
178
179 mplugin_modlogan_create_lines(ext_conf, graph);
180
181 sprintf(href, "<center><img src=\"%s%04i%02i%s\" alt=\"%s\" width=\"%d\" height=\"%d\"></center>\n",
182 IM_FILENAME,
183 state->year, state->month,
184 IM_FILEEXT,
185 _("Visit Duration"), graph->width, graph->height);
186
187 for (i = 0; i < graph->max_z; i++) {
188 free(graph->pairs[i]->values);
189 free(graph->pairs[i]);
190 }
191
192 for (i = 0; i < max_names; i++) {
193 free(graph->pair_names[i]);
194 }
195
196 free(graph->pair_names);
197 free(graph->pairs);
198 free(graph->name);
199 free(graph);
200
201 return href;
202 #else
203 return NULL;
204 #endif
205 }
206
207
208