Subversion Repositories mdb

Rev

Rev 8 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * Copyright (C) 2015 by Andreas Theofilu <andreas@theosys.at>
 *
 * All rights reserved. No warranty, explicit or implicit, provided.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Andreas Theofilu and his suppliers, if any.
 * The intellectual and technical concepts contained
 * herein are proprietary to Andreas Theofilu and its suppliers and
 * may be covered by European and Foreign Patents, patents in process,
 * and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Andreas Theofilu.
 */
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <stdlib.h>
#include <libgen.h>
#include <ctype.h>
#include <math.h>
#include <syslog.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sqlite3.h>
#include <id3.h>
#include "config.h"
#include "helplib.h"
#include "list.h"

struct callPars
{
        int s1;
        int start;
        int length;
        char *type;
};

int line;
int pos;

static int listCallback(void *hint, int argc, char **argv, char **azColName);
static int folderCallback(void *hint, int argc, char **argv, char **azColName);

int listSongs(int s1, char *p_type, int start, int length)
{
        char query[1024];
        char fname[256];
        sqlite3 *db;
        char *zErrMsg = 0;
        int rc;
        struct callPars cp;

        strcpy(fname, configs.home);
        strcat(fname, "/music.db");
        
        rc = sqlite3_open(fname, &db);
        
        if (rc)
        {
                syslog(LOG_WARNING, "Error opening database %s: %s", fname, sqlite3_errmsg(db));
                strcpy(query, "ERROR:LIST:Error opening database;");
                write (s1, query, strlen(query));
                return FALSE;
        }
        
        strcpy (query, "select id, title, interpret, album, genre from \"main\".\"musicdb\" ");
        strcat (query, "order by ");
        
        if (strcmp(p_type, "TITLE") == 0)
                strcat (query, "title");
        else if (strcmp(p_type, "ARTIST") == 0)
                strcat (query, "interpret");
        else if (strcmp(p_type, "ALBUM") == 0)
                strcat (query, "album");
        else if (strcmp(p_type, "GENRE") == 0)
                strcat (query, "genre");
        else            /* No or unknown type */
        {
                strcpy (query, "ERROR:LIST:Missing type;");
                write(s1, query, strlen(query));
                sqlite3_close(db);
                return FALSE;
        }

        cp.s1 = s1;
        cp.type = p_type;
        cp.start = start;
        cp.length = length;
        line = 0;
        pos = -1;

        if ((rc = sqlite3_exec(db, query, listCallback, (void *)&cp, &zErrMsg)) != SQLITE_OK)
        {
                syslog(LOG_WARNING, "SQL error [%s]: %s", query, zErrMsg);
                sqlite3_free(zErrMsg);
                sqlite3_close(db);
                strcpy(query, "ERROR:LIST:SQL error;");
                write (s1, query, strlen(query));
                return FALSE;
        }

        if (pos >= 0)
        {
                sprintf(query, "TOTAL:%d;", pos + 1);
                write (s1, query, strlen(query));
        }

        sqlite3_close(db);
        return TRUE;
}

int listFolders(int s1, char *p_type, int start, int length)
{
        char query[1024], field[16];
        char fname[256];
        sqlite3 *db;
        char *zErrMsg = 0;
        int rc;
        struct callPars cp;
        
        strcpy(fname, configs.home);
        strcat(fname, "/music.db");
        
        rc = sqlite3_open(fname, &db);
        
        if (rc)
        {
                syslog(LOG_WARNING, "Error opening database %s: %s", fname, sqlite3_errmsg(db));
                strcpy(query, "ERROR:FOLDER:Error opening database;");
                write (s1, query, strlen(query));
                return FALSE;
        }
                
        strcpy (query, "select distinct ");
        
        if (strcmp(p_type, "TITLE") == 0)
                strcpy (field, "title");
        else if (strcmp(p_type, "ARTIST") == 0)
                strcpy (field, "interpret");
        else if (strcmp(p_type, "ALBUM") == 0)
                strcpy (field, "album");
        else if (strcmp(p_type, "GENRE") == 0)
                strcpy (field, "genre");
        else            /* No or unknown type */
        {
                strcpy (query, "ERROR:FOLDER:Missing type;");
                write(s1, query, strlen(query));
                sqlite3_close(db);
                return FALSE;
        }

        strcat (query, field);
        strcat (query, " from \"main\".\"musicdb\" order by ");
        strcat (query, field);

        cp.s1 = s1;
        cp.type = p_type;
        cp.start = start;
        cp.length = length;
        line = 0;
        pos = -1;

        if ((rc = sqlite3_exec(db, query, folderCallback, (void *)&cp, &zErrMsg)) != SQLITE_OK)
        {
                syslog(LOG_WARNING, "SQL error [%s]: %s", query, zErrMsg);
                sqlite3_free(zErrMsg);
                sqlite3_close(db);
                strcpy(query, "ERROR:FOLDER:SQL error;");
                write (s1, query, strlen(query));
                return FALSE;
        }

        if (pos >= 0)
        {
                sprintf(query, "TOTAL:%d;", pos + 1);
                write (s1, query, strlen(query));
        }

        sqlite3_close(db);
        return TRUE;
}

