diff options
Diffstat (limited to 'LogThread.cpp')
-rw-r--r-- | LogThread.cpp | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/LogThread.cpp b/LogThread.cpp new file mode 100644 index 0000000..234ccbf --- /dev/null +++ b/LogThread.cpp @@ -0,0 +1,296 @@ +/** \file LogThread.cpp +\brief The thread to do the log but not block the main thread +\author alpha_one_x86 +\licence GPL3, see the file COPYING */ + +#include "LogThread.h" +#include "ResourcesManager.h" +#include "OptionEngine.h" +#include "cpp11addition.h" + +#ifdef Q_OS_WIN32 + #ifndef NOMINMAX + #define NOMINMAX + #endif + #include <windows.h> +#endif +#include <QMessageBox> + +std::string LogThread::text_header_copy="[Copy] "; +std::string LogThread::text_header_move="[Move] "; +std::string LogThread::text_header_skip="[Skip] "; +std::string LogThread::text_header_stop="[Stop] "; +std::string LogThread::text_header_error="[Error] "; +std::string LogThread::text_header_MkPath="[MkPath] "; +std::string LogThread::text_header_RmPath="[RmPath] "; + +std::string LogThread::text_var_source="%source%"; +std::string LogThread::text_var_size="%size%"; +std::string LogThread::text_var_destination="%destination%"; +std::string LogThread::text_var_path="%path%"; +std::string LogThread::text_var_error="%error%"; +std::string LogThread::text_var_mtime="%mtime%"; +std::string LogThread::text_var_time="%time%"; +std::string LogThread::text_var_timestring="%dd.MM.yyyy h:m:s%"; +#ifdef Q_OS_WIN32 +std::string LogThread::text_var_computer="%computer%"; +std::string LogThread::text_var_user="%user%"; +#endif +std::string LogThread::text_var_operation="%operation%"; +std::string LogThread::text_var_rmPath="%rmPath%"; +std::string LogThread::text_var_mkPath="%mkPath%"; + +LogThread::LogThread() +{ + sync=false; + + connect(OptionEngine::optionEngine,&OptionEngine::newOptionValue, this, &LogThread::newOptionValue); + + enabled=false; + + moveToThread(this); + start(QThread::IdlePriority); + + connect(this, &LogThread::newData, this,&LogThread::realDataWrite,Qt::QueuedConnection); + + newOptionValue("Write_log", "transfer", OptionEngine::optionEngine->getOptionValue("Write_log","transfer")); + newOptionValue("Write_log", "error", OptionEngine::optionEngine->getOptionValue("Write_log","error")); + newOptionValue("Write_log", "folder", OptionEngine::optionEngine->getOptionValue("Write_log","folder")); + newOptionValue("Write_log", "sync", OptionEngine::optionEngine->getOptionValue("Write_log","sync")); + newOptionValue("Write_log", "transfer_format", OptionEngine::optionEngine->getOptionValue("Write_log","transfer_format")); + newOptionValue("Write_log", "error_format", OptionEngine::optionEngine->getOptionValue("Write_log","error_format")); + newOptionValue("Write_log", "folder_format", OptionEngine::optionEngine->getOptionValue("Write_log","folder_format")); + newOptionValue("Write_log", "sync", OptionEngine::optionEngine->getOptionValue("Write_log","sync")); + newOptionValue("Write_log", "enabled", OptionEngine::optionEngine->getOptionValue("Write_log","enabled")); + #ifdef Q_OS_WIN32 + DWORD size=0; + WCHAR * computerNameW=new WCHAR[size]; + if(GetComputerNameW(computerNameW,&size)) + computer=QString::fromWCharArray(computerNameW,size-1).toStdString(); + else + computer="Unknown computer"; + delete computerNameW; + + WCHAR * userNameW=new WCHAR[size]; + if(GetUserNameW(userNameW,&size)) + user=QString::fromWCharArray(userNameW,size-1).toStdString(); + else + user="Unknown user"; + delete userNameW; + #endif + + #ifdef Q_OS_WIN32 + lineReturn="\r\n"; + #else + lineReturn="\n"; + #endif +} + +LogThread::~LogThread() +{ + closeLogs(); + quit(); + wait(); +} + +bool LogThread::logTransfer() const +{ + return enabled && log_enable_transfer; +} + +void LogThread::openLogs() +{ + if(stringtobool(OptionEngine::optionEngine->getOptionValue("Write_log","enabled"))==false) + return; + if(log.isOpen()) + { + QMessageBox::critical(NULL,tr("Error"),tr("Log file already open, error: %1").arg(log.errorString())); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"log file already open, error: "+log.errorString().toStdString()); + return; + } + log.setFileName(QString::fromStdString(OptionEngine::optionEngine->getOptionValue("Write_log","file"))); + if(sync) + { + if(!log.open(QIODevice::WriteOnly|QIODevice::Unbuffered)) + { + QMessageBox::critical(NULL,tr("Error"),tr("Unable to open the log file, error: %1").arg(log.errorString())); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to open the log file, error: "+log.errorString().toStdString()); + } + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"opened log: "+OptionEngine::optionEngine->getOptionValue("Write_log","file")); + } + else + { + if(!log.open(QIODevice::WriteOnly)) + { + QMessageBox::critical(NULL,tr("Error"),tr("Unable to open the log file, error: %1").arg(log.errorString())); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to open the log file, error: "+log.errorString().toStdString()); + } + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"opened log: "+OptionEngine::optionEngine->getOptionValue("Write_log","file")); + } +} + +void LogThread::closeLogs() +{ + if(log.isOpen() && data.size()>0) + log.write(data.data(),data.size()); + log.close(); +} + +void LogThread::newTransferStart(const Ultracopier::ItemOfCopyList &item) +{ + if(!logTransfer()) + return; + std::string text; + if(item.mode==Ultracopier::Copy) + text=LogThread::text_header_copy+transfer_format+lineReturn; + else + text=LogThread::text_header_move+transfer_format+lineReturn; + text=replaceBaseVar(text); + //Variable is %source%, %size%, %destination% + stringreplaceAll(text,LogThread::text_var_source,item.sourceFullPath); + stringreplaceAll(text,LogThread::text_var_size,std::to_string(item.size)); + stringreplaceAll(text,LogThread::text_var_destination,item.destinationFullPath); + stringreplaceAll(text,LogThread::text_var_time,QDateTime::currentDateTime().toString(QString::fromStdString(LogThread::text_var_timestring)).toStdString()); + emit newData(text); +} + +/** method called when new transfer is started */ +void LogThread::transferSkip(const Ultracopier::ItemOfCopyList &item) +{ + if(!logTransfer()) + return; + std::string text=LogThread::text_header_skip+transfer_format+lineReturn; + text=replaceBaseVar(text); + //Variable is %source%, %size%, %destination% + stringreplaceAll(text,LogThread::text_var_source,item.sourceFullPath); + stringreplaceAll(text,LogThread::text_var_size,std::to_string(item.size)); + stringreplaceAll(text,LogThread::text_var_destination,item.destinationFullPath); + stringreplaceAll(text,LogThread::text_var_time,QDateTime::currentDateTime().toString(QString::fromStdString(LogThread::text_var_timestring)).toStdString()); + emit newData(text); +} + +void LogThread::newTransferStop(const Ultracopier::ItemOfCopyList &item) +{ + if(!logTransfer()) + return; + std::string text=LogThread::text_header_stop+transfer_format+lineReturn; + text=replaceBaseVar(text); + //Variable is %source%, %size%, %destination% + stringreplaceAll(text,LogThread::text_var_source,item.sourceFullPath); + stringreplaceAll(text,LogThread::text_var_size,std::to_string(item.size)); + stringreplaceAll(text,LogThread::text_var_destination,item.destinationFullPath); + stringreplaceAll(text,LogThread::text_var_time,QDateTime::currentDateTime().toString(QString::fromStdString(LogThread::text_var_timestring)).toStdString()); + emit newData(text); +} + +void LogThread::error(const std::string &path,const uint64_t &size,const uint64_t &mtime,const std::string &error) +{ + if(!log_enable_error) + return; + std::string text=LogThread::text_header_error+error_format+lineReturn; + text=replaceBaseVar(text); + //Variable is %path%, %size%, %mtime%, %error% + stringreplaceAll(text,LogThread::text_var_path,path); + stringreplaceAll(text,LogThread::text_var_size,std::to_string(size)); + stringreplaceAll(text,LogThread::text_var_mtime,QDateTime::fromTime_t(static_cast<unsigned int>(mtime)).toString(Qt::ISODate).toStdString()); + stringreplaceAll(text,LogThread::text_var_error,error); + stringreplaceAll(text,LogThread::text_var_time,QDateTime::fromTime_t(static_cast<unsigned int>(mtime)).toString(QString::fromStdString(LogThread::text_var_timestring)).toStdString()); + emit newData(text); +} + +void LogThread::run() +{ + exec(); +} + +void LogThread::realDataWrite(const std::string &text) +{ + #ifdef ULTRACOPIER_DEBUG + if(!log.isOpen()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"transfer log not open"); + return; + } + #endif // ULTRACOPIER_DEBUG + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start"); + if(log.write(text.data(),text.size())==-1) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to write into transfer log: "+log.errorString().toStdString()); + return; + } + if(sync) + log.flush(); +} + +void LogThread::newOptionValue(const std::string &group,const std::string &name,const std::string &value) +{ + if(group!="Write_log") + return; + + if(name=="transfer_format") + transfer_format=value; + else if(name=="error_format") + error_format=value; + else if(name=="folder_format") + folder_format=value; + else if(name=="sync") + { + sync=stringtobool(value); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"sync flag is set on: "+value); + if(sync) + { + if(log.isOpen()) + log.flush(); + } + } + else if(name=="transfer") + log_enable_transfer=stringtobool(OptionEngine::optionEngine->getOptionValue("Write_log","enabled")) && stringtobool(value); + else if(name=="error") + log_enable_error=stringtobool(OptionEngine::optionEngine->getOptionValue("Write_log","enabled")) && stringtobool(value); + else if(name=="folder") + log_enable_folder=stringtobool(OptionEngine::optionEngine->getOptionValue("Write_log","enabled")) && stringtobool(value); + if(name=="enabled") + { + enabled=stringtobool(value); + if(enabled) + openLogs(); + else + closeLogs(); + } +} + +std::string LogThread::replaceBaseVar(std::string text) +{ + stringreplaceAll(text,LogThread::text_var_time,QDateTime::currentDateTime().toString(QString::fromStdString(LogThread::text_var_timestring)).toStdString()); + #ifdef Q_OS_WIN32 + stringreplaceAll(text,LogThread::text_var_computer,computer); + stringreplaceAll(text,LogThread::text_var_user,user); + #endif + return text; +} + +void LogThread::rmPath(const std::string &path) +{ + if(!logTransfer()) + return; + std::string text=LogThread::text_header_RmPath+folder_format+lineReturn; + text=replaceBaseVar(text); + //Variable is %operation% %path% + stringreplaceAll(text,LogThread::text_var_path,path); + stringreplaceAll(text,LogThread::text_var_operation,LogThread::text_var_rmPath); + emit newData(text); +} + +void LogThread::mkPath(const std::string &path) +{ + if(!logTransfer()) + return; + std::string text=LogThread::text_header_MkPath+folder_format+lineReturn; + text=replaceBaseVar(text); + //Variable is %operation% %path% + stringreplaceAll(text,LogThread::text_var_path,path); + stringreplaceAll(text,LogThread::text_var_operation,LogThread::text_var_mkPath); + emit newData(text); +} |