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)
41 /** Default ws.size value for the getPublishedBinaries request. */
42 static const int DEFAULT_WS_SIZE = 150;
44 static const char *QUERY_GET_DOWNLOAD_COUNT = "?ws.op=getDownloadCount";
46 QUERY_GET_DAILY_DOWNLOAD_TOTALS = "?ws.op=getDailyDownloadTotals";
48 static json_object *get_json_object(const char *url)
50 json_object *obj = NULL;
53 body = get_url_content(url, 0);
56 obj = json_tokener_parse(body);
66 static char *get_bpph_list_cache_key(const char *archive_url)
70 key = malloc(strlen(archive_url + 7) + strlen("/bpph") + 1);
71 sprintf(key, "%s/bpph", archive_url + 7);
76 static char *get_ddts_list_cache_key(const char *url)
80 key = malloc(strlen(url + 7) + strlen("/ddts") + 1);
81 sprintf(key, "%s/ddts", url + 7);
86 static struct bpph **get_bpph_list_from_cache(const char *key)
92 content = fcache_get(key);
96 json = json_tokener_parse(content);
100 list = json_object_to_bpph_list(json);
102 json_object_put(json);
108 static char *get_last_creation_date(struct bpph **list)
116 for (cur = list; *cur; cur++) {
117 t = (*cur)->date_created;
123 return time_to_ISO8601_time(&last);
129 * 'archive_url': LP URL of the archive.
130 * 'size': size of the reply array. Between 1-300, else default value is used.
132 static char *create_query_get_bpph(const char *archive_url,
136 static const char *default_opt = "?ws.op=getPublishedBinaries&ws.size=";
137 static const char *status_opt = "&status=";
141 if (size < 1 || size > 300)
142 size = DEFAULT_WS_SIZE;
144 n = strlen(archive_url) + strlen(default_opt) + 3 + 1;
147 n += strlen(status_opt) + strlen(status);
150 sprintf(url, "%s%s%d", archive_url, default_opt, size);
153 strcat(url, status_opt);
160 struct bpph **get_bpph_list(const char *archive_url,
161 const char *pkg_status,
164 char *url, *key, *tmp;
165 struct bpph **result;
166 struct json_object *o, *bpph_json, *o_next;
170 url = create_query_get_bpph(archive_url, pkg_status, ws_size);
172 key = get_bpph_list_cache_key(archive_url);
174 result = get_bpph_list_from_cache(key);
177 date = get_last_creation_date(result);
180 tmp = malloc(strlen(url)
181 + strlen("&created_since_date=")
184 strcat(tmp, "&created_since_date=");
196 o = get_json_object(url);
205 result = bpph_list_append_list(result,
206 json_object_to_bpph_list(o));
208 o_next = json_object_object_get(o, "next_collection_link");
211 url = strdup(json_object_get_string(o_next));
217 bpph_json = bpph_list_to_json(result);
218 fcache_put(key, json_object_to_json_string(bpph_json));
219 json_object_put(bpph_json);
227 int get_download_count(const char *archive_url)
229 int n = strlen(archive_url) + strlen(QUERY_GET_DOWNLOAD_COUNT) + 1;
230 char *url = malloc(n);
234 strcpy(url, archive_url);
235 strcat(url, QUERY_GET_DOWNLOAD_COUNT);
237 obj = get_json_object(url);
243 result = json_object_get_int(obj);
245 json_object_put(obj);
250 const struct distro_arch_series *get_distro_arch_series(const char *url)
253 const struct distro_arch_series *distro;
256 distro = cache_get(url);
258 return (struct distro_arch_series *)distro;
260 content = get_url_content(url, 1);
265 obj = json_tokener_parse(content);
272 distro = json_object_to_distro_arch_series(obj);
274 json_object_put(obj);
276 cache_put(url, distro, (void (*)(void *))&distro_arch_series_free);
281 const struct distro_series *get_distro_series(const char *url)
284 const struct distro_series *distro;
287 distro = cache_get(url);
289 return (struct distro_series *)distro;
291 content = get_url_content(url, 1);
296 obj = json_tokener_parse(content);
303 distro = json_object_to_distro_series(obj);
305 json_object_put(obj);
307 cache_put(url, distro, (void (*)(void *))&distro_series_free);
313 Convert ddts older than 4 weeks to the same JSON representation than
314 the LP one. Newer ddts are not stored in the cache because the data
315 may change during following days. It avoids to miss downloads which
316 are not yet taken in consideration by LP.
318 static json_object *ddts_to_json_for_cache(struct daily_download_total **ddts)
321 struct daily_download_total *ddt;
327 j_ddts = json_object_new_object();
329 tv = malloc(sizeof(struct timeval));
330 gettimeofday(tv, NULL);
332 while (ddts && *ddts) {
335 t = mktime(&(ddt->date));
337 d = difftime(tv->tv_sec, t);
339 if (d > 4 * 7 * 24 * 60 * 60) { /* older than 4 weeks */
340 date = tm_to_ISO8601_date(&ddt->date);
341 json_object_object_add(j_ddts,
343 json_object_new_int(ddt->count));
355 char *create_ddts_query(const char *binary_url, time_t st)
361 sdate = time_to_ISO8601_date(&st);
363 q = malloc(strlen(binary_url)
364 + strlen(QUERY_GET_DAILY_DOWNLOAD_TOTALS)
365 + strlen("&start_date=YYYY-MM-DD")
367 strcpy(q, binary_url);
368 strcat(q, QUERY_GET_DAILY_DOWNLOAD_TOTALS);
369 strcat(q, "&start_date=");
374 q = malloc(strlen(binary_url)
375 + strlen(QUERY_GET_DAILY_DOWNLOAD_TOTALS)
377 strcpy(q, binary_url);
378 strcat(q, QUERY_GET_DAILY_DOWNLOAD_TOTALS);
384 struct daily_download_total **get_daily_download_totals(const char *binary_url)
386 char *url, *key, *content;
387 json_object *j_ddts, *json;
388 struct daily_download_total **retrieved_ddts = NULL;
389 struct daily_download_total **cached_ddts;
390 struct daily_download_total **ddts;
393 key = get_ddts_list_cache_key(binary_url);
395 content = fcache_get(key);
397 json = json_tokener_parse(content);
404 cached_ddts = json_object_to_daily_download_totals(json);
405 json_object_put(json);
406 last_t = ddts_get_last_date(cached_ddts);
412 url = create_ddts_query(binary_url, last_t);
414 json = get_json_object(url);
419 retrieved_ddts = json_object_to_daily_download_totals(json);
421 ddts = ddts_merge(cached_ddts, retrieved_ddts);
423 json_object_put(json);
424 j_ddts = ddts_to_json_for_cache(ddts);
425 fcache_put(key, json_object_get_string(j_ddts));
426 json_object_put(j_ddts);
432 if (ddts != cached_ddts)
433 daily_download_total_list_free(cached_ddts);
434 daily_download_total_list_free(retrieved_ddts);