normalize #include
[ppastats.git] / src / lp.c
1 /*
2  * Copyright (C) 2011-2014 jeanfi@gmail.com
3  *
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.
8  *
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.
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 <stdio.h>
22 #include <string.h>
23
24 #include <list.h>
25 #include <lp.h>
26 #include <ptime.h>
27
28 struct distro_series *distro_series_new(const char *name,
29                                         const char *version,
30                                         const char *title,
31                                         const char *displayname)
32 {
33         struct distro_series *d;
34
35         d = malloc(sizeof(struct distro_series));
36
37         d->name = strdup(name);
38         d->version = strdup(version);
39         d->title = strdup(title);
40         d->displayname = strdup(displayname);
41
42         return d;
43 }
44
45 void distro_series_free(struct distro_series *d)
46 {
47         if (d) {
48                 free(d->name);
49                 free(d->version);
50                 free(d->title);
51                 free(d->displayname);
52
53                 free(d);
54         }
55 }
56
57 void bpph_free(struct bpph *b)
58 {
59         if (b) {
60                 free(b->binary_package_name);
61                 free(b->binary_package_version);
62                 free(b->distro_arch_series_link);
63                 free(b->self_link);
64                 free(b->status);
65                 free(b);
66         }
67 }
68
69 struct bpph *bpph_new(const char *binary_package_name,
70                       const char *binary_package_version,
71                       const char *distro_arch_series_link,
72                       const char *self_link,
73                       const char *status,
74                       int architecture_specific,
75                       time_t date_created)
76 {
77         struct bpph *h;
78
79         h = malloc(sizeof(struct bpph));
80
81         h->binary_package_name = strdup(binary_package_name);
82         h->binary_package_version = strdup(binary_package_version);
83         h->distro_arch_series_link = strdup(distro_arch_series_link);
84         h->self_link = strdup(self_link);
85         h->architecture_specific = architecture_specific;
86         h->status = strdup(status);
87         h->date_created = date_created;
88
89         return h;
90 }
91
92 void bpph_list_free(struct bpph **list)
93 {
94         struct bpph **cur;
95
96         if (list) {
97                 cur = list;
98
99                 while (*cur) {
100                         bpph_free(*cur);
101                         cur++;
102                 }
103
104                 free(list);
105         }
106 }
107
108 char *get_archive_url(const char *owner, const char *ppa)
109 {
110         char *url = malloc(strlen(URL_BASE_LP)
111                            +strlen("/~")
112                            +strlen(owner)
113                            +strlen("/+archive/")
114                            +strlen(ppa)
115                            +1);
116
117         strcpy(url, URL_BASE_LP);
118         strcat(url, "/~");
119         strcat(url, owner);
120         strcat(url, "/+archive/");
121         strcat(url, ppa);
122
123         return url;
124 }
125
126 struct distro_arch_series *distro_arch_series_new(const char *display_name,
127                                                   const char *title,
128                                                   const char *architecture_tag,
129                                                   int is_nominated_arch_indep,
130                                                   const char *distroseries_link)
131 {
132         struct distro_arch_series *d;
133
134         d = malloc(sizeof(struct distro_arch_series));
135
136         d->display_name = strdup(display_name);
137         d->title = strdup(title);
138         d->architecture_tag = strdup(architecture_tag);
139         d->is_nominated_arch_indep = is_nominated_arch_indep;
140         d->distroseries_link = strdup(distroseries_link);
141
142         return d;
143 }
144
145 void distro_arch_series_free(struct distro_arch_series *d)
146 {
147         free(d->display_name);
148         free(d->title);
149         free(d->architecture_tag);
150         free(d->distroseries_link);
151
152         free(d);
153 }
154
155 void distro_arch_series_list_free(struct distro_arch_series **list)
156 {
157         struct distro_arch_series **cur;
158
159         if (list) {
160                 cur = list;
161                 while (*cur) {
162                         distro_arch_series_free(*cur);
163                         cur++;
164                 }
165                 free(list);
166         }
167 }
168
169 void daily_download_total_list_free(struct daily_download_total **list)
170 {
171         if (list) {
172                 struct daily_download_total **cur = list;
173
174                 while (*cur) {
175                         free(*cur);
176                         cur++;
177                 }
178
179                 free(list);
180         }
181 }
182
183 struct bpph **bpph_list_add(struct bpph **list, struct bpph *new)
184 {
185         struct bpph **cur, *bpph, **result;
186
187         if (list)
188                 for (cur = list; *cur; cur++) {
189                         bpph = *cur;
190
191                         if (!strcmp(bpph->self_link, new->self_link))
192                                 return list;
193                 }
194
195         result = (struct bpph **)list_add((void **)list, new);
196
197         free(list);
198
199         return result;
200 }
201
202 struct bpph **bpph_list_append_list(struct bpph **list1, struct bpph **list2)
203 {
204         struct bpph **cur;
205
206         if (!list2)
207                 return list1;
208
209         for (cur = list2; *cur; cur++)
210                 list1 = bpph_list_add(list1, *cur);
211
212         return list1;
213 }
214
215 time_t ddts_get_last_date(struct daily_download_total **ddts)
216 {
217         struct daily_download_total **cur;
218         time_t t, last_t;
219
220         if (!ddts)
221                 return 0;
222
223         last_t = 0;
224         for (cur = ddts; *cur; cur++) {
225                 t = mktime(&(*cur)->date);
226                 if (t > last_t)
227                         last_t = t;
228         }
229
230         return last_t;
231 }
232
233 int ddts_length(struct daily_download_total **ddts)
234 {
235         int n;
236         struct daily_download_total **cur;
237
238         n = 0;
239
240         if (ddts)
241                 for (cur = ddts; *cur; cur++)
242                         n++;
243
244         return n;
245 }
246
247 struct daily_download_total *ddt_clone(struct daily_download_total *ddt)
248 {
249         struct daily_download_total *new;
250
251         new = malloc(sizeof(struct daily_download_total));
252
253         new->date = ddt->date;
254         new->count = ddt->count;
255
256         return new;
257 }
258
259 struct daily_download_total **
260 ddts_clone(struct daily_download_total **ddts)
261 {
262         int n, i;
263         struct daily_download_total **new;
264
265         n = ddts_length(ddts);
266
267         new = malloc((n + 1) * sizeof(struct daily_download_total *));
268
269         for (i = 0; i < n; i++)
270                 new[i] = ddt_clone(ddts[i]);
271
272         new[n] = NULL;
273
274         return new;
275 }
276
277 /*
278   Return a newly allocated list with an additional ddt.
279   All ddts are cloned.
280  */
281 static struct daily_download_total **add_ddt
282 (struct daily_download_total **totals, struct daily_download_total *total)
283 {
284         struct daily_download_total **cur, **ddts, **result;
285         struct daily_download_total *item;
286
287         if (totals) {
288                 cur = totals;
289                 while (*cur) {
290                         item = *cur;
291
292                         if (item->date.tm_year == total->date.tm_year &&
293                             item->date.tm_mon == total->date.tm_mon &&
294                             item->date.tm_mday == total->date.tm_mday) {
295                                 item->count = total->count;
296                                 return totals;
297                         }
298
299                         cur++;
300                 }
301         }
302
303         ddts = ddts_clone(totals);
304
305         result = (struct daily_download_total **)
306                 list_add((void **)ddts, ddt_clone((void *)total));
307
308         free(ddts);
309
310         return result;
311 }
312
313 struct daily_download_total **
314 ddts_merge(struct daily_download_total **ddts1,
315            struct daily_download_total **ddts2)
316 {
317         struct daily_download_total **ddts, **cur, **tmp;
318
319         if (ddts1) {
320                 ddts = ddts_clone(ddts1);
321         } else {
322                 ddts = malloc(sizeof(struct daily_download_total *));
323                 ddts[0] = NULL;
324         }
325
326         if (ddts2)
327                 for (cur = ddts2; *cur; cur++) {
328                         tmp = add_ddt(ddts, *cur);
329                         if (tmp != ddts) {
330                                 daily_download_total_list_free(ddts);
331                                 ddts = tmp;
332                         }
333                 }
334
335         return ddts;
336 }
337
338 int ddts_get_count(struct daily_download_total **ddts)
339 {
340         struct daily_download_total **cur;
341         int i;
342
343         i = 0;
344         for (cur = ddts; *cur; cur++)
345                 i += (*cur)->count;
346
347         return i;
348 }