import private svn
[ppastats.git] / src / lp_ws.c
1 /*
2     Copyright (C) 2011 jeanfi@gmail.com
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
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
17     02110-1301 USA
18 */
19
20 #include <stdlib.h>
21 #include <string.h>
22
23 #include <curl/curl.h>
24 #include <json/json.h>
25
26 #include "lp_ws.h"
27 #include "lp_json.h"
28
29 #define QUERY_GET_PUBLISHED_BINARIES \
30         "?ws.op=getPublishedBinaries&status=Published"
31 #define QUERY_GET_DOWNLOAD_COUNT "?ws.op=getDownloadCount"
32 #define QUERY_GET_DAILY_DOWNLOAD_TOTALS \
33         "?ws.op=getDailyDownloadTotals"
34
35 static CURL *curl;
36
37 struct ucontent {
38         char *data;
39         size_t len;
40 };
41
42 static size_t cbk_curl(void *buffer, size_t size, size_t nmemb, void *userp)
43 {
44         size_t realsize = size * nmemb;
45         struct ucontent *mem = (struct ucontent *)userp;
46
47         mem->data = realloc(mem->data, mem->len + realsize + 1);
48
49         memcpy(&(mem->data[mem->len]), buffer, realsize);
50         mem->len += realsize;
51         mem->data[mem->len] = 0;
52
53         return realsize;
54 }
55
56 static char *fetch_url(const char *url)
57 {
58         struct ucontent *content = malloc(sizeof(struct ucontent));
59         char *result = NULL;
60         long code;
61
62         if (!curl)
63                 curl = curl_easy_init();
64
65         if (!curl)
66                 exit(EXIT_FAILURE);
67
68         content->data = malloc(1);
69         content->data[0] = '\0';
70         content->len = 0;
71
72         curl_easy_setopt(curl, CURLOPT_URL, url);
73         curl_easy_setopt(curl, CURLOPT_VERBOSE, 0);
74         curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cbk_curl);
75         curl_easy_setopt(curl, CURLOPT_WRITEDATA, content);
76         curl_easy_setopt(curl, CURLOPT_USERAGENT, "ppastats/0.0");
77
78         if (curl_easy_perform(curl) == CURLE_OK) {
79
80                 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
81                 if (code == 200)
82                         result = content->data;
83         }
84
85         if (!result)
86                 free(content->data);
87
88         free(content);
89
90         return result;
91 }
92
93 static json_object *get_json_object(const char *url)
94 {
95         json_object *obj = NULL;
96         char *body;
97
98         body = fetch_url(url);
99
100         if (body) {
101                 obj = json_tokener_parse(body);
102
103                 free(body);
104
105                 return obj;
106         }
107
108         return NULL;
109 }
110
111 struct binary_package_publishing_history * *
112 get_binary_package_publishing_history_list(const char *archive_url)
113 {
114         char *url = malloc(strlen(archive_url)+
115                            strlen(QUERY_GET_PUBLISHED_BINARIES)+
116                            1);
117         json_object *o;
118         struct binary_package_publishing_history **result;
119
120         strcpy(url, archive_url);
121         strcat(url, QUERY_GET_PUBLISHED_BINARIES);
122
123         o = get_json_object(url);
124         free(url);
125
126         if (!o)
127                 return NULL;
128
129         result = json_object_to_binary_package_publishing_history_list(o);
130
131         json_object_put(o);
132
133         return result;
134 }
135
136 int get_download_count(const char *archive_url)
137 {
138         int n = strlen(archive_url) + strlen(QUERY_GET_DOWNLOAD_COUNT) + 1;
139         char *url = malloc(n);
140         int result;
141         json_object *obj;
142
143         strcpy(url, archive_url);
144         strcat(url, QUERY_GET_DOWNLOAD_COUNT);
145
146         obj = get_json_object(url);
147         free(url);
148
149         if (!obj)
150                 return -1;
151
152         result = json_object_get_int(obj);
153
154         json_object_put(obj);
155
156         return result;
157 }
158
159 struct distro_arch_series *get_distro_arch_series(const char *url)
160 {
161         json_object *obj;
162         struct distro_arch_series *distro;
163
164         obj = get_json_object(url);
165
166         if (!obj)
167                 return NULL;
168
169         distro = json_object_to_distro_arch_series(obj);
170
171         json_object_put(obj);
172
173         return distro;
174 }
175
176 struct daily_download_total **get_daily_download_totals(const char *binary_url)
177 {
178         char *url;
179         json_object *obj;
180         struct daily_download_total **result = NULL;
181
182         url = malloc(strlen(binary_url)+
183                      strlen(QUERY_GET_DAILY_DOWNLOAD_TOTALS)+1);
184
185         strcpy(url, binary_url);
186         strcat(url, QUERY_GET_DAILY_DOWNLOAD_TOTALS);
187
188         obj = get_json_object(url);
189
190         if (obj)
191                 result = json_object_to_daily_download_totals(obj);
192
193         free(url);
194         json_object_put(obj);
195
196         return result;
197 }