Remove "endl;" not necessary now
[kdenetwork.git] / kget / transfer-plugins / bittorrent / bttransfer.cpp
blobe9990abc78e18137dfcf0430ed3c4c9e91324335
1 /*
2 * Copyright (C) 2005 Felix Berger <felixberger@beldesign.de>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include "bttransfer.h"
21 #include "btthread.h"
23 #include <sigc++/bind.h>
24 #include <torrent/torrent.h>
25 #include <torrent/bencode.h>
26 #include <torrent/rate.h>
28 #include <kdebug.h>
29 #include <klocale.h>
30 #include <kiconloader.h>
32 #include <QDomElement>
33 #include <QFile>
35 BTTransfer::BTTransfer(TransferGroup* parent, TransferFactory* factory,
36 Scheduler* scheduler, const KUrl& src, const KUrl& dest,
37 const QDomElement * e)
38 : Transfer(parent, factory, scheduler, src, dest, e),
39 m_chunksTotal(0), m_chunksDownloaded(0),
40 m_peersConnected(0), m_peersNotConnected(0)
42 BTThread::initialize(); //check: is this thread active always?? :-O
43 kDebug(5001) << "new bt transfer";
45 //We already know that the file is local (the check is in the Factory)
46 QFile file(src.path());
47 kDebug(5001) << "Opening file: " << src.path();
49 if(file.open(QIODevice::ReadOnly))
51 kDebug(5001) << "***********Bittorrent file opened";
52 QByteArray data = file.readAll();
53 kDebug(5001) << "Stream of size: " << data.size();
54 kDebug(5001) << "Stream of data: " << endl << data.data();
55 bencodeStream.write(data.data(), data.size());
57 file.close();
59 else
61 kDebug(5001) << "***********Unable to open bittorrent file!";
62 kDebug(5001) << file.errorString();
65 connect(&timer, SIGNAL(timeout()), SLOT(update()));
68 BTTransfer::~BTTransfer()
70 BTThread::stop();
73 bool BTTransfer::isResumable() const
75 return true;
78 int BTTransfer::chunksTotal()
80 if (download.is_valid() && download.is_active())
81 return download.get_chunks_total();
82 else
83 return -1;
86 int BTTransfer::chunksDownloaded()
88 if (download.is_valid() && download.is_active())
89 return download.get_chunks_done();
90 else
91 return -1;
94 int BTTransfer::peersConnected()
96 if (download.is_valid() && download.is_active())
97 return download.get_peers_connected();
98 else
99 return -1;
103 int BTTransfer::peersNotConnected()
105 if (download.is_valid() && download.is_active())
106 return download.get_peers_not_connected();
107 else
108 return -1;
111 void BTTransfer::start()
113 startTime = QTime::currentTime();
114 setStatus(Job::Running, i18n("Analizing torrent.."), SmallIcon("xmag"));
115 setTransferChange(Tc_Status, true);
117 resume();
120 void BTTransfer::stop()
122 kDebug(5001) << endl << "bt stopped";
123 timer.stop();
124 if (download.is_valid())
126 download.stop();
127 // download.hash_save();
128 m_speed = 0;
129 setStatus(Job::Stopped, i18n("Stopped"), SmallIcon("process-stop"));
130 setTransferChange(Tc_Speed | Tc_Status, true);
132 startTime = QTime();
136 int BTTransfer::elapsedTime() const
138 return startTime.secsTo(QTime::currentTime());
141 int BTTransfer::remainingTime() const
143 // we should use the average rate here
144 int rate = speed();
145 return (rate <= 0) ? -1 :
146 (int)((totalSize() - processedSize()) / rate);
149 void BTTransfer::resume()
151 kDebug(5001) << endl << "resume dl";
152 if (!download.is_valid())
156 download = torrent::download_add(&bencodeStream);
157 // deallocate stream
158 bencodeStream.str(std::string());
159 // set directory
160 download.set_root_dir(std::string(qPrintable(dest().directory(false))));
162 if (download.get_entry_size() == 1)
164 //set filename too?
167 // trackerSucceeded = download.signal_tracker_succeded
168 // (sigc::bind(sigc::mem_fun(*this, &BTTransfer::trackerMessage),
169 // "succeeded"));
170 // trackerFailed = download.signal_tracker_failed
171 // (sigc::mem_fun(*this, &BTTransfer::trackerMessage));
173 downloadDone = download.signal_download_done
174 (sigc::mem_fun(*this, &BTTransfer::downloadFinished));
176 hashingDone = download.signal_hash_done
177 (sigc::mem_fun(*this, &BTTransfer::hashingFinished));
179 catch (std::exception& e)
181 // line below only compiles with exceptions activated
182 // kDebug(5001) << "exception " << e.what();
183 return;
185 kDebug(5001) << "still alive";
188 if(!download.is_active())
190 if (!download.is_open())
192 kDebug(5001) << endl << "second turn";
193 download.open();
195 if (!download.is_hash_checked())
197 download.hash_check(false);
198 return;
200 try
202 kDebug(5001) << endl << "third turn";
203 setStatus(status(), i18n("Connecting.."), SmallIcon("connect-creating"));
204 setTransferChange(Tc_Status, true);
206 download.start();
208 catch (std::exception& e)
210 // the line below only compiles with exceptions activated
211 // kDebug(5001) << "Resume exception " << e.what();
213 timer.start(1 * 1000);
214 return;
218 void BTTransfer::remove()
220 kDebug(5001) << endl << "bt removed";
221 timer.stop();
222 if (download.is_valid() && download.is_active())
224 download.stop();
225 download.close();
226 torrent::download_remove(download.get_hash());
230 void BTTransfer::trackerMessage(std::string msg)
232 kDebug(5001) << "trackerMessage";
233 kDebug(5001) << msg.c_str();
236 void BTTransfer::downloadFinished()
238 kDebug(5001) << "bt transfer done ";
239 setStatus(Job::Finished, i18n("Finished"), SmallIcon("ok"));
240 setTransferChange(Tc_Status, true);
243 void BTTransfer::hashingFinished()
245 kDebug(5001) << "hashing finished ";
247 setTransferChange(Tc_Status, true);
248 resume();
251 void BTTransfer::update()
253 kDebug(5001) << "update";
254 if (!download.is_valid() || !download.is_active())
256 kDebug(5001) << "timer running on invalid or inactive download";
257 timer.stop();
258 return;
261 // kDebug(5001) << "dl name " << download.get_name().c_str();
262 // kDebug(5001) << "processedSize " << download.get_bytes_done();
263 // kDebug(5001) << "rate down " << download.get_rate_down();
264 // kDebug(5001) << "rate up " << download.get_rate_up();
265 // kDebug(5001) << "bytes up " << download.get_bytes_up();
266 // kDebug(5001) << "bytes down " << download.get_bytes_down();
267 // kDebug(5001) << "chunk size " << download.get_chunks_size();
268 // kDebug(5001) << "chunks done " << download.get_chunks_done();
269 // kDebug(5001) << "chunks total " << download.get_chunks_total();
270 // kDebug(5001) << "peers conn " << download.get_peers_connected();
271 // kDebug(5001) << "handshakes " << torrent::get(torrent::HANDSHAKES_TOTAL);
273 BTThread::lock();
274 m_totalSize = download.get_bytes_total();
275 m_processedSize = download.get_bytes_done();
276 m_speed = download.get_read_rate().rate();
277 BTThread::unlock();
279 //Make sure we are really downloading the torrent before setting the status
280 //text to "Downloading.."
281 if( m_speed &&
282 (statusText() != i18n("Downloading..")) &&
283 (status() != Job::Finished) )
285 setStatus(status(), i18n("Downloading.."), SmallIcon("media-playback-start"));
286 setTransferChange(Tc_Status);
289 if (m_totalSize > 0)
291 m_percent = (int)((100.0 * m_processedSize) / m_totalSize);
292 setTransferChange(Tc_Percent);
295 if (m_chunksTotal != chunksTotal())
297 m_chunksTotal = chunksTotal();
298 setTransferChange(Tc_ChunksTotal);
301 if (m_chunksDownloaded != chunksDownloaded())
303 m_chunksDownloaded = chunksDownloaded();
304 setTransferChange(Tc_ChunksDownloaded);
307 if (m_peersConnected != peersConnected())
309 m_peersConnected = peersConnected();
310 setTransferChange(Tc_PeersConnected);
313 if (m_peersNotConnected != peersNotConnected())
315 m_peersNotConnected = peersNotConnected();
316 setTransferChange(Tc_PeersNotConnected);
319 setTransferChange(Tc_ProcessedSize | Tc_Speed | Tc_TotalSize, true);
322 void BTTransfer::save(QDomElement e) // krazy:exclude=passbyvalue
324 Transfer::save(e);
326 if (download.is_valid() && !download.is_active())
328 QDomDocument doc(e.ownerDocument());
329 QDomElement bencode(doc.createElement("bencode"));
330 e.appendChild(bencode);
331 std::stringstream s;
332 s << download.get_bencode();
333 bencode.appendChild(doc.createTextNode(s.str().c_str()));
337 void BTTransfer::load(const QDomElement &e)
339 if (!e.isNull())
341 Transfer::load(e);
343 QDomElement first(e.firstChild().toElement());
344 if (!first.isNull() && (first.tagName() == "bencode") )
346 bencodeStream << qPrintable(first.text());
351 #include "bttransfer.moc"