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>
46 static char *ppa_body;
47 static char *pkg_body;
48 static char *pkg_version_body;
51 void html_set_theme_dir(const char *theme_dir)
53 css_dir = path_append(theme_dir, "css");
54 js_dir = path_append(theme_dir, "js");
55 tpl_dir = path_append(theme_dir, "templates");
58 static char *path_new(const char *dir, const char *file, const char *suffixe)
62 /* [dir]/[file][suffixe] */
63 path = malloc(strlen(dir)+1+
65 (suffixe ? strlen(suffixe) : 0) +
71 strcat(path, suffixe);
76 static char *get_header(const char *title, const char *script)
78 char *res, *tmp, *path;
81 path = path_append(tpl_dir, "header.tpl");
82 header = file_get_content(path);
89 res = strrep(tmp, "@SCRIPT@", script);
95 res = strrep(tmp, "@TITLE@", title);
100 log_err("Failed to read header template: %s", path);
109 static const char *get_footer()
114 path = path_append(tpl_dir, "footer.tpl");
115 footer = file_get_content(path);
118 log_err("Failed to read footer template: %s", path);
126 static const char *get_pkg_version_body()
130 if (!pkg_version_body) {
131 path = path_append(tpl_dir, "pkg_version.tpl");
132 pkg_version_body = file_get_content(path);
134 if (!pkg_version_body)
135 log_err("Failed to read package version template: %s",
141 return pkg_version_body;
143 static const char *get_ppa_body()
148 path = path_append(tpl_dir, "ppa.tpl");
149 ppa_body = file_get_content(path);
152 log_err("Failed to read PPA template: %s", path);
160 static const char *get_pkg_body()
165 path = path_append(tpl_dir, "pkg.tpl");
166 pkg_body = file_get_content(path);
169 log_err("Failed to read package template: %s", path);
177 static void json_add_ddts(json_object *json,
178 struct daily_download_total **ddts)
180 json_object_object_add(json, "ddts", ddts_to_json(ddts));
183 static json_object *distro_to_json(struct distro_stats *d)
187 json = json_object_new_object();
189 json_object_object_add(json,
191 json_object_new_string(d->name));
193 json_object_object_add(json,
195 json_object_new_int(d->download_count));
197 json_add_ddts(json, d->ddts);
203 pkg_to_json(struct ppa_stats *ppa, struct package_stats *pkg)
205 json_object *json, *json_versions, *json_distros, *json_distro;
206 struct version_stats **versions;
207 struct distro_stats **distros, *d;
209 json = json_object_new_object();
211 json_object_object_add(json,
212 "ppa_name", json_object_new_string(ppa->name));
213 json_object_object_add(json,
215 json_object_new_string(ppa->owner));
217 json_object_object_add(json,
218 "name", json_object_new_string(pkg->name));
220 json_versions = json_object_new_array();
221 json_object_object_add(json, "versions", json_versions);
222 versions = pkg->versions;
224 json_object_array_add
226 json_object_new_string((*versions)->version));
231 distros = pkg->distros;
233 json_distros = json_object_new_array();
234 json_object_object_add(json, "distros", json_distros);
239 if (d->download_count) {
240 json_distro = distro_to_json(d);
242 json_object_array_add(json_distros,
250 json_add_ddts(json, pkg->daily_download_totals);
255 static char *version_to_json(struct ppa_stats *ppa,
256 struct package_stats *pkg,
257 struct version_stats *ver)
260 struct distro_stats **distros, *distro;
261 json_object *json, *json_distros, *json_distro, *json_archs, *json_arch;
262 struct arch_stats **archs;
264 json = json_object_new_object();
266 json_object_object_add(json,
267 "ppa_name", json_object_new_string(ppa->name));
268 json_object_object_add(json,
270 json_object_new_string(ppa->owner));
272 json_object_object_add(json,
273 "pkg_name", json_object_new_string(pkg->name));
275 json_object_object_add(json,
276 "name", json_object_new_string(ver->version));
278 json_object_object_add(json,
279 "date_created", time_to_json(ver->date_created));
281 json_add_ddts(json, ver->daily_download_totals);
283 distros = ver->distros;
284 json_distros = json_object_new_array();
285 json_object_object_add(json, "distros", json_distros);
288 json_distro = json_object_new_object();
290 json_object_array_add(json_distros, json_distro);
292 json_object_object_add(json_distro,
294 json_object_new_string(distro->name));
296 archs = distro->archs;
297 json_archs = json_object_new_array();
298 json_object_object_add(json_distro, "archs", json_archs);
300 json_arch = json_object_new_object();
302 json_object_object_add
305 json_object_new_string((*archs)->name));
307 json_object_object_add
310 json_object_new_int((*archs)->download_count));
312 json_object_array_add(json_archs, json_arch);
319 ret = strdup(json_object_to_json_string(json));
321 json_object_put(json);
326 static json_object *ppa_to_json(struct ppa_stats *ppa)
328 json_object *json, *json_pkgs, *json_pkg;
329 struct package_stats **pkgs;
331 json = json_object_new_object();
333 json_object_object_add(json,
334 "ppa_name", json_object_new_string(ppa->name));
335 json_object_object_add(json,
337 json_object_new_string(ppa->owner));
339 json_add_ddts(json, ppa->daily_download_totals);
341 pkgs = ppa->packages;
342 json_pkgs = json_object_new_array();
343 json_object_object_add(json, "packages", json_pkgs);
345 json_pkg = json_object_new_object();
346 json_object_array_add(json_pkgs, json_pkg);
348 json_object_object_add(json_pkg, "name",
349 json_object_new_string((*pkgs)->name));
351 json_object_object_add
353 json_object_new_int((*pkgs)->download_count));
362 create_html(const char *path,
364 const char *body_template,
373 header = get_header(title, script);
375 log_err(_("Failed to get the header template"));
379 f = fopen(path, "w");
382 log_err(_("Failed to open: %s"), path);
387 fputs(body_template, f);
389 footer = get_footer();
401 static char *ppa_display_name(const struct ppa_stats *ppa)
405 ret = malloc(4+strlen(ppa->name)+1+strlen(ppa->owner)+1);
407 sprintf(ret, "ppa:%s/%s", ppa->owner, ppa->name);
413 index_to_html(struct ppa_stats *ppa, const char *dir)
415 char *path, *json_path, *dname;
419 body = get_ppa_body();
421 log_err("Failed to create PPA page");
425 json = ppa_to_json(ppa);
426 json_path = path_new(dir, "index", ".json");
428 log_debug(_("generating %s"), json_path);
429 json_object_to_file(json_path, json);
430 json_object_put(json);
433 path = path_new(dir, "index", ".html");
434 dname = ppa_display_name(ppa);
435 create_html(path, dname, body, "ppastats_ppa();");
441 version_to_html(struct ppa_stats *ppa,
442 struct package_stats *pkg,
443 struct version_stats *version,
448 const char *script_tpl;
451 body = get_pkg_version_body();
453 log_err("Failed to create package version page");
457 json = version_to_json(ppa, pkg, version);
459 log_err("Failed to create package version page");
463 f_name = malloc(strlen(pkg->name)+1+strlen(version->version)+1);
464 sprintf(f_name, "%s_%s", pkg->name, version->version);
466 path = path_new(dir, f_name, ".html");
468 script_tpl = "var data = %s;\n ppastats_ver();";
469 script = malloc(strlen(script_tpl) - 2 + strlen(json) + 1);
470 sprintf(script, script_tpl, json);
472 create_html(path, f_name, body, script);
481 pkg_to_html(struct ppa_stats *ppa, struct package_stats *pkg, const char *dir)
483 char *path, *json_path, *script;
487 body = get_pkg_body();
489 log_err("Failed to create package page: %s", pkg->name);
493 json_path = path_new(dir, pkg->name, ".json");
494 json = pkg_to_json(ppa, pkg);
495 log_debug(_("Generating %s"), json_path);
497 json_object_to_file(json_path, json);
498 json_object_put(json);
501 path = path_new(dir, pkg->name, ".html");
502 script = malloc(strlen("ppastats_pkg(\"\");")+
506 sprintf(script, "ppastats_pkg(\"%s%s\");", pkg->name, ".json");
508 log_debug(_("Generating %s"), path);
510 create_html(path, pkg->name, body, script);
516 pkgs_to_html(struct ppa_stats *ppa,
517 struct package_stats **pkgs,
520 struct version_stats **versions;
523 pkg_to_html(ppa, *pkgs, dir);
525 versions = (*pkgs)->versions;
527 version_to_html(ppa, *pkgs, *versions, dir);
537 ppa_to_html(const char *owner,
539 const char *package_status,
540 const char *output_dir,
541 const int install_static_files,
544 struct ppa_stats *ppastats;
546 char *css_odir, *js_odir;
548 mkdirs(output_dir, 0777);
550 if (install_static_files) {
551 css_odir = path_append(output_dir, "css");
552 js_odir = path_append(output_dir, "js");
554 dir_rcopy(css_dir, css_odir);
555 dir_rcopy(js_dir, js_odir);
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);