1 |
/*************************************************************************** |
/*************************************************************************** |
2 |
* * |
* * |
3 |
* Copyright (C) 2007 Grigor Iliev * |
* Copyright (C) 2007, 2008 Grigor Iliev * |
4 |
* * |
* * |
5 |
* This program is free software; you can redistribute it and/or modify * |
* This program is free software; you can redistribute it and/or modify * |
6 |
* it under the terms of the GNU General Public License as published by * |
* it under the terms of the GNU General Public License as published by * |
20 |
|
|
21 |
#include "InstrumentsDbUtilities.h" |
#include "InstrumentsDbUtilities.h" |
22 |
|
|
23 |
|
#include "../common/File.h" |
24 |
#include "../common/global_private.h" |
#include "../common/global_private.h" |
25 |
|
|
|
#include <dirent.h> |
|
26 |
#include <errno.h> |
#include <errno.h> |
|
#include <ftw.h> |
|
27 |
|
|
28 |
#include "../common/Exception.h" |
#include "../common/Exception.h" |
29 |
#include "InstrumentsDb.h" |
#include "InstrumentsDb.h" |
504 |
int AddInstrumentsJob::GetFileCount() { |
int AddInstrumentsJob::GetFileCount() { |
505 |
int count = 0; |
int count = 0; |
506 |
|
|
507 |
DIR* pDir = opendir(FsDir.c_str()); |
try { |
508 |
if (pDir == NULL) { |
FileListPtr fileList = File::GetFiles(FsDir); |
|
std::stringstream ss; |
|
|
ss << "The scanning of directory `" << FsDir << "` failed: "; |
|
|
ss << strerror(errno); |
|
|
std::cerr << ss.str(); |
|
|
return 0; |
|
|
} |
|
|
|
|
|
struct dirent* pEnt = readdir(pDir); |
|
|
while (pEnt != NULL) { |
|
|
if (pEnt->d_type != DT_REG) { |
|
|
pEnt = readdir(pDir); |
|
|
continue; |
|
|
} |
|
509 |
|
|
510 |
String s(pEnt->d_name); |
for (int i = 0; i < fileList->size(); i++) { |
511 |
if(s.length() < 4) { |
String s = fileList->at(i); |
512 |
pEnt = readdir(pDir); |
if (s.length() < 4) continue; |
513 |
continue; |
if(!strcasecmp(".gig", s.substr(s.length() - 4).c_str())) count++; |
514 |
} |
} |
515 |
if(!strcasecmp(".gig", s.substr(s.length() - 4).c_str())) count++; |
} catch(Exception e) { |
516 |
|
e.PrintMessage(); |
517 |
pEnt = readdir(pDir); |
return 0; |
|
} |
|
|
|
|
|
if (closedir(pDir)) { |
|
|
std::stringstream ss; |
|
|
ss << "Failed to close directory `" << FsDir << "`: "; |
|
|
ss << strerror(errno); |
|
|
std::cerr << ss.str(); |
|
518 |
} |
} |
519 |
|
|
520 |
return count; |
return count; |
546 |
} |
} |
547 |
|
|
548 |
|
|
|
String DirectoryScanner::DbDir; |
|
|
String DirectoryScanner::FsDir; |
|
|
bool DirectoryScanner::Flat; |
|
|
ScanProgress* DirectoryScanner::pProgress; |
|
|
|
|
549 |
void DirectoryScanner::Scan(String DbDir, String FsDir, bool Flat, ScanProgress* pProgress) { |
void DirectoryScanner::Scan(String DbDir, String FsDir, bool Flat, ScanProgress* pProgress) { |
550 |
dmsg(2,("DirectoryScanner: Scan(DbDir=%s,FsDir=%s,Flat=%d)\n", DbDir.c_str(), FsDir.c_str(), Flat)); |
dmsg(2,("DirectoryScanner: Scan(DbDir=%s,FsDir=%s,Flat=%d)\n", DbDir.c_str(), FsDir.c_str(), Flat)); |
551 |
if (DbDir.empty() || FsDir.empty()) throw Exception("Directory expected"); |
if (DbDir.empty() || FsDir.empty()) throw Exception("Directory expected"); |
552 |
|
|
553 |
struct stat statBuf; |
this->DbDir = DbDir; |
554 |
int res = stat(FsDir.c_str(), &statBuf); |
this->FsDir = FsDir; |
|
if (res) { |
|
|
std::stringstream ss; |
|
|
ss << "Fail to stat `" << FsDir << "`: " << strerror(errno); |
|
|
throw Exception(ss.str()); |
|
|
} |
|
|
|
|
|
if (!S_ISDIR(statBuf.st_mode)) { |
|
|
throw Exception("Directory expected"); |
|
|
} |
|
|
|
|
|
DirectoryScanner::DbDir = DbDir; |
|
|
DirectoryScanner::FsDir = FsDir; |
|
555 |
if (DbDir.at(DbDir.length() - 1) != '/') { |
if (DbDir.at(DbDir.length() - 1) != '/') { |
556 |
DirectoryScanner::DbDir.append("/"); |
this->DbDir.append("/"); |
557 |
} |
} |
558 |
if (FsDir.at(FsDir.length() - 1) != '/') { |
if (FsDir.at(FsDir.length() - 1) != File::DirSeparator) { |
559 |
DirectoryScanner::FsDir.append("/"); |
this->FsDir.push_back(File::DirSeparator); |
560 |
} |
} |
561 |
DirectoryScanner::Flat = Flat; |
this->Flat = Flat; |
562 |
DirectoryScanner::pProgress = pProgress; |
this->pProgress = pProgress; |
563 |
|
|
564 |
ftw(FsDir.c_str(), FtwCallback, 10); |
File::WalkDirectoryTree(FsDir, this); |
565 |
} |
} |
566 |
|
|
567 |
int DirectoryScanner::FtwCallback(const char* fpath, const struct stat* sb, int typeflag) { |
void DirectoryScanner::DirectoryEntry(std::string Path) { |
568 |
dmsg(2,("DirectoryScanner: FtwCallback(fpath=%s)\n", fpath)); |
dmsg(2,("DirectoryScanner: DirectoryEntry(Path=%s)\n", Path.c_str())); |
|
if (typeflag != FTW_D) return 0; |
|
569 |
|
|
570 |
String dir = DbDir; |
String dir = DbDir; |
571 |
if (!Flat) { |
if (!Flat) { |
572 |
String subdir = fpath; |
String subdir = Path; |
573 |
if(subdir.length() > FsDir.length()) { |
if(subdir.length() > FsDir.length()) { |
574 |
subdir = subdir.substr(FsDir.length()); |
subdir = subdir.substr(FsDir.length()); |
575 |
dir += subdir; |
dir += subdir; |
578 |
|
|
579 |
InstrumentsDb* db = InstrumentsDb::GetInstrumentsDb(); |
InstrumentsDb* db = InstrumentsDb::GetInstrumentsDb(); |
580 |
|
|
581 |
if (HasInstrumentFiles(String(fpath))) { |
if (HasInstrumentFiles(Path)) { |
582 |
if (!db->DirectoryExist(dir)) db->AddDirectory(dir); |
if (!db->DirectoryExist(dir)) db->AddDirectory(dir); |
583 |
db->AddInstrumentsNonrecursive(dir, String(fpath), pProgress); |
db->AddInstrumentsNonrecursive(dir, Path, pProgress); |
584 |
} |
} |
|
|
|
|
return 0; |
|
585 |
}; |
}; |
586 |
|
|
587 |
bool DirectoryScanner::HasInstrumentFiles(String Dir) { |
bool DirectoryScanner::HasInstrumentFiles(String Dir) { |
588 |
return InstrumentFileCounter::Count(Dir) > 0; |
InstrumentFileCounter c; |
589 |
|
return c.Count(Dir) > 0; |
590 |
} |
} |
591 |
|
|
|
int InstrumentFileCounter::FileCount; |
|
|
|
|
592 |
int InstrumentFileCounter::Count(String FsDir) { |
int InstrumentFileCounter::Count(String FsDir) { |
593 |
dmsg(2,("InstrumentFileCounter: Count(FsDir=%s)\n", FsDir.c_str())); |
dmsg(2,("InstrumentFileCounter: Count(FsDir=%s)\n", FsDir.c_str())); |
594 |
if (FsDir.empty()) throw Exception("Directory expected"); |
if (FsDir.empty()) throw Exception("Directory expected"); |
595 |
FileCount = 0; |
FileCount = 0; |
596 |
|
|
597 |
struct stat statBuf; |
File::WalkDirectoryTree(FsDir, this); |
|
int res = stat(FsDir.c_str(), &statBuf); |
|
|
if (res) { |
|
|
std::stringstream ss; |
|
|
ss << "Fail to stat `" << FsDir << "`: " << strerror(errno); |
|
|
throw Exception(ss.str()); |
|
|
} |
|
|
|
|
|
if (!S_ISDIR(statBuf.st_mode)) { |
|
|
throw Exception("Directory expected"); |
|
|
} |
|
|
|
|
|
ftw(FsDir.c_str(), FtwCallback, 10); |
|
598 |
return FileCount; |
return FileCount; |
599 |
} |
} |
600 |
|
|
601 |
int InstrumentFileCounter::FtwCallback(const char* fpath, const struct stat* sb, int typeflag) { |
void InstrumentFileCounter::FileEntry(std::string Path) { |
602 |
if (typeflag != FTW_F) return 0; |
if(Path.length() < 4) return; |
603 |
String s = fpath; |
if(!strcasecmp(".gig", Path.substr(Path.length() - 4).c_str())) FileCount++; |
|
if(s.length() < 4) return 0; |
|
|
if(!strcasecmp(".gig", s.substr(s.length() - 4).c_str())) FileCount++; |
|
|
|
|
|
return 0; |
|
604 |
}; |
}; |
605 |
|
|
606 |
} // namespace LinuxSampler |
} // namespace LinuxSampler |