diff options
author | LarsAC <LarsAC@e10066b5-e1e2-0310-b819-94efdf66514b> | 2005-03-22 06:47:53 +0000 |
---|---|---|
committer | LarsAC <LarsAC@e10066b5-e1e2-0310-b819-94efdf66514b> | 2005-03-22 06:47:53 +0000 |
commit | e2de0c5ed7bbbe4b236246e8bfd71cc87c8d974f (patch) | |
tree | 616f2f0a482597e3968e281ccf8adcfd04f45bbc /muggle-plugin/mg_sync.c | |
parent | 101360901576c7e91196de60e2e6ebd6a4b145dd (diff) | |
download | vdr-plugin-muggle-0.1.6-BETA.tar.gz vdr-plugin-muggle-0.1.6-BETA.tar.bz2 |
Added 0.1.6 beta tag0.1.6-BETA
git-svn-id: https://vdr-muggle.svn.sourceforge.net/svnroot/vdr-muggle/tags/0.1.6-BETA@586 e10066b5-e1e2-0310-b819-94efdf66514b
Diffstat (limited to 'muggle-plugin/mg_sync.c')
-rw-r--r-- | muggle-plugin/mg_sync.c | 305 |
1 files changed, 305 insertions, 0 deletions
diff --git a/muggle-plugin/mg_sync.c b/muggle-plugin/mg_sync.c new file mode 100644 index 0000000..677c3f8 --- /dev/null +++ b/muggle-plugin/mg_sync.c @@ -0,0 +1,305 @@ +/*! + * \file mg_sync.c + * \brief synchronization between SQL and filesystem + * + * \version $Revision: 1.0 $ + * \date $Date: 2004-12-07 10:10:35 +0200 (Tue, 07 Dec 2004) $ + * \author Wolfgang Rohdewald + * \author Responsible author: $Author: wr $ + * + */ + +#include "mg_sync.h" + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <stdio.h> +#include <fts.h> +#include <sys/time.h> +#include <time.h> + +#include <mpegfile.h> +#include <flacfile.h> +#include <id3v2tag.h> +#include <fileref.h> + +#include "mg_tools.h" +#include "mg_mysql.h" +#include "mg_setup.h" + +char * +mgSync::sql_Cstring(TagLib::String s,char *buf) +{ + return m_db.sql_Cstring(s.toCString(),buf); +} + +char * +mgSync::lower(char *s) +{ + char *p=s; + while (*p) + { + int i=(int)(*p); + (*p)=(char)tolower(i); + p++; + } + return s; +} + +TagLib::String +mgSync::getlanguage(const char *filename) +{ + TagLib::String result = ""; + TagLib::ID3v2::Tag * id3v2tag=0; + if (!strcmp(c_extension,"flac")) + { + TagLib::FLAC::File f(filename); + id3v2tag = f.ID3v2Tag(); + if (id3v2tag) + { + TagLib::ID3v2::FrameList l = id3v2tag->frameListMap()["TLAN"]; + if (!l.isEmpty()) + result = l.front()->toString(); + } + } + else if (!strcmp(c_extension,"mp3")) + { + TagLib::MPEG::File f(filename); + id3v2tag = f.ID3v2Tag(); + if (id3v2tag) + { + TagLib::ID3v2::FrameList l = id3v2tag->frameListMap()["TLAN"]; + if (!l.isEmpty()) + result = l.front()->toString(); + } + } + return result; +} + +char * +mgSync::getAlbum(const char *c_album,const char *c_artist,const char *c_directory) +{ + char * result; + char *b; + asprintf(&b,"SELECT cddbid FROM album" + " WHERE title=%s AND artist=%s",c_album,c_artist); + result=m_db.sql_Cstring(m_db.get_col0(b)); + free(b); + if (!strcmp(result,"'NULL'")) + { + const char *directory="substring(tracks.mp3file,1,length(tracks.mp3file)" + "-instr(reverse(tracks.mp3file),'/'))"; + char *where; + asprintf(&where,"WHERE tracks.sourceid=album.cddbid " + "AND %s=%s " + "AND album.title=%s", + directory,c_directory, + c_album); + + // how many artists will the album have after adding this one? + asprintf(&b,"SELECT distinct album.artist FROM tracks, album %s " + " union select %s",where,c_artist); + MYSQL_RES *rows = m_db.exec_sql (b); + free(b); + long new_album_artists = m_db.affected_rows(); + mysql_free_result(rows); + if (new_album_artists>1) // is the album multi artist? + { + asprintf(&b,"SELECT album.cddbid FROM tracks, album %s",where); + free(result); + result=m_db.sql_Cstring(m_db.get_col0(b)); + free(b); + asprintf(&b,"UPDATE album SET artist='Various Artists' WHERE cddbid=%s",result); + m_db.exec_sql(b); + // here we could change all tracks.sourceid to result and delete + // the other album entries for this album, but that should only + // be needed if a pre 0.1.4 import has been done incorrectly, so we + // don't bother + } + else + { // no usable album found + free(result); + asprintf(&result,"'%ld-%9s",random(),c_artist+1); + char *p=strchr(result,0)-1; + if (*p!='\'') + *p='\''; + asprintf(&b,"INSERT INTO album SET title=%s,artist=%s,cddbid=%s", + c_album,c_artist,result); + m_db.exec_sql(b); + free(b); + } + free(where); + } + return result; +} + +mgSync::mgSync() +{ + m_genre_rows=0; + if (!m_db.Connected()) + return; + m_genre_rows = m_db.exec_sql ("SELECT id,genre from genre"); + MYSQL_ROW rx; + while ((rx = mysql_fetch_row (m_genre_rows)) != 0) + m_Genres[rx[1]]=rx[0]; + // init random number generator + struct timeval tv; + struct timezone tz; + gettimeofday( &tv, &tz ); + srandom( tv.tv_usec ); +} + +mgSync::~mgSync() +{ + if (m_genre_rows) mysql_free_result(m_genre_rows); +} + +void +mgSync::UpdateTrack(long trackid) +{ + char sql[7000]; + char *c_cddbid=getAlbum(c_album,c_artist,c_directory); + sprintf(sql,"UPDATE tracks SET artist=%s, title=%s,year=%d,sourceid=%s," + "tracknb=%d,length=%d,bitrate=%d,samplerate=%d," + "channels=%d,genre1=%s,lang=%s WHERE id=%ld", + c_artist,c_title,year,c_cddbid, + trackno,len,bitrate,sample, + channels,c_genre1,c_lang,trackid); + free(c_cddbid); + m_db.exec_sql(sql); +} + +void +mgSync::AddTrack() +{ + char sql[7000]; + char *c_cddbid=getAlbum(c_album,c_artist,c_directory); + sprintf(sql,"INSERT INTO tracks SET artist=%s,title=%s,year=%u,sourceid=%s," + "tracknb=%u,mp3file=%s,length=%d,bitrate=%d,samplerate=%d," + "channels=%d,genre1=%s,genre2='',lang=%s," + "folder1=%s,folder2=%s,folder3=%s,folder4=%s", + c_artist,c_title,year,c_cddbid, + trackno,c_mp3file,len,bitrate,sample, + channels,c_genre1,c_lang, + c_folder1,c_folder2,c_folder3,c_folder4); + free(c_cddbid); + m_db.exec_sql(sql); +} + +bool +mgSync::GetFileInfo(const char *filename) +{ + TagLib::FileRef f( filename) ; + if (f.isNull()) + return false; + TagLib::Tag *tag = f.tag(); + if (!f.tag()) + return false; + if (tag->album()=="") + strcpy(c_album,"'Unassigned'"); + else + sql_Cstring(tag->album(),c_album); + sql_Cstring(tag->artist(),c_artist); + sql_Cstring(tag->title(),c_title); + sql_Cstring(filename,c_directory); + char *slash=strrchr(c_directory,'/'); + if (slash) + { + *slash='\''; + *(slash+1)=0; + } + TagLib::String sgenre1=tag->genre(); + const char *genrename=sgenre1.toCString(); + const char *genreid=m_Genres[genrename].c_str(); + sql_Cstring(genreid,c_genre1); + sql_Cstring(getlanguage(filename),c_lang); + trackno=tag->track(); + year=tag->year(); + TagLib::AudioProperties *ap = f.audioProperties(); + len = ap->length(); // tracks.length + bitrate = ap->bitrate(); // tracks.bitrate + sample = ap->sampleRate(); //tracks.samplerate + channels = ap->channels(); //tracks.channels + if (m_db.HasFolderFields()) + { + char *folders[4]; + char *fbuf=SeparateFolders(filename,folders,4); + sql_Cstring(folders[0],c_folder1); + sql_Cstring(folders[1],c_folder2); + sql_Cstring(folders[2],c_folder3); + sql_Cstring(folders[3],c_folder4); + free(fbuf); + } + return true; +} + +void +mgSync::SyncFile(const char *filename) +{ + if (!strncmp(filename,"./",2)) // strip leading ./ + filename += 2; + if (strlen(filename)>255) + { + mgWarning("Length of file exceeds database field capacity: %s", filename); + return; + } + mgDebug(3,"Importing %s",filename); + sql_Cstring(filename,c_mp3file); + char sql[600]; + sprintf(sql,"SELECT id from tracks WHERE mp3file=%s",c_mp3file); + string s = m_db.get_col0(sql); + if (s!="NULL") + { + if (GetFileInfo(filename)) + UpdateTrack(atol(s.c_str())); + } + else + { + if (GetFileInfo(filename)) + AddTrack(); + } +} + +void +mgSync::Sync(char * const * path_argv, bool delete_missing) +{ + extern void showimportcount(unsigned int,bool final=false); + if (!m_db.Connected()) + return; + + unsigned int count=0; + m_db.CreateFolderFields(); + chdir(the_setup.ToplevelDir); + FTS *fts; + FTSENT *ftsent; + fts = fts_open( path_argv, FTS_LOGICAL, 0); + if (fts) + { + while ( (ftsent = fts_read(fts)) != NULL) + { + if (!((ftsent->fts_statp->st_mode)||S_IFREG)) + continue; + char *extension = strrchr(ftsent->fts_path,'.'); + if (!extension) + continue; + strcpy(c_extension,extension+1); + lower(c_extension); + if (!strcmp(c_extension,"flac") || !strcmp(c_extension,"ogg") || !strcmp(c_extension,"mp3")) + { + SyncFile(ftsent->fts_path); + count++; + if (count%1000==0) + showimportcount(count); + } + } + fts_close(fts); + } + showimportcount(count,true); +} + +void +mgSync::Create() +{ + m_db.Create(); +} |