added --debug option
authorJean-Philippe Orsini <jeanfi@gmail.com>
Mon, 16 May 2011 08:59:30 +0000 (08:59 +0000)
committerJean-Philippe Orsini <jeanfi@gmail.com>
Mon, 16 May 2011 08:59:30 +0000 (08:59 +0000)
added cache (for distro_arch_series and distro_series)
improved stats displayed

13 files changed:
src/Makefile.am
src/Makefile.in
src/cache.c [new file with mode: 0644]
src/cache.h [new file with mode: 0644]
src/html.c
src/lp.c
src/lp.h
src/lp_json.c
src/lp_json.h
src/lp_ws.c
src/lp_ws.h
src/main.c
src/ppastats.h [new file with mode: 0644]

index 4a81afd..1cd1da4 100644 (file)
@@ -6,11 +6,13 @@ LIBS += $(CURL_LIBS) $(JSON_LIBS)
 
 bin_PROGRAMS = ppastats
 ppastats_SOURCES = \
+       cache.h cache.c\
        html.h html.c\
        lp.h lp.c\
        lp_json.h lp_json.c\
        lp_ws.h lp_ws.c\
-       main.c 
+       main.c\
+       ppastats.h
 
 dist_man_MANS = ppastats.1
 
index 0ba5682..fc6b2a6 100644 (file)
@@ -46,8 +46,8 @@ CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
 am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"
 PROGRAMS = $(bin_PROGRAMS)
-am_ppastats_OBJECTS = html.$(OBJEXT) lp.$(OBJEXT) lp_json.$(OBJEXT) \
-       lp_ws.$(OBJEXT) main.$(OBJEXT)
+am_ppastats_OBJECTS = cache.$(OBJEXT) html.$(OBJEXT) lp.$(OBJEXT) \
+       lp_json.$(OBJEXT) lp_ws.$(OBJEXT) main.$(OBJEXT)
 ppastats_OBJECTS = $(am_ppastats_OBJECTS)
 ppastats_LDADD = $(LDADD)
 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
@@ -187,11 +187,13 @@ AM_CPPFLAGS = -Wall -std=gnu99 -Werror \
        $(CURL_CFLAGS) $(JSON_CFLAGS)
 
 ppastats_SOURCES = \
+       cache.h cache.c\
        html.h html.c\
        lp.h lp.c\
        lp_json.h lp_json.c\
        lp_ws.h lp_ws.c\
-       main.c 
+       main.c\
+       ppastats.h
 
 dist_man_MANS = ppastats.1
 all: all-am
@@ -275,6 +277,7 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cache.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/html.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lp.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lp_json.Po@am__quote@
diff --git a/src/cache.c b/src/cache.c
new file mode 100644 (file)
index 0000000..d70e308
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+    Copyright (C) 2011 jeanfi@gmail.com
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+    02110-1301 USA
+*/
+
+#include "cache.h"
+#include "ppastats.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+/*
+  Stupid cache implementation but should be enough for storing LP data.
+*/
+
+struct entry {
+       const char *key;
+       const void *value;
+       void (*fct_cleanup)(void *);
+};
+
+#define CAPACITY 1024
+
+struct cache {
+       int size;
+       struct entry entries[CAPACITY];
+};
+
+static struct cache cache;
+
+const void *cache_get(const char *key)
+{
+       int i;
+
+       for (i = 0; i < cache.size; i++)
+               if (!strcmp(cache.entries[i].key, key)) {
+                       if (debug)
+                               printf("DEBUG: cache hit %s\n", key);
+
+                       return cache.entries[i].value;
+               }
+
+       if (debug)
+               printf("DEBUG: cache miss %s\n", key);
+
+       return NULL;
+}
+
+void cache_put(const char *key, const void *value,
+              void (*fct_cleanup)(void *))
+{
+       if (cache.size == CAPACITY) {
+               fprintf(stderr, "WARNING: exceed cache capacity\n");
+               return ;
+       }
+
+       cache.entries[cache.size].key = strdup(key);
+       cache.entries[cache.size].value = value;
+       cache.entries[cache.size].fct_cleanup = fct_cleanup;
+
+       cache.size++;
+}
+
+void cache_cleanup()
+{
+       int i;
+
+       for (i = 0; i < cache.size; i++) {
+               free((char *)cache.entries[i].key);
+               cache.entries[i].fct_cleanup((void *)cache.entries[i].value);
+       }
+}
diff --git a/src/cache.h b/src/cache.h
new file mode 100644 (file)
index 0000000..c3462c9
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+    Copyright (C) 2011 jeanfi@gmail.com
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+    02110-1301 USA
+*/
+
+#ifndef _PPASTATS_CACHE_H_
+#define _PPASTATS_CACHE_H_
+
+const void *cache_get(const char *key);
+
+void cache_put(const char *key, const void *value,
+              void (*fct_cleanup)(void *));
+
+void cache_cleanup();
+
+#endif
index 9734c72..fb4dac1 100644 (file)
@@ -142,7 +142,7 @@ build_data_str(struct binary_package_publishing_history **list)
        data = json_object_new_array();
        for (i = 0; i < n; i++) {
                struct binary_package_publishing_history *binary;
-               struct distro_arch_series *dist;
+               const struct distro_arch_series *dist;
                struct daily_download_total **totals;
                struct daily_download_total **t_cur;
 
@@ -175,7 +175,6 @@ build_data_str(struct binary_package_publishing_history **list)
                }
 
                daily_download_total_list_free(totals);
