yhkylin-backup-tools/backup-daemon/parsebackuplist.cpp

601 lines
16 KiB
C++
Raw Normal View History

2021-08-17 10:07:35 +08:00
#include "parsebackuplist.h"
#include <QFile>
#include <QTextStream>
#include <QXmlStreamReader>
#include <QDebug>
2021-10-26 09:24:05 +08:00
#include <algorithm>
2021-08-17 10:07:35 +08:00
/*
<?xml version='1.0'?>
<backupList>
<BackupPoint>
<Comment>21-07-21 14:14:01</Comment>
<Time>21-07-21 14:14:03</Time>
<Uuid>{beecb746-561f-4fa1-99ba-19fb849a1ba7}</Uuid>
<Size>24.26KB</Size>
<State>backup finished</State>
<Type>2</Type>
2021-10-26 09:24:05 +08:00
<Position>0</Position>
<UserId>1000</UserId>
2021-08-17 10:07:35 +08:00
</BackupPoint>
</backupList>
*/
#define BACKUPLIST "backupList"
#define BACKUPPOINT "BackupPoint"
#define COMMENT "Comment"
#define TIME "Time"
#define UUID "Uuid"
#define SIZE "Size"
#define STATE "State"
#define TYPE "Type"
#define POSITION "Position"
2021-10-26 09:24:05 +08:00
#define USERID "UserId"
2021-11-11 16:03:58 +08:00
#define OS "OS"
#define ARCH "Arch"
#define ARCHDETECT "ArchDetect"
#define PREFIXDESTPATH "PrefixDestPath"
2021-11-11 16:03:58 +08:00
2021-08-17 10:07:35 +08:00
#define STATUE_BACKUP_FINESHED "backup finished"
ParseBackupList::ParseBackupList(const QString& xmlPath)
: m_xmlPath(xmlPath)
{
QFile xmlFile(m_xmlPath);
if (!xmlFile.exists() || 0 == xmlFile.size()) {
InitXml();
}
}
/**
* @brief xml文件
* @return
*/
bool ParseBackupList::InitXml()
{
QFile xmlFile(m_xmlPath);
if (!xmlFile.open(QIODevice::ReadWrite | QIODevice::Truncate))
return false;
QDomDocument doc;
QDomProcessingInstruction ins = doc.createProcessingInstruction("xml", "version=\'1.0\'");
doc.appendChild(ins);
QDomElement root = doc.createElement(BACKUPLIST);
doc.appendChild(root);
QTextStream out(&xmlFile);
doc.save(out, QDomNode::NodeType::CDATASectionNode);
xmlFile.close();
return true;
}
/**
* @brief xml格式是否正确
* @return
*/
bool ParseBackupList::isXmlCorrect()
{
QFile xmlFile(m_xmlPath);
if (!xmlFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug() << "Open file " << m_xmlPath << " failure";
return false;
}
QXmlStreamReader reader(&xmlFile);
while (!reader.atEnd()) {
if (reader.isStartElement()) {
}
reader.readNext();
}
if (reader.hasError()) {
qDebug() << "xml parse error!";
xmlFile.close();
return false;
}
xmlFile.close();
return true;
}
/**
* @brief xml文件
* @param doc
* @return
*/
bool ParseBackupList::Doc_setContent(QDomDocument& doc)
{
QFile xmlFile(m_xmlPath);
if (!xmlFile.open(QIODevice::ReadOnly)) {
2021-10-26 09:24:05 +08:00
qDebug() << "open backuplist.xml failed!";
2021-08-17 10:07:35 +08:00
return false;
}
QString errStr;
int errLine;
int errCol;
if (!doc.setContent(&xmlFile, false, &errStr, &errLine, &errCol)) {
qDebug() << QString("parse backuplist.xml error at line %1, column %2:%3").arg(errLine).arg(errCol).arg(errStr);
xmlFile.close();
return false;
}
xmlFile.close();
return true;
}
2021-10-26 09:24:05 +08:00
/**
* @brief ParseBackupList::BackupPoint::operator <
* @param other
* @return
*/
bool ParseBackupList::BackupPoint::operator < (const BackupPoint &other)
{
return other.m_time > this->m_time;
}
2021-08-17 10:07:35 +08:00
/**
* @brief backuplist.xml
* @param factoryBackupUuiduuid
* @return ParseResult枚举类型
* @author zhaominyong
* @since 2021/06/27
*/
ParseBackupList::ParseResult ParseBackupList::updateForFactoryRestore(const QString& factoryBackupUuid)
{
QDomDocument doc;
if (!Doc_setContent(doc))
return XML_PARSE_ERR;
QDomElement root = doc.documentElement();
QDomNodeList list = root.childNodes();
for (int i = 0; i < list.count(); i++) {
QDomNode node = list.at(i);
if (!node.isElement())
continue ;
QDomElement element = node.toElement();
QDomNodeList nodes = element.elementsByTagName(UUID);
if (0 < nodes.count()) {
QDomElement uuidElement = nodes.at(0).toElement();
QString tag = uuidElement.tagName();
QString text = uuidElement.text();
if (uuidElement.text() != factoryBackupUuid) {
root.removeChild(node);
--i;
}
}
}
QFile xmlFile(m_xmlPath);
if (!xmlFile.open(QIODevice::WriteOnly)) {
qDebug() << "update state failed";
return FAIL;
}
QTextStream out(&xmlFile);
doc.save(out, QDomNode::NodeType::EntityReferenceNode);
out.flush();
xmlFile.close();
return SUCCESS;
}
/**
* @brief comment查找uuid
* @param comment
* @return uuid
*/
QString ParseBackupList::findUuidByComment(const QString& comment)
{
QDomDocument doc;
if (!Doc_setContent(doc))
return "";
QDomElement root = doc.documentElement();
QDomNodeList list = root.childNodes();
for (int i = 0; i < list.count(); i++) {
QDomNode node = list.at(i);
if (!node.isElement())
continue;
QDomElement eleComment = node.firstChildElement(COMMENT);
if (eleComment.isNull())
continue;
if (comment != eleComment.text())
continue;
QDomElement eleUuid = node.firstChildElement(UUID);
if (eleUuid.isNull())
return "";
return eleUuid.text();
}
return "";
}
/**
* @brief Uuid查找备份点信息
* @param Uuid
* @return
*/
ParseBackupList::BackupPoint ParseBackupList::findBackupPointByUuid(const QString& Uuid)
{
BackupPoint backupPoint;
QDomDocument doc;
if (!Doc_setContent(doc))
return backupPoint;
QDomElement root = doc.documentElement();
QDomNodeList list = root.childNodes();
for (int i = 0; i < list.count(); i++) {
QDomNode node = list.at(i);
if (!node.isElement())
continue;
QDomElement eleUuid = node.firstChildElement(UUID);
if (eleUuid.isNull() || Uuid != eleUuid.text())
continue;
elementNodeToBackupPoint(node.toElement(), backupPoint);
return backupPoint;
}
return backupPoint;
}
2022-03-09 15:02:01 +08:00
/**
* @brief xml文件中备份点uuid和backupname的映射
* @param uuid_namexml文件中备份点uuid和backupname的映射
* @return
*/
void ParseBackupList::getXmlUuidNameMap(QMap<QString, QString> &uuid_name)
{
BackupPoint backupPoint;
QDomDocument doc;
if (!Doc_setContent(doc))
return ;
QDomElement root = doc.documentElement();
QDomNodeList list = root.childNodes();
for (int i = 0; i < list.count(); i++) {
QDomNode node = list.at(i);
if (!node.isElement())
continue;
QDomElement eleUuid = node.firstChildElement(UUID);
if (eleUuid.isNull() || eleUuid.text().isEmpty())
continue;
QDomElement eleBackupName = node.firstChildElement(COMMENT);
if (eleBackupName.isNull() || eleBackupName.text().isEmpty())
continue;
uuid_name.insert(eleUuid.text(), eleBackupName.text());
}
return ;
}
2021-08-17 10:07:35 +08:00
/**
* @brief
* @param customizePaths
*/
void ParseBackupList::getCustomizePaths(QStringList &customizePaths)
{
QDomDocument doc;
if (!Doc_setContent(doc))
return ;
QDomElement root = doc.documentElement();
QDomNodeList list = root.childNodes();
for (int i = 0; i < list.count(); i++) {
QDomNode node = list.at(i);
if (!node.isElement())
continue;
QDomElement elePrefixPath = node.firstChildElement(PREFIXDESTPATH);
if (!elePrefixPath.isNull()) {
2022-07-28 18:49:35 +08:00
customizePaths << elePrefixPath.text() + BACKUP_SNAPSHOTS_PATH;
}
}
}
/**
* @brief
2021-08-17 10:07:35 +08:00
* @return
*/
ParseBackupList::BackupPoint ParseBackupList::getLastSysBackupPoint()
{
BackupPoint backupPoint;
QDomDocument doc;
if (!Doc_setContent(doc))
return backupPoint;
QDomElement root = doc.documentElement();
QDomNodeList list = root.childNodes();
for (int i = 0; i < list.count(); i++) {
QDomNode node = list.at(i);
if (!node.isElement())
continue;
QDomElement eleType = node.firstChildElement(TYPE);
if (eleType.isNull() || (BackupType::BACKUP_SYSTEM != eleType.text().toInt() && BackupType::INC_BACKUP_SYSTEM != eleType.text().toInt()))
continue;
2021-12-09 10:00:07 +08:00
QDomElement eleUuid = node.firstChildElement(UUID);
if (eleUuid.isNull() || eleUuid.text() == AUTO_BACKUP_UUID)
continue;
2021-08-17 10:07:35 +08:00
QDomElement eleState = node.firstChildElement(STATE);
if (eleState.isNull() || eleState.text() != QString(STATUE_BACKUP_FINESHED))
continue;
QDomElement elePosition = node.firstChildElement(POSITION);
if (!elePosition.isNull() && elePosition.text().toInt() == BackupPosition::CUSTOMIZE)
continue;
2021-08-17 10:07:35 +08:00
elementNodeToBackupPoint(node.toElement(), backupPoint);
}
return backupPoint;
}
/**
* @brief elementNode --> BackupPoint
* @param node, QDomElement
* @param backupPoint, BackupPoint
*/
void ParseBackupList::elementNodeToBackupPoint(const QDomElement& node, BackupPoint& backupPoint)
{
QDomElement eleUuid = node.firstChildElement(UUID);
if (!eleUuid.isNull())
backupPoint.m_uuid = eleUuid.text();
QDomElement eleComment = node.firstChildElement(COMMENT);
if (!eleComment.isNull())
backupPoint.m_backupName = eleComment.text();
2021-12-26 18:15:21 +08:00
if (backupPoint.m_uuid == FACTORY_BACKUP_UUID)
backupPoint.m_backupName = QObject::tr("factory backup");
2021-08-17 10:07:35 +08:00
QDomElement eleTime = node.firstChildElement(TIME);
if (!eleTime.isNull())
backupPoint.m_time = eleTime.text();
QDomElement eleSize = node.firstChildElement(SIZE);
if (!eleSize.isNull())
backupPoint.m_size = eleSize.text();
QDomElement eleState = node.firstChildElement(STATE);
if (!eleState.isNull())
backupPoint.m_state = eleState.text();
QDomElement eleType = node.firstChildElement(TYPE);
if (!eleType.isNull())
backupPoint.m_type = eleType.text().toInt();
QDomElement elePosition = node.firstChildElement(POSITION);
2021-10-26 09:24:05 +08:00
if (!elePosition.isNull() && !elePosition.text().isEmpty())
2021-08-17 10:07:35 +08:00
backupPoint.m_iPosition = elePosition.text().toInt();
2021-10-26 09:24:05 +08:00
QDomElement eleUserId = node.firstChildElement(USERID);
if (!eleUserId.isNull())
backupPoint.m_userId = eleUserId.text();
2021-11-11 16:03:58 +08:00
QDomElement eleOS = node.firstChildElement(OS);
if (!eleOS.isNull())
backupPoint.m_os = eleOS.text();
QDomElement eleArch = node.firstChildElement(ARCH);
if (!eleArch.isNull())
backupPoint.m_arch = eleArch.text();
QDomElement eleArchDetect = node.firstChildElement(ARCHDETECT);
if (!eleArchDetect.isNull())
backupPoint.m_archdetect = eleArchDetect.text();
2021-12-06 14:55:00 +08:00
QDomElement elePrefixPath = node.firstChildElement(PREFIXDESTPATH);
if (!elePrefixPath.isNull()) {
backupPoint.m_path = elePrefixPath.text();
} else {
backupPoint.m_path = m_xmlPath;
backupPoint.m_path.replace(BACKUP_XML_PATH, "");
}
2021-08-17 10:07:35 +08:00
}
/**
* @brief backupPoint --> ElementNode
* @param backupPoint, BackupPoint
* @param node, QDomElement
*/
void ParseBackupList::backupPointToElementNode(const BackupPoint& backupPoint, QDomDocument& doc, QDomNode& node)
2021-08-17 10:07:35 +08:00
{
node.appendChild(createTextElement(doc, COMMENT, backupPoint.m_backupName));
node.appendChild(createTextElement(doc, TIME, backupPoint.m_time));
node.appendChild(createTextElement(doc, UUID, backupPoint.m_uuid));
node.appendChild(createTextElement(doc, SIZE, backupPoint.m_size));
node.appendChild(createTextElement(doc, STATE, backupPoint.m_state));
node.appendChild(createTextElement(doc, TYPE, QString::number(backupPoint.m_type)));
node.appendChild(createTextElement(doc, POSITION, QString::number(backupPoint.m_iPosition)));
2021-11-11 16:03:58 +08:00
if (!backupPoint.m_userId.isEmpty()) {
node.appendChild(createTextElement(doc, USERID, backupPoint.m_userId));
}
if (!backupPoint.m_os.isEmpty()) {
node.appendChild(createTextElement(doc, OS, backupPoint.m_os));
}
if (!backupPoint.m_arch.isEmpty()) {
node.appendChild(createTextElement(doc, ARCH, backupPoint.m_arch));
}
if (!backupPoint.m_archdetect.isEmpty()) {
node.appendChild(createTextElement(doc, ARCHDETECT, backupPoint.m_archdetect));
}
if (!backupPoint.m_path.isEmpty()) {
node.appendChild(createTextElement(doc, PREFIXDESTPATH, backupPoint.m_path));
}
2021-08-17 10:07:35 +08:00
}
/**
* @brief createTextElement
* @param tagName
* @param text
* @return <tagName>text</tagName>
*/
QDomElement ParseBackupList::createTextElement(QDomDocument& doc, const QString& tagName, const QString& text)
2021-08-17 10:07:35 +08:00
{
QDomElement node = doc.createElement(tagName);
QDomText textNode = doc.createTextNode(text);
2021-08-17 10:07:35 +08:00
node.appendChild(textNode);
return node;
}
/**
* @brief
* @param backupPoint,
* @return SUCCESS成功 XML_PARSE_ERR失败
*/
ParseBackupList::ParseResult ParseBackupList::addItem(const BackupPoint& backupPoint)
{
QDomDocument doc;
if (!Doc_setContent(doc))
return XML_PARSE_ERR;
QDomElement backupPointNode = doc.createElement(BACKUPPOINT);
backupPointToElementNode(backupPoint, doc, backupPointNode);
QDomElement root = doc.documentElement();
root.appendChild(backupPointNode);
QFile xmlFile(m_xmlPath);
if (!xmlFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
return FAIL;
QTextStream out(&xmlFile);
doc.save(out, QDomNode::NodeType::CDATASectionNode);
xmlFile.close();
return SUCCESS;
}
/**
* @brief
* @param backupPoint
* @return SUCCESS成功 XML_PARSE_ERR失败
*/
ParseBackupList::ParseResult ParseBackupList::updateItem(const BackupPoint & backupPoint)
{
QDomDocument doc;
if (!Doc_setContent(doc))
return XML_PARSE_ERR;
QDomElement root = doc.documentElement();
QDomNodeList list = root.childNodes();
2022-03-21 15:16:04 +08:00
int i = 0;
for (; i < list.count(); i++) {
QDomNode node = list.at(i);
if (!node.isElement())
continue;
QDomElement eleUuid = node.firstChildElement(UUID);
if (eleUuid.isNull() || backupPoint.m_uuid != eleUuid.text())
continue;
2022-03-21 15:16:04 +08:00
break ;
}
// 找到了旧节点
if (i < list.count()) {
// 移除旧节点,更新后的节点放到最后
root.removeChild(list.at(i));
QDomElement newNode = doc.createElement(BACKUPPOINT);
backupPointToElementNode(backupPoint, doc, newNode);
2022-03-21 15:16:04 +08:00
root.appendChild(newNode);
}
QFile xmlFile(m_xmlPath);
2021-09-01 15:46:24 +08:00
if (!xmlFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
return FAIL;
}
QTextStream out(&xmlFile);
doc.save(out, QDomNode::NodeType::EntityReferenceNode);
xmlFile.close();
return SUCCESS;
}
/**
* @brief
* @param uuid
* @return SUCCESS成功 XML_PARSE_ERR失败
*/
ParseBackupList::ParseResult ParseBackupList::deleteItem(const QString& uuid)
{
QDomDocument doc;
if (!Doc_setContent(doc))
return XML_PARSE_ERR;
QDomElement root = doc.documentElement();
QDomNodeList list = root.childNodes();
for (int i = 0; i < list.count(); i++) {
QDomNode node = list.at(i);
if (!node.isElement())
continue;
QDomElement eleUuid = node.firstChildElement(UUID);
if (eleUuid.isNull() || uuid != eleUuid.text())
continue;
root.removeChild(node);
break ;
}
QFile xmlFile(m_xmlPath);
if (!xmlFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
return FAIL;
}
QTextStream out(&xmlFile);
doc.save(out, QDomNode::NodeType::EntityReferenceNode);
xmlFile.close();
return SUCCESS;
}
2021-10-26 09:24:05 +08:00
/**
* @brief
* @return
*/
QList<ParseBackupList::BackupPoint> ParseBackupList::getBackupPointList()
{
QList<ParseBackupList::BackupPoint> backupPointList;
QDomDocument doc;
if (!Doc_setContent(doc))
return backupPointList;
QDomElement root = doc.documentElement();
QDomNodeList list = root.childNodes();
for (int i = 0; i < list.count(); i++) {
QDomNode node = list.at(i);
if (!node.isElement())
continue;
QDomElement eleUuid = node.firstChildElement(UUID);
if (eleUuid.isNull())
continue;
BackupPoint backupPoint;
elementNodeToBackupPoint(node.toElement(), backupPoint);
backupPointList << backupPoint;
}
2021-12-06 14:55:00 +08:00
// std::sort(backupPointList.begin(), backupPointList.end());
2021-10-26 09:24:05 +08:00
return backupPointList;
}