+static struct json_object *date_to_json(struct tm *tm)
+{
+ json_object *json;
+
+ json = json_object_new_array();
+ json_object_array_add(json, json_object_new_int(tm->tm_year+1900));
+ json_object_array_add(json, json_object_new_int(tm->tm_mon+1));
+ json_object_array_add(json, json_object_new_int(tm->tm_mday));
+
+ return json;
+}
+
+static void json_add_ddts(json_object *json,
+ struct daily_download_total **ddts)
+{
+ json_object *json_ddt, *json_ddts;
+ struct daily_download_total *ddt;
+
+ json_ddts = json_object_new_array();
+ json_object_object_add(json, "ddts", json_ddts);
+
+ if (!ddts)
+ return ;
+
+ while (*ddts) {
+ ddt = *ddts;
+
+ json_ddt = json_object_new_object();
+ json_object_object_add(json_ddt,
+ "value",
+ json_object_new_int(ddt->count));
+ json_object_object_add(json_ddt,
+ "time",
+ date_to_json(&ddt->date));
+
+ json_object_array_add(json_ddts, json_ddt);
+
+ ddts++;
+ }
+}
+
+static json_object *distro_to_json(struct distro_stats *d)
+{
+ json_object *json;
+
+ json = json_object_new_object();
+
+ json_object_object_add(json,
+ "name",
+ json_object_new_string(d->name));
+
+ json_object_object_add(json,
+ "count",
+ json_object_new_int(d->download_count));
+
+ json_add_ddts(json, d->ddts);
+
+ return json;
+}
+
+static json_object *
+pkg_to_json(struct ppa_stats *ppa, struct package_stats *pkg)
+{
+ json_object *json, *json_versions, *json_distros, *json_distro;
+ struct version_stats **versions;
+ struct distro_stats **distros, *d;
+
+ json = json_object_new_object();
+
+ json_object_object_add(json,
+ "ppa_name", json_object_new_string(ppa->name));
+ json_object_object_add(json,
+ "ppa_owner",
+ json_object_new_string(ppa->owner));
+
+ json_object_object_add(json,
+ "name", json_object_new_string(pkg->name));
+
+ json_versions = json_object_new_array();
+ json_object_object_add(json, "versions", json_versions);
+ versions = pkg->versions;
+ while (*versions) {
+ json_object_array_add
+ (json_versions,
+ json_object_new_string((*versions)->version));
+
+ versions++;
+ }
+
+ distros = pkg->distros;
+ if (distros) {
+ json_distros = json_object_new_array();
+ json_object_object_add(json, "distros", json_distros);
+
+ while (*distros) {
+ d = *distros;
+
+ if (d->download_count) {
+ json_distro = distro_to_json(d);
+
+ json_object_array_add(json_distros,
+ json_distro);
+ }
+
+ distros++;
+ }
+ }
+
+ json_add_ddts(json, pkg->daily_download_totals);
+
+ return json;
+}
+
+static char *version_to_json(struct ppa_stats *ppa,
+ struct package_stats *pkg,
+ struct version_stats *ver)
+{
+ char *ret;
+ struct distro_stats **distros, *distro;
+ json_object *json, *json_distros, *json_distro, *json_archs, *json_arch;
+ struct arch_stats **archs;
+
+ json = json_object_new_object();
+
+ json_object_object_add(json,
+ "ppa_name", json_object_new_string(ppa->name));
+ json_object_object_add(json,
+ "ppa_owner",
+ json_object_new_string(ppa->owner));
+
+ json_object_object_add(json,
+ "pkg_name", json_object_new_string(pkg->name));
+
+ json_object_object_add(json,
+ "name", json_object_new_string(ver->version));
+
+ json_add_ddts(json, ver->daily_download_totals);
+
+ distros = ver->distros;
+ json_distros = json_object_new_array();
+ json_object_object_add(json, "distros", json_distros);
+ while (*distros) {
+ distro = *distros;
+ json_distro = json_object_new_object();
+
+ json_object_array_add(json_distros, json_distro);
+
+ json_object_object_add(json_distro,
+ "name",
+ json_object_new_string(distro->name));
+
+ archs = distro->archs;
+ json_archs = json_object_new_array();
+ json_object_object_add(json_distro, "archs", json_archs);
+ while (*archs) {
+ json_arch = json_object_new_object();
+
+ json_object_object_add
+ (json_arch,
+ "name",
+ json_object_new_string((*archs)->name));
+
+ json_object_object_add
+ (json_arch,
+ "count",
+ json_object_new_int((*archs)->download_count));
+
+ json_object_array_add(json_archs, json_arch);
+ archs++;
+ }
+
+ distros++;
+ }
+
+ ret = strdup(json_object_to_json_string(json));
+
+ json_object_put(json);
+
+ return ret;
+}
+
+static json_object *ppa_to_json(struct ppa_stats *ppa)
+{
+ json_object *json, *json_pkgs, *json_pkg;
+ struct package_stats **pkgs;
+
+ json = json_object_new_object();
+
+ json_object_object_add(json,
+ "ppa_name", json_object_new_string(ppa->name));
+ json_object_object_add(json,
+ "ppa_owner",
+ json_object_new_string(ppa->owner));
+
+ json_add_ddts(json, ppa->daily_download_totals);
+
+ pkgs = ppa->packages;
+ json_pkgs = json_object_new_array();
+ json_object_object_add(json, "packages", json_pkgs);
+ while (*pkgs) {
+ json_pkg = json_object_new_object();
+ json_object_array_add(json_pkgs, json_pkg);
+
+ json_object_object_add(json_pkg, "name",
+ json_object_new_string((*pkgs)->name));
+
+ json_object_object_add
+ (json_pkg, "count",
+ json_object_new_int((*pkgs)->download_count));
+
+ pkgs++;
+ }
+
+ return json;
+}
+
+static void
+version_to_html(struct ppa_stats *ppa,
+ struct package_stats *pkg,
+ struct version_stats *version,
+ const char *dir)
+{
+ char *f_name, *path;
+ FILE *f;
+
+ f_name = malloc(strlen(pkg->name)+1+strlen(version->version)+1);
+ sprintf(f_name, "%s_%s", pkg->name, version->version);
+
+ path = path_new(dir, f_name, ".html");
+ f = fopen(path, "w");
+
+ if (!f) {
+ log_err(_("failed to open: %s"), path);
+ return ;
+ }
+
+ fprintf(f, HTML_VERSION_TEMPLATE,
+ version_to_json(ppa, pkg, version),
+ HTML_FOOTER);
+
+ fclose(f);
+
+ free(path);
+ free(f_name);
+}
+
+static void
+create_html(const char *path,
+ const char *title,
+ const char *body_template,
+ const char *script)
+{
+ FILE *f;
+
+ f = fopen(path, "w");
+
+ if (!f) {
+ log_err(_("failed to open: %s"), path);
+ return ;
+ }
+
+ fprintf(f, HTML_HEADER, title, script);
+ fputs(body_template, f);
+ fputs(HTML_FOOTER, f);
+
+ fclose(f);
+}
+
+static char *ppa_display_name(const struct ppa_stats *ppa)
+{
+ char *ret;
+
+ ret = malloc(4+strlen(ppa->name)+1+strlen(ppa->owner)+1);
+
+ sprintf(ret, "ppa:%s/%s", ppa->owner, ppa->name);
+
+ return ret;
+}
+
+static void
+index_to_html(struct ppa_stats *ppa, const char *dir)
+{
+ char *path, *json_path, *dname;
+ json_object *json;
+
+ json = ppa_to_json(ppa);
+ json_path = path_new(dir, "index", ".json");
+
+ log_debug(_("generating %s"), json_path);
+ json_object_to_file(json_path, json);
+ json_object_put(json);
+ free(json_path);
+
+ path = path_new(dir, "index", ".html");
+ dname = ppa_display_name(ppa);
+ create_html(path, dname, HTML_INDEX_TEMPLATE, "ppastats_ppa();");
+ free(path);
+ free(dname);
+}
+