Subversion Repositories mdb

Rev

Rev 31 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5 andreas 1
/*
2
 * Copyright (C) 2015 by Andreas Theofilu <andreas@theosys.at>
3
 *
4
 * All rights reserved. No warranty, explicit or implicit, provided.
5
 *
6
 * NOTICE:  All information contained herein is, and remains
7
 * the property of Andreas Theofilu and his suppliers, if any.
8
 * The intellectual and technical concepts contained
9
 * herein are proprietary to Andreas Theofilu and its suppliers and
10
 * may be covered by European and Foreign Patents, patents in process,
11
 * and are protected by trade secret or copyright law.
12
 * Dissemination of this information or reproduction of this material
13
 * is strictly forbidden unless prior written permission is obtained
14
 * from Andreas Theofilu.
15
 */
16
#include <stdio.h>
17
#include <string.h>
18
#include <strings.h>
19
#include <unistd.h>
20
#include <stdlib.h>
21
#include <libgen.h>
22
#include <ctype.h>
23
#include <math.h>
24
#include <syslog.h>
25
#include <errno.h>
26
#include <sys/stat.h>
27
#include <sys/types.h>
28
#include <fcntl.h>
29
#include <sqlite3.h>
30
#include <id3.h>
31
#include "config.h"
32
#include "helplib.h"
33
#include "list.h"
8 andreas 34
#include "user.h"
35
#include "play.h"
5 andreas 36
 
37
struct callPars
38
{
39
	int s1;
40
	int start;
41
	int length;
42
	char *type;
43
};
44
 
12 andreas 45
int globalLine;
46
int globalPos;
5 andreas 47
 
12 andreas 48
static int listCallback(int s1, char *type, int line, sqlite3_stmt *res);
5 andreas 49
static int folderCallback(void *hint, int argc, char **argv, char **azColName);
14 andreas 50
int countPlaylists();
5 andreas 51
 
