1 //
2 // This file is part of the aMule Project.
3 //
4 // Copyright (c) 2010-2011 Werner Mahr (Vollstrecker) <amule@vollstreckernet.de>
5 //
6 // Any parts of this program contributed by third-party developers are copyrighted
7 // by their respective authors.
8 //
9 // This program is free software; you can redistribute it and/or modify
10 // it under the terms of the GNU General Public License as published by
11 // the Free Software Foundation; either version 3 of the License, or
12 // (at your option) any later version.
13 //
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 // GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with this program; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
22 //
23 
24 #include "plasma-engine-plasmamule.h"
25 #include "qt-emc.h"
26 
27 #include <kdebug.h>
28 #include <knotification.h>
29 
30 #include <kio/scheduler.h>
31 
32 #include <plasma/datacontainer.h>
33 
34 #include <QDir>
35 #include <QTimer>
36 
37 #include <QtDBus/QDBusInterface>
38 
PlasmaMuleEngine(QObject * parent,const QVariantList & args)39 PlasmaMuleEngine::PlasmaMuleEngine (QObject* parent, const QVariantList& args)
40 	: Plasma::DataEngine (parent, args)
41 {
42 	Q_UNUSED (args)
43 	setMinimumPollingInterval (0);
44 }
45 
sourceRequestEvent(const QString & name)46 bool PlasmaMuleEngine::sourceRequestEvent (const QString &name)
47 {
48 	return updateSourceEvent (name);
49 }
50 
sources() const51 QStringList PlasmaMuleEngine::sources() const
52 {
53 	return QStringList() << "cat_dirs"
54 		<< "cat_names"
55 		<< "clients_in_up_queue"
56 		<< "config_found"
57 		<< "down_speed"
58 		<< "ed2k_state"
59 		<< "ed2k_server_name"
60 		<< "ed2k_server_ip"
61 		<< "ed2k_server_port"
62 		<< "ed2k_id_high_low"
63 		<< "kad_status"
64 		<< "nickname"
65 		<< "os_active"
66 		<< "session_bytes_downloaded"
67 		<< "session_bytes_uploaded"
68 		<< "shared_files_count"
69 		<< "total_bytes_downloaded"
70 		<< "total_bytes_uploaded"
71 		<< "up_speed"
72 		<< "uptime"
73 		<< "version";
74 }
75 
init()76 void PlasmaMuleEngine::init ()
77 {
78 	Home = QDir::homePath();
79 
80 	QTimer *timer = new QTimer(this);
81 	connect(timer, SIGNAL(timeout()), this, SLOT(timeout()));
82 	timer->start(60000);
83 	m_timer = TRUE;
84 	setData(I18N_NOOP("uptime"), 0);
85 
86 	if (!Home.endsWith("/"))
87 	{
88 		Home += "/";
89 	}
90 
91 	m_debugChannel = KDebug::registerArea ("plasmamule-engine",
92 #ifdef __DEBUG__
93 	true
94 #else
95 	false
96 #endif
97 	);
98 
99 	regDbus();
100 	initVals();
101 }
102 
regDbus()103 void PlasmaMuleEngine::regDbus ()
104 {
105 	new EngineAdaptor(this);
106 	QDBusConnection dbus = QDBusConnection::sessionBus();
107 	dbus.registerObject("/Link", this);
108 	kDebug(m_debugChannel) << "Registerred dbus: " << dbus.registerService("org.amule.engine");
109 }
110 
downloadFinished(KIO::Job * job,const QByteArray & data)111 void PlasmaMuleEngine::downloadFinished (KIO::Job* job,const QByteArray& data)
112 {
113 
114 	if (data.length() == 0)
115 	{
116 		KNotification::event(KNotification::Notification, QString("Download of %1 failed.").arg(job->queryMetaData("Name")));
117 		return;
118 	}
119 
120 	kDebug(m_debugChannel) << QString("Finished download of %1").arg(job->queryMetaData("Name"));
121 
122 	QString downloadFileName(QString("/tmp/plasmamule-download-%1.emulecollection").arg(qrand()));
123 
124 	QFile downloadFile(downloadFileName);
125 
126 	if (!downloadFile.open (QIODevice::WriteOnly | QIODevice::Append))
127 	{
128 		KNotification::event(KNotification::Notification, QString("%1 can't be written to temp-file.").arg(job->queryMetaData("Name")));
129 		return;
130 	}
131 
132 	QDataStream out(&downloadFile);
133 	out.writeRawData(data, data.length());
134 	downloadFile.close();
135 
136 	engine_add_link (downloadFileName, job->queryMetaData("Category").toInt(), job->queryMetaData("Name"));
137 
138 	downloadFile.remove();
139 }
140 
engine_add_link(const QString & link,const int & category,const QString & printname)141 void PlasmaMuleEngine::engine_add_link (const QString &link, const int &category, const QString &printname)
142 {
143 	kDebug(m_debugChannel) << "Received Link " << link << " with cat " << category;
144 
145 	QString link_to_write;
146 
147 
148 	if (link.startsWith("ed2k:") || link.startsWith("magnet:"))
149 	{
150 		link_to_write = link;
151 
152 		if (category > 0)
153 		{
154 			link_to_write.append(QString(":%1").arg(category));
155 		}
156 
157 		link_to_write.append("\n");
158 	} else if (link.contains(".emulecollection") && KUrl(link).isLocalFile())
159 	{
160 		qtEmc* collection = new qtEmc(link);
161 		if (collection->isValid())
162 		{
163 			QStringList links = collection->getLinks();
164 			for (QStringList::const_iterator constIterator = links.constBegin(); constIterator != links.constEnd(); ++constIterator)
165 			{
166 				link_to_write.append(*constIterator);
167 
168 				if (category > 0)
169 				{
170 					link_to_write.append(QString(":%1").arg(category));
171 				}
172 
173 				link_to_write.append("\n");
174 			}
175 		} else {
176 			KNotification::event(KNotification::Notification, collection->getErrorMessage());
177 		}
178 
179 		delete collection;
180 	} else {
181 		KIO::TransferJob *job = KIO::get(KUrl(link));
182 		job->addMetaData("Name", link);
183 		job->addMetaData("Category", QString(category));
184 		connect (job, SIGNAL(data(KIO::Job *, const QByteArray&)), this,
185 			SLOT(downloadFinished(KIO::Job *,const QByteArray&)));
186 		kDebug(m_debugChannel) << QString("Starting download of %1").arg(printname);
187 		return;
188 	}
189 
190 	QFile link_file (Home + ".aMule/ED2KLinks");
191 
192 	if (!link_file.open (QIODevice::WriteOnly | QIODevice::Append))
193 	{
194 		KNotification::event(KNotification::Notification, QString("Problem opening %1 for writing").arg(link_file.fileName()));
195 		return;
196 	}
197 
198 	QTextStream out (&link_file);
199 	out << link_to_write;
200 	out.flush();
201 	link_file.close();
202 
203 	KNotification::event(KNotification::Notification, QString("Downloading %1").arg(printname));
204 
205 }
206 
initVals()207 void PlasmaMuleEngine::initVals ()
208 {
209 	QStringList catDir;
210 	QStringList catName;
211 	QStringList tempIncomingDirs;
212 	QStringList cleanedIncomingDirs;
213 	QStringList::const_iterator constIterator;
214 
215 	QFile config_file (Home + ".aMule/amule.conf");
216 
217 	catName.append("Default");
218 	if (!config_file.open (QIODevice::ReadOnly | QIODevice::Text))
219 	{
220 		setData(I18N_NOOP ("config_found"), FALSE);
221 		return;
222 	}
223 
224 	QTextStream in (&config_file);
225 	while (!in.atEnd())
226 	{
227 		QString line = in.readLine();
228 		if (line.startsWith ("OnlineSignature="))
229 		{
230 			if (line.remove (0,line.indexOf ("=")+1) == "1")
231 			{
232 				m_OSActive = TRUE;
233 			} else {
234 				m_OSActive = FALSE;
235 			}
236 
237 			setData(I18N_NOOP ("os_active"), m_OSActive);
238 		} else if (line.contains ("OSDirectory"))
239 		{
240 			m_OSFile.setFileName(line.remove (0,line.indexOf ("=")+1) + "amulesig.dat");
241 
242 		} else if (line.contains ("Incoming"))
243 		{
244 			if (!tempIncomingDirs.contains(line.remove (0,line.indexOf ("=")+1)))
245 			{
246 				tempIncomingDirs.append(line.remove (0,line.indexOf ("=")+1));
247 			}
248 
249 			catDir.append(line.remove (0,line.indexOf ("=")+1));
250 		} else if (line.startsWith ("Title"))
251 		{
252 			catName.append(line.remove (0,line.indexOf ("=")+1));
253 		}
254         }
255 
256 	setData(I18N_NOOP ("cat_names"), catName);
257 	setData(I18N_NOOP ("cat_dirs"), catDir);
258 
259 	if (m_OSActive && !m_dirwatcher.contains(m_OSFile.fileName()))
260 	{
261 		kDebug(m_debugChannel) << "Registering: " << m_OSFile.fileName() << " for monitoring";
262 		m_dirwatcher.addFile (m_OSFile.fileName());
263 		connect (&m_dirwatcher, SIGNAL (dirty (const QString &)), SLOT (file_changed (const QString&)));
264 		connect (&m_dirwatcher, SIGNAL (created (const QString &)), SLOT (new_file (const QString&)));
265 	}
266 
267 	for (constIterator = tempIncomingDirs.constBegin(); constIterator != tempIncomingDirs.constEnd(); ++constIterator)
268 	{
269 		if (!m_dirwatcher.contains(*constIterator))
270 		{
271 			kDebug(m_debugChannel) << "Registering: " << *constIterator << " for monitoring";
272 			cleanedIncomingDirs.append (*constIterator);
273 			m_dirwatcher.addDir (*constIterator, KDirWatch::WatchFiles);
274 		} else {
275 			cleanedIncomingDirs.append (*constIterator);
276 		}
277 	}
278 
279 	for (constIterator = m_incoming_dirs.constBegin(); constIterator != m_incoming_dirs.constEnd(); ++constIterator)
280 	{
281 		if (!cleanedIncomingDirs.contains (*constIterator))
282 		{
283 			kDebug(m_debugChannel) << "Removing " << *constIterator << " from monitored dirs";
284 			m_dirwatcher.removeDir (*constIterator);
285 		}
286 	}
287 
288 	m_incoming_dirs = cleanedIncomingDirs;
289 	config_file.close ();
290 	setName("plasmamule");
291 	setData(I18N_NOOP ("config_found"), TRUE);
292 	scheduleSourcesUpdated();
293 }
294 
file_changed(const QString & path)295 void PlasmaMuleEngine::file_changed (const QString &path)
296 {
297 	if (path == m_OSFile.fileName())
298 	{
299 		kDebug(m_debugChannel) << "Rereading " << path;
300 		updateSourceEvent ("dummy");
301 	}
302 }
303 
new_file(const QString & path)304 void PlasmaMuleEngine::new_file (const QString &path)
305 {
306 	if (path != m_OSFile.fileName())
307 	{
308 		kDebug(m_debugChannel) << "File " << path << "was created";
309 		KNotification::event(KNotification::Notification, QString("Finished Download of %1").arg(path));
310 	} else {
311 		kDebug(m_debugChannel) << "Rereading " << path;
312 		updateSourceEvent ("dummy");
313 	}
314 }
315 
timeout()316 void PlasmaMuleEngine::timeout()
317 {
318 	initVals();
319 }
320 
updateSourceEvent(const QString & name)321 bool PlasmaMuleEngine::updateSourceEvent(const QString &name)
322 {
323 	Q_UNUSED (name)
324 
325 	if (m_OSFile.open (QIODevice::ReadOnly | QIODevice::Text) && m_OSActive)
326 	{
327 		QTextStream in (&m_OSFile);
328 		setData(I18N_NOOP("ed2k_state"), in.readLine().toInt());
329 		setData(I18N_NOOP("ed2k_server_name"), in.readLine());
330 		setData(I18N_NOOP("ed2k_server_ip"), in.readLine());
331 		setData(I18N_NOOP("ed2k_server_port"), in.readLine().toInt());
332 		setData(I18N_NOOP("ed2k_id_high_low"), in.readLine());
333 		setData(I18N_NOOP("kad_status"), in.readLine().toInt());
334 		setData(I18N_NOOP("down_speed"), in.readLine().toDouble());
335 		setData(I18N_NOOP("up_speed"), in.readLine().toDouble());
336 		setData(I18N_NOOP("clients_in_up_queue"), in.readLine().toInt());
337 		setData(I18N_NOOP("shared_files_count"), in.readLine().toInt());
338 		setData(I18N_NOOP("nickname"), in.readLine());
339 		setData(I18N_NOOP("total_bytes_downloaded"), in.readLine().toLongLong());
340 		setData(I18N_NOOP("total_bytes_uploaded"), in.readLine().toLongLong());
341 		setData(I18N_NOOP("version"), in.readLine());
342 		setData(I18N_NOOP("session_bytes_downloaded"), in.readLine().toLongLong());
343 		setData(I18N_NOOP("session_bytes_uploaded"), in.readLine().toLongLong());
344 		setData(I18N_NOOP("uptime"), in.readLine().toInt());
345 		m_OSFile.close();
346 		scheduleSourcesUpdated();
347 		return true;
348 	} else {
349 		return false;
350 	}
351 }
352 
K_EXPORT_PLASMA_DATAENGINE(plasmamule,PlasmaMuleEngine)353 K_EXPORT_PLASMA_DATAENGINE(plasmamule, PlasmaMuleEngine)
354 
355 EngineAdaptor::EngineAdaptor(QObject *parent): QDBusAbstractAdaptor(parent)
356 {
357 	setAutoRelaySignals(true);
358 }
359 
~EngineAdaptor()360 EngineAdaptor::~EngineAdaptor()
361 {
362 }
363 
engine_add_link(const QString & link,const int & category)364 void EngineAdaptor::engine_add_link(const QString &link, const int &category)
365 {
366 	QMetaObject::invokeMethod(parent(), "engine_add_link", Q_ARG(QString, link), Q_ARG(int, category), Q_ARG(QString, link));
367 }
368 
369 #include "plasma-engine-plasmamule.moc"
370