merged plib
[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 **l_cur = list;
95
96         while (*l_cur) {
97                 bpph_free(*l_cur);
98                 l_cur++;
99         }
100
101         free(list);
102 }
103
104 char *get_archive_url(const char *owner, const char *ppa)
105 {
106         char *url = malloc(strlen(URL_BASE_LP)
107                            +strlen("/~")
108                            +strlen(owner)
109                            +strlen("/+archive/")
110                            +strlen(ppa)
111                            +1);
112
113         strcpy(url, URL_BASE_LP);
114         strcat(url, "/~");
115         strcat(url, owner);
116         strcat(url, "/+archive/");
117         strcat(url, ppa);
118
119         return url;
120 }
121
122 struct distro_arch_series *distro_arch_series_new(const char *display_name,
123                                                   const char *title,
124                                                   const char *architecture_tag,
125                                                   int is_nominated_arch_indep,
126                                                   const char *distroseries_link)
127 {
128         struct distro_arch_series *d;
129
130         d = malloc(sizeof(struct distro_arch_series));
131
132         d->display_name = strdup(display_name);
133         d->title = strdup(title);
134         d->architecture_tag = strdup(architecture_tag);
135         d->is_nominated_arch_indep = is_nominated_arch_indep;
136         d->distroseries_link = strdup(distroseries_link);
137
138         return d;
139 }
140
141 void distro_arch_series_free(struct distro_arch_series *d)
142 {
143         free(d->display_name);
144         free(d->title);
145         free(d->architecture_tag);
146         free(d->distroseries_link);
147
148         free(d);
149 }
150
151 void distro_arch_series_list_free(struct distro_arch_series **list)
152 {
153         if (list) {
154                 while (*list) {
155                         distro_arch_series_free(*list);
156                         list++;
157                 }
158                 free(list);
159         }
160 }
161
162 void daily_download_total_list_free(struct daily_download_total **list)
163 {
164         if (list) {
165                 struct daily_download_total **cur = list;
166
167                 while (*cur) {
168                         free(*cur);
169                         cur++;
170                 }
171
172                 free(list);
173         }
174 }
175
176 struct bpph **bpph_list_add(struct bpph **list, struct bpph *new)
177 {
178         struct bpph **cur, *bpph;
179
180         if (list)
181                 for (cur = list; *cur; cur++) {
182                         bpph = *cur;
183
184                         if (!strcmp(bpph->self_link, new->self_link))
185                                 return list;
186                 }
187
188         return (struct bpph **)list_add((void **)list, new);
189 }
190
191 struct bpph **bpph_list_append_list(struct bpph **list1, struct bpph **list2)
192 {
193         struct bpph **cur;
194
195         if (!list2)
196                 return list1;
197
198         for (cur = list2; *cur; cur++)
199                 list1 = bpph_list_add(list1, *cur);
200
201         return list1;
202 }
203
204 time_t ddts_get_last_date(struct daily_download_total **ddts)
205 {
206         struct daily_download_total **cur;
207         time_t t, last_t;
208
209         if (!ddts)
210                 return 0;
211
212         last_t = 0;
213         for (cur = ddts; *cur; cur++) {
214                 t = mktime(&(*cur)->date);
215                 if (t > last_t)
216                         last_t = t;
217         }
218
219         return last_t;
220 }
221
222 int ddts_length(struct daily_download_total **ddts)
223 {
224         int n;
225         struct daily_download_total **cur;
226
227         n = 0;
228
229         if (ddts)
230                 for (cur = ddts; *cur; cur++)
231                         n++;
232
233         return n;
234 }
235
236
237 struct daily_download_total **add_total
238 (struct daily_download_total **totals, struct daily_download_total *total)
239 {
240         struct daily_download_total **cur;
241         struct daily_download_total *item;
242
243         if (totals) {
244                 cur = totals;
245                 while (*cur) {
246                         item = *cur;
247
248                         if (item->date.tm_year == total->date.tm_year &&
249                             item->date.tm_mon == total->date.tm_mon &&
250                             item->date.tm_mday == total->date.tm_mday) {
251                                 item->count = total->count;
252                                 return totals;
253                         }
254
255                         cur++;
256                 }
257         }
258
259         item = malloc(sizeof(struct daily_download_total));
260         memcpy(item, total, sizeof(struct daily_download_total));
261
262         return (struct daily_download_total **)
263                 list_add((void **)totals, (void *)item);
264 }
265
266
267 struct daily_download_total **
268 ddts_merge(struct daily_download_total **ddts1,
269            struct daily_download_total **ddts2)
270 {
271         struct daily_download_total **ddts, **cur, **tmp;
272
273         if (ddts1) {
274                 ddts = malloc((ddts_length(ddts1) + 1)
275                               * sizeof(struct daily_download_total *));
276                 memcpy(ddts, ddts1, (ddts_length(ddts1) + 1) * sizeof(void *));
277         } else {
278                 ddts = malloc(sizeof(struct daily_download_total *));
279                 ddts[0] = NULL;
280         }
281
282         if (ddts2)
283                 for (cur = ddts2; *cur; cur++) {
284                         tmp = add_total(ddts, *cur);
285                         if (tmp != ddts)
286                                 ddts = tmp;
287                 }
288
289         return ddts;
290 }
291
292 int ddts_get_count(struct daily_download_total **ddts)
293 {
294         struct daily_download_total **cur;
295         int i;
296
297         i = 0;
298         for (cur = ddts; *cur; cur++)
299                 i += (*cur)->count;
300
301         return i;
302 }