52
int listSongs(int s1, char *p_type, int start, int length)
53
{
11 andreas 54
	char query[1024], hv0[128];
5 andreas 55
	char fname[256];
56
	sqlite3 *db;
12 andreas 57
	sqlite3_stmt *res;
58
	int rc, pos, line;
5 andreas 59
 
60
	strcpy(fname, configs.home);
9 andreas 61
	strcat(fname, MUSICDB);
5 andreas 62
 
63
	rc = sqlite3_open(fname, &db);
64
 
65
	if (rc)
66
	{
67
		syslog(LOG_WARNING, "Error opening database %s: %s", fname, sqlite3_errmsg(db));
68
		strcpy(query, "ERROR:LIST:Error opening database;");
69
		write (s1, query, strlen(query));
70
		return FALSE;
71
	}
55 andreas 72
 
73
	if (configs.debug)
74
		syslog(LOG_DEBUG, "Listing %s ...", p_type);
75
 
12 andreas 76
	/* First count the future result set */
14 andreas 77
	if (strcmp(p_type, "QUEUE") && strcmp(p_type, "PLAYLIST"))
78
	{
79
		strcpy (query, "select count(*) as cnt from musicdb");
12 andreas 80
 
14 andreas 81
		if (sqlite3_prepare(db, query, -1, &res, NULL) != SQLITE_OK)
82
		{
83
			syslog(LOG_DAEMON, "Error preparing SQL statement [%s]: %s", query, sqlite3_errmsg(db));
84
			strcpy(query, "ERROR:USER:Error preparing a SQL statement;");
85
			write(s1, query, strlen(query));
86
			return FALSE;
87
		}
88
 
89
		if (sqlite3_step(res) == SQLITE_ROW)
90
			pos = sqlite3_column_int(res, 0);
91
		else
92
			pos = 0;
93
 
94
		sqlite3_finalize(res);
12 andreas 95
	}
14 andreas 96
	else if (!strcmp(p_type, "QUEUE"))
55 andreas 97
	{
98
		if (queueTotal <= 0)
99
		{
100
			int fd;
101
 
102
			strcpy(fname, configs.home);
103
			strcat(fname, NOWPLAY);
104
			sleep(1);
105
 
106
			if (queueTotal <= 0)
107
			{
108
				if ((fd = open(fname, O_RDONLY)) == -1)
109
				{
110
					syslog(LOG_WARNING, "Error opening queue %s: %s", fname, strerror(errno));
111
					strcpy(query, "ERROR:LIST:Error opening queue file;");
112
					write(s1, query, strlen(query));
113
					return FALSE;
114
				}
115
 
116
				scanQueue(fd);
117
				close(fd);
118
			}
119
		}
120
 
14 andreas 121
		pos = queueTotal;
55 andreas 122
	}
12 andreas 123
	else
14 andreas 124
		pos = countPlaylists();
12 andreas 125
 
55 andreas 126
	playQuiet = TRUE;
12 andreas 127
	sprintf(hv0, "TOTAL:%d;", pos);
128
	write(s1, hv0, strlen(hv0));
129
 
11 andreas 130
	strcpy (query, "select id, title, interpret, album, genre, cover from \"main\".\"musicdb\" ");
5 andreas 131
	strcat (query, "order by ");
132
 
133
	if (strcmp(p_type, "TITLE") == 0)
134
		strcat (query, "title");
135
	else if (strcmp(p_type, "ARTIST") == 0)
136
		strcat (query, "interpret");
137
	else if (strcmp(p_type, "ALBUM") == 0)
138
		strcat (query, "album");
139
	else if (strcmp(p_type, "GENRE") == 0)
140
		strcat (query, "genre");
8 andreas 141
	else if (strcmp(p_type, "QUEUE") == 0)
142
	{
143
		sqlite3_close(db);
55 andreas 144
		playQuiet = FALSE;
8 andreas 145
		return listQueue(s1, start, length);
146
	}
147
	else if (strcmp(p_type, "PLAYLIST") == 0)
148
	{
149
		sqlite3_close(db);
55 andreas 150
		playQuiet = FALSE;
8 andreas 151
		return listPlaylists(s1, start, length);
152
	}
24 andreas 153
	else if (strcmp(p_type, "USERS") == 0)
154
	{
155
		sqlite3_close(db);
55 andreas 156
		playQuiet = FALSE;
24 andreas 157
		return listUsers(s1, start, length);
158
	}
5 andreas 159
	else		/* No or unknown type */
160
	{
161
		strcpy (query, "ERROR:LIST:Missing type;");
162
		write(s1, query, strlen(query));
163
		sqlite3_close(db);
55 andreas 164
		playQuiet = FALSE;
5 andreas 165
		return FALSE;
166
	}
167
 
11 andreas 168
	/* Tell client which page to show */
169
	sprintf(hv0, "PAGE:%s;", p_type);
170
	write (s1, hv0, strlen (hv0));
171
 
172
	/* Retrieve data from database */
25 andreas 173
	line = pos = 0;
5 andreas 174
 
12 andreas 175
	if (sqlite3_prepare(db, query, -1, &res, NULL) != SQLITE_OK)
5 andreas 176
	{
12 andreas 177
		syslog(LOG_DAEMON, "Error preparing SQL statement [%s]: %s", query, sqlite3_errmsg(db));
178
		strcpy(query, "ERROR:USER:Error preparing a SQL statement;");
179
		write(s1, query, strlen(query));
55 andreas 180
		playQuiet = FALSE;
5 andreas 181
		return FALSE;
182
	}
183
 
12 andreas 184
	while ((rc = sqlite3_step(res)) == SQLITE_ROW)
5 andreas 185
	{
25 andreas 186
		pos++;
12 andreas 187
 
25 andreas 188
		if (pos >= start && pos < (start + length))
189
		{
190
			line++;
12 andreas 191
			listCallback(s1, p_type, line, res);
25 andreas 192
		}
12 andreas 193
 
25 andreas 194
		if (pos >= (start + length))
12 andreas 195
			break;
5 andreas 196
	}
197
 
12 andreas 198
	sqlite3_finalize(res);
5 andreas 199
	sqlite3_close(db);
55 andreas 200
	playQuiet = FALSE;
5 andreas 201
	return TRUE;
202
}
203
 
