/** \file ResourcesManager.cpp
\brief Define the class to manage and load the resources linked with the themes
\author alpha_one_x86
\licence GPL3, see the file COPYING */
#include <QDir>
#include <QFile>
#include <QApplication>
#include <QFileInfo>
#include "cpp11addition.h"
#include "ResourcesManager.h"
#include "FacilityEngine.h"
std::regex ResourcesManager::slashEnd;
/// \brief Create the manager and load the defaults variables
ResourcesManager::ResourcesManager()
{
slashEnd=std::regex("[/\\\\]$");
//load the internal path
searchPath.push_back(":/");
#ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE
//load the user path but only if exists and writable
//load the ultracopier path
#ifdef ULTRACOPIER_VERSION_PORTABLE
#ifdef ULTRACOPIER_VERSION_PORTABLEAPPS
ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"Ultracopier is compiled with the flag: ULTRACOPIER_VERSION_PORTABLEAPPS");
//load the data folder path
QDir dir(QApplication::applicationDirPath());
dir.cdUp();
dir.cdUp();
dir.cd(QStringLiteral("Data");
searchPath.push_back(ResourcesManager::AddSlashIfNeeded(dir.absolutePath().toStdString()));
writablePath=ResourcesManager::AddSlashIfNeeded(dir.absolutePath().toStdString());
#else
ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"Ultracopier is compiled with the flag: ULTRACOPIER_VERSION_PORTABLE");
//load the ultracopier path
QDir dir(QApplication::applicationDirPath());
dir.cd(QStringLiteral("Data"));
searchPath.push_back(ResourcesManager::AddSlashIfNeeded(dir.absolutePath().toStdString()));
writablePath=ResourcesManager::AddSlashIfNeeded(dir.absolutePath().toStdString());
#endif
#else
ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"Ultracopier is compiled as user privacy mode");
#ifdef Q_OS_WIN32
#define EXTRA_HOME_PATH QStringLiteral("\\ultracopier\\")
#else
#define EXTRA_HOME_PATH QStringLiteral("/.config/Ultracopier/")
#endif
#ifdef Q_OS_LINUX
QDir linuxArchIndepDir(QStringLiteral("/usr/share/ultracopier/"));
if(linuxArchIndepDir.exists())
searchPath.push_back(ResourcesManager::AddSlashIfNeeded(linuxArchIndepDir.absolutePath().toStdString()));
QDir linuxPluginsDir(QStringLiteral("/usr/lib/ultracopier/"));
if(linuxPluginsDir.exists())
searchPath.push_back(ResourcesManager::AddSlashIfNeeded(linuxPluginsDir.absolutePath().toStdString()));
#endif
//load the user path but only if exists and writable
QDir dir(QDir::homePath()+EXTRA_HOME_PATH);
if(dir.exists())
{
writablePath=ResourcesManager::AddSlashIfNeeded(dir.absolutePath().toStdString());
searchPath.push_back(ResourcesManager::AddSlashIfNeeded(dir.absolutePath().toStdString()));
} //if not exists try to create it
else if(dir.mkpath(dir.absolutePath()))
{
//if created, then have write permissions
writablePath=ResourcesManager::AddSlashIfNeeded(dir.absolutePath().toStdString());
searchPath.push_back(ResourcesManager::AddSlashIfNeeded(dir.absolutePath().toStdString()));
}
//load the ultracopier path
searchPath.push_back(ResourcesManager::AddSlashIfNeeded(QApplication::applicationDirPath().toStdString()));
#endif
#else
QDir dir(QApplication::applicationDirPath());
writablePath=ResourcesManager::AddSlashIfNeeded(dir.absolutePath().toStdString());
#endif
vectorRemoveDuplicatesForSmallList(searchPath);
#ifdef ULTRACOPIER_DEBUG
unsigned int index=0;
while(index<searchPath.size()) //look at each val
{
ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"searchPath.at("+std::to_string(index)+"): "+searchPath.at(index));
index++;
}
ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"writablePath: "+writablePath);
#endif // ULTRACOPIER_DEBUG
}
/// \brief Destroy the resource manager
ResourcesManager::~ResourcesManager()
{
}
/// \brief Get folder presence and the path
std::string ResourcesManager::getFolderReadPath(const std::string &path) const
{
unsigned int index=0;
while(index<searchPath.size()) //look at each val
{
QDir dir(QString::fromStdString(searchPath.at(index)+path));
if(dir.exists()) // if the path have been found, then return the full path
return ResourcesManager::AddSlashIfNeeded(dir.absolutePath().toStdString());
index++;
}
return std::string();
}
/// \brief Get folder presence, the path and check in the folder and sub-folder the file presence
std::string ResourcesManager::getFolderReadPathMultiple(const std::string &path,const std::vector<std::string> &fileToCheck) const
{
unsigned int index=0;
while(index<searchPath.size()) //look at each val
{
QDir dir(QString::fromStdString(searchPath.at(index)+path));
if(checkFolderContent(dir.absolutePath().toStdString(),fileToCheck))
return dir.absolutePath().toStdString()+FacilityEngine::separator();
index++;
}
return std::string();
}
bool ResourcesManager::checkFolderContent(const std::string &path,const std::vector<std::string> &fileToCheck) const
{
QDir dir(QString::fromStdString(path));
if(dir.exists()) // if the path have been found, then return the full path
{
bool allFileToCheckIsFound=true;
unsigned int index=0;
std::string partialPath=ResourcesManager::AddSlashIfNeeded(dir.absolutePath().toStdString());
while(index<fileToCheck.size()) //look at each val
{
if(!QFile::exists(QString::fromStdString(partialPath+fileToCheck.at(index)))) //if a file have been not found, consider the folder as not suitable
{
allFileToCheckIsFound=false;
break;
}
index++;
}
if(allFileToCheckIsFound==true) // if all file into have been found then return this path
return true;
}
return false;
}
/// \brief add / or \ in function of the platform at the end of path if both / and \ are not found
std::string ResourcesManager::AddSlashIfNeeded(const std::string &path)
{
if(path.empty())
return "/";
if(path.at(path.size()-1)=='/')
return path;
else
return path+FacilityEngine::separator();
}
/// \brief get the writable path
const std::string &ResourcesManager::getWritablePath() const
{
return writablePath;
}
/// \brief disable the writable path, if ultracopier is unable to write into
bool ResourcesManager::disableWritablePath()
{
bool returnVal=true;
if(writablePath.empty())
returnVal=false;
else
writablePath.clear();
return returnVal;
}
/// \brief get the read path
const std::vector<std::string> &ResourcesManager::getReadPath() const
{
return searchPath;
}
/// \brief remove folder
bool ResourcesManager::removeFolder(const std::string &dir)
{
ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"folder to remove: "+dir);
bool errorFound=false;
QDir currentDir(QString::fromStdString(dir));
QFileInfoList files = currentDir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot);
int index=0;
const int &loop_size=files.size();
while(index<loop_size)
{
if(files.at(index).isFile())
{
QFile file(files.at(index).absoluteFilePath());
if(!file.remove())
{
errorFound=true;
ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"remove file failed: "+file.errorString().toStdString());
}
else
ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"file removed: "+file.fileName().toStdString());
}
else if(files.at(index).isDir())
removeFolder(files.at(index).absoluteFilePath().toStdString());
else
ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unknow file type for: "+files.at(index).absoluteFilePath().toStdString());
index++;
}
if(!currentDir.rmpath(QString::fromStdString(dir)))
{
ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"remove path failed, check right and if is empty: "+dir);
errorFound=true;
}
return !errorFound;
}