+static char *get_header(const char *title, const char *script)
+{
+ const char *path;
+ char *res, *tmp;
+
+ if (!header) {
+ path = DEFAULT_WWW_DIR"/header.tpl";
+ header = file_get_content(path);
+
+ if (!header) {
+ log_err("Failed to read header template: %s", path);
+
+ return NULL;
+ }
+ }
+
+ tmp = strdup(header);
+ res = strrep(tmp, "@SCRIPT@", script);
+
+ if (res != tmp)
+ free(tmp);
+
+ tmp = res;
+ res = strrep(tmp, "@TITLE@", title);
+
+ if (res != tmp)
+ free(tmp);
+
+ return res;
+}
+
+static const char *get_footer()
+{
+ const char *path;
+
+ if (!footer) {
+ path = DEFAULT_WWW_DIR"/footer.tpl";
+ footer = file_get_content(path);
+
+ if (!footer)
+ log_err("Failed to read footer template: %s", path);
+ }
+
+ return footer;
+}
+
+static const char *get_pkg_version_body()
+{
+ const char *path;
+
+ if (!pkg_version_body) {
+ path = DEFAULT_WWW_DIR"/pkg_version.tpl";
+ pkg_version_body = file_get_content(path);
+
+ if (!pkg_version_body)
+ log_err("Failed to read package version template: %s",
+ path);
+ }
+
+ return pkg_version_body;
+}
+static const char *get_ppa_body()
+{
+ const char *path;
+
+ if (!ppa_body) {
+ path = DEFAULT_WWW_DIR"/ppa.tpl";
+ ppa_body = file_get_content(path);
+
+ if (!ppa_body)
+ log_err("Failed to read PPA template: %s", path);
+ }
+
+ return ppa_body;
+}
+
+static const char *get_pkg_body()
+{
+ const char *path;
+
+ if (!pkg_body) {
+ path = DEFAULT_WWW_DIR"/pkg.tpl";
+ pkg_body = file_get_content(path);
+
+ if (!pkg_body)
+ log_err("Failed to read package template: %s", path);
+ }
+
+ return pkg_body;
+}
+
+static void json_add_ddts(json_object *json,
+ struct daily_download_total **ddts)
+{
+ json_object_object_add(json, "ddts", ddts_to_json(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;
+}
+