8 andreas 204
int listQueue(int s1, int start, int length)
205
{
11 andreas 206
	int fd, line;
207
	char fname[256], hv0[256], buffer[8192];
208
	char *title, *artist, *album, *cover;
209
	int pos;
210
	QUEUE *act;
8 andreas 211
 
11 andreas 212
	if (pqueue == NULL)
8 andreas 213
	{
11 andreas 214
		strcpy (fname, configs.home);
215
		strcat (fname, NOWPLAY);
8 andreas 216
 
11 andreas 217
		if (access(fname, R_OK))
218
		{
219
			strcpy (hv0, "ERROR:LIST:No or empty queue;");
220
			write (s1, hv0, strlen(hv0));
221
			return FALSE;
222
		}
8 andreas 223
 
11 andreas 224
		if ((fd = open(fname, O_RDONLY)) <= 0)
225
		{
226
			syslog(LOG_WARNING, "Error opening file %s: %s", fname, strerror(errno));
227
			strcpy(hv0, "ERROR:LIST:Error opening queue;");
228
			write(s1, hv0, strlen(hv0));
229
			return FALSE;
230
		}
8 andreas 231
 
11 andreas 232
		scanQueue(fd);
233
		close(fd);
234
	}
8 andreas 235
 
11 andreas 236
	sprintf(hv0, "PAGE:QUEUE;TOTAL:%d;", queueTotal);
237
	write (s1, hv0, strlen(hv0));
238
	act = pqueue;
239
	pos = line = 1;
55 andreas 240
	playQuiet = TRUE;
8 andreas 241
 
11 andreas 242
	while (act)
8 andreas 243
	{
244
		if (pos < start)
25 andreas 245
		{
246
			act = act->next;
247
			pos++;
8 andreas 248
			continue;
25 andreas 249
		}
250
		else if (pos >= (start + length))
8 andreas 251
			break;
252
 
11 andreas 253
		title = urlencode(act->title);
254
		artist = urlencode(act->artist);
255
		album = urlencode(act->album);
256
		cover = urlencode(act->cover);
257
		sprintf(buffer, "LINE:QUEUE:%d:%d:", act->id, line);
8 andreas 258
 
259
		if (title != NULL)
260
		{
261
			strcat(buffer, title);
262
			free(title);
263
		}
264
		else
11 andreas 265
			strcat(buffer, act->title);
266
 
8 andreas 267
		strcat(buffer, ":");
11 andreas 268
 
8 andreas 269
		if (artist != NULL)
270
		{
271
			strcat(buffer, artist);
272
			free(artist);
273
		}
274
		else
11 andreas 275
			strcat(buffer, act->artist);
276
 
8 andreas 277
		strcat(buffer, ":");
11 andreas 278
 
8 andreas 279
		if (album != NULL)
280
		{
281
			strcat(buffer, album);
282
			free(album);
283
		}
284
		else
11 andreas 285
			strcat(buffer, act->album);
286
 
8 andreas 287
		strcat(buffer, ":");
11 andreas 288
		strcat(buffer, act->genre);
289
		strcat(buffer, ":");
290
 
291
		if (cover != NULL)
292
		{
293
			strcat(buffer, cover);
294
			free(cover);
295
		}
296
		else
297
			strcat(buffer, act->cover);
298
 
8 andreas 299
		strcat(buffer, ";");
300
		write(s1, buffer, strlen(buffer));
11 andreas 301
		act = act->next;
25 andreas 302
		pos++;
11 andreas 303
		line++;
8 andreas 304
	}
305
 
55 andreas 306
	playQuiet = FALSE;
8 andreas 307
	return TRUE;
308
}
309
 
