• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdenetwork API Reference
  • KDE Home
  • Contact Us
 

kget

  • sources
  • kde-4.14
  • kdenetwork
  • kget
  • transfer-plugins
  • bittorrent
bttransfer.cpp
Go to the documentation of this file.
1 /* This file is part of the KDE project
2 
3  Copyright (C) 2007-2008 Lukas Appelhans <l.appelhans@gmx.de>
4  Copyright (C) 2007 Joris Guisson <joris.guisson@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 
12 #include "bttransfer.h"
13 #include "bittorrentsettings.h"
14 #include "bttransferhandler.h"
15 //#include "btchunkselector.h"
16 #include "advanceddetails/monitor.h"
17 #include "core/kget.h"
18 #include "core/filemodel.h"
19 #include "core/download.h"
20 
21 #include <torrent/torrent.h>
22 #include <peer/peermanager.h>
23 #include <util/error.h>
24 #include <torrent/globals.h>
25 #include <torrent/server.h>
26 #include <util/constants.h>
27 #include <util/functions.h>
28 #include <util/log.h>
29 #include <peer/authenticationmonitor.h>
30 #include <interfaces/trackerinterface.h>
31 #include <utp/utpserver.h>
32 #include <version.h>
33 
34 #include <KDebug>
35 #include <KLocale>
36 #include <KIconLoader>
37 #include <KIO/CopyJob>
38 #include <KStandardDirs>
39 #include <KUrl>
40 #include <KMessageBox>
41 
42 #include <QFile>
43 #include <QDomElement>
44 #include <QFileInfo>
45 #include <QDir>
46 
47 #ifdef ERROR
48 #undef ERROR
49 #endif
50 
51 BTTransfer::BTTransfer(TransferGroup* parent, TransferFactory* factory,
52  Scheduler* scheduler, const KUrl& src, const KUrl& dest,
53  const QDomElement * e)
54  : Transfer(parent, factory, scheduler, src, dest, e),
55  torrent(0),
56  m_tmp(KStandardDirs::locateLocal("appdata", "tmp/")),
57  m_ready(false),
58  m_downloadFinished(false),
59  m_movingFile(false),
60  m_fileModel(0),
61  m_updateCounter(0)
62 {
63  m_directory = m_dest.upUrl();//FIXME test
64 
65  setCapabilities(Transfer::Cap_Moving | Transfer::Cap_Renaming | Transfer::Cap_Resuming | Transfer::Cap_SpeedLimit);
66 }
67 
68 BTTransfer::~BTTransfer()
69 {
70  if (torrent && m_ready)
71  torrent->setMonitor(0);
72 
73  delete torrent;
74 }
75 
76 void BTTransfer::deinit(Transfer::DeleteOptions options)
77 {
78  kDebug() << "****************************DEINIT";
79  if (torrent && (options & Transfer::DeleteFiles)) {//FIXME: Also delete when torrent does not exist
80  torrent->deleteDataFiles();
81  }
82  if (options & Transfer::DeleteTemporaryFiles) {
83  QDir tmpDir(m_tmp);
84  kDebug(5001) << m_tmp + m_source.fileName().remove(".torrent");
85  tmpDir.rmdir(m_source.fileName().remove(".torrent") + "/dnd");
86  tmpDir.cd(m_source.fileName().remove(".torrent"));
87  QStringList list = tmpDir.entryList();
88  foreach (const QString &file, list) {
89  tmpDir.remove(file);
90  }
91  tmpDir.cdUp();
92  tmpDir.rmdir(m_source.fileName().remove(".torrent"));
93 
94  //only remove the .torrent file if it was downloaded by KGet
95  if (!m_tmpTorrentFile.isEmpty()) {
96  kDebug(5001) << "Removing" << m_tmpTorrentFile;
97  QFile torrentFile(m_tmpTorrentFile);
98  torrentFile.remove();
99  }
100  }
101 }
102 
104 bool BTTransfer::isStalled() const
105 {
106  return (status() == Job::Running) && (downloadSpeed() == 0) && torrent && torrent->getStats().status == bt::STALLED;
107 }
108 
109 bool BTTransfer::isWorking() const
110 {
111  if (!torrent)
112  return false;
113  const bt::TorrentStats stats = torrent->getStats();
114  return (stats.status != bt::ERROR) && (stats.status != bt::STALLED) && (stats.status != bt::NO_SPACE_LEFT) && (stats.status != bt::INVALID_STATUS);
115 }
116 
117 void BTTransfer::start()
118 {
119  if (m_movingFile)
120  {
121  return;
122  }
123 
124  if (!torrent)
125  {
126  if (!m_source.isLocalFile())
127  {
128  kDebug(5001) << m_dest.path();
129  m_tmpTorrentFile = QString(KStandardDirs::locateLocal("appdata", "tmp/") + m_dest.fileName());
130  Download *download = new Download(m_source, m_tmpTorrentFile);
131 
132  setStatus(Job::Stopped, i18n("Downloading Torrent File...."), SmallIcon("document-save"));
133  setTransferChange(Tc_Status, true);
134 
135  //m_source = KStandardDirs::locateLocal("appdata", "tmp/") + m_source.fileName();
136  connect(download, SIGNAL(finishedSuccessfully(KUrl,QByteArray)), SLOT(btTransferInit(KUrl,QByteArray)));
137  }
138  else
139  btTransferInit();
140  }
141  else
142  startTorrent();
143 }
144 
145 bool BTTransfer::setDirectory(const KUrl &newDirectory)
146 {
147  //check if the newDestination is the same as the old
148  KUrl temp = newDirectory;
149  temp.addPath(torrent->getStats().torrent_name);
150  if (newDirectory.isValid() && (newDirectory != dest()) && (temp != dest()))
151  {
152  if (torrent->changeOutputDir(newDirectory.pathOrUrl(), bt::TorrentInterface::MOVE_FILES))
153  {
154  connect(torrent, SIGNAL(aboutToBeStarted(bt::TorrentInterface*,bool&)), this, SLOT(newDestResult()));
155  m_movingFile = true;
156  m_directory = newDirectory;
157  m_dest = m_directory;
158  m_dest.addPath(torrent->getStats().torrent_name);
159 
160  setStatus(Job::Stopped, i18nc("changing the destination of the file", "Changing destination"), SmallIcon("media-playback-pause"));
161  setTransferChange(Tc_Status, true);
162  return true;
163  }
164  }
165  m_movingFile = false;
166  return false;
167 }
168 
169 void BTTransfer::newDestResult()
170 {
171  disconnect(torrent, SIGNAL(aboutToBeStarted(bt::TorrentInterface*,bool&)), this, SLOT(newDestResult()));
172  m_movingFile = false;
173 
174  setStatus(Job::Running, i18nc("transfer state: downloading", "Downloading...."), SmallIcon("media-playback-start"));
175  setTransferChange(Tc_FileName | Tc_Status, true);
176 }
177 
178 void BTTransfer::stop()
179 {
180  if (m_movingFile)
181  return;
182 
183  if (m_ready)
184  {
185  stopTorrent();
186  }
187 }
188 
190 void BTTransfer::update()
191 {
192  if (m_movingFile)
193  {
194  return;
195  }
196 
197  if (torrent)
198  {
199  QStringList files;
200  if (torrent->hasMissingFiles(files))
201  {
202  torrent->recreateMissingFiles();
203  }
204  updateTorrent();
205  }
206  else
207  timer.stop();
208 }
209 
210 void BTTransfer::load(const QDomElement *element)
211 {
212  Transfer::load(element);
213 
214  if ((m_totalSize == m_downloadedSize) && (m_totalSize != 0))
215  {
216  setStatus(Job::Stopped, i18nc("transfer state: finished", "Finished"), SmallIcon("dialog-ok"));
217  }
218 }
219 
220 // void BTTransfer::save(const QDomElement &element)
221 // {
222 // kDebug(5001);
223 //
224 // QDomElement e = element;
225 //
226 // Transfer::save(e);
227 // }
228 
231 void BTTransfer::setPort(int port)
232 {
233  bt::Globals::instance().getTCPServer().changePort(port);
234  if (BittorrentSettings::enableUTP())
235  bt::Globals::instance().getUTPServer().changePort(port + 1);
236 }
237 
238 void BTTransfer::setSpeedLimits(int ulLimit, int dlLimit)
239 {
240  kDebug(5001);
241  if (!torrent)
242  return;
243 
244  torrent->setTrafficLimits(ulLimit * 1000, dlLimit * 1000);
245 }
246 
247 void BTTransfer::addTracker(const QString &url)
248 {
249  kDebug(5001);
250  if(torrent->getStats().priv_torrent) {
251  KMessageBox::sorry(0, i18n("Cannot add a tracker to a private torrent."));
252  return;
253  }
254 
255  if(!KUrl(url).isValid()) {
256  KMessageBox::error(0, i18n("Malformed URL."));
257  return;
258  }
259 
260  torrent->getTrackersList()->addTracker(url,true);
261 }
262 
265 void BTTransfer::startTorrent()
266 {
267  if (m_ready)
268  {
269  //kDebug(5001) << "Going to download that stuff :-0";
270  setSpeedLimits(uploadLimit(Transfer::InvisibleSpeedLimit), downloadLimit(Transfer::InvisibleSpeedLimit));//Set traffic-limits before starting
271  torrent->setMonitor(this);
272  torrent->start();
273  timer.start(250);
274  if (chunksTotal() == chunksDownloaded()/* && !m_downloadFinished*/) {
275  slotDownloadFinished(torrent);
276  } else {
277  setStatus(Job::Running, i18nc("transfer state: downloading", "Downloading...."), SmallIcon("media-playback-start"));
278  }
279  m_totalSize = torrent->getStats().total_bytes_to_download;
280  setTransferChange(Tc_Status | Tc_TrackersList | Tc_TotalSize, true);
281  updateFilesStatus();
282  }
283 }
284 
285 void BTTransfer::stopTorrent()
286 {
287  torrent->stop();
288  torrent->setMonitor(0);
289  m_downloadSpeed = 0;
290  timer.stop();
291 
292  if (m_downloadFinished)
293  {
294  setStatus(Job::Stopped, i18nc("transfer state: finished", "Finished"), SmallIcon("dialog-ok"));
295  }
296  else
297  {
298  setStatus(Job::Stopped, i18nc("transfer state: stopped", "Stopped"), SmallIcon("process-stop"));
299  }
300  setTransferChange(Tc_Status, true);
301 
302  updateFilesStatus();
303 }
304 
305 void BTTransfer::updateTorrent()
306 {
307  //kDebug(5001) << "Update torrent";
308  bt::UpdateCurrentTime();
309  bt::AuthenticationMonitor::instance().update();
310  torrent->update();
311 
312  ChangesFlags changesFlags = 0;
313 
314  if (m_downloadedSize != (m_downloadedSize = torrent->getStats().bytes_downloaded))
315  changesFlags |= Tc_DownloadedSize;
316 
317  if (m_uploadSpeed != static_cast<int>(torrent->getStats().upload_rate))
318  {
319  m_uploadSpeed = torrent->getStats().upload_rate;
320  changesFlags |= Tc_UploadSpeed;
321  }
322 
323  if (m_downloadSpeed != static_cast<int>(torrent->getStats().download_rate))
324  {
325  m_downloadSpeed = torrent->getStats().download_rate;
326  changesFlags |= Tc_DownloadSpeed;
327  }
328 
329  int percent = (chunksDownloaded() * 100) / chunksTotal();
330  if (m_percent != percent) {
331  m_percent = percent;
332  changesFlags |= Tc_Percent;
333  }
334 
335  setTransferChange(changesFlags, true);
336 
337  //update the files status every 3 seconds
338  if (!m_updateCounter)
339  {
340  updateFilesStatus();
341  m_updateCounter = 12;
342  }
343  --m_updateCounter;
344 }
345 
346 void BTTransfer::updateFilesStatus()
347 {
348  const Job::Status currentStatus = this->status();
349  if (!torrent)
350  {
351  return;
352  }
353  const bt::TorrentStats *stats = &torrent->getStats();
354  if (stats->multi_file_torrent)
355  {
356  QHash<KUrl, bt::TorrentFileInterface*>::const_iterator it;
357  QHash<KUrl, bt::TorrentFileInterface*>::const_iterator itEnd = m_files.constEnd();
358  for (it = m_files.constBegin(); it != itEnd; ++it)
359  {
360  QModelIndex status = m_fileModel->index(it.key(), FileItem::Status);
361  if (!(*it)->doNotDownload() && (currentStatus == Job::Running))
362  {
363  m_fileModel->setData(status, Job::Running);
364  }
365  else
366  {
367  m_fileModel->setData(status, Job::Stopped);
368  }
369  if (qFuzzyCompare((*it)->getDownloadPercentage(), 100.0f))
370  {
371  m_fileModel->setData(status, Job::Finished);
372  }
373  }
374  }
375  else
376  {
377  QModelIndexList indexes = fileModel()->fileIndexes(FileItem::Status);
378  if (indexes.count() != 1)
379  {
380  return;
381  }
382 
383  QModelIndex index = indexes.first();
384  if (stats->bytes_left_to_download)
385  {
386  if (currentStatus == Job::Running)
387  {
388  fileModel()->setData(index, Job::Running);
389  }
390  else
391  {
392  fileModel()->setData(index, Job::Stopped);
393  }
394  }
395  else
396  {
397  fileModel()->setData(index, Job::Finished);
398  }
399  }
400 }
401 
402 void BTTransfer::btTransferInit(const KUrl &src, const QByteArray &data)
403 {
404  Q_UNUSED(data)
405  kDebug(5001);
406  if (src != m_source && !src.isEmpty())
407  m_source = src;
408 
409  QFile file(m_source.toLocalFile());
410 
411  if (!file.open(QIODevice::ReadOnly)) {
412  setError(i18n("Torrent file does not exist"), SmallIcon("dialog-cancel"), Job::NotSolveable);
413  setTransferChange(Tc_Status, true);
414  return;
415  }
416 
417  setStatus(Job::Stopped, i18n("Analyzing torrent...."), SmallIcon("document-preview")); // jpetso says: you should probably use the "process-working" icon here (from the animations category), but that's a multi-frame PNG so it's hard for me to test
418  setTransferChange(Tc_Status, true);
419 
420  bt::InitLog(KStandardDirs::locateLocal("appdata", "torrentlog.log"), false, false);//initialize the torrent-log
421 
422  bt::SetClientInfo("KGet", 2, KDE_VERSION_MINOR, KDE_VERSION_RELEASE, bt::NORMAL, "KG");//Set client info to KGet
423 
424  bt::Uint16 i = 0;
425  while (!bt::Globals::instance().initTCPServer(BittorrentSettings::port() + i) && i < 10)
426  i++;
427 
428  if (i == 10) {
429  setError(i18n("Cannot initialize port..."), SmallIcon("dialog-cancel"));
430  setTransferChange(Tc_Status);
431  return;
432  }
433  if (BittorrentSettings::enableUTP()) {
434  while (!bt::Globals::instance().initUTPServer(BittorrentSettings::port() + i) && i < 10) //We don't care if it fails for now as UTP is experimental...
435  i++;
436  }
437 
438  QDir tmpDir(m_tmp + m_source.fileName().remove(".torrent"));
439  if (tmpDir.exists())
440  {
441  tmpDir.remove("torrent");
442  }
443  try
444  {
445  torrent = new bt::TorrentControl();
446 
447  if (!BittorrentSettings::tmpDir().isEmpty() && QFileInfo(BittorrentSettings::tmpDir()).isDir())
448  {
449  m_tmp = BittorrentSettings::tmpDir();
450  }
451 
452  m_ready = true;
453 
454  kDebug() << "Source:" << m_source.path() << "Destination:" << m_dest.path();
455  torrent->init(0, file.readAll(), m_tmp + m_source.fileName().remove(".torrent"), KUrl(m_dest.directory()).toLocalFile());
456 
457  m_dest = torrent->getStats().output_path;
458  if (!torrent->getStats().multi_file_torrent && (m_dest.fileName() != torrent->getStats().torrent_name))//TODO check if this is needed, so if that case is true at some point
459  {
460  m_dest.addPath(torrent->getStats().torrent_name);
461  }
462 
463  torrent->createFiles();
464 
465  torrent->setPreallocateDiskSpace(BittorrentSettings::preAlloc());
466 
467  connect(torrent, SIGNAL(stoppedByError(bt::TorrentInterface*,QString)), SLOT(slotStoppedByError(bt::TorrentInterface*,QString)));
468  connect(torrent, SIGNAL(finished(bt::TorrentInterface*)), this, SLOT(slotDownloadFinished(bt::TorrentInterface*)));
469  //FIXME connect(tc,SIGNAL(corruptedDataFound(bt::TorrentInterface*)), this, SLOT(emitCorruptedData(bt::TorrentInterface*)));//TODO: Fix it
470  }
471  catch (bt::Error &err)
472  {
473  m_ready = false;
474  torrent->deleteLater();
475  torrent = 0;
476  setError(err.toString(), SmallIcon("dialog-cancel"), Job::NotSolveable);
477  setTransferChange(Tc_Status);
478  return;
479  }
480  startTorrent();
481  connect(&timer, SIGNAL(timeout()), SLOT(update()));
482 }
483 
484 void BTTransfer::slotStoppedByError(const bt::TorrentInterface* &error, const QString &errormsg)
485 {
486  Q_UNUSED(error)
487  stop();
488  setError(errormsg, SmallIcon("dialog-cancel"), Job::NotSolveable);
489  setTransferChange(Tc_Status);
490 }
491 
492 void BTTransfer::slotDownloadFinished(bt::TorrentInterface* ti)
493 {
494  kDebug(5001) << "Start seeding *********************************************************************";
495  Q_UNUSED(ti)
496  m_downloadFinished = true;
497  //timer.stop();
498  setStatus(Job::FinishedKeepAlive, i18nc("Transfer status: seeding", "Seeding...."), SmallIcon("media-playback-start"));
499  setTransferChange(Tc_Status, true);
500 }
501 
503 KUrl::List BTTransfer::trackersList() const
504 {
505  if (!torrent)
506  return KUrl::List();
507 
508  KUrl::List trackers;
509  foreach (bt::TrackerInterface * tracker, torrent->getTrackersList()->getTrackers())
510  trackers << tracker->trackerURL();
511  return trackers;
512 }
513 
514 int BTTransfer::sessionBytesDownloaded() const
515 {
516  if (!torrent)
517  return -1;
518 
519  return torrent->getStats().session_bytes_downloaded;
520 }
521 
522 int BTTransfer::sessionBytesUploaded() const
523 {
524  if (!torrent)
525  return -1;
526 
527  return torrent->getStats().session_bytes_uploaded;
528 }
529 
530 int BTTransfer::chunksTotal() const
531 {
532  if (!torrent)
533  return -1;
534 
535  return torrent->getTorrent().getNumChunks();
536 }
537 
538 int BTTransfer::chunksDownloaded() const
539 {
540  if (!torrent)
541  return -1;
542 
543  return torrent->downloadedChunksBitSet().numOnBits();
544 }
545 
546 int BTTransfer::chunksExcluded() const
547 {
548  if (!torrent)
549  return -1;
550 
551  return torrent->excludedChunksBitSet().numOnBits();
552 }
553 
554 int BTTransfer::chunksLeft() const
555 {
556  if (!torrent)
557  return -1;
558 
559  return chunksTotal() - chunksDownloaded();
560 }
561 
562 int BTTransfer::seedsConnected() const
563 {
564  if (!torrent)
565  return -1;
566 
567  return torrent->getStats().seeders_connected_to;
568 }
569 
570 int BTTransfer::seedsDisconnected() const
571 {
572  if (!torrent)
573  return -1;
574 
575  return torrent->getStats().seeders_total;
576 }
577 
578 int BTTransfer::leechesConnected() const
579 {
580  if (!torrent)
581  return -1;
582 
583  return torrent->getStats().leechers_connected_to;
584 }
585 
586 int BTTransfer::leechesDisconnected() const
587 {
588  if (!torrent)
589  return -1;
590 
591  return torrent->getStats().leechers_total;
592 }
593 
594 int BTTransfer::elapsedTime() const
595 {
596  if (!torrent)
597  return -1;
598 
599  return torrent->getRunningTimeDL();
600 }
601 
602 int BTTransfer::remainingTime() const
603 {
604  if (!torrent)
605  return Transfer::remainingTime();
606 
607  return torrent->getETA();
608 }
609 
610 bt::TorrentControl * BTTransfer::torrentControl()
611 {
612  return torrent;
613 }
614 
615 bool BTTransfer::ready()
616 {
617  return m_ready;
618 }
619 
620 void BTTransfer::downloadRemoved(bt::ChunkDownloadInterface* cd)
621 {
622  if (static_cast<BTTransferHandler*>(handler())->torrentMonitor())
623  static_cast<BTTransferHandler*>(handler())->torrentMonitor()->downloadRemoved(cd);
624 
625  setTransferChange(Tc_ChunksDownloaded | Tc_ChunksExcluded | Tc_ChunksLeft, true);
626 }
627 
628 void BTTransfer::downloadStarted(bt::ChunkDownloadInterface* cd)
629 {
630  if (static_cast<BTTransferHandler*>(handler())->torrentMonitor())
631  static_cast<BTTransferHandler*>(handler())->torrentMonitor()->downloadStarted(cd);
632 
633  setTransferChange(Tc_ChunksDownloaded | Tc_ChunksExcluded | Tc_ChunksLeft, true);
634 }
635 
636 void BTTransfer::peerAdded(bt::PeerInterface* peer)
637 {
638  if (static_cast<BTTransferHandler*>(handler())->torrentMonitor())
639  static_cast<BTTransferHandler*>(handler())->torrentMonitor()->peerAdded(peer);
640 
641  setTransferChange(Tc_SeedsConnected | Tc_SeedsDisconnected | Tc_LeechesConnected | Tc_LeechesDisconnected, true);
642 }
643 
644 void BTTransfer::peerRemoved(bt::PeerInterface* peer)
645 {
646  if (static_cast<BTTransferHandler*>(handler())->torrentMonitor())
647  static_cast<BTTransferHandler*>(handler())->torrentMonitor()->peerRemoved(peer);
648 
649  setTransferChange(Tc_SeedsConnected | Tc_SeedsDisconnected | Tc_LeechesConnected | Tc_LeechesDisconnected, true);
650 }
651 
652 void BTTransfer::stopped()
653 {
654  if (static_cast<BTTransferHandler*>(handler())->torrentMonitor())
655  static_cast<BTTransferHandler*>(handler())->torrentMonitor()->stopped();
656 }
657 
658 void BTTransfer::destroyed()
659 {
660  if (static_cast<BTTransferHandler*>(handler())->torrentMonitor())
661  static_cast<BTTransferHandler*>(handler())->torrentMonitor()->destroyed();
662 }
663 
664 QList<KUrl> BTTransfer::files() const
665 {
666  QList<KUrl> urls;
667 
668  if (!torrent)
669  {
670  return urls;
671  }
672 
673  //multiple files
674  if (torrent->getStats().multi_file_torrent)
675  {
676  for (uint i = 0; i < torrent->getNumFiles(); ++i)
677  {
678  const QString path = torrent->getTorrentFile(i).getPathOnDisk();
679  urls.append(KUrl(path));
680  }
681  }
682  //one single file
683  else
684  {
685  KUrl temp = m_dest;
686  if (m_dest.fileName() != torrent->getStats().torrent_name)//TODO check if the body is ever entered!
687  {
688  temp.addPath(torrent->getStats().torrent_name);
689  }
690  urls.append(temp);
691  }
692 
693  return urls;
694 }
695 
696 void BTTransfer::filesSelected()
697 {
698  QModelIndexList indexes = fileModel()->fileIndexes(FileItem::File);
699  //one single file
700  if (indexes.count() == 1)
701  {
702  QModelIndex index = indexes.first();
703  const bool doDownload = index.data(Qt::CheckStateRole).toBool();
704  if (torrent && torrent->getStats().bytes_left_to_download)
705  {
706  if (doDownload)
707  {
708  start();
709  }
710  else
711  {
712  stop();
713  }
714  }
715  }
716  //multiple files
717  else
718  {
719  foreach (const QModelIndex &index, indexes)
720  {
721  const KUrl dest = fileModel()->getUrl(index);
722  const bool doDownload = index.data(Qt::CheckStateRole).toBool();
723  bt::TorrentFileInterface *file = m_files[dest];
724  file->setDoNotDownload(!doDownload);
725  }
726  }
727 
728 // setTransferChange(Tc_TotalSize | Tc_DownloadedSize | Tc_Percent, true);
729 }
730 
731 FileModel *BTTransfer::fileModel()//TODO correct file model for one-file-torrents
732 {
733  if (!m_fileModel)
734  {
735  if (!torrent)
736  {
737  return 0;
738  }
739 
740  //multiple files
741  if (torrent->getStats().multi_file_torrent)
742  {
743  for (bt::Uint32 i = 0; i < torrent->getNumFiles(); ++i)
744  {
745  bt::TorrentFileInterface *file = &torrent->getTorrentFile(i);
746  m_files[KUrl(file->getPathOnDisk())] = file;
747  }
748  m_fileModel = new FileModel(m_files.keys(), directory(), this);
749  // connect(m_fileModel, SIGNAL(rename(KUrl,KUrl)), this, SLOT(slotRename(KUrl,KUrl)));
750  connect(m_fileModel, SIGNAL(checkStateChanged()), this, SLOT(filesSelected()));
751 
752  //set the checkstate, the status and the size of the model items
753  QHash<KUrl, bt::TorrentFileInterface*>::const_iterator it;
754  QHash<KUrl, bt::TorrentFileInterface*>::const_iterator itEnd = m_files.constEnd();
755  const Job::Status curentStatus = this->status();
756  for (it = m_files.constBegin(); it != itEnd; ++it)
757  {
758  QModelIndex size = m_fileModel->index(it.key(), FileItem::Size);
759  m_fileModel->setData(size, static_cast<qlonglong>((*it)->getSize()));
760 
761  const bool doDownload = !(*it)->doNotDownload();
762  QModelIndex checkIndex = m_fileModel->index(it.key(), FileItem::File);
763  const Qt::CheckState checkState = doDownload ? Qt::Checked : Qt::Unchecked;
764  m_fileModel->setData(checkIndex, checkState, Qt::CheckStateRole);
765 
766  QModelIndex status = m_fileModel->index(it.key(), FileItem::Status);
767  if (doDownload && (curentStatus == Job::Running))
768  {
769  m_fileModel->setData(status, Job::Running);
770  }
771  else
772  {
773  m_fileModel->setData(status, Job::Stopped);
774  }
775  if (qFuzzyCompare((*it)->getDownloadPercentage(), 100.0f))
776  {
777  m_fileModel->setData(status, Job::Finished);
778  }
779  }
780  }
781  //one single file
782  else
783  {
784  QList<KUrl> urls;
785  KUrl temp = m_dest;
786  if (m_dest.fileName() != torrent->getStats().torrent_name)//TODO check if the body is ever entered!
787  {
788  temp.addPath(torrent->getStats().torrent_name);
789  }
790  const KUrl url = temp;
791  urls.append(url);
792 
793  m_fileModel = new FileModel(urls, directory(), this);
794  // connect(m_fileModel, SIGNAL(rename(KUrl,KUrl)), this, SLOT(slotRename(KUrl,KUrl)));
795  connect(m_fileModel, SIGNAL(checkStateChanged()), this, SLOT(filesSelected()));
796 
797  QModelIndex size = m_fileModel->index(url, FileItem::Size);
798  m_fileModel->setData(size, static_cast<qlonglong>(torrent->getStats().total_bytes));
799 
800  QModelIndex checkIndex = m_fileModel->index(url, FileItem::File);
801  m_fileModel->setData(checkIndex, Qt::Checked, Qt::CheckStateRole);
802 
803  QModelIndex status = m_fileModel->index(url, FileItem::Status);
804  if (this->status() == Job::Running)
805  {
806  m_fileModel->setData(status, Job::Running);
807  }
808  else
809  {
810  m_fileModel->setData(status, Job::Stopped);
811  }
812  if (!torrent->getStats().bytes_left_to_download)
813  {
814  m_fileModel->setData(status, Job::Finished);
815  }
816  }
817  }
818 
819  return m_fileModel;
820 }
821 
822 #include "bttransfer.moc"
QIODevice
QModelIndex
BTTransfer::trackersList
KUrl::List trackersList() const
Property-Functions.
Definition: bttransfer.cpp:503
FileItem::File
Definition: filemodel.h:45
BTTransfer::load
void load(const QDomElement *element)
Loads the transfer's info from the QDomElement.
Definition: bttransfer.cpp:210
BTTransfer::Tc_SeedsDisconnected
Definition: bttransfer.h:45
Transfer::ChangesFlags
int ChangesFlags
Definition: transfer.h:100
BTTransfer::remainingTime
virtual int remainingTime() const
Definition: bttransfer.cpp:602
Transfer::Tc_UploadSpeed
Definition: transfer.h:59
Transfer::Tc_FileName
Definition: transfer.h:52
Transfer::m_dest
KUrl m_dest
Definition: transfer.h:357
TransferGroup
class TransferGroup:
Definition: transfergroup.h:46
Scheduler
Scheduler class: what handle all the jobs in kget.
Definition: scheduler.h:32
Job::Finished
The job is stopped, but this also indicates that it stopped because an error occurred.
Definition: job.h:47
Download
Definition: download.h:23
BTTransfer::Tc_LeechesDisconnected
Definition: bttransfer.h:47
bttransferhandler.h
QHash::key
const Key key(const T &value) const
BTTransfer::Tc_TrackersList
Definition: bttransfer.h:50
Transfer::remainingTime
virtual int remainingTime() const
Definition: transfer.h:182
BTTransfer::isStalled
virtual bool isStalled() const
Reimplemented functions from Transfer-Class.
Definition: bttransfer.cpp:104
Transfer::m_downloadedSize
KIO::filesize_t m_downloadedSize
Definition: transfer.h:361
Job::Status
Status
The status property describes the current job status.
Definition: job.h:42
BTTransfer::seedsConnected
int seedsConnected() const
Definition: bttransfer.cpp:562
QByteArray
QFile::remove
bool remove()
Transfer::Cap_Renaming
Definition: transfer.h:75
BTTransfer::BTTransfer
BTTransfer(TransferGroup *parent, TransferFactory *factory, Scheduler *scheduler, const KUrl &src, const KUrl &dest, const QDomElement *e=0)
Definition: bttransfer.cpp:51
Job::FinishedKeepAlive
The job exited from its Running state successfully.
Definition: job.h:48
Transfer::Cap_Resuming
Definition: transfer.h:74
BTTransfer::files
virtual QList< KUrl > files() const
Definition: bttransfer.cpp:664
BTTransfer::setPort
void setPort(int port)
Public functions of BTTransfer.
Definition: bttransfer.cpp:231
Job::NotSolveable
Definition: job.h:71
Job
Definition: job.h:35
QDir::remove
bool remove(const QString &fileName)
BTTransfer::sessionBytesUploaded
int sessionBytesUploaded() const
Definition: bttransfer.cpp:522
download.h
Transfer::uploadLimit
int uploadLimit(SpeedLimit limit) const
Definition: transfer.cpp:168
BTTransfer::leechesConnected
int leechesConnected() const
Definition: bttransfer.cpp:578
BTTransfer::Tc_SeedsConnected
Definition: bttransfer.h:44
Transfer::percent
int percent() const
Definition: transfer.h:178
BTTransfer::deinit
void deinit(Transfer::DeleteOptions options)
Definition: bttransfer.cpp:76
BTTransfer::Tc_ChunksDownloaded
Definition: bttransfer.h:41
FileModel::fileIndexes
QModelIndexList fileIndexes(int column) const
Returns a list of pointers to all files of this model.
Definition: filemodel.cpp:475
QObject::disconnect
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
BTTransfer::setSpeedLimits
void setSpeedLimits(int ulLimit, int dlLimit)
Function used to set the SpeedLimits to the transfer.
Definition: bttransfer.cpp:238
BittorrentSettings::port
static int port()
Get Port.
Definition: bittorrentsettings.h:68
QFile
Transfer::downloadSpeed
int downloadSpeed() const
Definition: transfer.h:179
Transfer::m_totalSize
KIO::filesize_t m_totalSize
Definition: transfer.h:360
BTTransfer::isWorking
virtual bool isWorking() const
Definition: bttransfer.cpp:109
Transfer::Tc_Status
Definition: transfer.h:53
bttransfer.h
FileModel
This model represents the files that are being downloaded.
Definition: filemodel.h:101
BTTransfer::start
void start()
Definition: bttransfer.cpp:117
Transfer::m_downloadSpeed
int m_downloadSpeed
Definition: transfer.h:364
QList::append
void append(const T &value)
Job::Running
Definition: job.h:43
QDir::rmdir
bool rmdir(const QString &dirName) const
bittorrentsettings.h
Transfer::load
virtual void load(const QDomElement *element)
Loads the transfer's info from the QDomElement.
Definition: transfer.cpp:244
QHash::constEnd
const_iterator constEnd() const
QHash
BTTransfer::chunksTotal
int chunksTotal() const
Definition: bttransfer.cpp:530
Transfer::m_uploadSpeed
int m_uploadSpeed
Definition: transfer.h:365
BTTransfer
Definition: bttransfer.h:30
QDir::cd
bool cd(const QString &dirName)
QString::isEmpty
bool isEmpty() const
BTTransfer::Tc_LeechesConnected
Definition: bttransfer.h:46
BTTransfer::chunksExcluded
int chunksExcluded() const
Definition: bttransfer.cpp:546
BTTransfer::addTracker
void addTracker(const QString &url)
Definition: bttransfer.cpp:247
Transfer::DeleteTemporaryFiles
Definition: transfer.h:96
BTTransfer::Tc_ChunksExcluded
Definition: bttransfer.h:42
BTTransfer::leechesDisconnected
int leechesDisconnected() const
Definition: bttransfer.cpp:586
Transfer::Cap_Moving
Definition: transfer.h:76
QString
BTTransfer::torrentControl
bt::TorrentControl * torrentControl()
Definition: bttransfer.cpp:610
QList< KUrl >
Transfer::InvisibleSpeedLimit
Definition: transfer.h:91
BittorrentSettings::tmpDir
static QString tmpDir()
Get TmpDir.
Definition: bittorrentsettings.h:125
BTTransfer::seedsDisconnected
int seedsDisconnected() const
Definition: bttransfer.cpp:570
QDir::cdUp
bool cdUp()
QStringList
QHash::keys
QList< Key > keys() const
BTTransfer::setDirectory
virtual bool setDirectory(const KUrl &newDirectory)
Move the download to the new destination.
Definition: bttransfer.cpp:145
QFileInfo
BTTransfer::chunksDownloaded
int chunksDownloaded() const
Definition: bttransfer.cpp:538
QTimer::stop
void stop()
Transfer::Tc_DownloadSpeed
Definition: transfer.h:56
Transfer::setTransferChange
virtual void setTransferChange(ChangesFlags change, bool postEvent=false)
Makes the TransferHandler associated with this transfer know that a change in this transfer has occur...
Definition: transfer.cpp:338
BTTransfer::stop
void stop()
Definition: bttransfer.cpp:178
Job::Stopped
The job is being executed.
Definition: job.h:44
QDir
QHash::constBegin
const_iterator constBegin() const
BittorrentSettings::enableUTP
static bool enableUTP()
Get EnableUTP.
Definition: bittorrentsettings.h:87
Job::status
Status status() const
Definition: job.h:93
QModelIndex::data
QVariant data(int role) const
Transfer::handler
TransferHandler * handler()
Definition: transfer.cpp:217
BTTransfer::~BTTransfer
~BTTransfer()
Definition: bttransfer.cpp:68
Transfer::dest
const KUrl & dest() const
Definition: transfer.h:149
FileModel::setData
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole)
Definition: filemodel.cpp:390
BTTransfer::Tc_ChunksLeft
Definition: bttransfer.h:43
QDir::entryList
QStringList entryList(QFlags< QDir::Filter > filters, QFlags< QDir::SortFlag > sort) const
BTTransfer::ready
bool ready()
Definition: bttransfer.cpp:615
FileItem::Status
Definition: filemodel.h:46
kget.h
Transfer::Cap_SpeedLimit
Definition: transfer.h:72
Transfer::setStatus
void setStatus(Job::Status jobStatus, const QString &text=QString(), const QPixmap &pix=QPixmap())
Sets the Job status to jobStatus, the status text to text and the status pixmap to pix...
Definition: transfer.cpp:292
Transfer::Tc_TotalSize
Definition: transfer.h:54
QVariant::toBool
bool toBool() const
monitor.h
QTimer::start
void start(int msec)
Transfer::Tc_Percent
Definition: transfer.h:55
Transfer::Tc_DownloadedSize
Definition: transfer.h:63
BittorrentSettings::preAlloc
static bool preAlloc()
Get PreAlloc.
Definition: bittorrentsettings.h:144
Transfer::m_percent
int m_percent
Definition: transfer.h:363
Transfer::DeleteFiles
Definition: transfer.h:97
BTTransfer::chunksLeft
int chunksLeft() const
Definition: bttransfer.cpp:554
FileItem::Size
Definition: filemodel.h:47
FileModel::getUrl
KUrl getUrl(const QModelIndex &index)
The url on the filesystem (no check if the file exists yet!) of index, it can be a folder or file...
Definition: filemodel.cpp:544
BTTransfer::elapsedTime
virtual int elapsedTime() const
Definition: bttransfer.cpp:594
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
TransferFactory
TransferFactory.
Definition: transferfactory.h:52
BTTransfer::directory
virtual KUrl directory() const
Definition: bttransfer.h:71
Transfer::m_source
KUrl m_source
Definition: transfer.h:356
Transfer::setCapabilities
void setCapabilities(Capabilities capabilities)
Sets the capabilities and automatically emits capabilitiesChanged.
Definition: transfer.cpp:68
BTTransfer::sessionBytesDownloaded
int sessionBytesDownloaded() const
Definition: bttransfer.cpp:514
QDomElement
Job::setError
void setError(const QString &text, const QPixmap &pixmap, ErrorType type=AutomaticRetry, int errorId=-1)
Definition: job.cpp:65
Transfer::downloadLimit
int downloadLimit(SpeedLimit limit) const
Definition: transfer.cpp:176
QObject::destroyed
void destroyed(QObject *obj)
BTTransfer::fileModel
FileModel * fileModel()
Definition: bttransfer.cpp:731
BTTransferHandler
Definition: bttransferhandler.h:29
FileModel::index
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const
Definition: filemodel.cpp:436
filemodel.h
Transfer
Definition: transfer.h:36
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:28:43 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kget

Skip menu "kget"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdenetwork API Reference

Skip menu "kdenetwork API Reference"
  • kget
  • kopete
  •   kopete
  •   libkopete
  • krdc
  • krfb

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal