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)
40 /** Default ws.size value for the getPublishedBinaries request. */
41 static const int DEFAULT_WS_SIZE = 150;
43 static const char *QUERY_GET_DOWNLOAD_COUNT = "?ws.op=getDownloadCount";
45 QUERY_GET_DAILY_DOWNLOAD_TOTALS = "?ws.op=getDailyDownloadTotals";
47 static json_object *get_json_object(const char *url)
49 json_object *obj = NULL;
52 body = get_url_content(url, 0);
55 obj = json_tokener_parse(body);
65 static char *get_bpph_list_cache_key(const char *archive_url)
69 key = malloc(strlen(archive_url + 7) + strlen("/bpph") + 1);
70 sprintf(key, "%s/bpph", archive_url + 7);
75 static char *get_ddts_list_cache_key(const char *url)
79 key = malloc(strlen(url + 7) + strlen("/ddts") + 1);
80 sprintf(key, "%s/ddts", url + 7);
85 static struct bpph **get_bpph_list_from_cache(const char *key)
91 content = fcache_get(key);
95 json = json_tokener_parse(content);
99 list = json_object_to_bpph_list(json);
101 json_object_put(json);
107 static char *get_last_creation_date(struct bpph **list)
115 for (cur = list; *cur; cur++) {
116 t = (*cur)->date_created;
122 return time_to_str(last);
128 * 'archive_url': LP URL of the archive.
129 * 'size': size of the reply array. Between 1-300, else default value is used.
131 static char *create_query_get_bpph(const char *archive_url,
135 static const char *default_opt = "?ws.op=getPublishedBinaries&ws.size=";
136 static const char *status_opt = "&status=";
140 if (size < 1 || size > 300)
141 size = DEFAULT_WS_SIZE;
143 n = strlen(archive_url) + strlen(default_opt) + 3 + 1;
146 n += strlen(status_opt) + strlen(status);
149 sprintf(url, "%s%s%d", archive_url, default_opt, size);
152 strcat(url, status_opt);
159 struct bpph **get_bpph_list(const char *archive_url,
160 const char *pkg_status,
163 char *url, *key, *tmp;
164 struct bpph **result;
165 struct json_object *o, *bpph_json, *o_next;
169 url = create_query_get_bpph(archive_url, pkg_status, ws_size);
171 key = get_bpph_list_cache_key(archive_url);
173 result = get_bpph_list_from_cache(key);
176 date = get_last_creation_date(result);
179 tmp = malloc(strlen(url)
180 + strlen("&created_since_date=")
183 strcat(tmp, "&created_since_date=");
195 o = get_json_object(url);
204 result = bpph_list_append_list(result,
205 json_object_to_bpph_list(o));
207 o_next = json_object_object_get(o, "next_collection_link");
210 url = strdup(json_object_get_string(o_next));
216 bpph_json = bpph_list_to_json(result);
217 fcache_put(key, json_object_to_json_string(bpph_json));
218 json_object_put(bpph_json);
226 int get_download_count(const char *archive_url)
228 int n = strlen(archive_url) + strlen(QUERY_GET_DOWNLOAD_COUNT) + 1;
229 char *url = malloc(n);
233 strcpy(url, archive_url);
234 strcat(url, QUERY_GET_DOWNLOAD_COUNT);
236 obj = get_json_object(url);
242 result = json_object_get_int(obj);
244 json_object_put(obj);
249 const struct distro_arch_series *get_distro_arch_series(const char *url)
252 const struct distro_arch_series *distro;
255 distro = cache_get(url);
257 return (struct distro_arch_series *)distro;
259 content = get_url_content(url, 1);
264 obj = json_tokener_parse(content);
271 distro = json_object_to_distro_arch_series(obj);
273 json_object_put(obj);
275 cache_put(url, distro, (void (*)(void *))&distro_arch_series_free);
280 const struct distro_series *get_distro_series(const char *url)
283 const struct distro_series *distro;
286 distro = cache_get(url);
288 return (struct distro_series *)distro;
290 content = get_url_content(url, 1);
295 obj = json_tokener_parse(content);
302 distro = json_object_to_distro_series(obj);
304 json_object_put(obj);
306 cache_put(url, distro, (void (*)(void *))&distro_series_free);
311 char *date_to_str(struct tm tm)
315 str = malloc(4 + 1 + 2 + 1 + 2 + 1);
317 strftime(str, 11, "%Y-%m-%d", &tm);
323 Convert ddts older than 4 weeks to the same JSON representation than
324 the LP one. Newer ddts are not stored in the cache because the data
325 may change during following days. It avoids to miss downloads which
326 are not yet taken in consideration by LP.
328 static json_object *ddts_to_json_for_cache(struct daily_download_total **ddts)
331 struct daily_download_total *ddt;
337 j_ddts = json_object_new_object();
339 tv = malloc(sizeof(struct timeval));
340 gettimeofday(tv, NULL);
342 while (ddts && *ddts) {
345 t = mktime(&(ddt->date));
347 d = difftime(tv->tv_sec, t);
349 if (d > 4 * 7 * 24 * 60 * 60) { /* older than 4 weeks */
350 date = date_to_str(ddt->date);
351 json_object_object_add(j_ddts,
353 json_object_new_int(ddt->count));
365 static char *time_t_to_str(time_t t)
372 str = date_to_str(*tm);
377 char *create_ddts_query(const char *binary_url, time_t st)
383 sdate = time_t_to_str(st);
385 q = malloc(strlen(binary_url)
386 + strlen(QUERY_GET_DAILY_DOWNLOAD_TOTALS)
387 + strlen("&start_date=YYYY-MM-DD")
389 strcpy(q, binary_url);
390 strcat(q, QUERY_GET_DAILY_DOWNLOAD_TOTALS);
391 strcat(q, "&start_date=");
396 q = malloc(strlen(binary_url)
397 + strlen(QUERY_GET_DAILY_DOWNLOAD_TOTALS)
399 strcpy(q, binary_url);
400 strcat(q, QUERY_GET_DAILY_DOWNLOAD_TOTALS);
406 struct daily_download_total **get_daily_download_totals(const char *binary_url)
408 char *url, *key, *content;
409 json_object *j_ddts, *json;
410 struct daily_download_total **retrieved_ddts = NULL;
411 struct daily_download_total **cached_ddts;
412 struct daily_download_total **ddts;
415 key = get_ddts_list_cache_key(binary_url);
417 content = fcache_get(key);
419 json = json_tokener_parse(content);
424 cached_ddts = json_object_to_daily_download_totals(json);
425 last_t = ddts_get_last_date(cached_ddts);
431 url = create_ddts_query(binary_url, last_t);
433 json = get_json_object(url);
438 retrieved_ddts = json_object_to_daily_download_totals(json);
440 ddts = ddts_merge(cached_ddts, retrieved_ddts);
442 json_object_put(json);
443 j_ddts = ddts_to_json_for_cache(ddts);
444 fcache_put(key, json_object_get_string(j_ddts));
445 json_object_put(j_ddts);
452 free(retrieved_ddts);