5 andreas 310
int listFolders(int s1, char *p_type, int start, int length)
311
{
312
	char query[1024], field[16];
313
	char fname[256];
314
	sqlite3 *db;
315
	char *zErrMsg = 0;
316
	int rc;
317
	struct callPars cp;
318
 
319
	strcpy(fname, configs.home);
9 andreas 320
	strcat(fname, MUSICDB);
5 andreas 321
 
322
	rc = sqlite3_open(fname, &db);
323
 
324
	if (rc)
325
	{
326
		syslog(LOG_WARNING, "Error opening database %s: %s", fname, sqlite3_errmsg(db));
327
		strcpy(query, "ERROR:FOLDER:Error opening database;");
328
		write (s1, query, strlen(query));
329
		return FALSE;
330
	}
331
 
332
	strcpy (query, "select distinct ");
333
 
334
	if (strcmp(p_type, "TITLE") == 0)
335
		strcpy (field, "title");
336
	else if (strcmp(p_type, "ARTIST") == 0)
337
		strcpy (field, "interpret");
338
	else if (strcmp(p_type, "ALBUM") == 0)
339
		strcpy (field, "album");
340
	else if (strcmp(p_type, "GENRE") == 0)
341
		strcpy (field, "genre");
342
	else		/* No or unknown type */
343
	{
344
		strcpy (query, "ERROR:FOLDER:Missing type;");
345
		write(s1, query, strlen(query));
346
		sqlite3_close(db);
347
		return FALSE;
348
	}
349
 
350
	strcat (query, field);
25 andreas 351
	strcat (query, " from \"main\".\"musicdb\" order by ");
5 andreas 352
	strcat (query, field);
353
 
354
	cp.s1 = s1;
355
	cp.type = p_type;
356
	cp.start = start;
357
	cp.length = length;
12 andreas 358
	globalLine = 0;
25 andreas 359
	globalPos = 0;
55 andreas 360
	playQuiet = TRUE;
5 andreas 361
 
362
	if ((rc = sqlite3_exec(db, query, folderCallback, (void *)&cp, &zErrMsg)) != SQLITE_OK)
363
	{
364
		syslog(LOG_WARNING, "SQL error [%s]: %s", query, zErrMsg);
365
		sqlite3_free(zErrMsg);
366
		sqlite3_close(db);
367
		strcpy(query, "ERROR:FOLDER:SQL error;");
368
		write (s1, query, strlen(query));
369
		return FALSE;
370
	}
371
 
12 andreas 372
	if (globalPos >= 0)
5 andreas 373
	{
12 andreas 374
		sprintf(query, "TOTAL:%d;", globalPos + 1);
5 andreas 375
		write (s1, query, strlen(query));
376
	}
377
 
378
	sqlite3_close(db);
55 andreas 379
	playQuiet = FALSE;
5 andreas 380
	return TRUE;
381
}
382
 
12 andreas 383
static int listCallback(int s1, char *type, int line, sqlite3_stmt *res)
5 andreas 384
{
14 andreas 385
	int id;
12 andreas 386
	char id3_title[256], id3_artist[256], id3_album[256], id3_genre[256], id3_cover[256];
5 andreas 387
	char buffer[8192];
12 andreas 388
	char *title, *artist, *album;
5 andreas 389
 
390
	memset(id3_title, 0, sizeof(id3_title));
391
	memset(id3_artist, 0, sizeof(id3_artist));
392
	memset(id3_album, 0, sizeof(id3_album));
393
	memset(id3_genre, 0, sizeof(id3_genre));
11 andreas 394
	memset(id3_cover, 0, sizeof(id3_cover));
5 andreas 395
	id = -1;
12 andreas 396
	id = sqlite3_column_int(res, 0);
397
	strncpy(id3_title, (const char *)sqlite3_column_text(res, 1), sizeof(id3_title));
398
	strncpy(id3_artist, (const char *)sqlite3_column_text(res, 2), sizeof(id3_artist));
399
	strncpy(id3_album, (const char *)sqlite3_column_text(res, 3), sizeof(id3_album));
400
	strncpy(id3_genre, (const char *)sqlite3_column_text(res, 4), sizeof(id3_genre));
401
	strncpy(id3_cover, (const char *)sqlite3_column_text(res, 5), sizeof(id3_cover));
5 andreas 402
 
403
	title = urlencode(id3_title);
404
	artist = urlencode(id3_artist);
11 andreas 405
	album = urlencode(id3_album);
5 andreas 406
 
12 andreas 407
	sprintf(buffer, "LINE:%s:%d:%d:", type, id, line);
5 andreas 408
 
409
	if (title != NULL)
410
	{
411
		strcat(buffer, title);
412
		free(title);
413
	}
414
	else
415
		strcat(buffer, id3_title);
12 andreas 416
 
5 andreas 417
	strcat(buffer, ":");
12 andreas 418
 
5 andreas 419
	if (artist != NULL)
420
	{
421
		strcat(buffer, artist);
422
		free(artist);
423
	}
424
	else
425
		strcat(buffer, id3_artist);
12 andreas 426
 
5 andreas 427
	strcat(buffer, ":");
12 andreas 428
 
5 andreas 429
	if (album != NULL)
430
	{
431
		strcat(buffer, album);
432
		free(album);
433
	}
434
	else
435
		strcat(buffer, id3_album);
12 andreas 436
 
5 andreas 437
	strcat(buffer, ":");
438
	strcat(buffer, id3_genre);
11 andreas 439
	strcat(buffer, ":");
12 andreas 440
	strcat(buffer, id3_cover);
5 andreas 441
	strcat(buffer, ";");
12 andreas 442
	write(s1, buffer, strlen(buffer));
5 andreas 443
	return 0;
444
}
445
 