-               distro_arch_series_free(dist);
        }
 
        str = strdup(json_object_to_json_string(data));
index c80210b..e927b2e 100644 (file)
--- a/src/lp.c
+++ b/src/lp.c
 
 #include "lp.h"
 
+struct distro_series *distro_series_new(const char *name,
+                                       const char *version,
+                                       const char *title,
+                                       const char *displayname)
+{
+       struct distro_series *d;
+
+       d = malloc(sizeof(struct distro_series));
+
+       d->name = strdup(name);
+       d->version = strdup(version);
+       d->title = strdup(title);
+       d->displayname = strdup(displayname);
+
+       return d;
+}
+
+void distro_series_free(struct distro_series *d)
+{
+       if (d) {
+               free(d->name);
+               free(d->version);
+               free(d->title);
+               free(d->displayname);
+       }
+}
+
 void
 binary_package_publishing_history_free(struct binary_package_publishing_history *b)
 {
@@ -87,7 +114,8 @@ char *get_archive_url(const char *owner, const char *ppa)
 struct distro_arch_series *distro_arch_series_new(const char *display_name,
                                                  const char *title,
                                                  const char *architecture_tag,
-                                                 int is_nominated_arch_indep)
+                                                 int is_nominated_arch_indep,
+                                                 const char *distroseries_link)
 {
        struct distro_arch_series *d;
 
@@ -97,6 +125,7 @@ struct distro_arch_series *distro_arch_series_new(const char *display_name,
        d->title = strdup(title);
        d->architecture_tag = strdup(architecture_tag);
        d->is_nominated_arch_indep = is_nominated_arch_indep;
+       d->distroseries_link = strdup(distroseries_link);
 
        return d;
 }
@@ -106,6 +135,7 @@ void distro_arch_series_free(struct distro_arch_series *d)
        free(d->display_name);
        free(d->title);
        free(d->architecture_tag);
+       free(d->distroseries_link);
 
        free(d);
 }
index edb87d3..95415c6 100644 (file)
--- a/src/lp.h
+++ b/src/lp.h
@@ -43,14 +43,31 @@ struct distro_arch_series {
        char *title;
        char *architecture_tag;
        int is_nominated_arch_indep;
+       char *distroseries_link;
 };
 
+struct distro_series {
+       char *displayname;
+       char *name;
+       char *version;
+       char *title;
+};
+
+struct distro_series *distro_series_new(const char *name,
+                                       const char *version,
+                                       const char *title,
+                                       const char *displayname);
+
+void distro_series_free(struct distro_series *distro_series);
+
 void daily_download_total_list_free(struct daily_download_total **);
 
