#include #include #include #include #ifndef PATH_MAX // If not defined yet : do it # define PATH_MAX 2048 #endif namespace creaImageIO { //============================================================== Gimmick::Gimmick() : mImageAdder(0) { RegisterGimmickMessageTypes(); mSettings=0; mSynchronizer=0; } //============================================================== //============================================================== Gimmick::~Gimmick() { if(mSettings!=0) { mSettings->writeSettingsFile(); delete mSettings; } if(mSynchronizer!=0) { delete mSynchronizer; } } //============================================================== //============================================================== void Gimmick::Initialize() { std::string i_nameDB = "Local database"; // Create the UserSettings dir if does not exist CreateUserSettingsDirectory(); // Sets the current directory to the home dir mCurrentDirectory = GetHomeDirectory(); mSynchronizer= new Synchronizer(GetUserSettingsDirectory()); mSettings = new Settings(mCurrentDirectory); std::string dbpath = GetLocalDatabasePath(); // Create or open local database mLocalDatabase = createDB(i_nameDB, mCurrentDirectory + "\\.gimmick\\localdatabase_Descriptor.txt", dbpath); // Add it to the TreeHandlerMap mTreeHandlerMap[i_nameDB] = mLocalDatabase; //Add additional DB from user Settings addDBSettings(); // Creates files and directories database mTimestampDatabase = new TimestampDatabaseHandler(GetTimestampDatabasePath()); // Create or open local database if (! boost::filesystem::exists( GetTimestampDatabasePath() ) ) { std::string mess = "Timestamp database '"; mess += GetTimestampDatabasePath(); mess += "' does not exist : creating it"; GimmickMessage(1,mess<Create() ) { GimmickError("ERROR CREATING '"<Open() ) { GimmickError("ERROR OPENING '"<Open(true); mSettings->addDB(i_location); } } /////////////////////////////////////////////////////////////////////////// // create a DB from a attributes descriptor file for medical images // // @param i_name : DB name // // @param i_locDesc : location of descriptor file // // @param i_locDB : location of DB // // return : the SQLiteTreeHandler object on DB // ///////////////////////////////////////////////////////////////////////// SQLiteTreeHandler *Gimmick::createDB(const std::string &i_name, const std::string &i_locDesc, const std::string &i_locDB) { SQLiteTreeHandler *sqlTreeH = new SQLiteTreeHandler(i_locDB); // Create or open local database if (! boost::filesystem::exists(i_locDB) ) { std::string mess = "Local database '"; mess += i_locDB; mess += "' does not exist : creating it"; GimmickMessage(1,mess<GetTree().GetDescriptor().createDescriptorfromFile(i_locDesc); if ( ! sqlTreeH->Create(true) ) { GimmickError("ERROR CREATING '"<SetAttribute(0,"Name",i_name); } else { /// Open and test it GimmickMessage(1,"Opening local database '" <Open(true) ) { GimmickError("ERROR OPENING '"<second; } delete mTimestampDatabase; } //============================================================== //================================================================ // file separator #if defined(_WIN32) #define VALID_FILE_SEPARATOR "\\" #define INVALID_FILE_SEPARATOR "/" #else #define INVALID_FILE_SEPARATOR "\\" #define VALID_FILE_SEPARATOR "/" #endif //================================================================ //================================================================ const std::string& Gimmick::GetHomeDirectory() { if (mHomeDirectory.size()==0) { #if defined(__GNUC__) mHomeDirectory = getenv("HOME"); #elif defined(_WIN32) mHomeDirectory = getenv("USERPROFILE"); #endif } return mHomeDirectory; } //================================================================ const std::string& Gimmick::GetUserSettingsDirectory() { if (mUserSettingsDirectory.size()==0) { mUserSettingsDirectory = GetHomeDirectory(); mUserSettingsDirectory += "/.gimmick/"; boost::algorithm::replace_all( mUserSettingsDirectory, INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR); } return mUserSettingsDirectory; } //================================================================ //================================================================ int Gimmick::GetBinaryDirectory(char *pname, size_t pathsize) { #ifdef LINUX /* Oddly, the readlink(2) man page says no NULL is appended. */ /* So you have to do it yourself, based on the return value: */ pathsize --; /* Preserve a space to add the trailing NULL */ long result = readlink("/proc/self/exe", pname, pathsize); if (result > 0) { pname[result] = 0; /* add the #@!%ing NULL */ if ((access(pname, 0) == 0)) return 0; /* file exists, return OK */ /*else name doesn't seem to exist, return FAIL (falls through) */ } #endif /* LINUX */ #ifdef WIN32 long result = GetModuleFileName(NULL, pname, pathsize); if (result > 0) { /* fix up the dir slashes... */ int len = strlen(pname); int idx; for (idx = 0; idx < len; idx++) { if (pname[idx] == '\\') pname[idx] = '/'; } for (idx = len-1; idx >=0 ; idx--) { if (pname[idx] == '/') { pname[idx+1] = '\0'; idx = -1; } } if ((access(pname, 0) == 0)) return 0; /* file exists, return OK */ /*else name doesn't seem to exist, return FAIL (falls through) */ } #endif /* WIN32 */ #ifdef SOLARIS char *p = getexecname(); if (p) { /* According to the Sun manpages, getexecname will "normally" return an */ /* absolute path - BUT might not... AND that IF it is not, pre-pending */ /* getcwd() will "usually" be the correct thing... Urgh! */ /* check pathname is absolute (begins with a / ???) */ if (p[0] == '/') /* assume this means we have an absolute path */ { strncpy(pname, p, pathsize); if ((access(pname, 0) == 0)) return 0; /* file exists, return OK */ } else /* if not, prepend getcwd() then check if file exists */ { getcwd(pname, pathsize); long result = strlen(pname); strncat(pname, "/", (pathsize - result)); result ++; strncat(pname, p, (pathsize - result)); if ((access(pname, 0) == 0)) return 0; /* file exists, return OK */ /*else name doesn't seem to exist, return FAIL (falls through) */ } } #endif /* SOLARIS */ #ifdef MACOSX /* assume this is OSX */ /* from http://www.hmug.org/man/3/NSModule.html extern int _NSGetExecutablePath(char *buf, unsigned long *bufsize); _NSGetExecutablePath copies the path of the executable into the buffer and returns 0 if the path was successfully copied in the provided buffer. If the buffer is not large enough, -1 is returned and the expected buffer size is copied in *bufsize. Note that _NSGetExecutablePath will return "a path" to the executable not a "real path" to the executable. That is the path may be a symbolic link and not the real file. And with deep directories the total bufsize needed could be more than MAXPATHLEN. */ int status = -1; char *given_path = (char*)malloc(MAXPATHLEN * 2); if (!given_path) return status; uint32_t npathsize = MAXPATHLEN * 2; long result = _NSGetExecutablePath(given_path, &npathsize); if (result == 0) { /* OK, we got something - now try and resolve the real path... */ if (realpath(given_path, pname) != NULL) { if ((access(pname, 0) == 0)) status = 0; /* file exists, return OK */ } } free (given_path); return status; #endif /* MACOSX */ return -1; /* Path Lookup Failed */ } //================================================================ const std::string& Gimmick::GetLocalDatabasePath() { if (mLocalDatabasePath.size()==0) { mLocalDatabasePath = GetUserSettingsDirectory(); mLocalDatabasePath += "local_database.sqlite3"; boost::algorithm::replace_all( mLocalDatabasePath, INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR); } return mLocalDatabasePath; } //================================================================ //================================================================ const std::string& Gimmick::GetTimestampDatabasePath() { if (mTimestampDatabasePath.size()==0) { mTimestampDatabasePath = GetUserSettingsDirectory(); mTimestampDatabasePath += "timestamp_database.sqlite3"; boost::algorithm::replace_all( mTimestampDatabasePath, INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR); } return mTimestampDatabasePath; } //======================================================================== //======================================================================== void Gimmick::CreateUserSettingsDirectory() { if (! boost::filesystem::is_directory( GetUserSettingsDirectory() ) ) { GimmickMessage(1,"Directory '"<second; } //======================================================================== ///Returns the timestamp database handler TimestampDatabaseHandler* Gimmick::GetTimestampDatabase() const { return mTimestampDatabase; } //======================================================================== /// Add the files to the tree handler void Gimmick::AddFiles(const std::string& d, const std::vector& filenames) { GimmickMessage(2,"Adding files to '"<RemoveNode("PATH",node,d); mImageAdder.RemoveFile(node); } //======================================================================== //======================================================================== void Gimmick::CopyFiles(const std::vector& filenames, const std::string& d ) { TreeHandler * handler=GetTreeHandler(d); mImageAdder.SetCurrentDatabase(d); mImageAdder.SetTreeHandler(handler); mImageAdder.SetTimestampHandler(mTimestampDatabase); mImageAdder.SetSynchronizer(mSynchronizer); mImageAdder.CopyFiles(filenames, mSettings->getValue(SETTINGS_COPY_PATH)); } //======================================================================== std::string Gimmick::Synchronize(const std::string& d, bool repair, bool checkAttributes) { TreeHandler * handler=GetTreeHandler(d); mImageAdder.SetCurrentDatabase(d); mImageAdder.SetTreeHandler(handler); mImageAdder.SetTimestampHandler(mTimestampDatabase); mImageAdder.SetSynchronizer(mSynchronizer); return mImageAdder.Synchronize(repair, checkAttributes); } //======================================================================== /// void Gimmick::Print(const std::string& d) { GetTreeHandler(d)->GetTree().Print(); } //======================================================================== void Gimmick::GetSetting(const std::string& name, std::string& value) { value = mSettings->getValue(name); } //======================================================================== //======================================================================== void Gimmick::UpdateSetting(const std::string& name, const std::string& value) { mSettings->updateSetting(name,value); mSettings->writeSettingsFile(); } //======================================================================== void Gimmick::DeleteDrive(const std::string& drive) { for( TreeHandlerMapType::const_iterator it = mTreeHandlerMap.begin(); it!= mTreeHandlerMap.end(); ++it) { mImageAdder.SetTreeHandler(it->second); mImageAdder.DeleteDriveFromMainDB(drive); } mImageAdder.SetTimestampHandler(mTimestampDatabase); mImageAdder.SetSynchronizer(mSynchronizer); mImageAdder.DeleteDriveFromOtherDB(drive); } //======================================================================== void Gimmick::EditField(tree::Node* node, const std::string& d, const std::string& name, const std::string& key, const std::string& val) { TreeHandler * handler=GetTreeHandler(d); mImageAdder.SetCurrentDatabase(d); mImageAdder.SetTreeHandler(handler); mImageAdder.EditField(node,name,key,val); } //======================================================================== ///////////////////////////////////////////////////////////////////////// // add DB from Settings file // // @param : - // // return : - // ///////////////////////////////////////////////////////////////////////// void Gimmick::addDBSettings() { std::string pathSettings = mSettings->getValue(SETTINGS_DBPATH); // split to find all paths std::vector paths; std::string separator = ";"; std::string::size_type last_pos = pathSettings.find_first_not_of(separator); //find first separator std::string::size_type pos = pathSettings.find_first_of(separator, last_pos); while(std::string::npos != pos || std::string::npos != last_pos) { paths.push_back(pathSettings.substr(last_pos, pos - last_pos)); last_pos = pathSettings.find_first_not_of(separator, pos); pos = pathSettings.find_first_of(separator, last_pos); } std::vector::iterator it_path = paths.begin(); for(; it_path != paths.end(); ++it_path) { pos = it_path->find_last_of("\\"); last_pos = it_path->find_last_of("."); std::string name = it_path->substr(pos +1, last_pos -pos-1 ); addDB(name, it_path->c_str()); } } }