446
static int folderCallback(void *hint, int argc, char **argv, char **azColName)
447
{
448
	int i;
25 andreas 449
	char id3_buffer[256];
5 andreas 450
	char buffer[8192];
451
	char *buf;
452
	struct callPars *cp;
453
 
12 andreas 454
	globalPos++;
5 andreas 455
	cp = (struct callPars *)hint;
456
	memset(id3_buffer, 0, sizeof(id3_buffer));
457
 
12 andreas 458
	if (globalPos < cp->start || globalPos >= (cp->start + cp->length))
5 andreas 459
		return 0;
460
 
461
	for(i = 0; i < argc; i++)
462
	{
463
		if (strcasecmp(azColName[i], "title") == 0 || strcasecmp(azColName[i], "interpret") == 0 ||
464
			strcasecmp(azColName[i], "album") == 0 || strcasecmp(azColName[i], "genre") == 0)
465
			if (argv[i])
466
				strncpy(id3_buffer, argv[i], sizeof(id3_buffer));
467
	}
468
 
469
	buf = urlencode(id3_buffer);
12 andreas 470
	globalLine++;
5 andreas 471
 
12 andreas 472
	sprintf(buffer, "FOLDER:%s:%d:", cp->type, globalLine);
5 andreas 473
 
474
	if (buf != NULL)
475
	{
476
		strcat(buffer, buf);
477
		free(buf);
478
	}
479
	else
480
		strcat(buffer, id3_buffer);
481
 
482
	strcat(buffer, ";");
483
	write(cp->s1, buffer, strlen(buffer));
484
	return 0;
485
}
8 andreas 486
 
13 andreas 487
int listFolderContent(int s1, char *p_type, char *name, int start, int length)
488
{
489
	char query[1024], hv0[128], field[32];
490
	char fname[256];
491
	sqlite3 *db;
492
	sqlite3_stmt *res;
493
	int rc, pos, line;
494
 
495
	strcpy(fname, configs.home);
496
	strcat(fname, MUSICDB);
497
 
498
	if (!strcasecmp(p_type, "TITLE"))
499
		strcpy (field, "title");
500
	else if (!strcasecmp(p_type, "ARTIST"))
501
		strcpy (field, "interpret");
502
	else if (!strcasecmp(p_type, "ALBUM"))
503
		strcpy (field, "album");
504
	else if (!strcasecmp(p_type, "GENRE"))
505
		strcpy (field, "genre");
506
	else
507
	{
508
		strcpy (hv0, "ERROR:LIST:Missing valid type;");
509
		write(s1, hv0, strlen(hv0));
510
		return FALSE;
511
	}
512
 
513
	rc = sqlite3_open(fname, &db);
514
 
515
	if (rc)
516
	{
517
		syslog(LOG_WARNING, "Error opening database %s: %s", fname, sqlite3_errmsg(db));
518
		strcpy(query, "ERROR:LIST:Error opening database;");
519
		write (s1, query, strlen(query));
520
		return FALSE;
521
	}
522
 
523
	/* First count the future result set */
524
	sprintf (query, "select count(*) as cnt from musicdb where %s = \"%s\"", field, name);
525
 
526
	if (sqlite3_prepare(db, query, -1, &res, NULL) != SQLITE_OK)
527
	{
528
		syslog(LOG_DAEMON, "Error preparing SQL statement [%s]: %s", query, sqlite3_errmsg(db));
529
		strcpy(query, "ERROR:USER:Error preparing a SQL statement;");
530
		write(s1, query, strlen(query));
531
		return FALSE;
532
	}
533
 
534
	if (sqlite3_step(res) == SQLITE_ROW)
535
		pos = sqlite3_column_int(res, 0);
536
	else
537
		pos = 0;
55 andreas 538
 
539
	playQuiet = TRUE;
13 andreas 540
	sprintf(hv0, "TOTAL:%d;", pos);
541
	write(s1, hv0, strlen(hv0));
542
	sqlite3_finalize(res);
543
 
544
	sprintf (query, "select id, title, interpret, album, genre, cover from \"main\".\"musicdb\" where %s = \"%s\" order by title", field, name);
545
 
546
	/* Tell client which page to show */
25 andreas 547
	sprintf(hv0, "PAGE:%s;FOLDERNAME:%s;", p_type, name);
13 andreas 548
	write (s1, hv0, strlen (hv0));
549
 
550
	/* Retrieve data from database */
29 andreas 551
	line = pos = 1;
13 andreas 552
 
553
	if (sqlite3_prepare(db, query, -1, &res, NULL) != SQLITE_OK)
554
	{
555
		syslog(LOG_DAEMON, "Error preparing SQL statement [%s]: %s", query, sqlite3_errmsg(db));
556
		strcpy(query, "ERROR:LIST:Error preparing a SQL statement;");
557
		write(s1, query, strlen(query));
55 andreas 558
		playQuiet = FALSE;
13 andreas 559
		return FALSE;
560
	}
561
 
562
	while ((rc = sqlite3_step(res)) == SQLITE_ROW)
563
	{
29 andreas 564
		if (pos >= start && pos < (start + length))
565
		{
13 andreas 566
			listCallback(s1, p_type, line, res);
29 andreas 567
			line++;
568
		}
13 andreas 569
 
29 andreas 570
		if (pos >= (start + length))
13 andreas 571
			break;
29 andreas 572
 
573
		pos++;
13 andreas 574
	}
575
 
576
	sqlite3_finalize(res);
577
	sqlite3_close(db);
55 andreas 578
	playQuiet = FALSE;
13 andreas 579
	return TRUE;
580
}
581
 
