1 /*
2 * Copyright (C) 2008 MP3tunes, LLC
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library 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 GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #ifndef _GNU_SOURCE
20 #define _GNU_SOURCE
21 #endif
22 #include <string.h>
23 #include <stdlib.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
26 #include <unistd.h>
27 #include <curl/curl.h>
28 #include <libxml/encoding.h>
29 #include <libxml/xmlwriter.h>
30 #include <libxml/xmlreader.h>
31 #include <libxml/xpath.h>
32 #include "locker.h"
33 #include "md5.h"
34
35 typedef struct {
36 char *data;
37 size_t size;
38 int offset;
39 } chunk_t;
40
41 typedef struct {
42 CURL *curl;
43 char *url;
44 } request_t;
45
chunk_init(chunk_t ** chunk)46 void chunk_init(chunk_t** chunk) {
47 chunk_t *c = *chunk = (chunk_t*)malloc(sizeof(chunk_t));
48 c->data = NULL;
49 c->size = 0;
50 }
51
chunk_set_data(chunk_t * chunk,char * data)52 void chunk_set_data(chunk_t* chunk, char* data) {
53 chunk->data = data;
54 chunk->size = strlen(data);
55 }
56
chunk_deinit(chunk_t ** chunk)57 void chunk_deinit(chunk_t** chunk) {
58 chunk_t *c = *chunk;
59 free(c->data);
60 free(c);
61 }
62
63 struct xml_xpath_s {
64 xmlDocPtr document;
65 xmlXPathContextPtr xpath_ctx;
66 xmlNodePtr context;
67 };
68
69 typedef struct xml_xpath_s xml_xpath_t;
70
write_chunk_callback(void * ptr,size_t size,size_t nmemb,void * data)71 size_t write_chunk_callback( void *ptr, size_t size, size_t nmemb, void *data ) {
72 size_t realsize = size * nmemb;
73 chunk_t *chunk = (chunk_t *)data;
74 chunk->data = (char *)realloc( chunk->data, chunk->size + realsize + 1 );
75 if( chunk->data != NULL ) {
76 memcpy( &(chunk->data[ chunk->size ]), ptr, realsize );
77 chunk->size += realsize;
78 chunk->data[ chunk->size ] = 0;
79 }
80
81 return realsize;
82 }
83
xml_xpath_init(xmlDocPtr document)84 xml_xpath_t* xml_xpath_init(xmlDocPtr document) {
85 xml_xpath_t *result = malloc(sizeof(xml_xpath_t));
86 if (result == NULL)
87 return NULL;
88
89 result->document = document;
90 result->xpath_ctx = xmlXPathNewContext(result->document);
91 if(result->xpath_ctx == NULL) {
92 xmlFreeDoc(result->document);
93 free(result);
94 return NULL;
95 }
96 result->context = NULL;
97
98 return result;
99 }
100
xml_xpath_context_init(xml_xpath_t * xml_xpath,xmlNodePtr node)101 xml_xpath_t* xml_xpath_context_init(xml_xpath_t* xml_xpath, xmlNodePtr node) {
102 xml_xpath_t *result = malloc(sizeof(xml_xpath_t));
103 if (result == NULL)
104 return NULL;
105
106 result->document = xml_xpath->document;
107 result->xpath_ctx = xmlXPathNewContext(result->document);
108 if(result->xpath_ctx == NULL) {
109 xmlFreeDoc(result->document);
110 free(result);
111 return NULL;
112 }
113 result->xpath_ctx->node = node;
114 result->context = node;
115
116 return result;
117 }
118
xml_xpath_deinit(xml_xpath_t * xml_xpath)119 void xml_xpath_deinit(xml_xpath_t* xml_xpath) {
120 xmlXPathFreeContext(xml_xpath->xpath_ctx);
121 if (xml_xpath->context == NULL) {
122 xmlFreeDoc(xml_xpath->document);
123 }
124 free(xml_xpath);
125 }
126
xml_xpath_query(xml_xpath_t * xml_xpath,const char * xpath_expression)127 xmlXPathObjectPtr xml_xpath_query(xml_xpath_t *xml_xpath, const char* xpath_expression) {
128 xmlXPathObjectPtr xpath_obj;
129
130 xpath_obj = xmlXPathEvalExpression((xmlChar*)xpath_expression, xml_xpath->xpath_ctx);
131 if (xpath_obj == NULL) {
132 return NULL;
133 }
134 if (xpath_obj->type != XPATH_NODESET) {
135 xmlXPathFreeObject(xpath_obj);
136 return NULL;
137 }
138 return xpath_obj;
139 }
140
xml_get_text_from_nodeset(xmlNodeSetPtr nodeset)141 char* xml_get_text_from_nodeset(xmlNodeSetPtr nodeset) {
142 xmlNodePtr node;
143 xmlNodePtr child;
144 int total_nodes;
145 char* result = NULL;
146 total_nodes = (nodeset) ? nodeset->nodeNr : 0;
147
148 if (total_nodes != 1) {
149 return NULL;
150 }
151
152 if (nodeset->nodeTab[0]->type != XML_ELEMENT_NODE) {
153 return NULL;
154 }
155
156 node = nodeset->nodeTab[0];
157 child = node->children;
158 while (child && (XML_TEXT_NODE != child->type))
159 child = child->next;
160 if (child && (XML_TEXT_NODE == child->type)) {
161 result = strdup((char*)child->content);
162 }
163 return result;
164 }
165
xml_xpath_get_string(xml_xpath_t * xml_xpath,const char * xpath_expression)166 static char* xml_xpath_get_string(xml_xpath_t *xml_xpath, const char* xpath_expression) {
167 xmlXPathObjectPtr xpath_obj;
168 char* result = NULL;
169
170 xpath_obj = xml_xpath_query(xml_xpath, xpath_expression);
171 if (xpath_obj == NULL)
172 return NULL;
173
174 result = xml_get_text_from_nodeset(xpath_obj->nodesetval);
175
176 xmlXPathFreeObject(xpath_obj);
177
178 return result;
179 }
180
xml_xpath_get_integer(xml_xpath_t * xml_xpath,const char * xpath_expression)181 int xml_xpath_get_integer(xml_xpath_t *xml_xpath, const char* xpath_expression) {
182 int result = 0;
183 char* str = xml_xpath_get_string(xml_xpath, xpath_expression);
184 if (str != NULL) {
185 result = atoi(str);
186 }
187 free(str);
188 return result;
189 }
190
xml_xpath_get_float(xml_xpath_t * xml_xpath,const char * xpath_expression)191 float xml_xpath_get_float(xml_xpath_t *xml_xpath, const char* xpath_expression) {
192 float result = 0.0;
193 char* str = xml_xpath_get_string(xml_xpath, xpath_expression);
194 if (str != NULL) {
195 result = atof(str);
196 }
197 free(str);
198 return result;
199 }
200
mp3tunes_locker_init(mp3tunes_locker_object_t ** obj,const char * partner_token)201 int mp3tunes_locker_init( mp3tunes_locker_object_t **obj, const char *partner_token ) {
202 mp3tunes_locker_object_t *o = *obj = (mp3tunes_locker_object_t*)malloc(sizeof(mp3tunes_locker_object_t));
203 memset(o, 0, sizeof(*o));
204
205 o->partner_token = strdup(partner_token);
206 o->session_id = NULL;
207 o->error_message = NULL;
208
209 o->server_api = getenv("MP3TUNES_SERVER_API");
210 if(o->server_api == NULL) {
211 o->server_api = strdup(MP3TUNES_SERVER_API_URL);
212 }
213
214 o->server_content = getenv("MP3TUNES_SERVER_CONTENT");
215 if(o->server_content == NULL) {
216 o->server_content = strdup(MP3TUNES_SERVER_CONTENT_URL);
217 }
218
219 o->server_login = getenv("MP3TUNES_SERVER_LOGIN");
220 if(o->server_login == NULL) {
221 o->server_login = strdup(MP3TUNES_SERVER_LOGIN_URL);
222 }
223
224 return TRUE;
225 }
226
mp3tunes_locker_deinit(mp3tunes_locker_object_t ** obj)227 int mp3tunes_locker_deinit( mp3tunes_locker_object_t **obj ) {
228 mp3tunes_locker_object_t *o = *obj;
229 free(o->partner_token);
230 free(o->session_id);
231 free(o->error_message);
232 free(o);
233 return TRUE;
234 }
235
mp3tunes_request_init(request_t ** request)236 void mp3tunes_request_init(request_t **request) {
237 request_t *r = *request = malloc(sizeof(request_t));
238 r->curl = curl_easy_init();
239 r->url = NULL;
240 }
241
mp3tunes_request_deinit(request_t ** request)242 void mp3tunes_request_deinit(request_t **request) {
243 request_t *r = *request;
244 curl_easy_cleanup(r->curl);
245 free(r->url);
246 free(r);
247 }
248
mp3tunes_locker_api_generate_request_valist(mp3tunes_locker_object_t * obj,int server,const char * path,const char * first_name,va_list argp)249 static request_t* mp3tunes_locker_api_generate_request_valist(mp3tunes_locker_object_t *obj, int server, const char* path, const char* first_name, va_list argp) {
250 request_t *request;
251 char *server_url;
252 char *name, *value;
253 char *encoded_name, *encoded_value;
254
255 mp3tunes_request_init(&request);
256
257 switch (server) {
258 case MP3TUNES_SERVER_LOGIN:
259 server_url = obj->server_login;
260 break;
261 case MP3TUNES_SERVER_CONTENT:
262 server_url = obj->server_content;
263 break;
264 case MP3TUNES_SERVER_API:
265 server_url = obj->server_api;
266 break;
267 default:
268 mp3tunes_request_deinit(&request);
269 return NULL;
270 break;
271 }
272
273 char *url = 0;
274 size_t url_size = asprintf(&url, "http://%s/%s?", server_url, path) +1;
275 name = (char*) first_name;
276 while (name) {
277 char *url_part;
278
279 value = va_arg(argp, char*);
280
281 encoded_name = curl_easy_escape(request->curl, name, 0);
282 encoded_value = curl_easy_escape(request->curl, value, 0);
283 size_t url_part_size = asprintf(&url_part, "%s=%s&", encoded_name, encoded_value);
284 curl_free(encoded_name);
285 curl_free(encoded_value);
286
287 url = realloc(url, url_size += url_part_size);
288 strcat(url, url_part);
289
290 name = va_arg(argp, char*);
291 }
292
293 char *end_url_part = NULL;
294 size_t end_url_part_size = 0;
295 if (server != MP3TUNES_SERVER_LOGIN) {
296 if (obj->session_id != NULL) {
297 if (server == MP3TUNES_SERVER_API) {
298 end_url_part_size = asprintf(&end_url_part, "output=xml&sid=%s&partner_token=%s", obj->session_id, obj->partner_token);
299 } else {
300 end_url_part_size = asprintf(&end_url_part, "sid=%s&partner_token=%s", obj->session_id, obj->partner_token);
301 }
302 } else {
303 printf("Failed because of no session id\n");
304 free(url);
305 mp3tunes_request_deinit(&request);
306 return NULL;
307 }
308 } else {
309 end_url_part_size = asprintf(&end_url_part, "output=xml&partner_token=%s", obj->partner_token);
310 }
311 url = realloc(url, url_size += end_url_part_size);
312 strcat(url, end_url_part);
313
314 request->url = url;
315 return request;
316
317 }
318
mp3tunes_locker_api_generate_request(mp3tunes_locker_object_t * obj,int server,const char * path,const char * first_name,...)319 static request_t* mp3tunes_locker_api_generate_request(mp3tunes_locker_object_t *obj, int server, const char* path, const char* first_name, ...) {
320 va_list argp;
321 request_t *request;
322 va_start(argp, first_name);
323 request = mp3tunes_locker_api_generate_request_valist(obj, server, path, first_name, argp);
324 va_end(argp);
325 return request;
326 }
327
mp3tunes_locker_api_simple_fetch(mp3tunes_locker_object_t * obj,int server,const char * path,const char * first_name,...)328 static xml_xpath_t* mp3tunes_locker_api_simple_fetch(mp3tunes_locker_object_t *obj, int server, const char* path, const char* first_name, ...) {
329 request_t *request;
330 CURLcode res;
331 chunk_t *chunk;
332 va_list argp;
333
334 chunk_init(&chunk);
335
336 va_start(argp, first_name);
337
338 request = mp3tunes_locker_api_generate_request_valist(obj, server, path, first_name, argp);
339
340 va_end(argp);
341
342 if (request == NULL) {
343 chunk_deinit(&chunk);
344 return NULL;
345 }
346
347 curl_easy_setopt( request->curl, CURLOPT_URL, request->url );
348 curl_easy_setopt( request->curl, CURLOPT_WRITEFUNCTION, write_chunk_callback );
349 curl_easy_setopt( request->curl, CURLOPT_WRITEDATA, (void *)chunk );
350 curl_easy_setopt( request->curl, CURLOPT_USERAGENT, "liboboe/1.0" );
351 curl_easy_setopt( request->curl, CURLOPT_NOPROGRESS, 1 );
352
353 res = curl_easy_perform(request->curl);
354 /* curl_easy_cleanup(request->curl); */
355 mp3tunes_request_deinit(&request);
356
357 if (res != CURLE_OK) {
358 chunk_deinit(&chunk);
359 return NULL;
360 }
361
362 if (chunk->data == NULL) {
363 return NULL;
364 }
365
366 /*printf("Fetch result:\n%s\n", chunk->data);*/
367
368 xmlDocPtr document = xmlParseDoc((xmlChar*)chunk->data);
369
370 chunk_deinit(&chunk);
371
372 if (document == NULL) {
373 return NULL;
374 }
375
376 return xml_xpath_init(document);
377 }
378
mp3tunes_locker_api_post_fetch(mp3tunes_locker_object_t * obj,int server,const char * path,char * post_data)379 static xml_xpath_t* mp3tunes_locker_api_post_fetch(mp3tunes_locker_object_t *obj, int server, const char* path, char* post_data) {
380 request_t *request;
381 CURLcode res;
382 chunk_t *chunk;
383
384 chunk_init(&chunk);
385
386 request = mp3tunes_locker_api_generate_request(obj, server, path, NULL);
387 if (request == NULL) {
388 chunk_deinit(&chunk);
389 return NULL;
390 }
391
392 curl_easy_setopt( request->curl, CURLOPT_URL, request->url );
393 curl_easy_setopt( request->curl, CURLOPT_WRITEFUNCTION, write_chunk_callback );
394 curl_easy_setopt( request->curl, CURLOPT_WRITEDATA, (void *)chunk );
395 curl_easy_setopt( request->curl, CURLOPT_USERAGENT, "liboboe/1.0" );
396 curl_easy_setopt( request->curl, CURLOPT_POSTFIELDS, post_data);
397 curl_easy_setopt( request->curl, CURLOPT_NOPROGRESS, 1 );
398
399 res = curl_easy_perform(request->curl);
400 /* curl_easy_cleanup(request->curl); */
401 mp3tunes_request_deinit(&request);
402
403 if (res != CURLE_OK) {
404 chunk_deinit(&chunk);
405 return NULL;
406 }
407
408 if (chunk->data == NULL) {
409 return NULL;
410 }
411
412 printf("Fetch result:\n%s\n", chunk->data);
413
414 xmlDocPtr document = xmlParseDoc((xmlChar*)chunk->data);
415
416 chunk_deinit(&chunk);
417
418 if (document == NULL) {
419 return NULL;
420 }
421
422 return xml_xpath_init(document);
423 }
424
mp3tunes_locker_generate_download_url_from_file_key(mp3tunes_locker_object_t * obj,char * file_key)425 char* mp3tunes_locker_generate_download_url_from_file_key(mp3tunes_locker_object_t *obj, char *file_key) {
426 request_t *request;
427 char *path = malloc(256*sizeof(char));
428 char *ret;
429 snprintf(path, 256, "storage/lockerget/%s", file_key);
430 request = mp3tunes_locker_api_generate_request(obj, MP3TUNES_SERVER_CONTENT, path, NULL);
431 ret = request->url; request->url = NULL;
432 free(path);
433 mp3tunes_request_deinit(&request);
434 return ret;
435 }
436
mp3tunes_locker_generate_download_url_from_file_key_and_bitrate(mp3tunes_locker_object_t * obj,char * file_key,char * bitrate)437 char* mp3tunes_locker_generate_download_url_from_file_key_and_bitrate(mp3tunes_locker_object_t *obj, char *file_key, char* bitrate) {
438 request_t *request;
439 char *path = malloc(256*sizeof(char));
440 char *ret;
441 snprintf(path, 256, "storage/lockerget/%s", file_key);
442 request = mp3tunes_locker_api_generate_request(obj, MP3TUNES_SERVER_CONTENT, path, "bitrate", bitrate, NULL);
443 ret = request->url; request->url = NULL;
444 free(path);
445 mp3tunes_request_deinit(&request);
446 return ret;
447 }
448
449
mp3tunes_locker_login(mp3tunes_locker_object_t * obj,const char * username,const char * password)450 int mp3tunes_locker_login(mp3tunes_locker_object_t *obj, const char* username, const char* password) {
451 xml_xpath_t* xml_xpath;
452 char *status, *session_id;
453
454 xml_xpath = mp3tunes_locker_api_simple_fetch(obj, MP3TUNES_SERVER_LOGIN, "api/v1/login/", "username", username, "password", password, NULL);
455
456 if (xml_xpath == NULL) {
457 return -2;
458 }
459
460 status = xml_xpath_get_string(xml_xpath, "/mp3tunes/status");
461
462 if (status[0] != '1') {
463 /*printf("status is %s\n", status);*/
464 char* error = xml_xpath_get_string(xml_xpath, "/mp3tunes/errorMessage");
465 /*printf("error is %s\n", error);*/
466 obj->error_message = error;
467 free(status);
468 xml_xpath_deinit(xml_xpath);
469 return -1;
470 }
471 free(status);
472
473 session_id = xml_xpath_get_string(xml_xpath, "/mp3tunes/session_id");
474 obj->username = strdup(username);
475 obj->password = strdup(password);
476 obj->session_id = session_id;
477 xml_xpath_deinit(xml_xpath);
478
479 return 0;
480 }
481
mp3tunes_locker_session_valid(mp3tunes_locker_object_t * obj)482 int mp3tunes_locker_session_valid(mp3tunes_locker_object_t *obj) {
483
484 request_t *request;
485 CURLcode res;
486 chunk_t *chunk;
487
488 chunk_init(&chunk);
489
490 request = mp3tunes_locker_api_generate_request(obj, MP3TUNES_SERVER_API, "api/v1/accountData", NULL);
491 if (request == NULL) {
492 chunk_deinit(&chunk);
493 return -1;
494 }
495
496 curl_easy_setopt( request->curl, CURLOPT_URL, request->url );
497 curl_easy_setopt( request->curl, CURLOPT_WRITEFUNCTION, write_chunk_callback );
498 curl_easy_setopt( request->curl, CURLOPT_WRITEDATA, (void *)chunk );
499 curl_easy_setopt( request->curl, CURLOPT_NOBODY, 1 );
500 curl_easy_setopt( request->curl, CURLOPT_USERAGENT, "liboboe/1.0" );
501 curl_easy_setopt( request->curl, CURLOPT_HEADER, 1 );
502 curl_easy_setopt( request->curl, CURLOPT_NOPROGRESS, 1 );
503
504 res = curl_easy_perform(request->curl);
505 /* curl_easy_cleanup(request->curl); */
506 mp3tunes_request_deinit(&request);
507
508 if (res != CURLE_OK) {
509 chunk_deinit(&chunk);
510 return -1;
511 }
512
513 if (chunk->data == NULL) {
514 return -1;
515 }
516
517 char name[] = "X-MP3tunes-ErrorNo";
518 char value[] = "401001";
519 char *result = strstr (chunk->data, name);
520 if (result != 0)
521 {
522 int i = strcspn(result, "\n");
523 char *result1 = malloc(i + 1);
524 if (result1 == NULL)
525 return -1;
526
527 /* ensure result1 is null-terminated */
528 snprintf(result1, i+1, "%s", result);
529 /*printf("Header String: %s\n", result1);*/
530 result = strstr(result1, value);
531 free(result1);
532 if (result != 0) /* i.e., value could not be located hence there is no 404 error. */
533 return -1; /* session is invalid*/
534 }
535
536 /*printf("Fetch result:\n%s\n", chunk->data);*/
537 return 0; /* session is valid*/
538 }
539
mp3tunes_locker_list_init(struct mp3tunes_locker_list_s ** list)540 int mp3tunes_locker_list_init(struct mp3tunes_locker_list_s **list) {
541 struct mp3tunes_locker_list_s *l = *list = (struct mp3tunes_locker_list_s*)malloc(sizeof(struct mp3tunes_locker_list_s));
542 l->last_id = 0;
543 l->first = l->last = NULL;
544 return 0;
545 }
546
mp3tunes_locker_track_list_init(mp3tunes_locker_track_list_t ** list)547 int mp3tunes_locker_track_list_init(mp3tunes_locker_track_list_t **list) {
548 return mp3tunes_locker_list_init((struct mp3tunes_locker_list_s**)list);
549 }
550
mp3tunes_locker_artist_list_init(mp3tunes_locker_artist_list_t ** list)551 int mp3tunes_locker_artist_list_init(mp3tunes_locker_artist_list_t **list) {
552 return mp3tunes_locker_list_init((struct mp3tunes_locker_list_s**)list);
553 }
554
mp3tunes_locker_album_list_init(mp3tunes_locker_album_list_t ** list)555 int mp3tunes_locker_album_list_init(mp3tunes_locker_album_list_t **list) {
556 return mp3tunes_locker_list_init((struct mp3tunes_locker_list_s**)list);
557 }
558
mp3tunes_locker_playlist_list_init(mp3tunes_locker_playlist_list_t ** list)559 int mp3tunes_locker_playlist_list_init(mp3tunes_locker_playlist_list_t **list) {
560 return mp3tunes_locker_list_init((struct mp3tunes_locker_list_s**)list);
561 }
562
mp3tunes_locker_list_add(struct mp3tunes_locker_list_s ** list,void * value)563 int mp3tunes_locker_list_add(struct mp3tunes_locker_list_s **list, void* value) {
564 struct mp3tunes_locker_list_s *l = *list;
565 mp3tunes_locker_list_item_t *item = (mp3tunes_locker_list_item_t*)malloc(sizeof(mp3tunes_locker_list_item_t));
566 item->id = l->last_id++;
567 item->prev = l->last;
568 item->next = NULL;
569 item->value = value;
570
571 if (l->first) {
572 l->last = item->prev->next = item;
573 } else {
574 l->first = l->last = item;
575 }
576
577 return 0;
578 }
579
mp3tunes_locker_track_list_add(mp3tunes_locker_track_list_t ** list,mp3tunes_locker_track_t * track)580 int mp3tunes_locker_track_list_add(mp3tunes_locker_track_list_t **list, mp3tunes_locker_track_t *track) {
581 return mp3tunes_locker_list_add((struct mp3tunes_locker_list_s**)list, (void*)track);
582 }
583
mp3tunes_locker_artist_list_add(mp3tunes_locker_artist_list_t ** list,mp3tunes_locker_artist_t * artist)584 int mp3tunes_locker_artist_list_add(mp3tunes_locker_artist_list_t **list, mp3tunes_locker_artist_t *artist) {
585 return mp3tunes_locker_list_add((struct mp3tunes_locker_list_s**)list, (void*)artist);
586 }
587
mp3tunes_locker_album_list_add(mp3tunes_locker_album_list_t ** list,mp3tunes_locker_album_t * album)588 int mp3tunes_locker_album_list_add(mp3tunes_locker_album_list_t **list, mp3tunes_locker_album_t *album) {
589 return mp3tunes_locker_list_add((struct mp3tunes_locker_list_s**)list, (void*)album);
590 }
591
mp3tunes_locker_playlist_list_add(mp3tunes_locker_playlist_list_t ** list,mp3tunes_locker_playlist_t * album)592 int mp3tunes_locker_playlist_list_add(mp3tunes_locker_playlist_list_t **list, mp3tunes_locker_playlist_t *album) {
593 return mp3tunes_locker_list_add((struct mp3tunes_locker_list_s**)list, (void*)album);
594 }
595
mp3tunes_locker_list_deinit(struct mp3tunes_locker_list_s ** list)596 int mp3tunes_locker_list_deinit(struct mp3tunes_locker_list_s **list) {
597 struct mp3tunes_locker_list_s *l = *list;
598 if (l) {
599 mp3tunes_locker_list_item_t *list_item = l->first;
600 while(l->first) {
601 list_item = l->first->next;
602 free(l->first);
603 l->first = list_item;
604 }
605 free(l);
606 return 0;
607 }
608 return -1;
609 }
610
mp3tunes_locker_track_list_deinit(mp3tunes_locker_track_list_t ** track_list)611 int mp3tunes_locker_track_list_deinit(mp3tunes_locker_track_list_t **track_list) {
612 mp3tunes_locker_track_list_t *list = *track_list;
613 mp3tunes_locker_list_item_t *track_item = list->first;
614 mp3tunes_locker_track_t *track;
615
616 while (track_item != NULL) {
617 track = (mp3tunes_locker_track_t*)track_item->value;
618 free(track->trackTitle);
619 free(track->trackFileName);
620 free(track->trackFileKey);
621 free(track->downloadURL);
622 free(track->playURL);
623 free(track->albumTitle);
624 free(track->artistName);
625
626 free(track);
627 track_item = track_item->next;
628 }
629 return mp3tunes_locker_list_deinit((struct mp3tunes_locker_list_s**)track_list);
630 }
631
mp3tunes_locker_artist_list_deinit(mp3tunes_locker_artist_list_t ** artist_list)632 int mp3tunes_locker_artist_list_deinit(mp3tunes_locker_artist_list_t **artist_list) {
633 mp3tunes_locker_artist_list_t *list = *artist_list;
634 mp3tunes_locker_list_item_t *artist_item = list->first;
635 mp3tunes_locker_artist_t *artist;
636
637 while (artist_item != NULL) {
638 artist = (mp3tunes_locker_artist_t*)artist_item->value;
639 free(artist->artistName);
640
641 free(artist);
642 artist_item = artist_item->next;
643 }
644 return mp3tunes_locker_list_deinit((struct mp3tunes_locker_list_s**)artist_list);
645 }
646
mp3tunes_locker_album_list_deinit(mp3tunes_locker_album_list_t ** album_list)647 int mp3tunes_locker_album_list_deinit(mp3tunes_locker_album_list_t **album_list) {
648 mp3tunes_locker_album_list_t *list = *album_list;
649 mp3tunes_locker_list_item_t *album_item = list->first;
650 mp3tunes_locker_album_t *album;
651
652 while (album_item != NULL) {
653 album = (mp3tunes_locker_album_t*)album_item->value;
654 free(album->albumTitle);
655 free(album->artistName);
656
657 free(album);
658 album_item = album_item->next;
659 }
660 return mp3tunes_locker_list_deinit((struct mp3tunes_locker_list_s**)album_list);
661 }
662
mp3tunes_locker_playlist_list_deinit(mp3tunes_locker_playlist_list_t ** playlist_list)663 int mp3tunes_locker_playlist_list_deinit(mp3tunes_locker_playlist_list_t **playlist_list) {
664 mp3tunes_locker_playlist_list_t *list = *playlist_list;
665 mp3tunes_locker_list_item_t *playlist_item = list->first;
666 mp3tunes_locker_playlist_t *playlist;
667
668 while (playlist_item != NULL) {
669 playlist = (mp3tunes_locker_playlist_t*)playlist_item->value;
670 free(playlist->playlistId);
671 free(playlist->playlistTitle);
672 free(playlist->title);
673 free(playlist->fileName);
674
675 free(playlist);
676 playlist_item = playlist_item->next;
677 }
678 return mp3tunes_locker_list_deinit((struct mp3tunes_locker_list_s**)playlist_list);
679 }
680
_mp3tunes_locker_tracks(mp3tunes_locker_object_t * obj,mp3tunes_locker_track_list_t ** tracks,int artist_id,int album_id,const char * playlist_id)681 static int _mp3tunes_locker_tracks(mp3tunes_locker_object_t *obj, mp3tunes_locker_track_list_t **tracks, int artist_id, int album_id, const char* playlist_id) {
682 xml_xpath_t* xml_xpath;
683 xmlXPathObjectPtr xpath_obj;
684 xmlNodeSetPtr nodeset;
685 xmlNodePtr node;
686 int i;
687 char artist_id_s[15];
688 char album_id_s[15];
689
690 if (playlist_id == NULL) {
691 if (artist_id == -1 && album_id == -1) {
692 xml_xpath = mp3tunes_locker_api_simple_fetch(obj, MP3TUNES_SERVER_API, "api/v1/lockerData/", "type", "track", NULL);
693 } else if (artist_id != -1 && album_id == -1) {
694 snprintf(artist_id_s, 15, "%d", artist_id);
695 xml_xpath = mp3tunes_locker_api_simple_fetch(obj, MP3TUNES_SERVER_API, "api/v1/lockerData/", "type", "track", "artist_id", artist_id_s, NULL);
696 } else if (artist_id == -1 && album_id != -1) {
697 snprintf(album_id_s, 15, "%d", album_id);
698 xml_xpath = mp3tunes_locker_api_simple_fetch(obj, MP3TUNES_SERVER_API, "api/v1/lockerData/", "type", "track", "album_id", album_id_s, NULL);
699 } else {
700 snprintf(artist_id_s, 15, "%d", artist_id);
701 snprintf(album_id_s, 15, "%d", album_id);
702 xml_xpath = mp3tunes_locker_api_simple_fetch(obj, MP3TUNES_SERVER_API, "api/v1/lockerData/", "type", "track", "artist_id", artist_id_s, "album_id", album_id_s, NULL);
703 }
704 } else {
705 xml_xpath = mp3tunes_locker_api_simple_fetch(obj, MP3TUNES_SERVER_API, "api/v1/lockerData/", "type", "track", "playlist_id", playlist_id, NULL);
706 }
707
708 mp3tunes_locker_track_list_init(tracks);
709
710 if (xml_xpath == NULL) {
711 return -1;
712 }
713
714 xpath_obj = xml_xpath_query(xml_xpath, "/mp3tunes/trackList/item");
715
716 if (xpath_obj == NULL) {
717 return -1;
718 }
719
720 nodeset = xpath_obj->nodesetval;
721
722 for (i = 0; i < nodeset->nodeNr; i++) {
723 node = nodeset->nodeTab[i];
724 xml_xpath_t* xml_xpath_context = xml_xpath_context_init(xml_xpath, node);
725 mp3tunes_locker_track_t *track = (mp3tunes_locker_track_t*)malloc(sizeof(mp3tunes_locker_track_t));
726 memset(track, 0, sizeof(mp3tunes_locker_track_t));
727
728 track->trackId = xml_xpath_get_integer(xml_xpath_context, "trackId");
729 track->trackTitle = xml_xpath_get_string(xml_xpath_context, "trackTitle");
730 track->trackNumber = xml_xpath_get_integer(xml_xpath_context, "trackNumber");
731 track->trackLength = xml_xpath_get_float(xml_xpath_context, "trackLength");
732 track->trackFileName = xml_xpath_get_string(xml_xpath_context, "trackFileName");
733 track->trackFileKey = xml_xpath_get_string(xml_xpath_context, "trackFileKey");
734 track->trackFileSize = xml_xpath_get_integer(xml_xpath_context, "trackFileSize");
735 track->downloadURL = xml_xpath_get_string(xml_xpath_context, "downloadURL");
736 track->playURL = xml_xpath_get_string(xml_xpath_context, "playURL");
737 track->albumId = xml_xpath_get_integer(xml_xpath_context, "albumId");
738 track->albumTitle = xml_xpath_get_string(xml_xpath_context, "albumTitle");
739 track->albumYear = xml_xpath_get_integer(xml_xpath_context, "albumYear");
740 track->artistName = xml_xpath_get_string(xml_xpath_context, "artistName");
741 track->artistId = xml_xpath_get_integer(xml_xpath_context, "artistId");
742
743 mp3tunes_locker_track_list_add(tracks, track);
744 xml_xpath_deinit(xml_xpath_context);
745 }
746 xmlXPathFreeObject(xpath_obj);
747 xml_xpath_deinit(xml_xpath);
748 return 0;
749 }
750
mp3tunes_locker_tracks_search(mp3tunes_locker_object_t * obj,mp3tunes_locker_track_list_t ** tracks,char * search)751 int mp3tunes_locker_tracks_search( mp3tunes_locker_object_t *obj, mp3tunes_locker_track_list_t **tracks, char *search) {
752 xml_xpath_t* xml_xpath;
753 xmlXPathObjectPtr xpath_obj;
754 xmlNodeSetPtr nodeset;
755 xmlNodePtr node;
756 int i;
757
758 xml_xpath = mp3tunes_locker_api_simple_fetch(obj, MP3TUNES_SERVER_API, "api/v1/lockerSearch", "type", "track", "s", search, NULL);
759
760 mp3tunes_locker_track_list_init(tracks);
761
762 if (xml_xpath == NULL) {
763 return -1;
764 }
765
766 xpath_obj = xml_xpath_query(xml_xpath, "/mp3tunes/trackList/item");
767
768 if (xpath_obj == NULL) {
769 return -1;
770 }
771
772 nodeset = xpath_obj->nodesetval;
773
774 for (i = 0; i < nodeset->nodeNr; i++) {
775 node = nodeset->nodeTab[i];
776 xml_xpath_t* xml_xpath_context = xml_xpath_context_init(xml_xpath, node);
777 mp3tunes_locker_track_t *track = (mp3tunes_locker_track_t*)malloc(sizeof(mp3tunes_locker_track_t));
778 memset(track, 0, sizeof(mp3tunes_locker_track_t));
779
780 track->trackId = xml_xpath_get_integer(xml_xpath_context, "trackId");
781 track->trackTitle = xml_xpath_get_string(xml_xpath_context, "trackTitle");
782 track->trackNumber = xml_xpath_get_integer(xml_xpath_context, "trackNumber");
783 track->trackLength = xml_xpath_get_float(xml_xpath_context, "trackLength");
784 track->trackFileName = xml_xpath_get_string(xml_xpath_context, "trackFileName");
785 track->trackFileKey = xml_xpath_get_string(xml_xpath_context, "trackFileKey");
786 track->trackFileSize = xml_xpath_get_integer(xml_xpath_context, "trackFileSize");
787 track->downloadURL = xml_xpath_get_string(xml_xpath_context, "downloadURL");
788 track->playURL = xml_xpath_get_string(xml_xpath_context, "playURL");
789 track->albumId = xml_xpath_get_integer(xml_xpath_context, "albumId");
790 track->albumTitle = xml_xpath_get_string(xml_xpath_context, "albumTitle");
791 track->albumYear = xml_xpath_get_integer(xml_xpath_context, "albumYear");
792 track->artistName = xml_xpath_get_string(xml_xpath_context, "artistName");
793 track->artistId = xml_xpath_get_integer(xml_xpath_context, "artistId");
794
795 mp3tunes_locker_track_list_add(tracks, track);
796 xml_xpath_deinit(xml_xpath_context);
797 }
798 xmlXPathFreeObject(xpath_obj);
799 xml_xpath_deinit(xml_xpath);
800 return 0;
801 }
802
803
mp3tunes_locker_tracks(mp3tunes_locker_object_t * obj,mp3tunes_locker_track_list_t ** tracks)804 int mp3tunes_locker_tracks(mp3tunes_locker_object_t *obj, mp3tunes_locker_track_list_t **tracks) {
805 return _mp3tunes_locker_tracks(obj, tracks, -1, -1, NULL);
806 }
807
mp3tunes_locker_tracks_with_artist_id(mp3tunes_locker_object_t * obj,mp3tunes_locker_track_list_t ** tracks,int artist_id)808 int mp3tunes_locker_tracks_with_artist_id(mp3tunes_locker_object_t *obj, mp3tunes_locker_track_list_t **tracks, int artist_id) {
809 return _mp3tunes_locker_tracks(obj, tracks, artist_id, -1, NULL);
810 }
811
mp3tunes_locker_tracks_with_album_id(mp3tunes_locker_object_t * obj,mp3tunes_locker_track_list_t ** tracks,int album_id)812 int mp3tunes_locker_tracks_with_album_id(mp3tunes_locker_object_t *obj, mp3tunes_locker_track_list_t **tracks, int album_id) {
813 return _mp3tunes_locker_tracks(obj, tracks, -1, album_id, NULL);
814 }
815
mp3tunes_locker_tracks_with_artist_id_and_album_id(mp3tunes_locker_object_t * obj,mp3tunes_locker_track_list_t ** tracks,int artist_id,int album_id)816 int mp3tunes_locker_tracks_with_artist_id_and_album_id(mp3tunes_locker_object_t *obj, mp3tunes_locker_track_list_t **tracks, int artist_id, int album_id) {
817 return _mp3tunes_locker_tracks(obj, tracks, artist_id, album_id, NULL);
818 }
819
mp3tunes_locker_tracks_with_playlist_id(mp3tunes_locker_object_t * obj,mp3tunes_locker_track_list_t ** tracks,const char * playlist_id)820 int mp3tunes_locker_tracks_with_playlist_id(mp3tunes_locker_object_t *obj, mp3tunes_locker_track_list_t **tracks, const char* playlist_id) {
821 return _mp3tunes_locker_tracks(obj, tracks, -1, -1, playlist_id);
822 }
823
mp3tunes_locker_tracks_with_file_key(mp3tunes_locker_object_t * obj,const char * file_keys,mp3tunes_locker_track_list_t ** tracks)824 int mp3tunes_locker_tracks_with_file_key( mp3tunes_locker_object_t *obj, const char *file_keys, mp3tunes_locker_track_list_t **tracks ) {
825 xml_xpath_t* xml_xpath;
826 xmlXPathObjectPtr xpath_obj;
827 xmlNodeSetPtr nodeset;
828 xmlNodePtr node;
829 int i;
830
831 xml_xpath = mp3tunes_locker_api_simple_fetch(obj, MP3TUNES_SERVER_API, "api/v1/lockerData/", "type", "track", "key", file_keys, NULL);
832
833 mp3tunes_locker_track_list_init(tracks);
834
835 if (xml_xpath == NULL) {
836 return -1;
837 }
838
839 xpath_obj = xml_xpath_query(xml_xpath, "/mp3tunes/trackList/item");
840
841 if (xpath_obj == NULL) {
842 return -1;
843 }
844
845 nodeset = xpath_obj->nodesetval;
846
847 for (i = 0; i < nodeset->nodeNr; i++) {
848 node = nodeset->nodeTab[i];
849 xml_xpath_t* xml_xpath_context = xml_xpath_context_init(xml_xpath, node);
850 mp3tunes_locker_track_t *track = (mp3tunes_locker_track_t*)malloc(sizeof(mp3tunes_locker_track_t));
851 memset(track, 0, sizeof(mp3tunes_locker_track_t));
852
853 track->trackId = xml_xpath_get_integer(xml_xpath_context, "trackId");
854 track->trackTitle = xml_xpath_get_string(xml_xpath_context, "trackTitle");
855 track->trackNumber = xml_xpath_get_integer(xml_xpath_context, "trackNumber");
856 track->trackLength = xml_xpath_get_float(xml_xpath_context, "trackLength");
857 track->trackFileName = xml_xpath_get_string(xml_xpath_context, "trackFileName");
858 track->trackFileKey = xml_xpath_get_string(xml_xpath_context, "trackFileKey");
859 track->trackFileSize = xml_xpath_get_integer(xml_xpath_context, "trackFileSize");
860 track->downloadURL = xml_xpath_get_string(xml_xpath_context, "downloadURL");
861 track->playURL = xml_xpath_get_string(xml_xpath_context, "playURL");
862 track->albumId = xml_xpath_get_integer(xml_xpath_context, "albumId");
863 track->albumTitle = xml_xpath_get_string(xml_xpath_context, "albumTitle");
864 track->albumYear = xml_xpath_get_integer(xml_xpath_context, "albumYear");
865 track->artistName = xml_xpath_get_string(xml_xpath_context, "artistName");
866 track->artistId = xml_xpath_get_integer(xml_xpath_context, "artistId");
867
868 mp3tunes_locker_track_list_add(tracks, track);
869 xml_xpath_deinit(xml_xpath_context);
870 }
871 xmlXPathFreeObject(xpath_obj);
872 xml_xpath_deinit(xml_xpath);
873 return 0;
874
875 }
876
mp3tunes_locker_track_with_file_key(mp3tunes_locker_object_t * obj,const char * file_key,mp3tunes_locker_track_t ** track)877 int mp3tunes_locker_track_with_file_key( mp3tunes_locker_object_t *obj, const char *file_key, mp3tunes_locker_track_t **track ) {
878 xml_xpath_t* xml_xpath;
879 xmlXPathObjectPtr xpath_obj;
880 xmlNodeSetPtr nodeset;
881 xmlNodePtr node;
882
883 xml_xpath = mp3tunes_locker_api_simple_fetch(obj, MP3TUNES_SERVER_API, "api/v1/lockerData/", "type", "track", "key", file_key, NULL);
884
885 if (xml_xpath == NULL) {
886 return -1;
887 }
888
889 xpath_obj = xml_xpath_query(xml_xpath, "/mp3tunes/trackList/item");
890
891 if (xpath_obj == NULL) {
892 return -1;
893 }
894
895 nodeset = xpath_obj->nodesetval;
896 if ( nodeset->nodeNr == 1) {
897 node = nodeset->nodeTab[0];
898
899 xml_xpath_t* xml_xpath_context = xml_xpath_context_init(xml_xpath, node);
900 mp3tunes_locker_track_t *t = *track = (mp3tunes_locker_track_t*)malloc(sizeof(mp3tunes_locker_track_t));
901
902 t->trackId = xml_xpath_get_integer(xml_xpath_context, "trackId");
903 t->trackTitle = xml_xpath_get_string(xml_xpath_context, "trackTitle");
904 t->trackNumber = xml_xpath_get_integer(xml_xpath_context, "trackNumber");
905 t->trackLength = xml_xpath_get_float(xml_xpath_context, "trackLength");
906 t->trackFileName = xml_xpath_get_string(xml_xpath_context, "trackFileName");
907 t->trackFileKey = xml_xpath_get_string(xml_xpath_context, "trackFileKey");
908 t->trackFileSize = xml_xpath_get_integer(xml_xpath_context, "trackFileSize");
909 t->downloadURL = xml_xpath_get_string(xml_xpath_context, "downloadURL");
910 t->playURL = xml_xpath_get_string(xml_xpath_context, "playURL");
911 t->albumId = xml_xpath_get_integer(xml_xpath_context, "albumId");
912 t->albumTitle = xml_xpath_get_string(xml_xpath_context, "albumTitle");
913 t->albumYear = xml_xpath_get_integer(xml_xpath_context, "albumYear");
914 t->artistName = xml_xpath_get_string(xml_xpath_context, "artistName");
915 t->artistId = xml_xpath_get_integer(xml_xpath_context, "artistId");
916
917 xml_xpath_deinit(xml_xpath_context);
918 xmlXPathFreeObject(xpath_obj);
919 xml_xpath_deinit(xml_xpath);
920 return 0;
921 }
922 xmlXPathFreeObject(xpath_obj);
923 xml_xpath_deinit(xml_xpath);
924 return -1;
925 }
926
mp3tunes_locker_artists(mp3tunes_locker_object_t * obj,mp3tunes_locker_artist_list_t ** artists)927 int mp3tunes_locker_artists(mp3tunes_locker_object_t *obj, mp3tunes_locker_artist_list_t **artists) {
928 xml_xpath_t* xml_xpath;
929 xmlXPathObjectPtr xpath_obj;
930 xmlNodeSetPtr nodeset;
931 xmlNodePtr node;
932 int i;
933
934 xml_xpath = mp3tunes_locker_api_simple_fetch(obj, MP3TUNES_SERVER_API, "api/v1/lockerData/", "type", "artist", NULL);
935
936 mp3tunes_locker_artist_list_init(artists);
937
938 if (xml_xpath == NULL) {
939 return -1;
940 }
941
942 xpath_obj = xml_xpath_query(xml_xpath, "/mp3tunes/artistList/item");
943 if (xpath_obj == NULL) {
944 return -1;
945 }
946
947 nodeset = xpath_obj->nodesetval;
948
949 for (i = 0; i < nodeset->nodeNr; i++) {
950 node = nodeset->nodeTab[i];
951 xml_xpath_t* xml_xpath_context = xml_xpath_context_init(xml_xpath, node);
952 mp3tunes_locker_artist_t *artist = (mp3tunes_locker_artist_t*)malloc(sizeof(mp3tunes_locker_artist_t));
953 memset(artist, 0, sizeof(mp3tunes_locker_artist_t));
954
955 artist->artistId = xml_xpath_get_integer(xml_xpath_context, "artistId");
956 artist->artistName = xml_xpath_get_string(xml_xpath_context, "artistName");
957 artist->artistSize = xml_xpath_get_integer(xml_xpath_context, "artistSize");
958 artist->albumCount = xml_xpath_get_integer(xml_xpath_context, "albumCount");
959 artist->trackCount = xml_xpath_get_integer(xml_xpath_context, "trackCount");
960
961 mp3tunes_locker_artist_list_add(artists, artist);
962 xml_xpath_deinit(xml_xpath_context);
963 }
964 xmlXPathFreeObject(xpath_obj);
965 xml_xpath_deinit(xml_xpath);
966 return 0;
967 }
968
mp3tunes_locker_artists_search(mp3tunes_locker_object_t * obj,mp3tunes_locker_artist_list_t ** artists,char * search)969 int mp3tunes_locker_artists_search( mp3tunes_locker_object_t *obj, mp3tunes_locker_artist_list_t **artists, char *search) {
970 xml_xpath_t* xml_xpath;
971 xmlXPathObjectPtr xpath_obj;
972 xmlNodeSetPtr nodeset;
973 xmlNodePtr node;
974 int i;
975
976 xml_xpath = mp3tunes_locker_api_simple_fetch(obj, MP3TUNES_SERVER_API, "api/v1/lockerSearch", "type", "artist", "s", search, NULL);
977 mp3tunes_locker_artist_list_init(artists);
978
979 if (xml_xpath == NULL) {
980 return -1;
981 }
982
983 xpath_obj = xml_xpath_query(xml_xpath, "/mp3tunes/artistList/item");
984 if (xpath_obj == NULL) {
985 return -1;
986 }
987
988 nodeset = xpath_obj->nodesetval;
989
990 for (i = 0; i < nodeset->nodeNr; i++) {
991 node = nodeset->nodeTab[i];
992 xml_xpath_t* xml_xpath_context = xml_xpath_context_init(xml_xpath, node);
993 mp3tunes_locker_artist_t *artist = (mp3tunes_locker_artist_t*)malloc(sizeof(mp3tunes_locker_artist_t));
994 memset(artist, 0, sizeof(mp3tunes_locker_artist_t));
995
996 artist->artistId = xml_xpath_get_integer(xml_xpath_context, "artistId");
997 artist->artistName = xml_xpath_get_string(xml_xpath_context, "artistName");
998 artist->artistSize = xml_xpath_get_integer(xml_xpath_context, "artistSize");
999 artist->albumCount = xml_xpath_get_integer(xml_xpath_context, "albumCount");
1000 artist->trackCount = xml_xpath_get_integer(xml_xpath_context, "trackCount");
1001
1002 mp3tunes_locker_artist_list_add(artists, artist);
1003 xml_xpath_deinit(xml_xpath_context);
1004 }
1005 xmlXPathFreeObject(xpath_obj);
1006 xml_xpath_deinit(xml_xpath);
1007 return 0;
1008 }
1009
1010
mp3tunes_locker_albums_with_artist_id(mp3tunes_locker_object_t * obj,mp3tunes_locker_album_list_t ** albums,int artist_id)1011 int mp3tunes_locker_albums_with_artist_id(mp3tunes_locker_object_t *obj, mp3tunes_locker_album_list_t **albums, int artist_id) {
1012 xml_xpath_t* xml_xpath;
1013 xmlXPathObjectPtr xpath_obj;
1014 xmlNodeSetPtr nodeset;
1015 xmlNodePtr node;
1016 int i;
1017 char artist_id_string[15];
1018
1019 if (artist_id == -1) {
1020 xml_xpath = mp3tunes_locker_api_simple_fetch(obj, MP3TUNES_SERVER_API, "api/v1/lockerData/", "type", "album", NULL);
1021 } else {
1022 snprintf(artist_id_string, 15, "%d", artist_id);
1023 xml_xpath = mp3tunes_locker_api_simple_fetch(obj, MP3TUNES_SERVER_API, "api/v1/lockerData/", "type", "album", "artist_id", artist_id_string, NULL);
1024 }
1025
1026 mp3tunes_locker_album_list_init(albums);
1027
1028 if (xml_xpath == NULL) {
1029 return -1;
1030 }
1031
1032 xpath_obj = xml_xpath_query(xml_xpath, "/mp3tunes/albumList/item");
1033
1034 if (xpath_obj == NULL) {
1035 return -1;
1036 }
1037
1038 nodeset = xpath_obj->nodesetval;
1039
1040 for (i = 0; i < nodeset->nodeNr; i++) {
1041 node = nodeset->nodeTab[i];
1042 xml_xpath_t* xml_xpath_context = xml_xpath_context_init(xml_xpath, node);
1043 mp3tunes_locker_album_t *album = (mp3tunes_locker_album_t*)malloc(sizeof(mp3tunes_locker_album_t));
1044 memset(album, 0, sizeof(mp3tunes_locker_album_t));
1045
1046 album->albumId = xml_xpath_get_integer(xml_xpath_context, "albumId");
1047 album->albumTitle = xml_xpath_get_string(xml_xpath_context, "albumTitle");
1048 album->artistId = xml_xpath_get_integer(xml_xpath_context, "artistId");
1049 album->artistName = xml_xpath_get_string(xml_xpath_context, "artistName");
1050 album->trackCount = xml_xpath_get_integer(xml_xpath_context, "trackCount");
1051 album->albumSize = xml_xpath_get_integer(xml_xpath_context, "albumSize");
1052 album->hasArt = xml_xpath_get_integer(xml_xpath_context, "hasArt");
1053
1054 mp3tunes_locker_album_list_add(albums, album);
1055 xml_xpath_deinit(xml_xpath_context);
1056 }
1057 xmlXPathFreeObject(xpath_obj);
1058 xml_xpath_deinit(xml_xpath);
1059 return 0;
1060 }
1061
mp3tunes_locker_albums(mp3tunes_locker_object_t * obj,mp3tunes_locker_album_list_t ** albums)1062 int mp3tunes_locker_albums(mp3tunes_locker_object_t *obj, mp3tunes_locker_album_list_t **albums) {
1063 return mp3tunes_locker_albums_with_artist_id(obj, albums, -1);
1064 }
1065
mp3tunes_locker_albums_search(mp3tunes_locker_object_t * obj,mp3tunes_locker_album_list_t ** albums,char * search)1066 int mp3tunes_locker_albums_search( mp3tunes_locker_object_t *obj, mp3tunes_locker_album_list_t **albums, char *search) {
1067 xml_xpath_t* xml_xpath;
1068 xmlXPathObjectPtr xpath_obj;
1069 xmlNodeSetPtr nodeset;
1070 xmlNodePtr node;
1071 int i;
1072
1073 xml_xpath = mp3tunes_locker_api_simple_fetch(obj, MP3TUNES_SERVER_API, "api/v1/lockerSearch", "type", "album", "s", search, NULL);
1074
1075 mp3tunes_locker_album_list_init(albums);
1076
1077 if (xml_xpath == NULL) {
1078 return -1;
1079 }
1080
1081 xpath_obj = xml_xpath_query(xml_xpath, "/mp3tunes/albumList/item");
1082
1083 if (xpath_obj == NULL) {
1084 return -1;
1085 }
1086
1087 nodeset = xpath_obj->nodesetval;
1088
1089 for (i = 0; i < nodeset->nodeNr; i++) {
1090 node = nodeset->nodeTab[i];
1091 xml_xpath_t* xml_xpath_context = xml_xpath_context_init(xml_xpath, node);
1092 mp3tunes_locker_album_t *album = (mp3tunes_locker_album_t*)malloc(sizeof(mp3tunes_locker_album_t));
1093 memset(album, 0, sizeof(mp3tunes_locker_album_t));
1094
1095 album->albumId = xml_xpath_get_integer(xml_xpath_context, "albumId");
1096 album->albumTitle = xml_xpath_get_string(xml_xpath_context, "albumTitle");
1097 album->artistId = xml_xpath_get_integer(xml_xpath_context, "artistId");
1098 album->artistName = xml_xpath_get_string(xml_xpath_context, "artistName");
1099 album->trackCount = xml_xpath_get_integer(xml_xpath_context, "trackCount");
1100 album->albumSize = xml_xpath_get_integer(xml_xpath_context, "albumSize");
1101 album->hasArt = xml_xpath_get_integer(xml_xpath_context, "hasArt");
1102
1103 mp3tunes_locker_album_list_add(albums, album);
1104 xml_xpath_deinit(xml_xpath_context);
1105 }
1106 xmlXPathFreeObject(xpath_obj);
1107 xml_xpath_deinit(xml_xpath);
1108 return 0;
1109 }
1110
1111
1112
1113
mp3tunes_locker_playlists(mp3tunes_locker_object_t * obj,mp3tunes_locker_playlist_list_t ** playlists)1114 int mp3tunes_locker_playlists(mp3tunes_locker_object_t *obj, mp3tunes_locker_playlist_list_t **playlists) {
1115 xml_xpath_t* xml_xpath;
1116 xmlXPathObjectPtr xpath_obj;
1117 xmlNodeSetPtr nodeset;
1118 xmlNodePtr node;
1119 int i;
1120
1121 xml_xpath = mp3tunes_locker_api_simple_fetch(obj, MP3TUNES_SERVER_API, "api/v1/lockerData/", "type", "playlist", NULL);
1122
1123 mp3tunes_locker_playlist_list_init(playlists);
1124
1125 if (xml_xpath == NULL) {
1126 return -1;
1127 }
1128
1129 xpath_obj =xml_xpath_query(xml_xpath, "/mp3tunes/playlistList/item");
1130
1131 if (xpath_obj == NULL) {
1132 return -1;
1133 }
1134
1135 nodeset = xpath_obj->nodesetval;
1136
1137 for (i = 0; i < nodeset->nodeNr; i++) {
1138 node = nodeset->nodeTab[i];
1139 xml_xpath_t* xml_xpath_context = xml_xpath_context_init(xml_xpath, node);
1140 mp3tunes_locker_playlist_t *playlist = (mp3tunes_locker_playlist_t*)malloc(sizeof(mp3tunes_locker_playlist_t));
1141 memset(playlist, 0, sizeof(mp3tunes_locker_playlist_t));
1142
1143 playlist->playlistId = xml_xpath_get_string(xml_xpath_context, "playlistId");
1144 playlist->playlistTitle = xml_xpath_get_string(xml_xpath_context, "playlistTitle");
1145 playlist->title = xml_xpath_get_string(xml_xpath_context, "title");
1146 playlist->fileName = xml_xpath_get_string(xml_xpath_context, "fileName");
1147 playlist->fileCount = xml_xpath_get_integer(xml_xpath_context, "fileCount");
1148 playlist->playlistSize = xml_xpath_get_integer(xml_xpath_context, "playlistSize");
1149
1150 mp3tunes_locker_playlist_list_add(playlists, playlist);
1151 xml_xpath_deinit(xml_xpath_context);
1152 }
1153 xmlXPathFreeObject(xpath_obj);
1154 xml_xpath_deinit(xml_xpath);
1155 return 0;
1156 }
1157
mp3tunes_locker_search(mp3tunes_locker_object_t * obj,mp3tunes_locker_artist_list_t ** artists,mp3tunes_locker_album_list_t ** albums,mp3tunes_locker_track_list_t ** tracks,const char * query)1158 int mp3tunes_locker_search(mp3tunes_locker_object_t *obj, mp3tunes_locker_artist_list_t **artists, mp3tunes_locker_album_list_t **albums, mp3tunes_locker_track_list_t **tracks, const char *query) {
1159 xml_xpath_t* xml_xpath;
1160
1161 char type[20] = "";
1162 if( artists != NULL ) {
1163 strcat( type, "artist," );
1164 }
1165 if( albums != NULL ) {
1166 strcat( type, "album," );
1167 }
1168 if( tracks != NULL ) {
1169 strcat( type, "track," );
1170 }
1171 if( strlen(type) == 0 ) {
1172 return -1;
1173 }
1174 /*printf("type: '%s' query: '%s'\n", placeholder, query);*/
1175
1176 xml_xpath = mp3tunes_locker_api_simple_fetch(obj, MP3TUNES_SERVER_API, "api/v1/lockerSearch", "type", type, "s", query, NULL);
1177 if (xml_xpath == NULL)
1178 return -1;
1179
1180 if(artists != NULL) {
1181 xmlXPathObjectPtr xpath_obj;
1182 xmlNodeSetPtr nodeset;
1183 xmlNodePtr node;
1184 int i;
1185 mp3tunes_locker_artist_list_init(artists);
1186
1187 xpath_obj = xml_xpath_query(xml_xpath, "/mp3tunes/artistList/item");
1188 if (xpath_obj == NULL) {
1189 return -1;
1190 }
1191
1192 nodeset = xpath_obj->nodesetval;
1193
1194 for (i = 0; i < nodeset->nodeNr; i++) {
1195 node = nodeset->nodeTab[i];
1196 xml_xpath_t* xml_xpath_context = xml_xpath_context_init(xml_xpath, node);
1197 mp3tunes_locker_artist_t *artist = (mp3tunes_locker_artist_t*)malloc(sizeof(mp3tunes_locker_artist_t));
1198 memset(artist, 0, sizeof(mp3tunes_locker_artist_t));
1199
1200 artist->artistId = xml_xpath_get_integer(xml_xpath_context, "artistId");
1201 artist->artistName = xml_xpath_get_string(xml_xpath_context, "artistName");
1202 artist->artistSize = xml_xpath_get_integer(xml_xpath_context, "artistSize");
1203 artist->albumCount = xml_xpath_get_integer(xml_xpath_context, "albumCount");
1204 artist->trackCount = xml_xpath_get_integer(xml_xpath_context, "trackCount");
1205
1206 mp3tunes_locker_artist_list_add(artists, artist);
1207 xml_xpath_deinit(xml_xpath_context);
1208 }
1209 xmlXPathFreeObject(xpath_obj);
1210 }
1211
1212 if( albums != NULL ) {
1213 xmlXPathObjectPtr xpath_obj;
1214 xmlNodeSetPtr nodeset;
1215 xmlNodePtr node;
1216 int i;
1217
1218 mp3tunes_locker_album_list_init(albums);
1219
1220 xpath_obj = xml_xpath_query(xml_xpath, "/mp3tunes/albumList/item");
1221
1222 if (xpath_obj == NULL) {
1223 return -1;
1224 }
1225
1226 nodeset = xpath_obj->nodesetval;
1227
1228 for (i = 0; i < nodeset->nodeNr; i++) {
1229 node = nodeset->nodeTab[i];
1230 xml_xpath_t* xml_xpath_context = xml_xpath_context_init(xml_xpath, node);
1231 mp3tunes_locker_album_t *album = (mp3tunes_locker_album_t*)malloc(sizeof(mp3tunes_locker_album_t));
1232 memset(album, 0, sizeof(mp3tunes_locker_album_t));
1233
1234 album->albumId = xml_xpath_get_integer(xml_xpath_context, "albumId");
1235 album->albumTitle = xml_xpath_get_string(xml_xpath_context, "albumTitle");
1236 album->artistId = xml_xpath_get_integer(xml_xpath_context, "artistId");
1237 album->artistName = xml_xpath_get_string(xml_xpath_context, "artistName");
1238 album->trackCount = xml_xpath_get_integer(xml_xpath_context, "trackCount");
1239 album->albumSize = xml_xpath_get_integer(xml_xpath_context, "albumSize");
1240 album->hasArt = xml_xpath_get_integer(xml_xpath_context, "hasArt");
1241
1242 mp3tunes_locker_album_list_add(albums, album);
1243 xml_xpath_deinit(xml_xpath_context);
1244 }
1245 xmlXPathFreeObject(xpath_obj);
1246 }
1247 if( tracks != NULL) {
1248 xmlXPathObjectPtr xpath_obj;
1249 xmlNodeSetPtr nodeset;
1250 xmlNodePtr node;
1251 int i;
1252
1253 mp3tunes_locker_track_list_init(tracks);
1254
1255 xpath_obj = xml_xpath_query(xml_xpath, "/mp3tunes/trackList/item");
1256
1257 if (xpath_obj == NULL) {
1258 return -1;
1259 }
1260
1261 nodeset = xpath_obj->nodesetval;
1262
1263 for (i = 0; i < nodeset->nodeNr; i++) {
1264 node = nodeset->nodeTab[i];
1265 xml_xpath_t* xml_xpath_context = xml_xpath_context_init(xml_xpath, node);
1266 mp3tunes_locker_track_t *track = (mp3tunes_locker_track_t*)malloc(sizeof(mp3tunes_locker_track_t));
1267 memset(track, 0, sizeof(mp3tunes_locker_track_t));
1268
1269 track->trackId = xml_xpath_get_integer(xml_xpath_context, "trackId");
1270 track->trackTitle = xml_xpath_get_string(xml_xpath_context, "trackTitle");
1271 track->trackNumber = xml_xpath_get_integer(xml_xpath_context, "trackNumber");
1272 track->trackLength = xml_xpath_get_float(xml_xpath_context, "trackLength");
1273 track->trackFileName = xml_xpath_get_string(xml_xpath_context, "trackFileName");
1274 track->trackFileKey = xml_xpath_get_string(xml_xpath_context, "trackFileKey");
1275 track->trackFileSize = xml_xpath_get_integer(xml_xpath_context, "trackFileSize");
1276 track->downloadURL = xml_xpath_get_string(xml_xpath_context, "downloadURL");
1277 track->playURL = xml_xpath_get_string(xml_xpath_context, "playURL");
1278 track->albumId = xml_xpath_get_integer(xml_xpath_context, "albumId");
1279 track->albumTitle = xml_xpath_get_string(xml_xpath_context, "albumTitle");
1280 track->albumYear = xml_xpath_get_integer(xml_xpath_context, "albumYear");
1281 track->artistName = xml_xpath_get_string(xml_xpath_context, "artistName");
1282 track->artistId = xml_xpath_get_integer(xml_xpath_context, "artistId");
1283
1284 mp3tunes_locker_track_list_add(tracks, track);
1285 xml_xpath_deinit(xml_xpath_context);
1286 }
1287 xmlXPathFreeObject(xpath_obj);
1288 }
1289 xml_xpath_deinit(xml_xpath);
1290 return 0;
1291 }
1292
mp3tunes_locker_sync_down(mp3tunes_locker_object_t * obj,char * type,char * bytes_local,char * files_local,char * keep_local_files,char * playlist_id)1293 int mp3tunes_locker_sync_down(mp3tunes_locker_object_t *obj, char* type, char* bytes_local, char* files_local, char* keep_local_files, char* playlist_id) {
1294 xml_xpath_t* xml_xpath;
1295 xmlBufferPtr buf;
1296 xmlTextWriterPtr writer;
1297
1298 buf = xmlBufferCreate();
1299 if (buf == NULL) {
1300 return -1;
1301 }
1302
1303 writer = xmlNewTextWriterMemory(buf, 0);
1304
1305 if (writer == NULL) {
1306 return -1;
1307 }
1308
1309 if (xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL) < 0) {
1310 return -1;
1311 }
1312
1313 if (xmlTextWriterStartElement(writer, BAD_CAST "sync") < 0) {
1314 return -1;
1315 }
1316
1317 if (xmlTextWriterStartElement(writer, BAD_CAST "options") < 0) {
1318 return -1;
1319 }
1320
1321 if (xmlTextWriterStartElement(writer, BAD_CAST "direction") < 0) {
1322 return -1;
1323 }
1324
1325 if (xmlTextWriterWriteAttribute(writer, BAD_CAST "sync_down", BAD_CAST "1") < 0) {
1326 return -1;
1327 }
1328
1329 if (xmlTextWriterEndElement(writer) < 0) {
1330 return -1;
1331 }
1332
1333 if (xmlTextWriterStartElement(writer, BAD_CAST "file_sync") < 0) {
1334 return -1;
1335 }
1336
1337 if (xmlTextWriterWriteAttribute(writer, BAD_CAST "type", BAD_CAST type) < 0) {
1338 return -1;
1339 }
1340
1341 if (xmlTextWriterEndElement(writer) < 0) {
1342 return -1;
1343 }
1344
1345 if (xmlTextWriterStartElement(writer, BAD_CAST "max") < 0) {
1346 return -1;
1347 }
1348
1349 if (bytes_local) {
1350 if (xmlTextWriterWriteAttribute(writer, BAD_CAST "bytes_local", BAD_CAST bytes_local) < 0) {
1351 return -1;
1352 }
1353 }
1354
1355 if (files_local) {
1356 if (xmlTextWriterWriteAttribute(writer, BAD_CAST "files_local", BAD_CAST files_local) < 0) {
1357 return -1;
1358 }
1359 }
1360
1361 if (keep_local_files) {
1362 if (xmlTextWriterWriteAttribute(writer, BAD_CAST "keep_local_files", BAD_CAST files_local) < 0) {
1363 return -1;
1364 }
1365 }
1366
1367 if (xmlTextWriterEndElement(writer) < 0) {
1368 return -1;
1369 }
1370
1371 if (playlist_id) {
1372 if (xmlTextWriterStartElement(writer, BAD_CAST "playlist") < 0) {
1373 return -1;
1374 }
1375
1376 if (xmlTextWriterWriteAttribute(writer, BAD_CAST "id", BAD_CAST playlist_id) < 0) {
1377 return -1;
1378 }
1379
1380 if (xmlTextWriterEndElement(writer) < 0) {
1381 return -1;
1382 }
1383 }
1384
1385 if (xmlTextWriterEndDocument(writer) < 0) {
1386 return -1;
1387 }
1388
1389 xmlFreeTextWriter(writer);
1390
1391 xml_xpath = mp3tunes_locker_api_post_fetch(obj, MP3TUNES_SERVER_API, "api/v1/lockerSync/", (char*)buf->content);
1392 if( xml_xpath == NULL)
1393 return -1;
1394
1395 printf("Sync:\n%s\n", (const char *) buf->content);
1396
1397 free(xml_xpath);
1398 xmlBufferFree(buf);
1399 return 0;
1400 }
1401
mp3tunes_locker_generate_track_from_file_key(mp3tunes_locker_object_t * obj,char * file_key,mp3tunes_locker_track_list_t ** tracks)1402 int mp3tunes_locker_generate_track_from_file_key(mp3tunes_locker_object_t *obj, char *file_key, mp3tunes_locker_track_list_t **tracks ) {
1403 xml_xpath_t* xml_xpath;
1404 xmlXPathObjectPtr xpath_obj;
1405 xmlNodeSetPtr nodeset;
1406 xmlNodePtr node;
1407 int i;
1408
1409 xml_xpath = mp3tunes_locker_api_simple_fetch(obj, MP3TUNES_SERVER_API, "api/v1/lockerData/", "type", "track", "key", file_key, NULL);
1410
1411 mp3tunes_locker_track_list_init(tracks);
1412
1413 if (xml_xpath == NULL) {
1414 return -1;
1415 }
1416
1417 xpath_obj = xml_xpath_query(xml_xpath, "/mp3tunes/trackList/item");
1418
1419 if (xpath_obj == NULL) {
1420 return -1;
1421 }
1422
1423 nodeset = xpath_obj->nodesetval;
1424
1425 for (i = 0; i < nodeset->nodeNr; i++) {
1426 node = nodeset->nodeTab[i];
1427 xml_xpath_t* xml_xpath_context = xml_xpath_context_init(xml_xpath, node);
1428 mp3tunes_locker_track_t *track = (mp3tunes_locker_track_t*)malloc(sizeof(mp3tunes_locker_track_t));
1429 memset(track, 0, sizeof(mp3tunes_locker_track_t));
1430
1431 track->trackId = xml_xpath_get_integer(xml_xpath_context, "trackId");
1432 track->trackTitle = xml_xpath_get_string(xml_xpath_context, "trackTitle");
1433 track->trackNumber = xml_xpath_get_integer(xml_xpath_context, "trackNumber");
1434 track->trackLength = xml_xpath_get_float(xml_xpath_context, "trackLength");
1435 track->trackFileName = xml_xpath_get_string(xml_xpath_context, "trackFileName");
1436 track->trackFileKey = xml_xpath_get_string(xml_xpath_context, "trackFileKey");
1437 track->trackFileSize = xml_xpath_get_integer(xml_xpath_context, "trackFileSize");
1438 track->downloadURL = xml_xpath_get_string(xml_xpath_context, "downloadURL");
1439 track->playURL = xml_xpath_get_string(xml_xpath_context, "playURL");
1440 track->albumId = xml_xpath_get_integer(xml_xpath_context, "albumId");
1441 track->albumTitle = xml_xpath_get_string(xml_xpath_context, "albumTitle");
1442 track->albumYear = xml_xpath_get_integer(xml_xpath_context, "albumYear");
1443 track->artistName = xml_xpath_get_string(xml_xpath_context, "artistName");
1444 track->artistId = xml_xpath_get_integer(xml_xpath_context, "artistId");
1445
1446 mp3tunes_locker_track_list_add(tracks, track);
1447 xml_xpath_deinit(xml_xpath_context);
1448 }
1449 xmlXPathFreeObject(xpath_obj);
1450 xml_xpath_deinit(xml_xpath);
1451 return 0;
1452
1453 }
1454
mp3tunes_locker_generate_filekey(const char * filename)1455 char* mp3tunes_locker_generate_filekey(const char *filename) {
1456 return md5_calc_file_signature(filename);
1457 }
1458
mp3tunes_locker_upload_track(mp3tunes_locker_object_t * obj,const char * path)1459 int mp3tunes_locker_upload_track(mp3tunes_locker_object_t *obj, const char *path) {
1460 request_t *request;
1461 FILE * hd_src ;
1462 int hd ;
1463 struct stat file_info;
1464 char* file_key = mp3tunes_locker_generate_filekey(path);
1465
1466 if (file_key == NULL)
1467 return -1;
1468
1469 /* get the file size of the local file */
1470 hd = open(path, O_RDONLY);
1471 if (hd == -1) {
1472 free(file_key);
1473 return -1;
1474 }
1475
1476 fstat(hd, &file_info);
1477 close(hd);
1478 /* get a FILE * of the same file*/
1479 hd_src = fopen(path, "rb");
1480
1481 /* create the request url */
1482 char *url = malloc(256*sizeof(char));
1483 snprintf(url, 256, "storage/lockerput/%s", file_key);
1484 free(file_key);
1485 request = mp3tunes_locker_api_generate_request(obj, MP3TUNES_SERVER_CONTENT, url, NULL);
1486 if (request == NULL) {
1487 fclose(hd_src);
1488 return -1;
1489 }
1490
1491 /*chunk_init(&chunk);*/
1492 /*curl_easy_setopt( request->curl, CURLOPT_READFUNCTION, read_callback);*/
1493 curl_easy_setopt( request->curl, CURLOPT_UPLOAD, 1L);
1494 curl_easy_setopt( request->curl, CURLOPT_PUT, 1L);
1495 curl_easy_setopt( request->curl, CURLOPT_URL, request->url);
1496 curl_easy_setopt( request->curl, CURLOPT_READDATA, hd_src);
1497 curl_easy_setopt( request->curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)file_info.st_size);
1498 curl_easy_setopt( request->curl, CURLOPT_USERAGENT, "liboboe/1.0" );
1499 /*printf("uploading...\n");*/
1500 /* this returns a CURLcode which should probably be checked for success etc... */
1501 curl_easy_perform(request->curl);
1502 /* curl_easy_cleanup(request->curl); */
1503 mp3tunes_request_deinit(&request);
1504 free(url);
1505
1506 fclose(hd_src); /* close the local file */
1507 return 0;
1508 }
1509
mp3tunes_locker_load_track(mp3tunes_locker_object_t * obj,const char * url)1510 int mp3tunes_locker_load_track(mp3tunes_locker_object_t *obj, const char *url) {
1511 xml_xpath_t* xml_xpath;
1512 char *status;
1513 xml_xpath = mp3tunes_locker_api_simple_fetch(obj, MP3TUNES_SERVER_LOGIN, "api/v0/lockerLoad/", "email", obj->username, "url", url, "sid", obj->session_id, NULL);
1514
1515 if (xml_xpath == NULL) {
1516 return -2;
1517 }
1518
1519 status = xml_xpath_get_string(xml_xpath, "/mp3tunes/status");
1520
1521 if (status[0] != '1') {
1522 /*printf("status is %s\n", status);*/
1523 char* error = xml_xpath_get_string(xml_xpath, "/mp3tunes/errorMessage");
1524 /*printf("error is %s\n", error);*/
1525 obj->error_message = error;
1526 free(status);
1527 xml_xpath_deinit(xml_xpath);
1528 return -1;
1529 }
1530 free(status);
1531 xml_xpath_deinit(xml_xpath);
1532
1533 return 0;
1534
1535 }
1536