1 /* This file is part of the KDE project
2
3 Copyright (C) 2007 - 2014 by Lukas Appelhans <l.appelhans@gmx.de>
4 Copyright (C) 2008 by Javier Goday <jgoday@gmail.com>
5
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10 */
11 #include "core/transferhistorystore_xml_p.h"
12
13 #include <QDomDocument>
14 #include <QFile>
15 #include <QTextStream>
16
17 #include "kget_debug.h"
18 #include <QDebug>
19
SaveThread(QObject * parent,const QString & url,const QList<TransferHistoryItem> & list)20 XmlStore::SaveThread::SaveThread(QObject *parent, const QString &url, const QList<TransferHistoryItem> &list) : QThread(parent),
21 m_url(url),
22 m_items(list),
23 m_item()
24 {
25 }
26
SaveThread(QObject * parent,const QString & url,const TransferHistoryItem & item)27 XmlStore::SaveThread::SaveThread(QObject *parent, const QString &url, const TransferHistoryItem &item) : QThread(parent),
28 m_url(url),
29 m_items(),
30 m_item(item)
31 {
32 }
33
run()34 void XmlStore::SaveThread::run()
35 {
36 QFile file(m_url);
37 QDomDocument *doc;
38 QDomElement root;
39
40 if (!file.exists())
41 {
42 doc = new QDomDocument("Transfers");
43 root = doc->createElement("Transfers");
44 doc->appendChild(root);
45 }
46 else
47 {
48 doc = new QDomDocument();
49 doc->setContent(&file);
50 file.close();
51 root = doc->documentElement();
52 doc->appendChild(root);
53 }
54
55 QDomElement e = doc->createElement("Transfer");
56 root.appendChild(e);
57
58 e.setAttribute("Source", m_item.source());
59 e.setAttribute("Dest", m_item.dest());
60 e.setAttribute("Time", QDateTime::currentDateTime().toSecsSinceEpoch());
61 e.setAttribute("Size", QString::number(m_item.size()));
62 e.setAttribute("State", QString::number(m_item.state()));
63
64 if (file.open(QFile::WriteOnly | QFile::Truncate)) {
65 QTextStream stream( &file );
66 doc->save( stream, 0 );
67 file.close();
68 }
69 delete doc;
70 }
71
DeleteThread(QObject * parent,const QString & url,const TransferHistoryItem & item)72 XmlStore::DeleteThread::DeleteThread(QObject *parent, const QString &url, const TransferHistoryItem &item) : QThread(parent),
73 m_url(url),
74 m_item(item),
75 m_items()
76 {
77 }
78
run()79 void XmlStore::DeleteThread::run()
80 {
81 QDomDocument doc("tempHistory");
82 QFile file(m_url);
83
84 QString error;
85 int line;
86 int column;
87
88 if (!doc.setContent(&file, &error, &line, &column))
89 {
90 qCDebug(KGET_DEBUG) << "Error1" << error << line << column;
91 return;
92 }
93 file.close();
94
95 QDomElement root = doc.documentElement();
96
97 QDomNodeList list = root.elementsByTagName("Transfer");
98
99 int nItems = list.length();
100
101 for (int i = 0 ; i < nItems ; i++) {
102 QDomElement element = list.item(i).toElement();
103
104 if(QString::compare(element.attribute("Source"), m_item.source()) == 0) {
105 root.removeChild(element);
106 }
107 else {
108 TransferHistoryItem item;
109 item.setDest(element.attribute("Dest"));
110 item.setSource(element.attribute("Source"));
111 item.setSize(element.attribute("Size").toInt());
112 item.setDateTime(QDateTime::fromSecsSinceEpoch(element.attribute("Time").toUInt()));
113 item.setState(element.attribute("State").toInt());
114 m_items << item;
115 }
116 }
117
118 if (file.open(QFile::WriteOnly | QFile::Truncate)) {
119 QTextStream stream( &file );
120 doc.save(stream, 0);
121 file.close();
122 doc.clear();
123 }
124 }
125
LoadThread(QObject * parent,const QString & url)126 XmlStore::LoadThread::LoadThread(QObject *parent, const QString &url) : QThread(parent),
127 m_url(url)
128 {
129 }
130
run()131 void XmlStore::LoadThread::run()
132 {
133 qRegisterMetaType<TransferHistoryItem>("TransferHistoryItem");
134 QDomDocument doc("tempHistory");
135 QFile file(m_url);
136
137 QString error;
138 int line;
139 int column;
140 int total;
141
142 if (!doc.setContent(&file, &error, &line, &column))
143 {
144 qCDebug(KGET_DEBUG) << "Error1" << error << line << column;
145 file.close();
146 return;
147 }
148
149 QDomElement root = doc.documentElement();
150 total = root.childNodes().size();
151
152 QDomNodeList list = root.elementsByTagName("Transfer");
153
154 int nItems = list.length();
155
156 for (int i = 0 ; i < nItems ; i++)
157 {
158 QDomElement dom = list.item(i).toElement();
159
160 TransferHistoryItem item;
161 item.setDest(dom.attribute("Dest"));
162 item.setSource(dom.attribute("Source"));
163 item.setSize(dom.attribute("Size").toInt());
164 item.setDateTime(QDateTime::fromSecsSinceEpoch(dom.attribute("Time").toUInt()));
165 item.setState(dom.attribute("State").toInt());
166
167 Q_EMIT elementLoaded(i, total, item);
168 }
169 doc.clear();
170 file.close();
171 }
172
XmlStore(const QString & url)173 XmlStore::XmlStore(const QString &url) : TransferHistoryStore(),
174 m_storeUrl(url),
175 m_loadThread(nullptr),
176 m_saveThread(nullptr),
177 m_deleteThread(nullptr)
178 {
179 }
180
~XmlStore()181 XmlStore::~XmlStore()
182 {
183 if(m_loadThread && m_loadThread->isRunning()) {
184 m_loadThread->terminate();
185 }
186
187 if(m_saveThread && m_saveThread->isRunning()) {
188 m_saveThread->terminate();
189 }
190
191 if(m_deleteThread && m_deleteThread->isRunning()) {
192 m_deleteThread->terminate();
193 }
194
195 delete m_loadThread;
196 delete m_saveThread;
197 delete m_deleteThread;
198 }
199
load()200 void XmlStore::load()
201 {
202 m_items.clear();
203 // TODO: only load if necessary
204 m_loadThread = new XmlStore::LoadThread(this, m_storeUrl);
205
206 connect(m_loadThread, &QThread::finished, this, &TransferHistoryStore::loadFinished);
207 connect(m_loadThread, &LoadThread::elementLoaded,
208 this, &TransferHistoryStore::elementLoaded);
209 connect(m_loadThread, &LoadThread::elementLoaded,
210 this, &XmlStore::slotLoadElement);
211 m_loadThread->start();
212 }
213
clear()214 void XmlStore::clear()
215 {
216 QFile::remove(m_storeUrl);
217 }
218
saveItem(const TransferHistoryItem & item)219 void XmlStore::saveItem(const TransferHistoryItem &item)
220 {
221 m_saveThread = new XmlStore::SaveThread(this, m_storeUrl, item);
222
223 connect(m_saveThread, &QThread::finished, this, &TransferHistoryStore::saveFinished);
224 connect(m_saveThread, &SaveThread::elementLoaded,
225 this, &TransferHistoryStore::elementLoaded);
226 m_saveThread->start();
227 }
228
deleteItem(const TransferHistoryItem & item)229 void XmlStore::deleteItem(const TransferHistoryItem &item)
230 {
231 Q_UNUSED(item)
232
233 m_deleteThread = new XmlStore::DeleteThread(this, m_storeUrl, item);
234
235 connect(m_deleteThread, &QThread::finished, this, &XmlStore::slotDeleteElement);
236
237 m_deleteThread->start();
238 }
239
slotLoadElement(int number,int total,const TransferHistoryItem & item)240 void XmlStore::slotLoadElement(int number, int total, const TransferHistoryItem &item)
241 {
242 Q_UNUSED(number)
243 Q_UNUSED(total)
244 m_items.append(item);
245 }
246
slotDeleteElement()247 void XmlStore::slotDeleteElement()
248 {
249 m_items.clear();
250 m_items << m_deleteThread->items();
251
252 Q_EMIT loadFinished();
253 }
254
255
256