8 andreas 582
/*
14 andreas 583
 * Count the playlists of the users and return the result.
584
 */
585
int countPlaylists()
586
{
587
	USERS *act;
588
	int count;
589
 
590
	count = 0;
591
	act = userchain;
592
 
593
	while (act)
594
	{
595
		count++;
596
		act = act->next;
597
	}
598
 
599
	return count;
600
}
601
 
602
/*
8 andreas 603
 * List the playlists of the current user.
604
 */
605
int listPlaylists(int s1, int start, int length)
606
{
607
	USERS *act;
608
	char hv0[512], *user, *playlist;
29 andreas 609
	int pos, line;
8 andreas 610
 
611
	if (userchain == NULL)
612
	{
613
		strcpy(hv0, "ERROR:PLAYLIST:No user selected;");
614
		write(s1, hv0, strlen(hv0));
615
		return FALSE;
616
	}
617
 
55 andreas 618
	playQuiet = TRUE;
31 andreas 619
	strcpy(hv0, "PAGE:PLAYLIST;");
620
	write(s1, hv0, strlen(hv0));
621
 
8 andreas 622
	act = userchain;
29 andreas 623
	pos = line = 1;
8 andreas 624
 
625
	while (act)
626
	{
627
		if (pos < start)
628
		{
629
			act = act->next;
630
			continue;
631
		}
632
 
9 andreas 633
		if (pos >= (start + length))
8 andreas 634
			break;
635
 
636
		user = urlencode(act->uname);
637
		playlist = urlencode(act->playlist);
29 andreas 638
		sprintf(hv0, "PLAYLIST:%d:%d:%s:%s;", line, act->id, user, playlist);
9 andreas 639
		write (s1, hv0, strlen(hv0));
8 andreas 640
 
641
		if (user)
642
			free (user);
643
 
644
		if (playlist)
645
			free (playlist);
646
 
647
		act = act->next;
29 andreas 648
		line++;
8 andreas 649
	}
650
 
55 andreas 651
	playQuiet = FALSE;
8 andreas 652
	return TRUE;
653
}
9 andreas 654
 
