summaryrefslogtreecommitdiff
path: root/LogThread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'LogThread.cpp')
-rw-r--r--LogThread.cpp296
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);
+}