static int listCallback(void *hint, int argc, char **argv, char **azColName)
{
        int i, id;
        char id3_title[256], id3_artist[256], id3_album[256], id3_genre[256];
        char buffer[8192];
        char *title, *artist, *album;
        struct callPars *cp;

        pos++;
        cp = (struct callPars *)hint;
        memset(id3_title, 0, sizeof(id3_title));
        memset(id3_artist, 0, sizeof(id3_artist));
        memset(id3_album, 0, sizeof(id3_album));
        memset(id3_genre, 0, sizeof(id3_genre));
        id = -1;

        if (pos < cp->start || pos >= (cp->start + cp->length))
                return 0;

        for(i = 0; i < argc; i++)
        {
                if (strcasecmp(azColName[i], "id") == 0)
                        if (argv[i])
                                id = atoi(argv[i]);

                if (strcasecmp(azColName[i], "title") == 0)
                        if (argv[i])
                                strncpy(id3_title, argv[i], sizeof(id3_title));

                if (strcasecmp(azColName[i], "interpret") == 0)
                        if (argv[i])
                                strncpy(id3_artist, argv[i], sizeof(id3_artist));
                        
                if (strcasecmp(azColName[i], "album") == 0)
                        if (argv[i])
                                strncpy(id3_album, argv[i], sizeof(id3_album));
                                
                if (strcasecmp(azColName[i], "genre") == 0)
                        if (argv[i])
                                strncpy(id3_genre, argv[i], sizeof(id3_genre));
        }

        title = urlencode(id3_title);
        artist = urlencode(id3_artist);
        album = urldecode(id3_album);
/*      title = artist = album = NULL; */
        line++;

        sprintf(buffer, "LINE:%s:%d:%d:", cp->type, id, line);

        if (title != NULL)
        {
                strcat(buffer, title);
                free(title);
        }
        else
                strcat(buffer, id3_title);
        
        strcat(buffer, ":");
        
        if (artist != NULL)
        {
                strcat(buffer, artist);
                free(artist);
        }
        else
                strcat(buffer, id3_artist);
        
        strcat(buffer, ":");
        
        if (album != NULL)
        {
                strcat(buffer, album);
                free(album);
        }
        else
                strcat(buffer, id3_album);
        
        strcat(buffer, ":");
        strcat(buffer, id3_genre);
        strcat(buffer, ";");
        write(cp->s1, buffer, strlen(buffer));
        return 0;
}

static int folderCallback(void *hint, int argc, char **argv, char **azColName)
{
        int i;
        char id3_buffer[256];
        char buffer[8192];
        char *buf;
        struct callPars *cp;

        pos++;
        cp = (struct callPars *)hint;
        memset(id3_buffer, 0, sizeof(id3_buffer));

        if (pos < cp->start || pos >= (cp->start + cp->length))
                return 0;

        for(i = 0; i < argc; i++)
        {
                if (strcasecmp(azColName[i], "title") == 0 || strcasecmp(azColName[i], "interpret") == 0 ||
                        strcasecmp(azColName[i], "album") == 0 || strcasecmp(azColName[i], "genre") == 0)
                        if (argv[i])
                                strncpy(id3_buffer, argv[i], sizeof(id3_buffer));
        }

        buf = urlencode(id3_buffer);
        line++;

        sprintf(buffer, "FOLDER:%s:%d:", cp->type, line);

        if (buf != NULL)
        {
                strcat(buffer, buf);
                free(buf);
        }
        else
                strcat(buffer, id3_buffer);

        strcat(buffer, ";");
        write(cp->s1, buffer, strlen(buffer));
        return 0;
}