655
int listUserPlaylist(int s1, const char *user, const char *playlist, int start, int length)
656
{
657
	char query[1024], hv0[128], buffer[8192];
658
	char fname[256];
659
	sqlite3 *db;
660
	int rc, id, total, pos, line;
661
	sqlite3_stmt *res;
11 andreas 662
	char id3_title[256], id3_artist[256], id3_album[256], id3_genre[256], id3_cover[512];
14 andreas 663
	char *title, *artist, *album, *cover;
9 andreas 664
	USERS *act;
665
 
666
	if (playlist == NULL)
667
	{
668
		strcpy(hv0, "ERROR:LIST:Missing name of playlist;");
669
		write (s1, hv0, strlen(hv0));
670
		return FALSE;
671
	}
672
 
673
	/* Check current user */
674
	if (user != NULL)
675
	{
676
		if (userchain == NULL || strcmp(userchain->uname, user))
677
		{
678
			if (!selectUser(s1, user))
679
				return FALSE;
680
		}
681
	}
682
 
683
	/* Find the playlist */
684
	act = userchain;
685
 
686
	while (act)
687
	{
688
		if (!strcmp(act->playlist, playlist))
689
			break;
690
 
691
		act = act->next;
692
	}
693
 
694
	if (act == NULL)
695
	{
696
		strcpy(hv0, "ERROR:LIST:Playlist not found;");
697
		write (s1, hv0, strlen(hv0));
698
		return FALSE;
699
	}
700
 
701
	strcpy(fname, configs.home);
702
	strcat(fname, MUSICDB);
703
 
704
	rc = sqlite3_open(fname, &db);
705
 
706
	if (rc)
707
	{
708
		syslog(LOG_WARNING, "Error opening database %s: %s", fname, sqlite3_errmsg(db));
709
		strcpy(query, "ERROR:USER:Error opening database;");
710
		write (s1, query, strlen(query));
711
		return FALSE;
712
	}
14 andreas 713
 
55 andreas 714
	playQuiet = TRUE;
31 andreas 715
	strcpy(hv0, "PAGE:PLAYLIST;");
716
	write(s1, hv0, strlen(hv0));
717
 
29 andreas 718
	sprintf(query, "select count(*) from \"main\".\"playlists\" where userid = %d", act->id);
719
 
14 andreas 720
	if (sqlite3_prepare(db, query, -1, &res, NULL) != SQLITE_OK)
721
	{
722
		syslog(LOG_DAEMON, "Error preparing SQL statement [%s]: %s", query, sqlite3_errmsg(db));
723
		strcpy(hv0, "ERROR:USER:Error preparing a SQL statement;");
724
		write(s1, hv0, strlen(hv0));
55 andreas 725
		playQuiet = FALSE;
14 andreas 726
		return FALSE;
727
	}
728
 
729
	if ((rc = sqlite3_step(res)) == SQLITE_ROW)
730
	{
731
		total = sqlite3_column_int(res, 0);
732
		sprintf(hv0, "TOTAL:%d;", total);
733
		write (s1, hv0, strlen(hv0));
734
	}
735
 
736
	sqlite3_finalize(res);
11 andreas 737
	strcpy (query, "select id, title, interpret, album, genre, cover from musicdb as a where ");
9 andreas 738
	strcat (query, "(select musicid from playlists as b where a.id = b.musicid and b.userid = ");
739
	sprintf(hv0, "%d", act->id);
740
	strcat (query, hv0);
741
	strcat (query, ")");
742
 
743
	if (sqlite3_prepare(db, query, -1, &res, NULL) != SQLITE_OK)
744
	{
745
		syslog(LOG_DAEMON, "Error preparing SQL statement [%s]: %s", query, sqlite3_errmsg(db));
746
		strcpy(hv0, "ERROR:USER:Error preparing a SQL statement;");
747
		write(s1, hv0, strlen(hv0));
55 andreas 748
		playQuiet = FALSE;
9 andreas 749
		return FALSE;
750
	}
751
 
752
	pos = 1;
753
	line = 0;
754
 
755
	while ((rc = sqlite3_step(res)) == SQLITE_ROW)
756
	{
757
		if (pos < start)
758
		{
759
			pos++;
760
			continue;
761
		}
762
 
763
		if (pos >= (start + length))
764
			break;
765
 
766
		line++;
767
		memset(id3_title, 0, sizeof(id3_title));
768
		memset(id3_artist, 0, sizeof(id3_artist));
769
		memset(id3_album, 0, sizeof(id3_album));
770
		memset(id3_genre, 0, sizeof(id3_genre));
11 andreas 771
		memset(id3_cover, 0, sizeof(id3_cover));
9 andreas 772
		id = sqlite3_column_int(res, 0);
773
		strncpy(id3_title, (const char *)sqlite3_column_text(res, 1), sizeof(id3_title));
774
		strncpy(id3_artist, (const char *)sqlite3_column_text(res, 2), sizeof(id3_artist));
775
		strncpy(id3_album, (const char *)sqlite3_column_text(res, 3), sizeof(id3_album));
776
		strncpy(id3_genre, (const char *)sqlite3_column_text(res, 4), sizeof(id3_genre));
11 andreas 777
		strncpy(id3_cover, (const char *)sqlite3_column_text(res, 5), sizeof(id3_cover));
9 andreas 778
		title = urlencode(id3_title);
779
		artist = urlencode(id3_artist);
780
		album = urlencode(id3_album);
11 andreas 781
		cover = urlencode(id3_cover);
782
 
9 andreas 783
		if (title != NULL)
784
		{
785
			strncpy(id3_title, title, sizeof(id3_title));
786
			free(title);
787
		}
11 andreas 788
 
9 andreas 789
		if (artist != NULL)
790
		{
791
			strncpy(id3_artist, artist, sizeof(id3_artist));
792
			free(artist);
793
		}
11 andreas 794
 
9 andreas 795
		if (album != NULL)
796
		{
797
			strncpy(id3_album, album, sizeof(id3_album));
798
			free(album);
799
		}
11 andreas 800
 
801
		if (cover != NULL)
802
		{
803
			strncpy(id3_cover, cover, sizeof(id3_cover));
804
			free(cover);
805
		}
806
 
807
		sprintf (buffer, "LINE:PLAYLIST:%d:%d:%s:%s:%s:%s:%s;", id, line, id3_title, id3_artist, id3_album, id3_genre, id3_cover);
9 andreas 808
		write (s1, buffer, strlen(buffer));
809
		pos++;
810
	}
811
 
812
	sqlite3_finalize(res);
813
	sqlite3_close(db);
55 andreas 814
	playQuiet = FALSE;
9 andreas 815
	return TRUE;
816
}
24 andreas 817
 
