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()),
51 if (m_source
.url().isEmpty())
54 if (!m_source
.isLocalFile())
56 kDebug(5001) << m_dest
.path();
57 BTDownload
*download
= new BTDownload(m_source
);
59 setStatus(Job::Stopped
, i18n("Downloading Torrent-File.."), SmallIcon("document-save"));
60 setTransferChange(Tc_Status
, true);
62 m_source
= KStandardDirs::locateLocal("appdata", "tmp/") + m_source
.fileName();
63 connect(download
, SIGNAL(finishedSuccessfully(KUrl
)), SLOT(init(KUrl
)));
69 void BTTransfer::init(KUrl src
)
72 if (src
!= m_source
&& !src
.isEmpty())
75 setStatus(Job::Stopped
, i18n("Stopped"), SmallIcon("process-stop"));
76 setTransferChange(Tc_Status
, true);
78 bt::InitLog(KStandardDirs::locateLocal("appdata", "torrentlog.log"));//initialize the torrent-log
80 bt::SetClientInfo("KGet",2,0,1,bt::RELEASE_CANDIDATE
,"KG");
85 kDebug(5001) << "Trying to set port to" << BittorrentSettings::port() + i
;
86 bt::Globals::instance().initServer(BittorrentSettings::port() + i
);
88 }while (!bt::Globals::instance().getServer().isOK() && i
< 10);
90 if (!bt::Globals::instance().getServer().isOK())
95 torrent
= new bt::TorrentControl();
97 if (!BittorrentSettings::tmpDir().isEmpty())
99 m_tmp
= BittorrentSettings::tmpDir();
100 kDebug(5001) << "Trying to set" << m_tmp
<< " as tmpDir";
101 if (!QFileInfo(m_tmp
).isDir())
102 m_tmp
= KStandardDirs::locateLocal("appdata", "tmp/");
105 m_tmp
= KStandardDirs::locateLocal("appdata", "tmp/");
109 torrent
->init(0, m_source
.url().remove("file://"), m_tmp
+ m_source
.fileName().remove(".torrent"),
110 m_dest
.directory().remove("file://"), 0);
112 if (torrent
->getStats().multi_file_torrent
)
113 m_dest
= torrent
->getStats().output_path
;
115 m_dest
= torrent
->getDataDir() + torrent
->getStats().torrent_name
;
117 torrent
->createFiles();
119 torrent
->setPreallocateDiskSpace(BittorrentSettings::preAlloc());
120 //torrent->setMaxShareRatio(1); //TODO: Make configurable...
121 kDebug(5001) << "Source:" << m_source
.url();
122 kDebug(5001) << "Dest:" << m_dest
.url();
123 kDebug(5001) << "Temp:" << m_tmp
;
125 connect(torrent
, SIGNAL(stoppedByError(bt::TorrentInterface
*, QString
)), SLOT(slotStoppedByError(bt::TorrentInterface
*, QString
)));
126 connect(torrent
, SIGNAL(finished(bt::TorrentInterface
*)), this, SLOT(slotDownloadFinished(bt::TorrentInterface
* )));
127 //FIXME connect(tc,SIGNAL(corruptedDataFound( bt::TorrentInterface* )), this, SLOT(emitCorruptedData( bt::TorrentInterface* )));
129 catch (bt::Error
&err
)
131 kDebug(5001) << err
.toString();
133 connect(&timer
, SIGNAL(timeout()), SLOT(update()));
136 BTTransfer::~BTTransfer()
143 bool BTTransfer::isResumable() const
149 void BTTransfer::start()
155 kDebug(5001) << "Going to download that stuff :-0";
156 kDebug(5001) << "Here we are";
158 kDebug(5001) << "Got started??";
160 setStatus(Job::Running
, i18n("Downloading.."), SmallIcon("media-playback-start"));
161 kDebug(5001) << "Jepp, it does";
162 m_totalSize
= totalSize();
163 setTransferChange(Tc_Status
| Tc_TrackersList
| Tc_TotalSize
, true);
164 kDebug(5001) << "Completely";
165 setTrafficLimits(m_ulLimit
, m_dlLimit
);
169 void BTTransfer::stop()
177 setStatus(Job::Stopped
, i18n("Stopped"), SmallIcon("process-stop"));
178 setTransferChange(Tc_Status
, true);
182 void BTTransfer::update()
189 if (torrent
->hasMissingFiles(files
))
191 kDebug(5001) << "Recreate Missing Files";
192 torrent
->recreateMissingFiles();
195 kDebug(5001) << "Update torrent";
196 bt::UpdateCurrentTime();
197 bt::AuthenticationMonitor::instance().update();
198 kDebug(5001) << "Ignore this ;)";
200 kDebug(5001) << "Done";
202 m_percent
= percent();
204 setTransferChange(Tc_ProcessedSize
| Tc_Speed
| Tc_Percent
, true);
210 void BTTransfer::save(const QDomElement
&element
)
214 void BTTransfer::load(const QDomElement
&e
)
218 void BTTransfer::slotStoppedByError(bt::TorrentInterface
* error
, QString errormsg
)
220 kDebug(5001) << errormsg
;
223 void BTTransfer::setPort(int port
)
226 bt::Globals::instance().getServer().changePort(port
);
229 void BTTransfer::slotDownloadFinished(bt::TorrentInterface
* ti
)
233 setStatus(Job::Finished
, i18n("Finished"), SmallIcon("ok"));
234 setTransferChange(Tc_Status
, true);
237 void BTTransfer::setTrafficLimits(int ulLimit
, int dlLimit
)
243 torrent
->setTrafficLimits(ulLimit
* 1000, dlLimit
* 1000);
248 void BTTransfer::addTracker(QString url
)
250 kDebug(5001) << "YOU TOOOOOOOOOOOOOOOOOOOOOOOOO" << url
;
251 if(torrent
->getStats().priv_torrent
)
253 KMessageBox::sorry(0, i18n("Cannot add a tracker to a private torrent."));
257 if(!KUrl(url
).isValid())
259 KMessageBox::error(0, i18n("Malformed URL."));
263 torrent
->getTrackersList()->addTracker(url
,true);
266 /**Property-Functions**/
267 KUrl::List
BTTransfer::trackersList() const
273 const KUrl::List trackers
= torrent
->getTrackersList()->getTrackerURLs();
277 int BTTransfer::dlRate() const
283 return torrent
->getStats().download_rate
;
286 int BTTransfer::ulRate() const
292 return torrent
->getStats().upload_rate
;
295 int BTTransfer::totalSize() const
301 return torrent
->getStats().total_bytes_to_download
;
304 int BTTransfer::sessionBytesDownloaded() const
310 return torrent
->getStats().session_bytes_downloaded
;
313 int BTTransfer::sessionBytesUploaded() const
319 return torrent
->getStats().session_bytes_uploaded
;
322 int BTTransfer::chunksTotal() const
328 return torrent
->getTorrent().getNumChunks();
331 int BTTransfer::chunksDownloaded() const
337 return torrent
->downloadedChunksBitSet().numOnBits();
340 int BTTransfer::chunksExcluded() const
346 return torrent
->excludedChunksBitSet().numOnBits();
349 int BTTransfer::chunksLeft() const
355 return chunksTotal() - chunksDownloaded();
358 int BTTransfer::seedsConnected() const
364 return torrent
->getStats().seeders_connected_to
;
367 int BTTransfer::seedsDisconnected() const
373 return torrent
->getStats().seeders_total
;
376 int BTTransfer::leechesConnected() const
382 return torrent
->getStats().leechers_connected_to
;
385 int BTTransfer::leechesDisconnected() const
391 return torrent
->getStats().leechers_total
;
394 int BTTransfer::elapsedTime() const
400 return torrent
->getRunningTimeDL();
403 int BTTransfer::remainingTime() const
409 return torrent
->getETA();
412 int BTTransfer::ulLimit() const
421 int BTTransfer::dlLimit() const
430 bt::TorrentControl
* BTTransfer::torrentControl()
436 int BTTransfer::percent() const
442 return ((float) chunksDownloaded() / (float) chunksTotal()) * 100;
445 bool BTTransfer::ready()
451 #include "bttransfer.moc"