-struct distro_arch_series *distro_arch_series_new(const char *display_name,
-                                                 const char *title,
-                                                 const char *architecture_tag,
-                                                 int is_nominated_arch_indep);
+struct distro_arch_series *
+distro_arch_series_new(const char *display_name,
+                      const char *title,
+                      const char *architecture_tag,
+                      int is_nominated_arch_indep,
+                      const char *distroseries_link);
 
 void distro_arch_series_free(struct distro_arch_series *);
 
index 088d189..1c31ccb 100644 (file)
@@ -58,6 +58,7 @@ struct distro_arch_series *json_object_to_distro_arch_series(json_object *o)
        const char *title;
        const char *architecture_tag;
        boolean is_nominated_arch_indep;
+       const char *distroseries_link;
 
 
        display_name = json_object_get_string
@@ -69,14 +70,44 @@ struct distro_arch_series *json_object_to_distro_arch_series(json_object *o)
        architecture_tag = json_object_get_string
                (json_object_object_get(o, "architecture_tag"));
 
+       distroseries_link = json_object_get_string
+               (json_object_object_get(o, "distroseries_link"));
+
        is_nominated_arch_indep = json_object_get_boolean
                (json_object_object_get(o, "is_nominated_arch_indep"));
 
        return distro_arch_series_new(display_name,
                                      title,
                                      architecture_tag,
-                                     is_nominated_arch_indep);
+                                     is_nominated_arch_indep,
+                                     distroseries_link);
 }
+struct distro_series *json_object_to_distro_series(json_object *o)
+{
+       const char *displayname;
+       const char *title;
+       const char *name;
+       const char *version;
+
+       displayname = json_object_get_string
+               (json_object_object_get(o, "displayname"));
+
+       title = json_object_get_string
+               (json_object_object_get(o, "title"));
+
+       version = json_object_get_string
+               (json_object_object_get(o, "version"));
+
+       name = json_object_get_string
+               (json_object_object_get(o, "name"));
+
+       return distro_series_new(name,
+                                version,
+                                title,
+                                displayname);
+}
+
+
 
 struct binary_package_publishing_history * *
 json_object_to_binary_package_publishing_history_list(json_object *o)
index 9d40a54..09b6891 100644 (file)
@@ -31,6 +31,7 @@ struct binary_package_publishing_history * *
 json_object_to_binary_package_publishing_history_list(json_object *o);
 
 struct distro_arch_series *json_object_to_distro_arch_series(json_object *o);
+struct distro_series *json_object_to_distro_series(json_object *o);
 
 struct daily_download_total * *
 json_object_to_daily_download_totals(json_object *o);
index a6b95d1..aa6ace7 100644 (file)
 #include <curl/curl.h>
 #include <json/json.h>
 
+#include "cache.h"
 #include "lp_ws.h"
 #include "lp_json.h"
+#include "ppastats.h"
 
 #define QUERY_GET_PUBLISHED_BINARIES \
        "?ws.op=getPublishedBinaries&status=Published"
@@ -59,8 +61,13 @@ static char *fetch_url(const char *url)
        char *result = NULL;
        long code;
 
-       if (!curl)
+       if (debug)
+               printf("DEBUG: fetch_url %s\n", url);
+
+       if (!curl) {
+               curl_global_init(CURL_GLOBAL_ALL);
                curl = curl_easy_init();
+       }
 
        if (!curl)
                exit(EXIT_FAILURE);
@@ -156,10 +163,14 @@ int get_download_count(const char *archive_url)
        return result;
 }
 
-struct distro_arch_series *get_distro_arch_series(const char *url)
+const struct distro_arch_series *get_distro_arch_series(const char *url)
 {
        json_object *obj;
-       struct distro_arch_series *distro;
+       const struct distro_arch_series *distro;
+
+       distro = cache_get(url);
+       if (distro)
+               return (struct distro_arch_series *)distro;
 
        obj = get_json_object(url);
 
@@ -170,6 +181,31 @@ struct distro_arch_series *get_distro_arch_series(const char *url)
 
        json_object_put(obj);
 
+       cache_put(url, distro, (void (*)(void *))&distro_arch_series_free);
+
+       return distro;
+}
+
+const struct distro_series *get_distro_series(const char *url)
+{
+       json_object *obj;
+       const struct distro_series *distro;
+
+       distro = cache_get(url);
+       if (distro)
+               return (struct distro_series *)distro;
+
+       obj = get_json_object(url);
+
+       if (!obj)
+               return NULL;
+
+       distro = json_object_to_distro_series(obj);
+
+       json_object_put(obj);
+
+       cache_put(url, distro, (void (*)(void *))&distro_series_free);
+
        return distro;
 }
 
