469 lines
17 KiB
C++
469 lines
17 KiB
C++
|
#include "FileHelper.h"
|
|||
|
|
|||
|
#include <QDir>
|
|||
|
#include <QApplication>
|
|||
|
#include <QDebug>
|
|||
|
#include <QJsonDocument>
|
|||
|
#include <QJsonObject>
|
|||
|
#include <QJsonArray>
|
|||
|
#include <QFile>
|
|||
|
#include <QFileInfo>
|
|||
|
|
|||
|
const QString kConfigName = "/ProjectDisplay/config.json";
|
|||
|
constexpr int16_t kDefualtPort = 9527;
|
|||
|
|
|||
|
template<typename T>
|
|||
|
T clamp(const T& value, const T& minValue, const T& maxValue)
|
|||
|
{
|
|||
|
return qMax(minValue, qMin(value, maxValue));
|
|||
|
}
|
|||
|
|
|||
|
bool FileHelper::GetItemFromJsonConfig(QString& addr, QMap<QString, QString>* items) {
|
|||
|
if (nullptr == items) {
|
|||
|
qDebug() << "items is nullptr";
|
|||
|
return false;
|
|||
|
}
|
|||
|
const QString configPath = QApplication::applicationDirPath() + kConfigName;
|
|||
|
QFile inputFile(configPath);
|
|||
|
if (!inputFile.open(QIODevice::ReadOnly))
|
|||
|
{
|
|||
|
qDebug() << "Failed to open file for reading. config=" << configPath;
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
// 读取文件内容并关闭文件
|
|||
|
QByteArray fileData = inputFile.readAll();
|
|||
|
inputFile.close();
|
|||
|
|
|||
|
// 解析 JSON 数据
|
|||
|
QJsonParseError jsonError;
|
|||
|
QJsonDocument jsonDocument = QJsonDocument::fromJson(fileData, &jsonError);
|
|||
|
if (jsonError.error != QJsonParseError::NoError)
|
|||
|
{
|
|||
|
qDebug() << "Failed to parse JSON data:" << jsonError.errorString() << " config=" << configPath;
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
// 将 JSON 数据转换为 JSON 对象
|
|||
|
QJsonObject jsonObject = jsonDocument.object();
|
|||
|
if (jsonObject.contains("server") && jsonObject["server"].isString()) {
|
|||
|
addr = jsonObject["server"].toString();
|
|||
|
}
|
|||
|
else {
|
|||
|
addr = "127.0.0.1:9527";
|
|||
|
}
|
|||
|
|
|||
|
if (!jsonObject.contains("data") || !jsonObject["data"].isArray()) {
|
|||
|
qDebug() << "Failed to parse JSON not find key of data, or data value is not array config=" << configPath;
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
QJsonArray jsonArray = jsonObject["data"].toArray();
|
|||
|
for (qint32 i = 0; i < jsonArray.size(); ++i) {
|
|||
|
if (!jsonArray.at(i).isObject()) {
|
|||
|
qDebug() << "jsonArray is not object config=" << configPath;
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
QJsonObject item = jsonArray.at(i).toObject();
|
|||
|
if (!item.contains("name") || !item["name"].isString() ||
|
|||
|
!item.contains("path") || !item["path"].isString()) {
|
|||
|
qDebug() << "not find index / path in item config config=" << configPath;
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
items->insert(item["name"].toString(), item["path"].toString());
|
|||
|
}
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
bool FileHelper::GetItemFromJsonConfig(Config* config) {
|
|||
|
if (nullptr == config) {
|
|||
|
qDebug() << "config is nullptr";
|
|||
|
return false;
|
|||
|
}
|
|||
|
const QString configPath = QApplication::applicationDirPath() + kConfigName;
|
|||
|
QFile inputFile(configPath);
|
|||
|
if (!inputFile.open(QIODevice::ReadOnly)) {
|
|||
|
qDebug() << "Failed to open file for reading. config=" << configPath;
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
// 读取文件内容并关闭文件
|
|||
|
QByteArray fileData = inputFile.readAll();
|
|||
|
inputFile.close();
|
|||
|
|
|||
|
// 解析 JSON 数据
|
|||
|
QJsonParseError jsonError;
|
|||
|
QJsonDocument jsonDocument = QJsonDocument::fromJson(fileData, &jsonError);
|
|||
|
if (jsonError.error != QJsonParseError::NoError) {
|
|||
|
qDebug() << "Failed to parse JSON data:" << jsonError.errorString() << " config=" << configPath;
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
// 将 JSON 数据转换为 JSON 对象
|
|||
|
QJsonObject jsonObject = jsonDocument.object();
|
|||
|
if (jsonObject.contains("port") && jsonObject["port"].isDouble()) {
|
|||
|
config->port = jsonObject["port"].toInt();
|
|||
|
} else {
|
|||
|
config->port = kDefualtPort;
|
|||
|
}
|
|||
|
|
|||
|
if (!jsonObject.contains("data") || !jsonObject["data"].isArray()) {
|
|||
|
qDebug() << "Failed to parse JSON not find key of data, or data value is not array config=" << configPath;
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
const QJsonArray datas = jsonObject["data"].toArray();
|
|||
|
for (int i = 0; i < datas.size(); ++i) {
|
|||
|
const QJsonObject data = datas.at(i).toObject();
|
|||
|
MedianItem mediaItem;
|
|||
|
if (!data.contains("name") || !data["name"].isString()) {
|
|||
|
qDebug() << "Failed to parse JSON not find key of name, or name value is not array config=" << configPath;
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
mediaItem.name = data["name"].toString();
|
|||
|
|
|||
|
if (!data.contains("index") || !data["index"].isDouble()) {
|
|||
|
qDebug() << "Failed to parse JSON not find key of index, or index value is not array config=" << configPath;
|
|||
|
return false;
|
|||
|
}
|
|||
|
mediaItem.index = data["index"].toInt();
|
|||
|
|
|||
|
if (!data.contains("type") || !data["type"].isDouble()) {
|
|||
|
qDebug() << "Failed to parse JSON not find key of type, or type value is not array config=" << configPath;
|
|||
|
return false;
|
|||
|
}
|
|||
|
mediaItem.type = data["type"].toInt();
|
|||
|
|
|||
|
if (!data.contains("data") || !data["data"].isArray()) {
|
|||
|
qDebug() << "Failed to parse JSON not find key of data, or data value is not array config=" << configPath;
|
|||
|
return false;
|
|||
|
}
|
|||
|
const QJsonArray itemDatas = data["data"].toArray();
|
|||
|
QSet<int32_t> test;
|
|||
|
for (int i = 0; i < itemDatas.size(); ++i) {
|
|||
|
const QJsonObject mediaInfoData = itemDatas.at(i).toObject();
|
|||
|
MediaInfo mediaInfo;
|
|||
|
if (!mediaInfoData.contains("id") || !mediaInfoData["id"].isDouble()) {
|
|||
|
qDebug() << "Failed to parse JSON not find key of id, or name id is not array config=" << configPath;
|
|||
|
return false;
|
|||
|
}
|
|||
|
mediaInfo.id = mediaInfoData["id"].toInt();
|
|||
|
|
|||
|
if (!mediaInfoData.contains("button") || !mediaInfoData["button"].isString()) {
|
|||
|
qDebug() << "Failed to parse JSON not find key of button, or button value is not array config=" << configPath;
|
|||
|
return false;
|
|||
|
}
|
|||
|
mediaInfo.button = mediaInfoData["button"].toString();
|
|||
|
|
|||
|
if (!mediaInfoData.contains("name") || !mediaInfoData["name"].isString()) {
|
|||
|
// qDebug() << "Failed to parse JSON not find key of name, or name value is not array config=" << configPath;
|
|||
|
mediaInfo.name = "";
|
|||
|
//return false;
|
|||
|
} else {
|
|||
|
mediaInfo.name = mediaInfoData["name"].toString();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
if (!mediaInfoData.contains("describe") || !mediaInfoData["describe"].isString()) {
|
|||
|
qDebug() << "Failed to parse JSON not find key of type, or type value is not array config=" << configPath;
|
|||
|
return false;
|
|||
|
}
|
|||
|
mediaInfo.describe = mediaInfoData["describe"].toString();
|
|||
|
|
|||
|
if (!mediaInfoData.contains("images") || !mediaInfoData["images"].isArray()) {
|
|||
|
qDebug() << "Failed to parse JSON not find key of images, or images value is not array config=" << configPath;
|
|||
|
return false;
|
|||
|
}
|
|||
|
const QJsonArray images = mediaInfoData["images"].toArray();
|
|||
|
for (int i = 0; i < images.size(); ++i) {
|
|||
|
mediaInfo.images.append(images[i].toString());
|
|||
|
}
|
|||
|
|
|||
|
if (!mediaInfoData.contains("start") || !mediaInfoData["start"].isDouble()) {
|
|||
|
mediaInfo.start = 0;
|
|||
|
} else {
|
|||
|
int start = mediaInfoData["start"].toInt();
|
|||
|
mediaInfo.start = clamp(start, 0, 2);
|
|||
|
}
|
|||
|
|
|||
|
if (!mediaInfoData.contains("end") || !mediaInfoData["end"].isString()) {
|
|||
|
mediaInfo.end = QPointF(0.0f, 0.0f);
|
|||
|
} else {
|
|||
|
QString end = mediaInfoData["end"].toString();
|
|||
|
QStringList pointCoordinates = end.split(",");
|
|||
|
|
|||
|
if (pointCoordinates.size() == 2) {
|
|||
|
bool xConversionOk, yConversionOk;
|
|||
|
qreal x = pointCoordinates[0].trimmed().toDouble(&xConversionOk);
|
|||
|
qreal y = pointCoordinates[1].trimmed().toDouble(&yConversionOk);
|
|||
|
|
|||
|
if (xConversionOk && yConversionOk) {
|
|||
|
mediaInfo.end = QPointF(x, y);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (!mediaInfoData.contains("scope") || !mediaInfoData["scope"].isArray()) {
|
|||
|
qDebug() << "Failed to parse JSON not find key of scope, or scope value is not array config=" << configPath;
|
|||
|
return false;
|
|||
|
} else {
|
|||
|
const QJsonArray scope = mediaInfoData["scope"].toArray();
|
|||
|
if (scope.size() == 5) {
|
|||
|
mediaInfo.scope.x = scope[0].toInt();
|
|||
|
mediaInfo.scope.y = scope[1].toDouble();
|
|||
|
mediaInfo.scope.width = scope[2].toInt();
|
|||
|
mediaInfo.scope.height = scope[3].toInt();
|
|||
|
mediaInfo.scope.shape = scope[4].toInt();
|
|||
|
}
|
|||
|
else if (scope.size() == 6) {
|
|||
|
mediaInfo.scope.x = scope[0].toInt();
|
|||
|
mediaInfo.scope.y = scope[1].toDouble();
|
|||
|
mediaInfo.scope.width = scope[2].toInt();
|
|||
|
mediaInfo.scope.height = scope[3].toInt();
|
|||
|
mediaInfo.scope.shape = scope[4].toInt();
|
|||
|
mediaInfo.scope.rotate = scope[5].toInt();
|
|||
|
}
|
|||
|
else {
|
|||
|
qDebug() << "Failed to parse JSON not find key of scope, or scope value is not 5 config=" << configPath;
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (test.contains(mediaInfo.id)) {
|
|||
|
qDebug() << "test.contains is exits" << mediaInfo.id;
|
|||
|
return false;
|
|||
|
}
|
|||
|
test.insert(mediaInfo.id);
|
|||
|
|
|||
|
if (mediaInfo.id != i + 1) {
|
|||
|
qDebug() << "test.contains is exits" << mediaInfo.id;
|
|||
|
return false;
|
|||
|
}
|
|||
|
if (mediaItem.datas.contains(mediaInfo.id)) {
|
|||
|
qDebug() << "dmediaItem.datas is exits" << mediaInfo.button;
|
|||
|
return false;
|
|||
|
}
|
|||
|
mediaItem.datas.insert(mediaInfo.id, std::move(mediaInfo));
|
|||
|
}
|
|||
|
|
|||
|
if (config->datas.contains(mediaItem.index)) {
|
|||
|
qDebug() << "datas.contains is exits" << mediaItem.index;
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
config->datas.insert(mediaItem.index, std::move(mediaItem));
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
bool FileHelper::SaveItemToJsonConfig(Config* config, const QString& path) {
|
|||
|
if (nullptr == config) {
|
|||
|
qDebug() << __FUNCTION__ << "config is nullptr";
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
QJsonObject root;
|
|||
|
root.insert("port", config->port);
|
|||
|
|
|||
|
QJsonArray jsonData;
|
|||
|
|
|||
|
const QMap<int32_t, MedianItem>& datas = config->datas;
|
|||
|
for (const auto& data : datas) {
|
|||
|
QJsonObject item;
|
|||
|
item.insert("name", data.name);
|
|||
|
item.insert("index", data.index);
|
|||
|
item.insert("type", data.type);
|
|||
|
|
|||
|
QJsonArray itemDatas;
|
|||
|
const QMap<int32_t, MediaInfo>& dataDatas = data.datas;
|
|||
|
for (const auto& dataData : dataDatas) {
|
|||
|
QJsonObject dataItem;
|
|||
|
dataItem.insert("id", dataData.id);
|
|||
|
dataItem.insert("button", dataData.button);
|
|||
|
dataItem.insert("name", dataData.name);
|
|||
|
dataItem.insert("describe", dataData.describe);
|
|||
|
|
|||
|
QJsonArray images;
|
|||
|
for (const auto& image : dataData.images) {
|
|||
|
images.append(image);
|
|||
|
}
|
|||
|
dataItem.insert("images", images);
|
|||
|
dataItem.insert("start", dataData.start);
|
|||
|
|
|||
|
QString end = QString("%1,%2").arg(dataData.end.x()).arg(dataData.end.y());
|
|||
|
dataItem.insert("end", end);
|
|||
|
|
|||
|
QJsonArray scope;
|
|||
|
scope.append(dataData.scope.x);
|
|||
|
scope.append(dataData.scope.y);
|
|||
|
scope.append(dataData.scope.width);
|
|||
|
scope.append(dataData.scope.height);
|
|||
|
scope.append(dataData.scope.shape);
|
|||
|
scope.append(dataData.scope.rotate);
|
|||
|
dataItem.insert("scope", scope);
|
|||
|
itemDatas.append(dataItem);
|
|||
|
}
|
|||
|
item.insert("data", itemDatas);
|
|||
|
jsonData.append(item);
|
|||
|
}
|
|||
|
|
|||
|
root.insert("data", jsonData);
|
|||
|
|
|||
|
QJsonDocument document;
|
|||
|
document.setObject(root);
|
|||
|
|
|||
|
QFile jsonFile(path);
|
|||
|
if (!jsonFile.open(QFile::WriteOnly)) {
|
|||
|
qDebug() << __FUNCTION__ << " write json file failed";
|
|||
|
return false;
|
|||
|
}
|
|||
|
jsonFile.write(document.toJson());
|
|||
|
jsonFile.close();
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
QString FileHelper::GetResoucePath(const QString& name) {
|
|||
|
const QString resourcePath = QString("%1/%2").arg(QApplication::applicationDirPath()).arg(name);
|
|||
|
return resourcePath;
|
|||
|
}
|
|||
|
|
|||
|
QStringList FileHelper::GetAllMediaFiles(const QString& path, bool* success) {
|
|||
|
QDir dir(path);
|
|||
|
if (!dir.exists()) {
|
|||
|
if (success) { *success = false; }
|
|||
|
return QStringList();
|
|||
|
}
|
|||
|
|
|||
|
QStringList nameFilters;
|
|||
|
nameFilters << "*.png" << "*.jpg" << "*.jpeg" << "*.gif" << "*.bmp"
|
|||
|
<< "*.mp4" << "*.avi" << "*.mkv" << "*.mov" << "*.wmv";
|
|||
|
|
|||
|
QStringList files = dir.entryList(nameFilters, QDir::Files);
|
|||
|
if (success) { *success = true; }
|
|||
|
return files;
|
|||
|
}
|
|||
|
|
|||
|
bool FileHelper::GeneratJsonConfig(const QString& path) {
|
|||
|
QString resourcePath = GetResoucePath(path);
|
|||
|
bool success = false;
|
|||
|
QStringList mediaFiles = GetAllMediaFiles(resourcePath, &success);
|
|||
|
if (!success) {
|
|||
|
qDebug() << "GetAllMediaFiles failes";
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
QJsonArray jsonArray;
|
|||
|
qint32 index = 0;
|
|||
|
for (const auto& path : mediaFiles) {
|
|||
|
QJsonObject jsonObject;
|
|||
|
jsonObject["index"] = index++;
|
|||
|
jsonObject["path"] = path;
|
|||
|
jsonArray.append(jsonObject);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
QJsonObject jsonObject;
|
|||
|
jsonObject["data"] = jsonArray;
|
|||
|
|
|||
|
// 创建 JSON 文档
|
|||
|
|
|||
|
const QString configPath = resourcePath + kConfigName;
|
|||
|
QFile outputFile(configPath);
|
|||
|
if (outputFile.open(QIODevice::WriteOnly)) {
|
|||
|
QJsonDocument jsonDocument(jsonObject);
|
|||
|
outputFile.write(jsonDocument.toJson());
|
|||
|
outputFile.close();
|
|||
|
qDebug() << "JSON file saved at:" << configPath;
|
|||
|
return true;
|
|||
|
}
|
|||
|
else {
|
|||
|
qDebug() << "Failed to open file for writing. path=" << configPath;
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
bool FileHelper::GetProjectFromJsonConfig(const QString& path, QMap<qint32, QString>* items) {
|
|||
|
if (nullptr == items) {
|
|||
|
qDebug() << "items is nullptr";
|
|||
|
return false;
|
|||
|
}
|
|||
|
const QString configPath = GetResoucePath(path) + kConfigName;
|
|||
|
QFile inputFile(configPath);
|
|||
|
if (!inputFile.open(QIODevice::ReadOnly))
|
|||
|
{
|
|||
|
qDebug() << "Failed to open file for reading. config=" << configPath;
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
// 读取文件内容并关闭文件
|
|||
|
QByteArray fileData = inputFile.readAll();
|
|||
|
inputFile.close();
|
|||
|
|
|||
|
// 解析 JSON 数据
|
|||
|
QJsonParseError jsonError;
|
|||
|
QJsonDocument jsonDocument = QJsonDocument::fromJson(fileData, &jsonError);
|
|||
|
if (jsonError.error != QJsonParseError::NoError)
|
|||
|
{
|
|||
|
qDebug() << "Failed to parse JSON data:" << jsonError.errorString() << " config=" << configPath;
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
// 将 JSON 数据转换为 JSON 对象
|
|||
|
QJsonObject jsonObject = jsonDocument.object();
|
|||
|
if (!jsonObject.contains("data") || !jsonObject["data"].isArray()) {
|
|||
|
qDebug() << "Failed to parse JSON not find key of data, or data value is not array config=" << configPath;
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
QJsonArray jsonArray = jsonObject["data"].toArray();
|
|||
|
for (qint32 i = 0; i < jsonArray.size(); ++i) {
|
|||
|
if (!jsonArray.at(i).isObject()) {
|
|||
|
qDebug() << "jsonArray is not object config=" << configPath;
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
QJsonObject item = jsonArray.at(i).toObject();
|
|||
|
if (!item.contains("index") || !item["index"].isDouble() ||
|
|||
|
!item.contains("path") || !item["path"].isString()) {
|
|||
|
qDebug() << "not find index / path in item config config=" << configPath;
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
items->insert(item["index"].toInt(), item["path"].toString());
|
|||
|
}
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
FileHelper::MediaType FileHelper::GetMediaType(const QString& path, const QString& name, QString& resource) {
|
|||
|
const QString mediaPath = GetResoucePath(path) + QString("/") + name;
|
|||
|
resource = mediaPath;
|
|||
|
QFileInfo fileInfo(mediaPath);
|
|||
|
QString suffix = fileInfo.suffix();
|
|||
|
|
|||
|
if (suffix.isEmpty()) {
|
|||
|
qDebug() << "The file type is unknown.";
|
|||
|
return MediaType::Unknown;
|
|||
|
}
|
|||
|
else if (suffix == "jpg" || suffix == "png" ) {
|
|||
|
qDebug() << "The file is a image.";
|
|||
|
return MediaType::Image;
|
|||
|
}
|
|||
|
else if (suffix == "gif") {
|
|||
|
qDebug() << "The file is a gif.";
|
|||
|
return MediaType::Gif;
|
|||
|
}
|
|||
|
else if (suffix == "mp4" || suffix == "avi" || suffix == "mkv") {
|
|||
|
qDebug() << "The file is a video.";
|
|||
|
return MediaType::Video;
|
|||
|
}
|
|||
|
else {
|
|||
|
qDebug() << "The file type is not supported.";
|
|||
|
}
|
|||
|
return MediaType::Unknown;
|
|||
|
}
|