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_str(&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);
312 char *date_to_str(struct tm tm)
316 str = malloc(4 + 1 + 2 + 1 + 2 + 1);
318 strftime(str, 11, "%Y-%m-%d", &tm);
324 Convert ddts older than 4 weeks to the same JSON representation than
325 the LP one. Newer ddts are not stored in the cache because the data
326 may change during following days. It avoids to miss downloads which
327 are not yet taken in consideration by LP.
329 static json_object *ddts_to_json_for_cache(struct daily_download_total **ddts)
332 struct daily_download_total *ddt;
338 j_ddts = json_object_new_object();
340 tv = malloc(sizeof(struct timeval));
341 gettimeofday(tv, NULL);
343 while (ddts && *ddts) {
346 t = mktime(&(ddt->date));
348 d = difftime(tv->tv_sec, t);
350 if (d > 4 * 7 * 24 * 60 * 60) { /* older than 4 weeks */
351 date = date_to_str(ddt->date);
352 json_object_object_add(j_ddts,
354 json_object_new_int(ddt->count));
366 static char *time_t_to_str(time_t t)
373 str = date_to_str(*tm);
378 char *create_ddts_query(const char *binary_url, time_t st)
384 sdate = time_t_to_str(st);
386 q = malloc(strlen(binary_url)
387 + strlen(QUERY_GET_DAILY_DOWNLOAD_TOTALS)
388 + strlen("&start_date=YYYY-MM-DD")
390 strcpy(q, binary_url);
391 strcat(q, QUERY_GET_DAILY_DOWNLOAD_TOTALS);
392 strcat(q, "&start_date=");
397 q = malloc(strlen(binary_url)
398 + strlen(QUERY_GET_DAILY_DOWNLOAD_TOTALS)
400 strcpy(q, binary_url);
401 strcat(q, QUERY_GET_DAILY_DOWNLOAD_TOTALS);
407 struct daily_download_total **get_daily_download_totals(const char *binary_url)
409 char *url, *key, *content;
410 json_object *j_ddts, *json;
411 struct daily_download_total **retrieved_ddts = NULL;
412 struct daily_download_total **cached_ddts;
413 struct daily_download_total **ddts;
416 key = get_ddts_list_cache_key(binary_url);
418 content = fcache_get(key);
420 json = json_tokener_parse(content);
425 cached_ddts = json_object_to_daily_download_totals(json);
426 last_t = ddts_get_last_date(cached_ddts);
432 url = create_ddts_query(binary_url, last_t);
434 json = get_json_object(url);
439 retrieved_ddts = json_object_to_daily_download_totals(json);
441 ddts = ddts_merge(cached_ddts, retrieved_ddts);
443 json_object_put(json);
444 j_ddts = ddts_to_json_for_cache(ddts);
445 fcache_put(key, json_object_get_string(j_ddts));
446 json_object_put(j_ddts);
453 free(retrieved_ddts);