412 lines
12 KiB
C++
412 lines
12 KiB
C++
#include "fileparser.h"
|
||
|
||
#include <QFile>
|
||
#include <QFileInfo>
|
||
#include <QJsonDocument>
|
||
#include <QJsonArray>
|
||
#include <QJsonObject>
|
||
#include <QJsonValue>
|
||
#include <QDir>
|
||
#include <QUrl>
|
||
#include <QEventLoop>
|
||
#include <QTimer>
|
||
#include <QNetworkAccessManager>
|
||
#include <QNetworkRequest>
|
||
#include <QNetworkReply>
|
||
|
||
const QStringList WECHAT_FILE_LIST = {"wechatVideo", "wechatMusic", "wechatDocument", "wechatPicture"};
|
||
const QStringList QQ_FILE_LIST = {"qqVideo", "qqMusic", "qqDocument", "qqPicture"};
|
||
const QString QQ_KEY = "qq";
|
||
const QString WECHAT_KEY = "wechat";
|
||
const QString LINE_SEP = "\n";
|
||
const QString COL_SEP = ":";
|
||
const QString IS_UPDATED_TREE = "1";
|
||
const QString IS_UPDATED_FALSE = "0";
|
||
|
||
FileParSer::FileParSer(QUrl url, QObject *parent) : QObject(parent)
|
||
{
|
||
m_url = url;
|
||
}
|
||
FileParSer::~FileParSer() {}
|
||
|
||
void FileParSer::getItemCountList(QString path, QMap<QString, int> &map)
|
||
{
|
||
map.clear();
|
||
QFile *file = new QFile(path);
|
||
if (!file->open(QIODevice::ReadOnly)) {
|
||
// 打开文件失败
|
||
qCritical() << "fail to open file" << path;
|
||
delete file;
|
||
file = nullptr;
|
||
return;
|
||
}
|
||
QByteArray data = file->readAll();
|
||
QString str = data;
|
||
QStringList strList = str.split(LINE_SEP);
|
||
int qqFileNum = 0;
|
||
int wechatFileNum = 0;
|
||
for (int i = 0; i < strList.count(); ++i) {
|
||
QString info = strList.value(i);
|
||
QStringList infoList = info.split(COL_SEP);
|
||
QString key = infoList.value(KEY_INDEX::KEYNAME);
|
||
QString fileNum = infoList.value(KEY_INDEX::NUM);
|
||
int num = 0;
|
||
if (!fileNum.isEmpty()) {
|
||
num = fileNum.toInt();
|
||
}
|
||
if (!key.isEmpty()) {
|
||
map.insert(key, num);
|
||
}
|
||
if (WECHAT_FILE_LIST.contains(key)) {
|
||
// 累计微信文件数量
|
||
wechatFileNum += num;
|
||
}
|
||
if (QQ_FILE_LIST.contains(key)) {
|
||
// 累计QQ文件数量
|
||
qqFileNum += num;
|
||
}
|
||
}
|
||
map.insert(WECHAT_KEY, wechatFileNum);
|
||
map.insert(QQ_KEY, qqFileNum);
|
||
file->close();
|
||
file->deleteLater();
|
||
file = nullptr;
|
||
return;
|
||
}
|
||
|
||
void FileParSer::getFileInfoList(QString path, QList<FileInfo> &fileList, QString flag)
|
||
{
|
||
fileList.clear();
|
||
QFile *file = new QFile(path);
|
||
if (!file->open(QIODevice::ReadOnly)) {
|
||
// 打开文件失败
|
||
qCritical() << "fail to open file" << path;
|
||
delete file;
|
||
file = nullptr;
|
||
return;
|
||
}
|
||
|
||
QByteArray data = file->readAll();
|
||
QString strInfoAll = data;
|
||
if (strInfoAll.isEmpty()) {
|
||
qInfo() << path << " isEmpty";
|
||
return;
|
||
}
|
||
QByteArray infoJsonBuf = strInfoAll.toUtf8();
|
||
QJsonDocument infoJsonDoc = QJsonDocument::fromJson(infoJsonBuf);
|
||
QJsonArray infoArray = infoJsonDoc.array();
|
||
for (int i = 0; i < infoArray.size(); i++) {
|
||
QJsonObject infoObj = infoArray.at(i).toObject();
|
||
FileInfo fileInfo;
|
||
fileInfo.setId(infoObj.value("id").toInt());
|
||
fileInfo.setName(infoObj.value("name").toString());
|
||
QString dateTime = infoObj.value("date").toString();
|
||
fileInfo.setDateTime(dateTime);
|
||
fileInfo.setDate(dateTime.mid(0, dateTime.lastIndexOf(" ")));
|
||
double size = infoObj.value("size").toDouble();
|
||
QString sizeStr = QString::number(size, 'f', 0);
|
||
fileInfo.setSize(sizeStr.toLongLong());
|
||
fileInfo.setType(FileInfo::judgmentType(fileInfo.name()));
|
||
fileInfo.setPath(infoObj.value("path").toString());
|
||
QString thumbPath = infoObj.value("thumbPath").toString();
|
||
if (!thumbPath.isEmpty()) {
|
||
// 获取缩略图路径
|
||
fileInfo.setThumbnailPath(path.mid(0, path.lastIndexOf("/")) + "/thumbnail/" + flag
|
||
+ thumbPath.mid(thumbPath.lastIndexOf("/") + 1, thumbPath.size()));
|
||
}
|
||
fileList.append(fileInfo);
|
||
}
|
||
file->close();
|
||
file->deleteLater();
|
||
file = nullptr;
|
||
|
||
return;
|
||
}
|
||
|
||
void FileParSer::getThumbList(QString path, QStringList &list)
|
||
{
|
||
list.clear();
|
||
QFile *file = new QFile(path);
|
||
if (!file->open(QIODevice::ReadOnly)) {
|
||
// 打开文件失败
|
||
qCritical() << "fail to open file" << path;
|
||
delete file;
|
||
file = nullptr;
|
||
return;
|
||
}
|
||
|
||
QByteArray data = file->readAll();
|
||
QString strInfoAll = data;
|
||
if (strInfoAll.isEmpty()) {
|
||
qInfo() << path << " isEmpty";
|
||
return;
|
||
}
|
||
QByteArray infoJsonBuf = strInfoAll.toUtf8();
|
||
QJsonDocument infoJsonDoc = QJsonDocument::fromJson(infoJsonBuf);
|
||
QJsonArray infoArray = infoJsonDoc.array();
|
||
for (int i = 0; i < infoArray.size(); i++) {
|
||
QJsonObject infoObj = infoArray.at(i).toObject();
|
||
QString thumbPath = infoObj.value("thumbPath").toString();
|
||
list.append(thumbPath);
|
||
}
|
||
file->close();
|
||
file->deleteLater();
|
||
file = nullptr;
|
||
|
||
return;
|
||
}
|
||
|
||
bool FileParSer::isNeedUpdate(QString sourceFile, QString targetData, QString key)
|
||
{
|
||
if (targetData.isEmpty()) {
|
||
qCritical() << "The update content is empty!";
|
||
return false;
|
||
}
|
||
// 读取源文件
|
||
QFile *file = new QFile(sourceFile);
|
||
bool openFlag;
|
||
if (!file->exists()) {
|
||
qInfo() << "FileNum file does not exists!";
|
||
QDir downDir(sourceFile.mid(0, sourceFile.lastIndexOf("/")));
|
||
if (!downDir.exists()) {
|
||
// 文件夹不存在,创建文件夹
|
||
downDir.mkpath(sourceFile.mid(0, sourceFile.lastIndexOf("/")));
|
||
}
|
||
// 本地没有fileNum文件,直接创建
|
||
QString data = addAllItemInfo(targetData);
|
||
openFlag = writeNumInfo(file, data);
|
||
if (!openFlag) {
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
openFlag = file->open(QIODevice::ReadOnly | QIODevice::Text);
|
||
if (!openFlag) {
|
||
// 打开文件失败
|
||
qCritical() << "Fail to open file: FileNum";
|
||
file->deleteLater();
|
||
return false;
|
||
}
|
||
QString sourceData = file->readAll();
|
||
file->close();
|
||
|
||
// 目标文件时间戳
|
||
QString targetTimeStamp = "";
|
||
// 源文件时间戳
|
||
QString sourceTimeStamp = "";
|
||
bool isNeedUpdate = true;
|
||
|
||
targetTimeStamp = getTimeStamp(targetData);
|
||
sourceTimeStamp = getTimeStamp(sourceData);
|
||
if (sourceTimeStamp == targetTimeStamp) {
|
||
if (key.isEmpty()) {
|
||
qInfo() << "FileNum does not need to be updated.";
|
||
isNeedUpdate = false;
|
||
file->deleteLater();
|
||
} else {
|
||
if (getIsUpdate(sourceData, key)) {
|
||
qInfo() << key << " sync last required update.";
|
||
isNeedUpdate = true;
|
||
QString data = updateItem(sourceData, key);
|
||
openFlag = writeNumInfo(file, data);
|
||
if (!openFlag) {
|
||
return false;
|
||
}
|
||
} else {
|
||
qInfo() << key << " does not need to be updated.";
|
||
isNeedUpdate = false;
|
||
file->deleteLater();
|
||
}
|
||
}
|
||
} else {
|
||
// 时间戳更新,更新文件内容
|
||
qInfo() << "File information needs to be updated.";
|
||
isNeedUpdate = true;
|
||
QString data = updateItemInfo(sourceData, targetData, key);
|
||
openFlag = writeNumInfo(file, data);
|
||
if (!openFlag) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return isNeedUpdate;
|
||
}
|
||
|
||
bool FileParSer::setKeyItemInfo(QString path, QString key)
|
||
{
|
||
QFile *file = new QFile(path);
|
||
bool openFlag;
|
||
if (!file->exists()) {
|
||
qInfo() << "FileNum file does not exists!";
|
||
file->deleteLater();
|
||
// 本地没有fileNum文件
|
||
return false;
|
||
}
|
||
|
||
openFlag = file->open(QIODevice::ReadOnly | QIODevice::Text);
|
||
if (!openFlag) {
|
||
// 打开文件失败
|
||
qCritical() << "Fail to open file: FileNum";
|
||
file->deleteLater();
|
||
return false;
|
||
}
|
||
QString sourceData = file->readAll();
|
||
file->close();
|
||
|
||
QString data = updateItem(sourceData, key);
|
||
openFlag = writeNumInfo(file, data);
|
||
if (!openFlag) {
|
||
qInfo() << "setKeyItemInfo ERROR!";
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
QString FileParSer::getTimeStamp(QString data, QString key)
|
||
{
|
||
QStringList strList = data.split(LINE_SEP);
|
||
if (key.isEmpty()) {
|
||
// 获取fileNum版本号
|
||
return strList.value(0);
|
||
}
|
||
for (int i = 1; i < strList.count(); ++i) {
|
||
QString info = strList.value(i);
|
||
QStringList infoList = info.split(COL_SEP);
|
||
if (key == infoList.value(KEY_INDEX::KEYNAME)) {
|
||
return infoList.value(KEY_INDEX::VERSION);
|
||
}
|
||
}
|
||
return QString("");
|
||
}
|
||
|
||
bool FileParSer::writeNumInfo(QFile *file, QString data)
|
||
{
|
||
if (data.isEmpty()) {
|
||
qCritical() << "NumInfoData isEmpty!";
|
||
return false;
|
||
}
|
||
bool openFlag = file->open(QIODevice::WriteOnly | QIODevice::Text);
|
||
if (!openFlag) {
|
||
// 打开文件失败
|
||
qCritical() << "Fail to open file: fileNum";
|
||
file->deleteLater();
|
||
return openFlag;
|
||
}
|
||
QByteArray dataArr = data.toLatin1();
|
||
char *buffer = dataArr.data();
|
||
file->write(buffer);
|
||
file->flush();
|
||
file->close();
|
||
file->deleteLater();
|
||
|
||
return openFlag;
|
||
}
|
||
|
||
QString FileParSer::addAllItemInfo(QString data)
|
||
{
|
||
QStringList strList = data.split(LINE_SEP);
|
||
data.clear();
|
||
data.append(strList.value(0) + LINE_SEP);
|
||
for (int i = 1; i < strList.count(); ++i) {
|
||
QString info = strList.value(i);
|
||
info.append(COL_SEP + IS_UPDATED_TREE);
|
||
if (i == strList.count() - 1) {
|
||
data.append(info);
|
||
} else {
|
||
data.append(info + LINE_SEP);
|
||
}
|
||
}
|
||
return data;
|
||
}
|
||
|
||
QString FileParSer::updateItemInfo(QString sourceData, QString targetData, QString key)
|
||
{
|
||
QMap<QString, QString> targetMap;
|
||
QMap<QString, QString> sourceMap;
|
||
targetMap.clear();
|
||
sourceMap.clear();
|
||
setInfoMap(targetData, targetMap);
|
||
setInfoMap(sourceData, sourceMap);
|
||
|
||
QString data = "";
|
||
data.append(targetData.split(LINE_SEP).value(0) + LINE_SEP);
|
||
|
||
for (int i = 0; i < FILENUM_KEY_LIST.count(); i++) {
|
||
QString keyName = FILENUM_KEY_LIST.value(i);
|
||
QString itemData = sourceMap.value(keyName);
|
||
QStringList infoList = itemData.split(COL_SEP);
|
||
// 目标文件时间戳
|
||
QString targetTimeStamp = getTimeStamp(targetData, keyName);
|
||
// 源文件时间戳
|
||
QString sourceTimeStamp = getTimeStamp(sourceData, keyName);
|
||
|
||
if (sourceTimeStamp != targetTimeStamp) {
|
||
itemData = targetMap.value(keyName);
|
||
if (key == keyName) {
|
||
itemData.append(COL_SEP + IS_UPDATED_FALSE);
|
||
} else {
|
||
itemData.append(COL_SEP + IS_UPDATED_TREE);
|
||
}
|
||
}
|
||
if (i == FILENUM_KEY_LIST.count() - 1) {
|
||
data.append(itemData);
|
||
} else {
|
||
data.append(itemData + LINE_SEP);
|
||
}
|
||
}
|
||
|
||
return data;
|
||
}
|
||
|
||
QString FileParSer::updateItem(QString data, QString key)
|
||
{
|
||
QStringList strList = data.split(LINE_SEP);
|
||
QString resultData = "";
|
||
resultData.append(strList.value(0) + LINE_SEP);
|
||
for (int i = 1; i < strList.count(); ++i) {
|
||
QString itemData = strList.value(i);
|
||
QStringList infoList = itemData.split(COL_SEP);
|
||
if (key == infoList.value(KEY_INDEX::KEYNAME)) {
|
||
itemData = itemData.mid(0, itemData.lastIndexOf(COL_SEP) + 1);
|
||
itemData.append(IS_UPDATED_FALSE);
|
||
}
|
||
if (i == strList.count() - 1) {
|
||
resultData.append(itemData);
|
||
} else {
|
||
resultData.append(itemData + LINE_SEP);
|
||
}
|
||
}
|
||
return resultData;
|
||
}
|
||
|
||
bool FileParSer::getIsUpdate(QString data, QString key)
|
||
{
|
||
QStringList strList = data.split(LINE_SEP);
|
||
if (key.isEmpty()) {
|
||
// 获取fileNum版本号
|
||
qCritical() << "IsUpdate key isEmpty!";
|
||
return true;
|
||
}
|
||
for (int i = 1; i < strList.count(); ++i) {
|
||
QString info = strList.value(i);
|
||
QStringList infoList = info.split(COL_SEP);
|
||
if (key == infoList.value(KEY_INDEX::KEYNAME) && infoList.value(KEY_INDEX::ISUPDATE) == IS_UPDATED_TREE) {
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
|
||
void FileParSer::setInfoMap(QString data, QMap<QString, QString> &map)
|
||
{
|
||
QStringList strList = data.split(LINE_SEP);
|
||
for (int i = 1; i < strList.count(); ++i) {
|
||
QString info = strList.value(i);
|
||
QStringList infoList = info.split(COL_SEP);
|
||
map.insert(infoList.value(KEY_INDEX::KEYNAME), info);
|
||
}
|
||
return;
|
||
} |