2025-06-17 16:42:39 +08:00
|
|
|
#include "Util.h"
|
2025-06-14 23:25:16 +08:00
|
|
|
|
|
|
|
|
#include <QDateTime>
|
|
|
|
|
#include <QDebug>
|
2025-06-15 23:13:30 +08:00
|
|
|
#include <QDir>
|
2025-06-25 10:54:04 +08:00
|
|
|
#include <QFileInfo>
|
2025-06-14 23:25:16 +08:00
|
|
|
#include <QMutex>
|
2025-06-15 23:13:30 +08:00
|
|
|
#include <QStandardPaths>
|
2025-11-09 18:10:54 +08:00
|
|
|
#include <QStorageInfo>
|
2025-11-06 23:12:13 +08:00
|
|
|
#include <QUuid>
|
2025-10-23 09:46:54 +08:00
|
|
|
#include <fversion.h>
|
2025-06-14 23:25:16 +08:00
|
|
|
#include <iostream>
|
|
|
|
|
#include <spdlog/fmt/bundled/color.h>
|
|
|
|
|
#include <spdlog/fmt/fmt.h>
|
|
|
|
|
#include <spdlog/sinks/rotating_file_sink.h>
|
|
|
|
|
#include <spdlog/sinks/stdout_color_sinks.h>
|
|
|
|
|
#include <spdlog/spdlog.h>
|
|
|
|
|
|
|
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
|
#include <windows.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static QMutex msgMutex;
|
|
|
|
|
static std::shared_ptr<spdlog::logger> logger;
|
|
|
|
|
|
|
|
|
|
Util::Util()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-15 23:13:30 +08:00
|
|
|
QString Util::GetUserHome()
|
|
|
|
|
{
|
|
|
|
|
QString homePath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
|
|
|
|
|
if (homePath.isEmpty()) {
|
|
|
|
|
qWarning() << "Failed to get user home directory";
|
|
|
|
|
homePath = QDir::homePath();
|
|
|
|
|
}
|
|
|
|
|
return homePath;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-20 10:33:03 +08:00
|
|
|
QString Util::GetCurConfigPath(const QString& sub)
|
|
|
|
|
{
|
|
|
|
|
// Get user's home directory
|
|
|
|
|
QString homePath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
|
|
|
|
|
if (homePath.isEmpty()) {
|
|
|
|
|
qWarning() << "Failed to get user home directory";
|
|
|
|
|
return QString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto configPath = QDir(homePath).absoluteFilePath(".config");
|
|
|
|
|
// Append subdirectory if provided
|
|
|
|
|
if (!sub.isEmpty()) {
|
|
|
|
|
configPath = QDir(configPath).absoluteFilePath(sub);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create the directory if it doesn't exist
|
|
|
|
|
QDir dir(configPath);
|
|
|
|
|
if (!dir.exists()) {
|
|
|
|
|
if (!dir.mkpath(".")) {
|
|
|
|
|
qWarning() << "Failed to create config directory:" << configPath;
|
|
|
|
|
return QString();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return QDir::cleanPath(configPath);
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-18 14:53:56 +08:00
|
|
|
QString Util::Join(const QString& path, const QString& name)
|
|
|
|
|
{
|
|
|
|
|
return QDir::cleanPath(path + QDir::separator() + name);
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-14 23:25:16 +08:00
|
|
|
void Util::InitLogger(const QString& logPath, const QString& mark)
|
|
|
|
|
{
|
|
|
|
|
auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(logPath.toStdString(), 1024 * 1024 * 50, 3);
|
|
|
|
|
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
|
|
|
|
|
file_sink->set_pattern("[%Y-%m-%d %H:%M:%S.%e][%l]: %v");
|
|
|
|
|
console_sink->set_pattern("%^[%Y-%m-%d %H:%M:%S.%e][%l]: %v%$");
|
|
|
|
|
std::vector<spdlog::sink_ptr> sinks{file_sink, console_sink};
|
|
|
|
|
logger = std::make_shared<spdlog::logger>(mark.toStdString(), sinks.begin(), sinks.end());
|
|
|
|
|
logger->set_level(spdlog::level::debug);
|
|
|
|
|
spdlog::register_logger(logger);
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-20 13:03:27 +08:00
|
|
|
// do not check exit
|
2025-06-17 16:42:39 +08:00
|
|
|
QString Util::Get2FilePath(const QString& file, const QString& directory)
|
|
|
|
|
{
|
|
|
|
|
if (file.isEmpty() || directory.isEmpty()) {
|
|
|
|
|
return QString();
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-20 13:03:27 +08:00
|
|
|
QString fileName = QFileInfo(file).fileName();
|
|
|
|
|
QString cleanDir = QDir::cleanPath(directory);
|
|
|
|
|
QString fullPath = QDir(cleanDir).filePath(fileName);
|
2025-06-17 16:42:39 +08:00
|
|
|
|
2025-06-20 13:03:27 +08:00
|
|
|
return QDir::cleanPath(fullPath);
|
2025-06-17 16:42:39 +08:00
|
|
|
}
|
|
|
|
|
|
2025-06-14 23:25:16 +08:00
|
|
|
void Util::ConsoleMsgHander(QtMsgType type, const QMessageLogContext& context, const QString& msg)
|
|
|
|
|
{
|
|
|
|
|
Q_UNUSED(context);
|
|
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
case QtDebugMsg:
|
|
|
|
|
logger->debug(msg.toStdString());
|
|
|
|
|
break;
|
|
|
|
|
case QtInfoMsg:
|
|
|
|
|
logger->info(msg.toStdString());
|
|
|
|
|
break;
|
|
|
|
|
case QtWarningMsg:
|
|
|
|
|
logger->warn(msg.toStdString());
|
|
|
|
|
break;
|
|
|
|
|
case QtCriticalMsg:
|
|
|
|
|
logger->error(msg.toStdString());
|
|
|
|
|
break;
|
|
|
|
|
case QtFatalMsg:
|
|
|
|
|
logger->critical(msg.toStdString());
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
logger->warn("Unknown QtMsgType type.");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-06-15 14:31:54 +08:00
|
|
|
|
2025-10-23 09:46:54 +08:00
|
|
|
QString Util::GetVersion()
|
|
|
|
|
{
|
2025-10-23 09:52:47 +08:00
|
|
|
auto ver = QString("frelay %1 %2 %3").arg(VERSION_NUM, VERSION_DEV, VERSION_GIT_COMMIT);
|
2025-10-23 09:46:54 +08:00
|
|
|
return ver;
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-05 13:09:12 +08:00
|
|
|
bool Util::FileExist(const QString& path)
|
|
|
|
|
{
|
|
|
|
|
return QFile::exists(path);
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-06 23:12:13 +08:00
|
|
|
bool Util::DirExist(const QString& path, bool isFilePath)
|
2025-11-05 13:09:12 +08:00
|
|
|
{
|
2025-11-06 23:12:13 +08:00
|
|
|
if (path.isEmpty()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString dirPath = path;
|
|
|
|
|
if (isFilePath) {
|
|
|
|
|
QFileInfo fileInfo(path);
|
|
|
|
|
dirPath = fileInfo.absolutePath();
|
|
|
|
|
} else {
|
|
|
|
|
QFileInfo dirInfo(path);
|
|
|
|
|
dirPath = dirInfo.absoluteFilePath();
|
|
|
|
|
}
|
|
|
|
|
QDir dir(dirPath);
|
|
|
|
|
return dir.exists();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString Util::UUID()
|
|
|
|
|
{
|
|
|
|
|
return QUuid::createUuid().toString().remove("{").remove("}");
|
2025-11-05 13:09:12 +08:00
|
|
|
}
|
|
|
|
|
|
2025-11-09 18:10:54 +08:00
|
|
|
QVector<QString> Util::GetLocalDrivers()
|
|
|
|
|
{
|
|
|
|
|
QVector<QString> result;
|
|
|
|
|
auto drivers = QStorageInfo::mountedVolumes();
|
|
|
|
|
for (const auto& driver : drivers) {
|
|
|
|
|
if (driver.isValid() && driver.isReady()) {
|
|
|
|
|
result.push_back(driver.rootPath());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-15 14:31:54 +08:00
|
|
|
QString DirFileHelper::GetErr() const
|
|
|
|
|
{
|
|
|
|
|
return QString();
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-19 15:37:39 +08:00
|
|
|
DirFileHelper::DirFileHelper(QObject* parent) : QObject(parent)
|
2025-06-15 14:31:54 +08:00
|
|
|
{
|
2025-06-20 16:00:18 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GlobalData* GlobalData::Ins()
|
|
|
|
|
{
|
|
|
|
|
static GlobalData instance;
|
|
|
|
|
return &instance;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GlobalData::SetLocalRoot(const QString& root)
|
|
|
|
|
{
|
|
|
|
|
QMutexLocker locker(&mutex_);
|
2025-06-22 01:17:44 +08:00
|
|
|
LocalRoot_ = root;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GlobalData::SetLocalID(const QString& id)
|
|
|
|
|
{
|
|
|
|
|
QMutexLocker locker(&mutex_);
|
|
|
|
|
LocalID_ = id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GlobalData::SetRemoteID(const QString& id)
|
|
|
|
|
{
|
|
|
|
|
QMutexLocker locker(&mutex_);
|
|
|
|
|
RemoteID_ = id;
|
2025-06-20 16:00:18 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GlobalData::SetRemoteRoot(const QString& root)
|
|
|
|
|
{
|
|
|
|
|
QMutexLocker locker(&mutex_);
|
2025-06-22 01:17:44 +08:00
|
|
|
RemoteRoot_ = root;
|
2025-06-20 16:00:18 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString GlobalData::GetLocalRoot() const
|
|
|
|
|
{
|
|
|
|
|
return LocalRoot_;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-22 01:17:44 +08:00
|
|
|
QString GlobalData::GetLocalID() const
|
|
|
|
|
{
|
|
|
|
|
return LocalID_;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-20 16:00:18 +08:00
|
|
|
QString GlobalData::GetRemoteRoot() const
|
|
|
|
|
{
|
|
|
|
|
return RemoteRoot_;
|
2025-06-22 01:17:44 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString GlobalData::GetRemoteID() const
|
|
|
|
|
{
|
|
|
|
|
return RemoteID_;
|
2025-06-27 22:13:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string GlobalData::GetConfigPath() const
|
|
|
|
|
{
|
|
|
|
|
return ConfigPath_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GlobalData::SetConfigPath(const std::string& path)
|
|
|
|
|
{
|
|
|
|
|
ConfigPath_ = path;
|
|
|
|
|
}
|