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 39PlasmaMuleEngine::PlasmaMuleEngine (QObject* parent, const QVariantList& args) 40 : Plasma::DataEngine (parent, args) 41{ 42 Q_UNUSED (args) 43 setMinimumPollingInterval (0); 44} 45 46bool PlasmaMuleEngine::sourceRequestEvent (const QString &name) 47{ 48 return updateSourceEvent (name); 49} 50 51QStringList 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 76void 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 103void 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 111void 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 141void 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 207void 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 295void 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 304void 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 316void PlasmaMuleEngine::timeout() 317{ 318 initVals(); 319} 320 321bool 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 353K_EXPORT_PLASMA_DATAENGINE(plasmamule, PlasmaMuleEngine) 354 355EngineAdaptor::EngineAdaptor(QObject *parent): QDBusAbstractAdaptor(parent) 356{ 357 setAutoRelaySignals(true); 358} 359 360EngineAdaptor::~EngineAdaptor() 361{ 362} 363 364void 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