📄 musiccatalog.cpp
字号:
m_database->StoreSubVersion(DATABASE_SUB_VERSION);
m_catMutex->Release();
m_bSurpressAddMessages = false;
if (!m_sigs->empty() && m_context->aps->IsTurnedOn())
m_context->target->AcceptEvent(new Event(INFO_UnsignaturedTracksExist));
return kError_NoErr;
}
void MusicCatalog::StartGeneratingSigs(void)
{
set<string> *newset = new set<string>;
set<string>::iterator i = m_sigs->begin();
for (; i != m_sigs->end(); i++) {
newset->insert(*i);
}
m_context->target->AcceptEvent(new GenerateSignatureEvent(newset));
}
void MusicCatalog::StopGeneratingSigs(void)
{
m_context->target->AcceptEvent(new Event(CMD_KillSigThread));
}
void MusicCatalog::SetDatabase(const char *path)
{
if (m_database)
delete m_database;
m_database = new Database(path, METADATABASE_VERSION);
if (!m_database->Working()) {
delete m_database;
m_database = NULL;
}
if (m_database) {
//if (m_database->IsUpgraded())
// m_context->target->AcceptEvent(new Event(INFO_DatabaseUpgraded));
RePopulateFromDatabase();
if (m_timeout == 0)
PruneDatabase(true, true);
Sort();
}
}
typedef struct PruneThreadStruct {
MusicCatalog *mc;
Thread *thread;
bool sendmessages;
} PruneThreadStruct;
void MusicCatalog::PruneDatabase(bool sendmessages, bool spawn)
{
if (spawn) {
Thread *thread = Thread::CreateThread();
if (thread) {
PruneThreadStruct *pts = new PruneThreadStruct;
pts->mc = this;
pts->sendmessages = sendmessages;
pts->thread = thread;
thread->Create(prune_thread_function, pts, true);
}
}
else {
PruneThread(sendmessages);
}
}
void MusicCatalog::prune_thread_function(void *arg)
{
PruneThreadStruct *pts = (PruneThreadStruct *)arg;
pts->mc->PruneThread(pts->sendmessages);
delete pts->thread;
delete pts;
}
void MusicCatalog::PruneThread(bool sendmessages)
{
m_catMutex->Acquire();
char *key = m_database->NextKey(NULL);
struct stat st;
while (key) {
if (!strncmp("file://", key, 7)) {
uint32 length = strlen(key) + 1;
char *filename = new char[length];
if (IsntError(URLToFilePath(key, filename, &length))) {
if (-1 == stat(filename, &st)) {
if (sendmessages) {
Remove(key);
key = NULL;
}
else {
m_database->Remove(key);
m_trackCount--;
key = NULL;
}
}
}
delete [] filename;
}
key = m_database->NextKey(key);
}
m_catMutex->Release();
}
void MusicCatalog::PruneDirectory(string &directory)
{
m_catMutex->Acquire();
char *key = m_database->NextKey(NULL);
struct stat st;
while (key) {
if (!strncmp("file://", key, 7)) {
uint32 length = strlen(key) + 1;
char *filename = new char[length];
if (IsntError(URLToFilePath(key, filename, &length))) {
if (!strncmp(directory.c_str(), filename, directory.size())) {
if (-1 == stat(filename, &st)) {
Remove(key);
key = NULL;
}
}
}
delete [] filename;
}
key = m_database->NextKey(key);
}
m_catMutex->Release();
}
typedef struct MusicSearchThreadStruct {
MusicCatalog *mc;
vector<string> pathList;
bool bSendMessages;
Thread *thread;
} MusicSearchThreadStruct;
void MusicCatalog::SearchMusic(vector<string> &pathList, bool bBrowserMessages)
{
if (!m_database->Working())
return;
Thread *thread = Thread::CreateThread();
if (thread) {
MusicSearchThreadStruct *mst = new MusicSearchThreadStruct;
mst->mc = this;
mst->pathList = pathList;
mst->thread = thread;
mst->bSendMessages = bBrowserMessages;
thread->Create(musicsearch_thread_function, mst, true);
}
}
void MusicCatalog::StopSearchMusic(void)
{
m_exit = true;
}
void MusicCatalog::musicsearch_thread_function(void *arg)
{
MusicSearchThreadStruct *mst = (MusicSearchThreadStruct *)arg;
mst->mc->m_mutex->Acquire();
mst->mc->m_exit = false;
mst->mc->DoSearchPaths(mst->pathList, mst->bSendMessages);
if (mst->bSendMessages)
mst->mc->AcceptEvent(new Event(INFO_SearchMusicDone));
mst->mc->m_mutex->Release();
delete mst->thread;
delete mst;
}
void MusicCatalog::DoSearchPaths(vector<string> &pathList, bool bSendMessages)
{
vector<string>::iterator i;
if (!bSendMessages)
m_addImmediately = true;
for(i = pathList.begin(); i != pathList.end(); i++)
DoSearchMusic((char *)(*i).c_str(), bSendMessages);
m_addImmediately = false;
}
void MusicCatalog::DoSearchMusic(char *path, bool bSendMessages)
{
WIN32_FIND_DATA find;
HANDLE handle;
string search = path;
#ifndef WIN32
if (!strcmp(path, "/dev") || !strcmp(path, "/proc"))
return;
#endif
if (bSendMessages)
{
string info = string("Searching: ") + search;
m_context->player->AcceptEvent(new BrowserMessageEvent(info));
}
if (search[search.size() - 1] != DIR_MARKER)
search.append(DIR_MARKER_STR);
search.append("*");
#ifdef WIN32
search.append(".*");
#endif
handle = FindFirstFile((char *)search.c_str(), &find);
if (handle != INVALID_HANDLE_VALUE)
{
do
{
char *fileExt;
#ifndef WIN32
if (find.dwFileAttributes & FILE_ATTRIBUTE_SYMLINK)
continue;
#endif
if (find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if (!(!strcmp("." , find.cFileName) || !strcmp("..", find.cFileName)))
{
string newDir = path;
if (path[strlen(path) - 1] != DIR_MARKER)
newDir.append(DIR_MARKER_STR);
newDir.append(find.cFileName);
DoSearchMusic((char *)newDir.c_str(), bSendMessages);
}
}
else
{
#ifdef WIN32
string dirtest = path;
if (path[strlen(path) - 1] != DIR_MARKER)
dirtest.append(DIR_MARKER_STR);
dirtest.append(find.cFileName);
struct stat stdir;
stat(dirtest.c_str(), &stdir);
if (stdir.st_mode & _S_IFDIR) {
DoSearchMusic((char *)dirtest.c_str(), bSendMessages);
continue;
}
#endif
fileExt = m_context->player->GetExtension(find.cFileName);
if (fileExt && m_plm->IsSupportedPlaylistFormat(fileExt) &&
strcmp("currentlist.m3u", find.cFileName))
{
string file = path;
file.append(DIR_MARKER_STR);
file.append(find.cFileName);
uint32 urlLength = strlen(file.c_str()) + 10;
char *url = new char[urlLength];
if (IsntError(FilePathToURL(file.c_str(), url, &urlLength)))
m_database->Insert(url, "P");
if (m_addImmediately)
AddPlaylist(url);
delete [] url;
}
else if (fileExt &&
m_context->player->IsSupportedExtension(fileExt))
{
string file = path;
file.append(DIR_MARKER_STR);
file.append(find.cFileName);
char *tempurl = new char[file.length() + 10];
uint32 length = file.length() + 10;
if (IsError(FilePathToURL(file.c_str(), tempurl, &length)))
{
delete [] tempurl;
delete [] fileExt;
continue;
}
if (!bSendMessages) {
MetaData *tdata = ReadMetaDataFromDatabase(tempurl);
if (tdata) {
delete tdata;
delete [] tempurl;
delete [] fileExt;
continue;
}
}
PlaylistItem *plist = new PlaylistItem(tempurl);
m_plm->RetrieveMetaDataNow(plist);
MetaData *tempdata = ReadMetaDataFromDatabase(tempurl);
if (!tempdata || !m_addImmediately) {
MetaData newmdata = (MetaData)plist->GetMetaData();
if (tempdata)
newmdata.SetGUID(tempdata->GUID());
WriteMetaDataToDatabase(tempurl, newmdata);
}
if (m_addImmediately)
AddSong(tempurl);
if (tempdata)
delete tempdata;
delete plist;
delete [] tempurl;
}
if (fileExt)
delete [] fileExt;
}
}
while (FindNextFile(handle, &find) && !m_exit);
FindClose(handle);
}
}
void MusicCatalog::WriteMetaDataToDatabase(const char *url,
const MetaData metadata,
MetadataStorageType type)
{
if (!m_database->Working())
return;
string ost;
char *num = new char[4096];
char *temp = new char[1024];
const char *kDatabaseDelimiter = " ";
if (type == kTypeStream)
ost.append("S");
else
ost.append("M");
ost.append(kDatabaseDelimiter);
ost.append("11");
ost.append(kDatabaseDelimiter);
sprintf(num, "%ld%s", (long int)metadata.Artist().size(), kDatabaseDelimiter);
ost.append(num);
sprintf(num, "%ld%s", (long int)metadata.Album().size(), kDatabaseDelimiter);
ost.append(num);
sprintf(num, "%ld%s", (long int)metadata.Title().size(), kDatabaseDelimiter);
ost.append(num);
sprintf(num, "%ld%s", (long int)metadata.Comment().size(), kDatabaseDelimiter);
ost.append(num);
sprintf(num, "%ld%s", (long int)metadata.Genre().size(), kDatabaseDelimiter);
ost.append(num);
sprintf(temp, "%ld", (long int)metadata.Year());
sprintf(num, "%ld%s", (long int)strlen(temp), kDatabaseDelimiter);
ost.append(num);
sprintf(temp, "%ld", (long int)metadata.Track());
sprintf(num, "%ld%s", (long int)strlen(temp), kDatabaseDelimiter);
ost.append(num);
sprintf(temp, "%ld", (long int)metadata.Time());
sprintf(num, "%ld%s", (long int)strlen(temp), kDatabaseDelimiter);
ost.append(num);
sprintf(temp, "%ld", (long int)metadata.Size());
sprintf(num, "%ld%s", (long int)strlen(temp), kDatabaseDelimiter);
ost.append(num);
sprintf(temp, "%ld", (long int)metadata.PlayCount());
sprintf(num, "%ld%s", (long int)strlen(temp), kDatabaseDelimiter);
ost.append(num);
sprintf(num, "%ld%s", (long int)metadata.GUID().size(), kDatabaseDelimiter);
ost.append(num);
ost.append(metadata.Artist());
ost.append(metadata.Album());
ost.append(metadata.Title());
ost.append(metadata.Comment());
ost.append(metadata.Genre());
sprintf(temp, "%ld", (long int)metadata.Year());
ost.append(temp);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -