Files
frelay/Util/Util.cpp

384 lines
9.4 KiB
C++
Raw Permalink Normal View History

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>
2026-03-24 22:25:00 +08:00
#include <QDirIterator>
2025-11-16 19:23:59 +08:00
#include <QFileDevice>
#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);
}
2026-03-25 14:53:24 +08:00
QString Util::Join(const QString& path, const QString& mid, const QString& name)
{
return QDir::cleanPath(path + QDir::separator() + mid + 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);
}
2026-03-25 14:53:24 +08:00
QString Util::GetFileDir(const QString& path)
{
QFileInfo fileInfo(path);
return fileInfo.absolutePath();
}
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;
}
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-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();
}
2025-11-16 19:23:59 +08:00
QString Util::Rename(const QString& from, const QString& to, bool isDir)
{
if (isDir) {
QDir dir;
if (dir.rename(from, to)) {
return "";
}
2025-11-16 20:26:08 +08:00
return tr("请确认是否无权限操作或者被占用。");
2025-11-16 19:23:59 +08:00
} else {
QFile f(from);
if (f.rename(to)) {
return "";
}
return f.errorString();
}
}
2025-11-06 23:12:13 +08:00
QString Util::UUID()
{
return QUuid::createUuid().toString().remove("{").remove("}");
}
2025-11-09 18:10:54 +08:00
QVector<QString> Util::GetLocalDrivers()
{
QVector<QString> result;
auto drivers = QStorageInfo::mountedVolumes();
2026-03-25 14:53:24 +08:00
for (const auto& driver : std::as_const(drivers)) {
2025-11-09 18:10:54 +08:00
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();
}
2026-03-24 22:25:00 +08:00
bool DirFileHelper::GetAllFiles(const QString& rootPath, QVector<QString>& files)
{
QDir rootDir(rootPath);
if (!rootDir.exists()) {
qWarning() << "目录不存在:" << rootPath;
return false;
}
QString absoluteRootPath = rootDir.absolutePath();
QDirIterator it(absoluteRootPath, QDir::Files | QDir::NoSymLinks | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
while (it.hasNext()) {
it.next();
QFileInfo fileInfo = it.fileInfo();
if (fileInfo.isFile()) {
QString absoluteFilePath = fileInfo.absoluteFilePath();
QString relativePath = absoluteFilePath.mid(absoluteRootPath.length());
if (relativePath.startsWith('/') || relativePath.startsWith('\\')) {
relativePath = relativePath.mid(1);
}
files.append(relativePath);
}
}
return true;
}
2026-03-25 14:53:24 +08:00
bool DirFileHelper::GetAllFiles(const QString& rootPath, const QString& mid, QVector<FileStruct>& files)
{
auto fileRoot = Util::Join(rootPath, mid);
QDir rootDir(fileRoot);
if (!rootDir.exists()) {
qWarning() << "目录不存在:" << fileRoot;
return false;
}
QString absoluteRootPath = rootDir.absolutePath();
QDirIterator it(absoluteRootPath, QDir::Files | QDir::NoSymLinks | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
while (it.hasNext()) {
it.next();
QFileInfo fileInfo = it.fileInfo();
if (fileInfo.isFile()) {
QString absoluteFilePath = fileInfo.absoluteFilePath();
QString relativePath = absoluteFilePath.mid(absoluteRootPath.length());
if (relativePath.startsWith('/') || relativePath.startsWith('\\')) {
relativePath = relativePath.mid(1);
}
FileStruct fst;
fst.root = rootPath;
fst.mid = mid;
fst.relative = relativePath;
files.append(fst);
}
}
return true;
}
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_);
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_);
RemoteRoot_ = root;
2025-06-20 16:00:18 +08:00
}
QString GlobalData::GetLocalRoot() const
{
return LocalRoot_;
}
QString GlobalData::GetLocalID() const
{
return LocalID_;
}
2025-06-20 16:00:18 +08:00
QString GlobalData::GetRemoteRoot() const
{
return RemoteRoot_;
}
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;
}
2025-11-16 20:26:08 +08:00
QString Util::Delete(const QString& path)
{
QFileInfo fileInfo(path);
if (!fileInfo.exists()) {
return tr("文件或目录不存在: %1").arg(path);
}
if (fileInfo.isFile()) {
QFile file(path);
if (file.remove()) {
return "";
} else {
return tr("删除文件失败: %1").arg(file.errorString());
}
} else if (fileInfo.isDir()) {
QDir dir(path);
if (dir.removeRecursively()) {
return "";
} else {
return tr("删除目录失败,确认是否占用或者无权限操作。");
}
} else {
return tr("不支持的文件类型: %1").arg(path);
}
2025-11-16 20:51:56 +08:00
}
QString Util::NewDir(const QString& path)
{
if (path.isEmpty()) {
return tr("路径不能为空");
}
if (QDir(path).exists()) {
return tr("目录已存在: %1").arg(path);
}
QFileInfo pathInfo(path);
QDir parentDir = pathInfo.absoluteDir();
if (!parentDir.exists()) {
return tr("父目录不存在: %1").arg(parentDir.absolutePath());
}
QFileInfo parentInfo(parentDir.absolutePath());
if (!parentInfo.isWritable()) {
return tr("父目录无写入权限: %1").arg(parentDir.absolutePath());
}
QDir dir;
if (dir.mkpath(path)) {
return "";
} else {
return tr("创建目录失败: %1").arg(path);
}
2026-03-25 14:53:24 +08:00
}