2 * Copyright (C) 2011-2014 jeanfi@gmail.com
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 #define _(String) gettext(String)
28 #include <sys/types.h>
42 static char *ppa_body;
43 static char *pkg_body;
44 static char *pkg_version_body;
47 static char *path_new(const char *dir, const char *file, const char *suffixe)
51 /* [dir]/[file][suffixe] */
52 path = malloc(strlen(dir)+1+
54 (suffixe ? strlen(suffixe) : 0) +
60 strcat(path, suffixe);
65 static char *get_header(const char *title, const char *script)
71 path = DEFAULT_WWW_DIR"/header.tpl";
72 header = file_get_content(path);
75 log_err("Failed to read header template: %s", path);
82 res = strrep(tmp, "@SCRIPT@", script);
88 res = strrep(tmp, "@TITLE@", title);
96 static const char *get_footer()
101 path = DEFAULT_WWW_DIR"/footer.tpl";
102 footer = file_get_content(path);
105 log_err("Failed to read footer template: %s", path);
111 static const char *get_pkg_version_body()
115 if (!pkg_version_body) {
116 path = DEFAULT_WWW_DIR"/pkg_version.tpl";
117 pkg_version_body = file_get_content(path);
119 if (!pkg_version_body)
120 log_err("Failed to read package version template: %s",
124 return pkg_version_body;
126 static const char *get_ppa_body()
131 path = DEFAULT_WWW_DIR"/ppa.tpl";
132 ppa_body = file_get_content(path);
135 log_err("Failed to read PPA template: %s", path);
141 static const char *get_pkg_body()
146 path = DEFAULT_WWW_DIR"/pkg.tpl";
147 pkg_body = file_get_content(path);
150 log_err("Failed to read package template: %s", path);
156 static void json_add_ddts(json_object *json,
157 struct daily_download_total **ddts)
159 json_object_object_add(json, "ddts", ddts_to_json(ddts));
162 static json_object *distro_to_json(struct distro_stats *d)
166 json = json_object_new_object();
168 json_object_object_add(json,
170 json_object_new_string(d->name));
172 json_object_object_add(json,
174 json_object_new_int(d->download_count));
176 json_add_ddts(json, d->ddts);
182 pkg_to_json(struct ppa_stats *ppa, struct package_stats *pkg)
184 json_object *json, *json_versions, *json_distros, *json_distro;
185 struct version_stats **versions;
186 struct distro_stats **distros, *d;
188 json = json_object_new_object();
190 json_object_object_add(json,
191 "ppa_name", json_object_new_string(ppa->name));
192 json_object_object_add(json,
194 json_object_new_string(ppa->owner));
196 json_object_object_add(json,
197 "name", json_object_new_string(pkg->name));
199 json_versions = json_object_new_array();
200 json_object_object_add(json, "versions", json_versions);
201 versions = pkg->versions;
203 json_object_array_add
205 json_object_new_string((*versions)->version));
210 distros = pkg->distros;
212 json_distros = json_object_new_array();
213 json_object_object_add(json, "distros", json_distros);
218 if (d->download_count) {
219 json_distro = distro_to_json(d);
221 json_object_array_add(json_distros,
229 json_add_ddts(json, pkg->daily_download_totals);
234 static char *version_to_json(struct ppa_stats *ppa,
235 struct package_stats *pkg,
236 struct version_stats *ver)
239 struct distro_stats **distros, *distro;
240 json_object *json, *json_distros, *json_distro, *json_archs, *json_arch;
241 struct arch_stats **archs;
243 json = json_object_new_object();
245 json_object_object_add(json,
246 "ppa_name", json_object_new_string(ppa->name));
247 json_object_object_add(json,
249 json_object_new_string(ppa->owner));
251 json_object_object_add(json,
252 "pkg_name", json_object_new_string(pkg->name));
254 json_object_object_add(json,
255 "name", json_object_new_string(ver->version));
257 json_object_object_add(json,
258 "date_created", time_to_json(ver->date_created));
260 json_add_ddts(json, ver->daily_download_totals);
262 distros = ver->distros;
263 json_distros = json_object_new_array();
264 json_object_object_add(json, "distros", json_distros);
267 json_distro = json_object_new_object();
269 json_object_array_add(json_distros, json_distro);
271 json_object_object_add(json_distro,
273 json_object_new_string(distro->name));
275 archs = distro->archs;
276 json_archs = json_object_new_array();
277 json_object_object_add(json_distro, "archs", json_archs);
279 json_arch = json_object_new_object();
281 json_object_object_add
284 json_object_new_string((*archs)->name));
286 json_object_object_add
289 json_object_new_int((*archs)->download_count));
291 json_object_array_add(json_archs, json_arch);
298 ret = strdup(json_object_to_json_string(json));
300 json_object_put(json);
305 static json_object *ppa_to_json(struct ppa_stats *ppa)
307 json_object *json, *json_pkgs, *json_pkg;
308 struct package_stats **pkgs;
310 json = json_object_new_object();
312 json_object_object_add(json,
313 "ppa_name", json_object_new_string(ppa->name));
314 json_object_object_add(json,
316 json_object_new_string(ppa->owner));
318 json_add_ddts(json, ppa->daily_download_totals);
320 pkgs = ppa->packages;
321 json_pkgs = json_object_new_array();
322 json_object_object_add(json, "packages", json_pkgs);
324 json_pkg = json_object_new_object();
325 json_object_array_add(json_pkgs, json_pkg);
327 json_object_object_add(json_pkg, "name",
328 json_object_new_string((*pkgs)->name));
330 json_object_object_add
332 json_object_new_int((*pkgs)->download_count));
341 create_html(const char *path,
343 const char *body_template,
352 header = get_header(title, script);
354 log_err(_("Failed to get the header template"));
358 f = fopen(path, "w");
361 log_err(_("Failed to open: %s"), path);
366 fputs(body_template, f);
368 footer = get_footer();
380 static char *ppa_display_name(const struct ppa_stats *ppa)
384 ret = malloc(4+strlen(ppa->name)+1+strlen(ppa->owner)+1);
386 sprintf(ret, "ppa:%s/%s", ppa->owner, ppa->name);
392 index_to_html(struct ppa_stats *ppa, const char *dir)
394 char *path, *json_path, *dname;
398 body = get_ppa_body();
400 log_err("Failed to create PPA page");
404 json = ppa_to_json(ppa);
405 json_path = path_new(dir, "index", ".json");
407 log_debug(_("generating %s"), json_path);
408 json_object_to_file(json_path, json);
409 json_object_put(json);
412 path = path_new(dir, "index", ".html");
413 dname = ppa_display_name(ppa);
414 create_html(path, dname, body, "ppastats_ppa();");
420 version_to_html(struct ppa_stats *ppa,
421 struct package_stats *pkg,
422 struct version_stats *version,
427 const char *script_tpl;
430 body = get_pkg_version_body();
432 log_err("Failed to create package version page");
436 json = version_to_json(ppa, pkg, version);
438 log_err("Failed to create package version page");
442 f_name = malloc(strlen(pkg->name)+1+strlen(version->version)+1);
443 sprintf(f_name, "%s_%s", pkg->name, version->version);
445 path = path_new(dir, f_name, ".html");
447 script_tpl = "var data = %s;\n ppastats_ver();";
448 script = malloc(strlen(script_tpl) - 2 + strlen(json) + 1);
449 sprintf(script, script_tpl, json);
451 create_html(path, f_name, body, script);
460 pkg_to_html(struct ppa_stats *ppa, struct package_stats *pkg, const char *dir)
462 char *path, *json_path, *script;
466 body = get_pkg_body();
468 log_err("Failed to create package page: %s", pkg->name);
472 json_path = path_new(dir, pkg->name, ".json");
473 json = pkg_to_json(ppa, pkg);
474 log_debug(_("Generating %s"), json_path);
476 json_object_to_file(json_path, json);
477 json_object_put(json);
480 path = path_new(dir, pkg->name, ".html");
481 script = malloc(strlen("ppastats_pkg(\"\");")+
485 sprintf(script, "ppastats_pkg(\"%s%s\");", pkg->name, ".json");
487 log_debug(_("Generating %s"), path);
489 create_html(path, pkg->name, body, script);
495 pkgs_to_html(struct ppa_stats *ppa,
496 struct package_stats **pkgs,
499 struct version_stats **versions;
502 pkg_to_html(ppa, *pkgs, dir);
504 versions = (*pkgs)->versions;
506 version_to_html(ppa, *pkgs, *versions, dir);
516 ppa_to_html(const char *owner,
518 const char *package_status,
519 const char *output_dir,
520 const int install_static_files,
523 struct ppa_stats *ppastats;
525 char *css_dir, *js_dir;
527 static char *www_files[]
528 = { DEFAULT_WWW_DIR"/jquery.min.js", "js/jquery.min.js",
529 DEFAULT_WWW_DIR"/ppastats.js", "js/ppastats.js",
530 DEFAULT_WWW_DIR"/jqplot.dateAxisRenderer.min.js",
531 "js/jqplot.dateAxisRenderer.min.js",
532 DEFAULT_WWW_DIR"/jquery.jqplot.min.js",
533 "js/jquery.jqplot.min.js",
534 DEFAULT_WWW_DIR"/excanvas.js", "js/excanvas.js",
535 DEFAULT_WWW_DIR"/ppastats.css", "css/ppastats.css",
536 DEFAULT_WWW_DIR"/wpitchoune.css", "css/wpitchoune.css",
537 DEFAULT_WWW_DIR"/jquery.jqplot.min.css",
538 "css/jquery.jqplot.min.css" };
540 mkdirs(output_dir, 0777);
542 if (install_static_files) {
543 css_dir = path_append(output_dir, "css");
544 js_dir = path_append(output_dir, "js");
546 mkdir(css_dir, 0777);
549 for (i = 0; i < 8; i++) {
550 f_dst = path_append(output_dir, www_files[2*i+1]);
552 log_debug(_("Copying %s %s"), www_files[2*i], f_dst);
553 file_copy(www_files[2*i], f_dst);
561 ppastats = create_ppa_stats(owner, ppa, package_status, ws_size);
563 path = path_new(output_dir, "ppa", ".html");
565 pkgs_to_html(ppastats, ppastats->packages, output_dir);
567 index_to_html(ppastats, output_dir);
569 ppa_stats_free(ppastats);
580 free(pkg_version_body);