kylin-connectivity/filesync/fileparser.cpp

412 lines
12 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}