1 /* This file is part of the KDE project
3 Copyright (C) 2007 Lukas Appelhans <l.appelhans@gmx.de>
4 Copyright (C) 2007 Joris Guisson <joris.guisson@gmail.com>
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.
12 #include "bttransfer.h"
13 #include "bittorrentsettings.h"
15 #include "core/kget.h"
17 #include <torrent/torrent.h>
18 #include <peer/peermanager.h>
19 #include <util/error.h>
20 #include <torrent/globals.h>
21 #include <torrent/server.h>
22 #include <util/constants.h>
23 #include <util/functions.h>
25 #include <peer/authenticationmonitor.h>
26 #include <btdownload.h>
27 #include <btversion.h>
31 #include <KIconLoader>
32 #include <KStandardDirs>
34 #include <KMessageBox>
37 #include <QDomElement>
40 BTTransfer::BTTransfer(TransferGroup
* parent
, TransferFactory
* factory
,
41 Scheduler
* scheduler
, const KUrl
& src
, const KUrl
& dest
,
42 const QDomElement
* e
)
43 : Transfer(parent
, factory
, scheduler
, src
, dest
, e
),
46 m_dlLimit(BittorrentSettings::downloadLimit()),
47 m_ulLimit(BittorrentSettings::uploadLimit()),
48 m_ratio(BittorrentSettings::maxShareRatio()),
52 if (m_source
.url().isEmpty())
59 BTTransfer::~BTTransfer()
66 /**Reimplemented functions from Transfer-Class (transfer.cpp)**/
67 bool BTTransfer::isResumable() const
73 void BTTransfer::start()
78 if (!m_source
.isLocalFile())
80 kDebug(5001) << m_dest
.path();
81 BTDownload
*download
= new BTDownload(m_source
);
83 setStatus(Job::Stopped
, i18n("Downloading Torrent-File.."), SmallIcon("document-save"));
84 setTransferChange(Tc_Status
, true);
86 m_source
= KStandardDirs::locateLocal("appdata", "tmp/") + m_source
.fileName();
87 connect(download
, SIGNAL(finishedSuccessfully(KUrl
)), SLOT(init(KUrl
)));
96 void BTTransfer::stop()
105 void BTTransfer::update()
112 if (torrent
->hasMissingFiles(files
))
114 kDebug(5001) << "Recreate Missing Files";
115 torrent
->recreateMissingFiles();
123 void BTTransfer::load(const QDomElement
&e
)
126 m_source
= KUrl(e
.attribute("Source"));
127 m_dest
= KUrl(e
.attribute("Dest"));
129 m_totalSize
= e
.attribute("TotalSize").toULongLong();
130 m_processedSize
= e
.attribute("ProcessedSize").toULongLong();
132 if( m_totalSize
!= 0)
133 m_percent
= (int)((100.0 * m_processedSize
) / m_totalSize
);
137 m_ulLimit
= e
.attribute("Upload-Limit").toInt();
138 m_dlLimit
= e
.attribute("Download-Limit").toInt();
140 if((m_totalSize
== m_processedSize
) && (m_totalSize
!= 0))
142 setStatus(Job::Finished
, i18n("Finished"), SmallIcon("dialog-ok"));
143 // "ok" icon should probably be "dialog-success", but we don't have that icon in KDE 4.0
147 setStatus(status(), i18n("Stopped"), SmallIcon("process-stop"));
151 void BTTransfer::save(const QDomElement
&element
)
155 QDomElement e
= element
;
159 e
.setAttribute("Upload-Limit", ulLimit());
160 e
.setAttribute("Download-Limit", dlLimit());
163 /**Public functions of BTTransfer**/
165 void BTTransfer::setPort(int port
)
168 bt::Globals::instance().getServer().changePort(port
);
171 void BTTransfer::setTrafficLimits(int ulLimit
, int dlLimit
)
177 torrent
->setTrafficLimits(ulLimit
* 1000, dlLimit
* 1000);
182 void BTTransfer::setMaxShareRatio(float ratio
)
184 if (m_ratio
!= ratio
)
188 torrent
->setMaxShareRatio(m_ratio
);
191 void BTTransfer::addTracker(QString url
)
194 if(torrent
->getStats().priv_torrent
)
196 KMessageBox::sorry(0, i18n("Cannot add a tracker to a private torrent."));
200 if(!KUrl(url
).isValid())
202 KMessageBox::error(0, i18n("Malformed URL."));
206 torrent
->getTrackersList()->addTracker(url
,true);
209 /**Private functions**/
211 void BTTransfer::startTorrent()
215 kDebug(5001) << "Going to download that stuff :-0";
216 setTrafficLimits(m_ulLimit
, m_dlLimit
);//Set traffic-limits before starting
217 kDebug(5001) << "Here we are";
219 kDebug(5001) << "Got started??";
221 setStatus(Job::Running
, i18n("Downloading.."), SmallIcon("media-playback-start"));
222 kDebug(5001) << "Jepp, it does";
223 m_totalSize
= totalSize();
224 setTransferChange(Tc_Status
| Tc_TrackersList
| Tc_TotalSize
, true);
225 kDebug(5001) << "Completely";
229 void BTTransfer::stopTorrent()
234 setStatus(Job::Stopped
, i18n("Stopped"), SmallIcon("process-stop"));
235 setTransferChange(Tc_Status
, true);
238 void BTTransfer::updateTorrent()
240 kDebug(5001) << "Update torrent";
241 bt::UpdateCurrentTime();
242 bt::AuthenticationMonitor::instance().update();
243 kDebug(5001) << "Ignore this ;)";
245 kDebug(5001) << "Done";
247 m_percent
= percent();
248 m_processedSize
= processedSize();
250 setTransferChange(Tc_ProcessedSize
| Tc_Speed
| Tc_Percent
, true);
253 void BTTransfer::init(KUrl src
)
256 if (src
!= m_source
&& !src
.isEmpty())
259 setStatus(Job::Running
, i18n("Analizing 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
260 setTransferChange(Tc_Status
, true);
262 bt::InitLog(KStandardDirs::locateLocal("appdata", "torrentlog.log"));//initialize the torrent-log
264 bt::SetClientInfo("KGet",2,0,0,bt::NORMAL
,"KG");//Set client info to KGet, WARNING: Pls change this for every release
269 kDebug(5001) << "Trying to set port to" << BittorrentSettings::port() + i
;
270 bt::Globals::instance().initServer(BittorrentSettings::port() + i
);
272 }while (!bt::Globals::instance().getServer().isOK() && i
< 10);
274 if (!bt::Globals::instance().getServer().isOK())
279 torrent
= new bt::TorrentControl();
281 if (!BittorrentSettings::tmpDir().isEmpty())
283 m_tmp
= BittorrentSettings::tmpDir();
284 kDebug(5001) << "Trying to set" << m_tmp
<< " as tmpDir";
285 if (!QFileInfo(m_tmp
).isDir())
286 m_tmp
= KStandardDirs::locateLocal("appdata", "tmp/");
289 m_tmp
= KStandardDirs::locateLocal("appdata", "tmp/");
293 torrent
->init(0, m_source
.url().remove("file://"), m_tmp
+ m_source
.fileName().remove(".torrent"),
294 m_dest
.directory().remove("file://"), 0);
296 if (torrent
->getStats().multi_file_torrent
)
297 m_dest
= torrent
->getStats().output_path
;
299 m_dest
= torrent
->getDataDir() + torrent
->getStats().torrent_name
;
301 torrent
->createFiles();
303 torrent
->setPreallocateDiskSpace(BittorrentSettings::preAlloc());
305 setMaxShareRatio(m_ratio
);
306 setTrafficLimits(m_ulLimit
, m_dlLimit
);
308 connect(torrent
, SIGNAL(stoppedByError(bt::TorrentInterface
*, QString
)), SLOT(slotStoppedByError(bt::TorrentInterface
*, QString
)));
309 connect(torrent
, SIGNAL(finished(bt::TorrentInterface
*)), this, SLOT(slotDownloadFinished(bt::TorrentInterface
* )));
310 //FIXME connect(tc,SIGNAL(corruptedDataFound( bt::TorrentInterface* )), this, SLOT(emitCorruptedData( bt::TorrentInterface* )));
312 catch (bt::Error
&err
)
314 kDebug(5001) << err
.toString();
318 connect(&timer
, SIGNAL(timeout()), SLOT(update()));
321 void BTTransfer::slotStoppedByError(bt::TorrentInterface
* error
, QString errormsg
)
323 kDebug(5001) << errormsg
;
326 void BTTransfer::slotDownloadFinished(bt::TorrentInterface
* ti
)
330 setStatus(Job::Finished
, i18n("Finished"), SmallIcon("dialog-ok"));
331 setTransferChange(Tc_Status
, true);
334 /**Property-Functions**/
335 KUrl::List
BTTransfer::trackersList() const
341 const KUrl::List trackers
= torrent
->getTrackersList()->getTrackerURLs();
345 int BTTransfer::dlRate() const
351 return torrent
->getStats().download_rate
;
354 int BTTransfer::ulRate() const
360 return torrent
->getStats().upload_rate
;
363 float BTTransfer::totalSize() const
369 return torrent
->getStats().total_bytes_to_download
;
372 float BTTransfer::processedSize() const
378 return torrent
->getStats().bytes_downloaded
;
381 int BTTransfer::sessionBytesDownloaded() const
387 return torrent
->getStats().session_bytes_downloaded
;
390 int BTTransfer::sessionBytesUploaded() const
396 return torrent
->getStats().session_bytes_uploaded
;
399 int BTTransfer::chunksTotal() const
405 return torrent
->getTorrent().getNumChunks();
408 int BTTransfer::chunksDownloaded() const
414 return torrent
->downloadedChunksBitSet().numOnBits();
417 int BTTransfer::chunksExcluded() const
423 return torrent
->excludedChunksBitSet().numOnBits();
426 int BTTransfer::chunksLeft() const
432 return chunksTotal() - chunksDownloaded();
435 int BTTransfer::seedsConnected() const
441 return torrent
->getStats().seeders_connected_to
;
444 int BTTransfer::seedsDisconnected() const
450 return torrent
->getStats().seeders_total
;
453 int BTTransfer::leechesConnected() const
459 return torrent
->getStats().leechers_connected_to
;
462 int BTTransfer::leechesDisconnected() const
468 return torrent
->getStats().leechers_total
;
471 int BTTransfer::elapsedTime() const
477 return torrent
->getRunningTimeDL();
480 int BTTransfer::remainingTime() const
486 return torrent
->getETA();
489 int BTTransfer::ulLimit() const
498 int BTTransfer::dlLimit() const
507 bt::TorrentControl
* BTTransfer::torrentControl()
513 int BTTransfer::percent() const
519 return ((float) chunksDownloaded() / (float) chunksTotal()) * 100;
522 bool BTTransfer::ready()
528 #include "bttransfer.moc"