818
int listUsers(int s1, int start, int length)
819
{
820
	char query[1024], hv0[256];
821
	char fname[256], uname[128], *un;
822
	sqlite3 *db;
823
	int rc, id, total, pos;
824
	sqlite3_stmt *res;
825
 
826
	rc = sqlite3_open(fname, &db);
827
 
828
	if (rc)
829
	{
830
		syslog(LOG_WARNING, "Error opening database %s: %s", fname, sqlite3_errmsg(db));
831
		strcpy(query, "ERROR:LIST:Error opening database;");
832
		write (s1, query, strlen(query));
833
		return FALSE;
834
	}
835
 
836
	sprintf(query, "select distinct count(*) from users order by uname");
837
 
838
	if (sqlite3_prepare(db, query, -1, &res, NULL) != SQLITE_OK)
839
	{
840
		syslog(LOG_DAEMON, "Error preparing SQL statement [%s]: %s", query, sqlite3_errmsg(db));
841
		strcpy(hv0, "ERROR:USER:Error preparing a SQL statement;");
842
		write(s1, hv0, strlen(hv0));
843
		return FALSE;
844
	}
845
 
846
	if ((rc = sqlite3_step(res)) == SQLITE_ROW)
847
	{
848
		total = sqlite3_column_int(res, 0);
849
		sprintf(hv0, "TOTAL:%d;", total);
850
		write (s1, hv0, strlen(hv0));
851
	}
852
 
853
	sqlite3_finalize(res);
854
 
855
	strcpy (query, "select distinct uname, id from users order by users");
856
 
857
	if (sqlite3_prepare(db, query, -1, &res, NULL) != SQLITE_OK)
858
	{
859
		syslog(LOG_DAEMON, "Error preparing SQL statement [%s]: %s", query, sqlite3_errmsg(db));
860
		strcpy(hv0, "ERROR:USER:Error preparing a SQL statement;");
861
		write(s1, hv0, strlen(hv0));
862
		return FALSE;
863
	}
864
 
865
	pos = 0;
55 andreas 866
	playQuiet = TRUE;
24 andreas 867
 
868
	while ((rc = sqlite3_step(res)) == SQLITE_ROW)
869
	{
870
		pos++;
871
 
872
		if (pos < start)
873
			continue;
874
 
875
		if (pos >= (start + length))
876
			break;
877
 
878
		strncpy(uname, (const char *)sqlite3_column_text(res, 0), sizeof(uname));
879
		id = sqlite3_column_int(res, 1);
880
		un = urlencode(uname);
881
 
882
		if (un)
883
		{
884
			strncpy(uname, un, sizeof(uname));
885
			free(un);
886
		}
887
 
888
		sprintf(hv0, "USERS:%d:%d:%s;", id, pos+1, uname);
889
		write(s1, hv0, strlen(hv0));
890
	}
891
 
892
	sqlite3_finalize(res);
893
	sqlite3_close(db);
55 andreas 894
	playQuiet = FALSE;
24 andreas 895
	return TRUE;
896
}