@@ -187,11 +223,21 @@ struct daily_download_total **get_daily_download_totals(const char *binary_url)
 
        obj = get_json_object(url);
 
-       if (obj)
+       if (obj) {
                result = json_object_to_daily_download_totals(obj);
+               json_object_put(obj);
+       }
 
        free(url);
-       json_object_put(obj);
 
        return result;
 }
+
+void lp_ws_cleanup()
+{
+       if (debug)
+               printf("DEBUG: cleanup CURL\n");
+
+       curl_easy_cleanup(curl);
+       curl_global_cleanup();
+}
index 30d6d75..f4489dc 100644 (file)
@@ -27,8 +27,12 @@ get_binary_package_publishing_history_list(const char *archive_url);
 
 int get_download_count(const char *archive_url);
 
-struct distro_arch_series *get_distro_arch_series(const char *url);
+const struct distro_arch_series *get_distro_arch_series(const char *url);
 
 struct daily_download_total **get_daily_download_totals(const char *binary_url);
 
+const struct distro_series *get_distro_series(const char *distro_series_url);
+
+void lp_ws_cleanup();
+
 #endif
index 0df293d..02861ea 100644 (file)
 #include <stdio.h>
 #include <string.h>
 
+#include "cache.h"
 #include "html.h"
 #include "lp_ws.h"
 #include "config.h"
+#include "ppastats.h"
 
+int debug;
 static const char *program_name;
 
 static void display_published_binaries(const char *owner, const char *ppa)
@@ -44,15 +47,18 @@ static void display_published_binaries(const char *owner, const char *ppa)
        e_cur = list;
        while (*e_cur) {
                struct binary_package_publishing_history *binary;
-               struct distro_arch_series *dist;
+               const struct distro_arch_series *arch;
+               const struct distro_series *distro;
 
                binary = *e_cur;
-               dist = get_distro_arch_series(binary->distro_arch_series_link);
+               arch = get_distro_arch_series(binary->distro_arch_series_link);
+               distro = get_distro_series(arch->distroseries_link);
 
-               printf("%s %s %s %d\n",
-                      dist->display_name,
+               printf("%s %s %s(%s): %d\n",
                       binary->binary_package_name,
                       binary->binary_package_version,
+                      distro->name,
+                      arch->architecture_tag,
                       get_download_count(binary->self_link));
                e_cur++;
        }
@@ -64,6 +70,7 @@ static struct option long_options[] = {
        {"version", no_argument, 0, 'v'},
        {"help", no_argument, 0, 'h'},
        {"html", no_argument, 0, 't'},
+       {"debug", no_argument, 0, 'd'},
        {0, 0, 0, 0}
 };
 
@@ -117,12 +124,15 @@ int main(int argc, char **argv)
 
        program_name = argv[0];
 
-       while ((optc = getopt_long(argc, argv, "vht", long_options,
+       while ((optc = getopt_long(argc, argv, "vhtd", long_options,
                                   NULL)) != -1) {
                switch (optc) {
                case 't':
                        output_html = 1;
                        break;
+               case 'd':
+                       debug = 1;
+                       break;
                case 'h':
                        print_help();
                        exit(EXIT_SUCCESS);
@@ -149,5 +159,9 @@ int main(int argc, char **argv)
        else
                display_published_binaries(owner, ppa);
 
+       /* for valgrind.... */
+       lp_ws_cleanup();
+       cache_cleanup();
+
        exit(EXIT_SUCCESS);
 }
diff --git a/src/ppastats.h b/src/ppastats.h
new file mode 100644 (file)
index 0000000..4eabf01
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+    Copyright (C) 2011 jeanfi@gmail.com
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+    02110-1301 USA
+*/
+
+#ifndef _PPASTATS_PPASTATS_H_
+#define _PPASTATS_PPASTATS_H_
+
+extern int debug;
+
+#endif