diff options
Diffstat (limited to 'mugglei.c')
-rwxr-xr-x | mugglei.c | 170 |
1 files changed, 140 insertions, 30 deletions
@@ -16,7 +16,8 @@ using namespace std; MYSQL *db;
-char *host, *user, *pass, *dbname;
+string host, user, pass, dbname;
+bool import_assorted;
int init_database()
{
@@ -26,8 +27,8 @@ int init_database() return -1;
}
- if( mysql_real_connect( db, host, user, pass,
- dbname, 0, NULL, 0 ) == NULL )
+ if( mysql_real_connect( db, host.c_str(), user.c_str(), pass.c_str(), dbname.c_str(),
+ 0, NULL, 0 ) == NULL )
{
return -2;
}
@@ -61,9 +62,22 @@ time_t get_db_modification_time( long uid ) return mt;
}
-long find_file_in_database( string filename )
+TagLib::String escape_string( MYSQL *db, TagLib::String s )
{
- MYSQL_RES *result = mgSqlReadQuery( db, "SELECT id FROM tracks WHERE mp3file=\"%s\"", filename.c_str() );
+ char *buf = strdup( s.toCString() );
+ char *escbuf = (char *) malloc( 2*strlen( buf ) + 1 );
+
+ int len = mysql_real_escape_string( db, escbuf, buf, strlen( buf ) );
+
+ return TagLib::String( escbuf );
+}
+
+long find_file_in_database( MYSQL *db, string filename )
+{
+ TagLib::String file = TagLib::String( filename.c_str() );
+ file = escape_string( db, file );
+
+ MYSQL_RES *result = mgSqlReadQuery( db, "SELECT id FROM tracks WHERE mp3file=\"%s\"", file.toCString() );
MYSQL_ROW row = mysql_fetch_row( result );
// obtain ID and return
@@ -73,7 +87,6 @@ long find_file_in_database( string filename ) // read tags from the mp3 file and store them into the corresponding database entry
void update_db( long uid, string filename )
{
- // char title[1024], album[1024], year[5], artist[1024], cddbid[20], trackno[5];
TagLib::String title, album, artist, genre, cddbid;
uint trackno, year;
@@ -92,20 +105,53 @@ void update_db( long uid, string filename ) artist = tag->artist();
trackno = tag->track();
genre = tag->genre();
+
+ title = escape_string( db, title );
+ album = escape_string( db, album );
+ artist = escape_string( db, artist );
- // TODO: CD identifier (?), playcounter, popularimeter?, volume adjustment
+ // TODO: CD identifier (if it exists), playcounter, popularimeter (rating?), volume adjustment, lyrics, cover
// finally update the database
// obtain associated album or create
if( album == "" )
- { // no album found, associate with default album
- cddbid = "0000unknown0000";
+ { // no album found, create default album for artist
+ MYSQL_RES *result = mgSqlReadQuery( db, "SELECT cddbid FROM album WHERE title=\"Unassigned\" AND artist=\"%s\"", artist.toCString() );
+ MYSQL_ROW row = mysql_fetch_row( result );
+
+ // Default album does not yet exist (num rows == 0)
+ int nrows = mysql_num_rows(result);
+ if( nrows == 0 )
+ {
+ // create new album entry "Unassigned" for this artist
+ long id = random();
+ char *buf;
+ asprintf( &buf, "%d-%s", id, tag->artist().toCString() );
+ cddbid = TagLib::String( buf ).substr( 0, 20 );
+ cddbid = escape_string( db, cddbid );
+ free( buf );
+
+ mgSqlWriteQuery( db, "INSERT INTO album (artist,title,cddbid) VALUES (\"%s\", \"Unassigned\", \"%s\")", artist.toCString(), cddbid.toCString() );
+ }
+ else
+ { // use first album found as source id for the track
+ cddbid = row[0];
+ }
}
else
{ // album tag found, associate or create
- MYSQL_RES *result = mgSqlReadQuery( db, "SELECT cddbid FROM album WHERE title=\"%s\" AND artist=\"%s\"",
- album.toCString(), artist.toCString() );
+ MYSQL_RES *result;
+ if( import_assorted )
+ { // lookup an existing album by title only (artist should be "Various Artists"
+ result = mgSqlReadQuery( db, "SELECT cddbid FROM album WHERE title=\"%s\" AND artist=\"Various Artists\"",
+ album.toCString(), artist.toCString() );
+ }
+ else
+ {
+ result = mgSqlReadQuery( db, "SELECT cddbid FROM album WHERE title=\"%s\" AND artist=\"%s\"",
+ album.toCString(), artist.toCString() );
+ }
MYSQL_ROW row = mysql_fetch_row( result );
// num rows == 0 ?
@@ -115,11 +161,17 @@ void update_db( long uid, string filename ) // create new album entry
long id = random();
char *buf;
- asprintf( &buf, "%d-%s", id, album.toCString() );
+ asprintf( &buf, "%d-%s", id, tag->album().toCString() );
cddbid = TagLib::String( buf ).substr( 0, 20 );
+ cddbid = escape_string( db, cddbid );
free( buf );
-
- mgSqlWriteQuery( db, "INSERT INTO album (artist,title,cddbid) VALUES (\"%s\", \"%s\", \"%s\")", artist.toCString(), album.toCString(), cddbid.toCString() );
+
+ if( import_assorted )
+ { // in this case, the album author is "Various Artists"
+ mgSqlWriteQuery( db, "INSERT INTO album (artist,title,cddbid) VALUES (\"Various Artists\", \"%s\", \"%s\")", album.toCString(), cddbid.toCString() ); }
+ else
+ {
+ mgSqlWriteQuery( db, "INSERT INTO album (artist,title,cddbid) VALUES (\"%s\", \"%s\", \"%s\")", artist.toCString(), album.toCString(), cddbid.toCString() ); }
}
else
{ // use first album found as source id for the track
@@ -138,8 +190,8 @@ void update_db( long uid, string filename ) // int t = title.find( "'" );
// int a = artist.find( "'" );
mgSqlWriteQuery( db,
- "INSERT INTO tracks (artist,title,year,sourceid,tracknb,mp3file)"
- " VALUES (\"%s\", \"%s\", %d, \"%s\", %d, \"%s\")",
+ "INSERT INTO tracks (artist,title,genre1,genre2,year,sourceid,tracknb,mp3file)"
+ " VALUES (\"%s\", \"%s\", \"\", \"\", %d, \"%s\", %d, \"%s\")",
artist.toCString(), title.toCString(), year, cddbid.toCString(), trackno, filename.c_str() );
/*
cout << "-- TAG --" << endl;
@@ -160,12 +212,12 @@ void update_tags( long uid, string filename ) }
-void evaluate_file( string filename )
+void evaluate_file( MYSQL *db, string filename )
{
if( 0 == init_database() )
{
// is filename stored in database?
- long uid = find_file_in_database( filename );
+ long uid = find_file_in_database( db, filename );
if( uid >= 0 )
{
// currently only update database, do not consider writing changes from the db back
@@ -198,33 +250,91 @@ void evaluate_file( string filename ) int main( int argc, char *argv[] )
{
- host = "134.130.124.222";
- user = "root";
- dbname = "giantdisc";
- pass = NULL;
- /*
+ int option_index;
+ string filename;
+
+ if( argc < 2 )
+ { // we need at least a filename!
+ cout << "mugglei -- import helper for Muggle VDR plugin" << endl;
+ cout << "(C) Lars von Wedel" << endl;
+ cout << "This is free software; see the source for copying conditions." << endl;
+ cout << "" << endl;
+ cout << "Options:" << endl;
+ cout << " -h <hostname> - specify host of mySql database server (default is 'localhost')" << endl;
+ cout << " -n <database> - specify database name (default is 'GiantDisc')" << endl;
+ cout << " -u <username> - specify user of mySql database (default is empty)" << endl;
+ cout << " -p <password> - specify password of user (default is empty password)" << endl;
+ cout << " -f <filename> - name of music file to import" << endl;
+ cout << " -a - import track as if it was on an assorted album" << endl;
+
+ exit( 1 );
+ }
+
+ // option defaults
host = "localhost";
- user = "vdr";
dbname = "GiantDisc";
- pass = NULL;
- */
+ user = "";
+ pass = "";
+ import_assorted = false;
+
+ // parse command line options
+ while( 1 )
+ {
+ int c = getopt(argc, argv, "h:u:p:n:af:");
+
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+ case 0:
+ { // long option
+
+ } break;
+ case 'h':
+ {
+ host = optarg;
+ } break;
+ case 'u':
+ {
+ user = optarg;
+ } break;
+ case 'p':
+ {
+ pass = optarg;
+ } break;
+ case 'd':
+ {
+ dbname = optarg;
+ } break;
+ case 'a':
+ {
+ import_assorted = true;
+ } break;
+ case 'f':
+ {
+ filename = optarg;
+ } break;
+ }
+ }
+ // init random number generator
struct timeval tv;
struct timezone tz;
gettimeofday( &tv, &tz );
- srandom( tv.tv_usec );
+ srandom( tv.tv_usec );
int res = init_database();
if( !res )
{
- update_db( 0, string( argv[1] ) );
+ update_db( 0, filename );
}
else
{
- printf( "Database initialization failed. Exiting.\n" );
+ cout << "Database initialization failed. Exiting.\n" << endl;
}
-
+
return res;
}
|