File indexing completed on 2024-02-18 04:58:19

0001 /* This file is part of the KDE project
0002 
0003    Copyright (C) 2007 - 2014 by Lukas Appelhans <l.appelhans@gmx.de>
0004    Copyright (C) 2008 by Javier Goday <jgoday@gmail.com>
0005 
0006    This program is free software; you can redistribute it and/or
0007    modify it under the terms of the GNU General Public
0008    License as published by the Free Software Foundation; either
0009    version 2 of the License, or (at your option) any later version.
0010 */
0011 #include "core/transferhistorystore_xml_p.h"
0012 
0013 #include <QDomDocument>
0014 #include <QFile>
0015 #include <QTextStream>
0016 
0017 #include "kget_debug.h"
0018 #include <QDebug>
0019 
0020 XmlStore::SaveThread::SaveThread(QObject *parent, const QString &url, const QList<TransferHistoryItem> &list)
0021     : QThread(parent)
0022     , m_url(url)
0023     , m_items(list)
0024     , m_item()
0025 {
0026 }
0027 
0028 XmlStore::SaveThread::SaveThread(QObject *parent, const QString &url, const TransferHistoryItem &item)
0029     : QThread(parent)
0030     , m_url(url)
0031     , m_items()
0032     , m_item(item)
0033 {
0034 }
0035 
0036 void XmlStore::SaveThread::run()
0037 {
0038     QFile file(m_url);
0039     QDomDocument *doc;
0040     QDomElement root;
0041 
0042     if (!file.exists()) {
0043         doc = new QDomDocument("Transfers");
0044         root = doc->createElement("Transfers");
0045         doc->appendChild(root);
0046     } else {
0047         doc = new QDomDocument();
0048         doc->setContent(&file);
0049         file.close();
0050         root = doc->documentElement();
0051         doc->appendChild(root);
0052     }
0053 
0054     QDomElement e = doc->createElement("Transfer");
0055     root.appendChild(e);
0056 
0057     e.setAttribute("Source", m_item.source());
0058     e.setAttribute("Dest", m_item.dest());
0059     e.setAttribute("Time", QDateTime::currentDateTime().toSecsSinceEpoch());
0060     e.setAttribute("Size", QString::number(m_item.size()));
0061     e.setAttribute("State", QString::number(m_item.state()));
0062 
0063     if (file.open(QFile::WriteOnly | QFile::Truncate)) {
0064         QTextStream stream(&file);
0065         doc->save(stream, 0);
0066         file.close();
0067     }
0068     delete doc;
0069 }
0070 
0071 XmlStore::DeleteThread::DeleteThread(QObject *parent, const QString &url, const TransferHistoryItem &item)
0072     : QThread(parent)
0073     , m_url(url)
0074     , m_item(item)
0075     , m_items()
0076 {
0077 }
0078 
0079 void XmlStore::DeleteThread::run()
0080 {
0081     QDomDocument doc("tempHistory");
0082     QFile file(m_url);
0083 
0084     QString error;
0085     int line;
0086     int column;
0087 
0088     if (!doc.setContent(&file, &error, &line, &column)) {
0089         qCDebug(KGET_DEBUG) << "Error1" << error << line << column;
0090         return;
0091     }
0092     file.close();
0093 
0094     QDomElement root = doc.documentElement();
0095 
0096     QDomNodeList list = root.elementsByTagName("Transfer");
0097 
0098     int nItems = list.length();
0099 
0100     for (int i = 0; i < nItems; i++) {
0101         QDomElement element = list.item(i).toElement();
0102 
0103         if (QString::compare(element.attribute("Source"), m_item.source()) == 0) {
0104             root.removeChild(element);
0105         } else {
0106             TransferHistoryItem item;
0107             item.setDest(element.attribute("Dest"));
0108             item.setSource(element.attribute("Source"));
0109             item.setSize(element.attribute("Size").toInt());
0110             item.setDateTime(QDateTime::fromSecsSinceEpoch(element.attribute("Time").toUInt()));
0111             item.setState(element.attribute("State").toInt());
0112             m_items << item;
0113         }
0114     }
0115 
0116     if (file.open(QFile::WriteOnly | QFile::Truncate)) {
0117         QTextStream stream(&file);
0118         doc.save(stream, 0);
0119         file.close();
0120         doc.clear();
0121     }
0122 }
0123 
0124 XmlStore::LoadThread::LoadThread(QObject *parent, const QString &url)
0125     : QThread(parent)
0126     , m_url(url)
0127 {
0128 }
0129 
0130 void XmlStore::LoadThread::run()
0131 {
0132     qRegisterMetaType<TransferHistoryItem>("TransferHistoryItem");
0133     QDomDocument doc("tempHistory");
0134     QFile file(m_url);
0135 
0136     QString error;
0137     int line;
0138     int column;
0139     int total;
0140 
0141     if (!doc.setContent(&file, &error, &line, &column)) {
0142         qCDebug(KGET_DEBUG) << "Error1" << error << line << column;
0143         file.close();
0144         return;
0145     }
0146 
0147     QDomElement root = doc.documentElement();
0148     total = root.childNodes().size();
0149 
0150     QDomNodeList list = root.elementsByTagName("Transfer");
0151 
0152     int nItems = list.length();
0153 
0154     for (int i = 0; i < nItems; i++) {
0155         QDomElement dom = list.item(i).toElement();
0156 
0157         TransferHistoryItem item;
0158         item.setDest(dom.attribute("Dest"));
0159         item.setSource(dom.attribute("Source"));
0160         item.setSize(dom.attribute("Size").toInt());
0161         item.setDateTime(QDateTime::fromSecsSinceEpoch(dom.attribute("Time").toUInt()));
0162         item.setState(dom.attribute("State").toInt());
0163 
0164         // do not load expired items
0165         if (item.isExpired(TransferHistoryStore::getSettingsExpiryAge())) {
0166             continue;
0167         }
0168 
0169         Q_EMIT elementLoaded(i, total, item);
0170     }
0171     doc.clear();
0172     file.close();
0173 }
0174 
0175 XmlStore::XmlStore(const QString &url)
0176     : TransferHistoryStore()
0177     , m_storeUrl(url)
0178     , m_loadThread(nullptr)
0179     , m_saveThread(nullptr)
0180     , m_deleteThread(nullptr)
0181 {
0182 }
0183 
0184 XmlStore::~XmlStore()
0185 {
0186     if (m_loadThread && m_loadThread->isRunning()) {
0187         m_loadThread->terminate();
0188     }
0189 
0190     if (m_saveThread && m_saveThread->isRunning()) {
0191         m_saveThread->terminate();
0192     }
0193 
0194     if (m_deleteThread && m_deleteThread->isRunning()) {
0195         m_deleteThread->terminate();
0196     }
0197 
0198     deleteExpiredItems();
0199 
0200     delete m_loadThread;
0201     delete m_saveThread;
0202     delete m_deleteThread;
0203 }
0204 
0205 void XmlStore::load()
0206 {
0207     m_items.clear();
0208     // TODO: only load if necessary
0209     m_loadThread = new XmlStore::LoadThread(this, m_storeUrl);
0210 
0211     connect(m_loadThread, &QThread::finished, this, &TransferHistoryStore::loadFinished);
0212     connect(m_loadThread, &LoadThread::elementLoaded, this, &TransferHistoryStore::elementLoaded);
0213     connect(m_loadThread, &LoadThread::elementLoaded, this, &XmlStore::slotLoadElement);
0214     m_loadThread->start();
0215 }
0216 
0217 void XmlStore::clear()
0218 {
0219     QFile::remove(m_storeUrl);
0220 }
0221 
0222 void XmlStore::saveItem(const TransferHistoryItem &item)
0223 {
0224     m_saveThread = new XmlStore::SaveThread(this, m_storeUrl, item);
0225 
0226     connect(m_saveThread, &QThread::finished, this, &TransferHistoryStore::saveFinished);
0227     connect(m_saveThread, &SaveThread::elementLoaded, this, &TransferHistoryStore::elementLoaded);
0228     m_saveThread->start();
0229 }
0230 
0231 void XmlStore::deleteItem(const TransferHistoryItem &item)
0232 {
0233     Q_UNUSED(item)
0234 
0235     m_deleteThread = new XmlStore::DeleteThread(this, m_storeUrl, item);
0236 
0237     connect(m_deleteThread, &QThread::finished, this, &XmlStore::slotDeleteElement);
0238 
0239     m_deleteThread->start();
0240 }
0241 
0242 void XmlStore::slotLoadElement(int number, int total, const TransferHistoryItem &item)
0243 {
0244     Q_UNUSED(number)
0245     Q_UNUSED(total)
0246     m_items.append(item);
0247 }
0248 
0249 void XmlStore::slotDeleteElement()
0250 {
0251     m_items.clear();
0252     m_items << m_deleteThread->items();
0253 
0254     Q_EMIT loadFinished();
0255 }
0256 
0257 #include "moc_transferhistorystore_xml_p.cpp"