Browse Source

- rough port to libtorrent v0.14.0. This is probably buggy but it compiles without warnings

adaptive-webui-19844
Christophe Dumez 16 years ago
parent
commit
764b4e72ca
  1. 2
      INSTALL
  2. 6
      configure
  3. 6
      qcm/libtorrent-rasterbar.qcm
  4. BIN
      src/Icons/skin/connecting.png
  5. 22
      src/arborescence.h
  6. 406
      src/bittorrent.cpp
  7. 1
      src/bittorrent.h
  8. 120
      src/createtorrent_imp.cpp
  9. 13
      src/createtorrent_imp.h
  10. 128
      src/deleteThread.h
  11. 25
      src/downloadingTorrents.cpp
  12. 12
      src/eventmanager.cpp
  13. 1
      src/icons.qrc
  14. 4
      src/previewSelect.h
  15. 6
      src/properties_imp.cpp
  16. 12
      src/qtorrenthandle.cpp
  17. 8
      src/qtorrenthandle.h
  18. 6
      src/realprogressbarthread.cpp
  19. 2
      src/src.pro
  20. 91
      src/torrentAddition.h
  21. 2
      src/webui/scripts/client.js

2
INSTALL

@ -17,7 +17,7 @@ Dependencies: @@ -17,7 +17,7 @@ Dependencies:
- Qt >= 4.3.0 (libqt-devel, libqtgui, libqtcore, libqtnetwork, libqtxml)
Qt >= 4.4.0 is advised
- libtorrent-rasterbar by Arvid Norberg (>= v0.13.1 REQUIRED)
- libtorrent-rasterbar by Arvid Norberg (>= v0.14.0 REQUIRED)
-> http://www.qbittorrent.org/download.php (advised)
-> http://www.libtorrent.net
Be careful: another library (the one used by rTorrent) uses a similar name.

6
configure vendored

@ -376,13 +376,13 @@ class qc_libtorrent_rasterbar : public ConfObj @@ -376,13 +376,13 @@ class qc_libtorrent_rasterbar : public ConfObj
{
public:
qc_libtorrent_rasterbar(Conf *c) : ConfObj(c) {}
QString name() const { return "libtorrent-rasterbar >= 0.13"; }
QString name() const { return "libtorrent-rasterbar >= 0.14"; }
QString shortname() const { return "libtorrent-rasterbar"; }
bool exec(){
QString s;
s = conf->getenv("QC_WITH_LIBTORRENT_INC");
if(!s.isEmpty()) {
if(!conf->checkHeader(s, "libtorrent/lsd.hpp")) {
if(!conf->checkHeader(s, "libtorrent/magnet_uri.hpp")) {
return false;
}
}else{
@ -391,7 +391,7 @@ public: @@ -391,7 +391,7 @@ public:
sl << "/usr/local/include";
bool found = false;
foreach(s, sl){
if(conf->checkHeader(s, "libtorrent/lsd.hpp")){
if(conf->checkHeader(s, "libtorrent/magnet_uri.hpp")){
found = true;
break;
}

6
qcm/libtorrent-rasterbar.qcm

@ -10,13 +10,13 @@ class qc_libtorrent_rasterbar : public ConfObj @@ -10,13 +10,13 @@ class qc_libtorrent_rasterbar : public ConfObj
{
public:
qc_libtorrent_rasterbar(Conf *c) : ConfObj(c) {}
QString name() const { return "libtorrent-rasterbar >= 0.13"; }
QString name() const { return "libtorrent-rasterbar >= 0.14"; }
QString shortname() const { return "libtorrent-rasterbar"; }
bool exec(){
QString s;
s = conf->getenv("QC_WITH_LIBTORRENT_INC");
if(!s.isEmpty()) {
if(!conf->checkHeader(s, "libtorrent/lsd.hpp")) {
if(!conf->checkHeader(s, "libtorrent/magnet_uri.hpp")) {
return false;
}
}else{
@ -25,7 +25,7 @@ public: @@ -25,7 +25,7 @@ public:
sl << "/usr/local/include";
bool found = false;
foreach(s, sl){
if(conf->checkHeader(s, "libtorrent/lsd.hpp")){
if(conf->checkHeader(s, "libtorrent/magnet_uri.hpp")){
found = true;
break;
}

BIN
src/Icons/skin/connecting.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 576 B

22
src/arborescence.h

@ -172,27 +172,27 @@ class arborescence { @@ -172,27 +172,27 @@ class arborescence {
torrent_file *root;
public:
arborescence(torrent_info t) {
torrent_info::file_iterator fi = t.begin_files();
if(t.num_files() > 1) {
root = new torrent_file(0, misc::toQString(t.name()), true);
arborescence(boost::intrusive_ptr<torrent_info> t) {
torrent_info::file_iterator fi = t->begin_files();
if(t->num_files() > 1) {
root = new torrent_file(0, misc::toQString(t->name()), true);
} else {
// XXX: Will crash if there is no file in torrent
root = new torrent_file(0, misc::toQString(t.name()), false, fi->size, 0);
root = new torrent_file(0, misc::toQString(t->name()), false, fi->size, 0);
return;
}
int i = 0;
while(fi != t.end_files()) {
while(fi != t->end_files()) {
QString path = QDir::cleanPath(misc::toQString(fi->path.string()));
addFile(path, fi->size, i);
fi++;
++i;
}
qDebug("real size: %ld, tree size: %ld", (long)t.total_size(), (long)root->getSize());
Q_ASSERT(root->getSize() == t.total_size());
qDebug("real size: %ld, tree size: %ld", (long)t->total_size(), (long)root->getSize());
Q_ASSERT(root->getSize() == t->total_size());
}
arborescence(torrent_info t, std::vector<float> fp, int *prioritiesTab) {
arborescence(torrent_info const& t, std::vector<size_type> fp, int *prioritiesTab) {
torrent_info::file_iterator fi = t.begin_files();
if(t.num_files() > 1) {
qDebug("More than one file in the torrent, setting a folder as root");
@ -200,13 +200,13 @@ class arborescence { @@ -200,13 +200,13 @@ class arborescence {
} else {
// XXX: Will crash if there is no file in torrent
qDebug("one file in the torrent, setting it as root with index 0");
root = new torrent_file(0, misc::toQString(t.name()), false, fi->size, 0, fp[0], prioritiesTab[0]);
root = new torrent_file(0, misc::toQString(t.name()), false, fi->size, 0, fp[0]/t.file_at(0).size, prioritiesTab[0]);
return;
}
int i = 0;
while(fi != t.end_files()) {
QString path = QDir::cleanPath(misc::toQString(fi->path.string()));
addFile(path, fi->size, i, fp[i], prioritiesTab[i]);
addFile(path, fi->size, i, fp[i]/t.file_at(i).size, prioritiesTab[i]);
fi++;
++i;
}

406
src/bittorrent.cpp

@ -28,7 +28,6 @@ @@ -28,7 +28,6 @@
#include "bittorrent.h"
#include "misc.h"
#include "downloadThread.h"
#include "deleteThread.h"
#include "filterParserThread.h"
#include <libtorrent/extensions/metadata_transfer.hpp>
@ -55,7 +54,7 @@ bittorrent::bittorrent() : timerScan(0), DHTEnabled(false), preAllocateAll(false @@ -55,7 +54,7 @@ bittorrent::bittorrent() : timerScan(0), DHTEnabled(false), preAllocateAll(false
s = new session(fingerprint("qB", VERSION_MAJOR, VERSION_MINOR, VERSION_BUGFIX, 0));
}
// Set severity level of libtorrent session
s->set_severity_level(alert::info);
s->set_alert_mask(alert::error_notification|alert::peer_notification|alert::port_mapping_notification|alert::storage_notification|alert::tracker_notification|alert::status_notification|alert::ip_block_notification);
// Enabling metadata plugin
s->add_extension(&create_metadata_plugin);
timerAlerts = new QTimer();
@ -68,8 +67,6 @@ bittorrent::bittorrent() : timerScan(0), DHTEnabled(false), preAllocateAll(false @@ -68,8 +67,6 @@ bittorrent::bittorrent() : timerScan(0), DHTEnabled(false), preAllocateAll(false
downloader = new downloadThread(this);
connect(downloader, SIGNAL(downloadFinished(QString, QString)), this, SLOT(processDownloadedFile(QString, QString)));
connect(downloader, SIGNAL(downloadFailure(QString, QString)), this, SLOT(handleDownloadFailure(QString, QString)));
// File deleter (thread)
deleter = new deleteThread(this);
BigRatioTimer = 0;
filterParser = 0;
downloadQueue = 0;
@ -94,7 +91,6 @@ bittorrent::~bittorrent() { @@ -94,7 +91,6 @@ bittorrent::~bittorrent() {
// Disable directory scanning
disableDirectoryScanning();
// Delete our objects
delete deleter;
delete fastResumeSaver;
delete timerAlerts;
if(BigRatioTimer)
@ -123,16 +119,6 @@ void bittorrent::preAllocateAllFiles(bool b) { @@ -123,16 +119,6 @@ void bittorrent::preAllocateAllFiles(bool b) {
if(change) {
qDebug("PreAllocateAll changed, reloading all torrents!");
preAllocateAll = b;
// Reload All unfinished torrents
QString hash;
foreach(hash, unfinishedTorrents) {
QTorrentHandle h = getTorrentHandle(hash);
if(!h.is_valid()) {
qDebug("/!\\ Error: Invalid handle");
continue;
}
reloadTorrent(h, b);
}
}
}
@ -543,8 +529,7 @@ qlonglong bittorrent::getETA(QString hash) const { @@ -543,8 +529,7 @@ qlonglong bittorrent::getETA(QString hash) const {
QTorrentHandle h = getTorrentHandle(hash);
if(!h.is_valid()) return -1;
switch(h.state()) {
case torrent_status::downloading:
case torrent_status::connecting_to_tracker: {
case torrent_status::downloading: {
if(!TorrentsStartTime.contains(hash)) return -1;
int timeElapsed = TorrentsStartTime.value(hash).secsTo(QDateTime::currentDateTime());
double avg_speed;
@ -614,12 +599,11 @@ void bittorrent::deleteTorrent(QString hash, bool permanent) { @@ -614,12 +599,11 @@ void bittorrent::deleteTorrent(QString hash, bool permanent) {
}
QString savePath = h.save_path();
QString fileName = h.name();
arborescence *files_arb = 0;
if(permanent){
files_arb = new arborescence(h.get_torrent_info());
}
// Remove it from session
s->remove_torrent(h.get_torrent_handle());
if(permanent)
s->remove_torrent(h.get_torrent_handle(), session::delete_files);
else
s->remove_torrent(h.get_torrent_handle());
// Remove it from torrent backup directory
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
QStringList filters;
@ -666,12 +650,6 @@ void bittorrent::deleteTorrent(QString hash, bool permanent) { @@ -666,12 +650,6 @@ void bittorrent::deleteTorrent(QString hash, bool permanent) {
QFile::remove(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".prio");
if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".queued"))
QFile::remove(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".queued");
if(permanent && files_arb != 0) {
// Remove from Hard drive
qDebug("Removing this on hard drive: %s", qPrintable(savePath+QDir::separator()+fileName));
// Deleting in a thread to avoid GUI freeze
deleter->deleteTorrent(savePath, files_arb);
}
if(permanent)
addConsoleMessage(tr("'%1' was removed permanently.", "'xxx.avi' was removed permanently.").arg(fileName));
else
@ -894,7 +872,6 @@ void bittorrent::loadWebSeeds(QString hash) { @@ -894,7 +872,6 @@ void bittorrent::loadWebSeeds(QString hash) {
// Add a torrent to the bittorrent session
void bittorrent::addTorrent(QString path, bool fromScanDir, QString from_url, bool resumed) {
QTorrentHandle h;
entry resume_data;
bool fastResume=false;
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
QString file, dest_file, scan_dir;
@ -914,202 +891,163 @@ void bittorrent::addTorrent(QString path, bool fromScanDir, QString from_url, bo @@ -914,202 +891,163 @@ void bittorrent::addTorrent(QString path, bool fromScanDir, QString from_url, bo
}
Q_ASSERT(!file.startsWith("http://", Qt::CaseInsensitive) && !file.startsWith("https://", Qt::CaseInsensitive) && !file.startsWith("ftp://", Qt::CaseInsensitive));
qDebug("Adding %s to download list", file.toUtf8().data());
std::ifstream in(file.toUtf8().data(), std::ios_base::binary);
in.unsetf(std::ios_base::skipws);
try{
// Decode torrent file
entry e = bdecode(std::istream_iterator<char>(in), std::istream_iterator<char>());
// Getting torrent file informations
boost::intrusive_ptr<torrent_info> t(new torrent_info(e));
qDebug(" -> Hash: %s", misc::toString(t->info_hash()).c_str());
qDebug(" -> Name: %s", t->name().c_str());
QString hash = misc::toQString(t->info_hash());
if(file.startsWith(torrentBackup.path())) {
boost::intrusive_ptr<torrent_info> t;
try {
// Getting torrent file informations
t = new torrent_info(file.toUtf8().data());
} catch(std::exception&) {
if(!from_url.isNull()) {
addConsoleMessage(tr("Unable to decode torrent file: '%1'", "e.g: Unable to decode torrent file: '/home/y/xxx.torrent'").arg(from_url), QString::fromUtf8("red"));
//emit invalidTorrent(from_url);
QFile::remove(file);
}else{
addConsoleMessage(tr("Unable to decode torrent file: '%1'", "e.g: Unable to decode torrent file: '/home/y/xxx.torrent'").arg(file), QString::fromUtf8("red"));
//emit invalidTorrent(file);
}
addConsoleMessage(tr("This file is either corrupted or this isn't a torrent."),QString::fromUtf8("red"));
if(fromScanDir) {
// Remove .corrupt file in case it already exists
QFile::remove(file+".corrupt");
//Rename file extension so that it won't display error message more than once
QFile::rename(file,file+".corrupt");
}
}
qDebug(" -> Hash: %s", misc::toString(t->info_hash()).c_str());
qDebug(" -> Name: %s", t->name().c_str());
QString hash = misc::toQString(t->info_hash());
if(file.startsWith(torrentBackup.path())) {
QFileInfo fi(file);
QString old_hash = fi.baseName();
if(old_hash != hash){
qDebug("* ERROR: Strange, hash changed from %s to %s", old_hash.toUtf8().data(), hash.toUtf8().data());
qDebug("* ERROR: Strange, hash changed from %s to %s", old_hash.toUtf8().data(), hash.toUtf8().data());
}
}
if(s->find_torrent(t->info_hash()).is_valid()) {
}
// Check if torrent is already in download list
if(s->find_torrent(t->info_hash()).is_valid()) {
qDebug("/!\\ Torrent is already in download list");
// Update info Bar
if(!fromScanDir) {
if(!from_url.isNull()) {
// If download from url, remove temp file
QFile::remove(file);
addConsoleMessage(tr("'%1' is already in download list.", "e.g: 'xxx.avi' is already in download list.").arg(from_url));
//emit duplicateTorrent(from_url);
}else{
addConsoleMessage(tr("'%1' is already in download list.", "e.g: 'xxx.avi' is already in download list.").arg(file));
//emit duplicateTorrent(file);
}
if(!from_url.isNull()) {
// If download from url, remove temp file
QFile::remove(file);
addConsoleMessage(tr("'%1' is already in download list.", "e.g: 'xxx.avi' is already in download list.").arg(from_url));
//emit duplicateTorrent(from_url);
}else{
addConsoleMessage(tr("'%1' is already in download list.", "e.g: 'xxx.avi' is already in download list.").arg(file));
//emit duplicateTorrent(file);
}
}else{
// Delete torrent from scan dir
QFile::remove(file);
// Delete torrent from scan dir
QFile::remove(file);
}
return;
}
//Getting fast resume data if existing
if(torrentBackup.exists(hash+".fastresume")) {
try{
std::stringstream strStream;
strStream << hash.toStdString() << ".fastresume";
boost::filesystem::ifstream resume_file(fs::path(torrentBackup.path().toUtf8().data()) / strStream.str(), std::ios_base::binary);
resume_file.unsetf(std::ios_base::skipws);
resume_data = bdecode(std::istream_iterator<char>(resume_file), std::istream_iterator<char>());
fastResume=true;
}catch (invalid_encoding&) {}
catch (fs::filesystem_error&) {}
}
QString savePath = getSavePath(hash);
// Save save_path to hard drive
QFile savepath_file(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".savepath"));
if(!savepath_file.exists()) {
}
add_torrent_params p;
//Getting fast resume data if existing
std::vector<char> buf;
if (load_file((torrentBackup.path()+hash+QString(".fastresume")).toUtf8().data(), buf) == 0) {
fastResume = true;
p.resume_data = &buf;
}
QString savePath = getSavePath(hash);
// Save save_path to hard drive
QFile savepath_file(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".savepath"));
if(!savepath_file.exists()) {
savepath_file.open(QIODevice::WriteOnly | QIODevice::Text);
savepath_file.write(savePath.toUtf8());
savepath_file.close();
}
// Adding files to bittorrent session
if(preAllocateAll) {
h = s->add_torrent(t, fs::path(savePath.toUtf8().data()), resume_data, storage_mode_allocate, true);
qDebug(" -> Full allocation mode");
}else{
h = s->add_torrent(t, fs::path(savePath.toUtf8().data()), resume_data, storage_mode_sparse, true);
qDebug(" -> Sparse allocation mode");
}
if(!h.is_valid()) {
}
p.save_path = savePath.toUtf8().data();
p.ti = t;
// Preallocate all?
if(preAllocateAll)
p.storage_mode = storage_mode_allocate;
else
p.storage_mode = storage_mode_sparse;
// Start in pause
p.paused = true;
p.duplicate_is_error = false; // Already checked
p.auto_managed = true;
// Adding torrent to bittorrent session
h = s->add_torrent(p);
// Check if it worked
if(!h.is_valid()) {
// No need to keep on, it failed.
qDebug("/!\\ Error: Invalid handle");
// If download from url, remove temp file
if(!from_url.isNull()) QFile::remove(file);
return;
}
// Connections limit per torrent
h.set_max_connections(maxConnecsPerTorrent);
// Uploads limit per torrent
h.set_max_uploads(maxUploadsPerTorrent);
// Load filtered files
loadFilesPriorities(h);
// Load custom url seeds
loadWebSeeds(hash);
// Load speed limit from hard drive
loadTorrentSpeedLimits(hash);
// Load ratio data
loadDownloadUploadForTorrent(hash);
// Load trackers
bool loaded_trackers = loadTrackerFile(hash);
// Doing this to order trackers well
if(!loaded_trackers) {
}
// Connections limit per torrent
h.set_max_connections(maxConnecsPerTorrent);
// Uploads limit per torrent
h.set_max_uploads(maxUploadsPerTorrent);
// Load filtered files
loadFilesPriorities(h);
// Load custom url seeds
loadWebSeeds(hash);
// Load speed limit from hard drive
loadTorrentSpeedLimits(hash);
// Load ratio data
loadDownloadUploadForTorrent(hash);
// Load trackers
bool loaded_trackers = loadTrackerFile(hash);
// Doing this to order trackers well
if(!loaded_trackers) {
saveTrackerFile(hash);
loadTrackerFile(hash);
}
QString newFile = torrentBackup.path() + QDir::separator() + hash + ".torrent";
if(file != newFile) {
}
QString newFile = torrentBackup.path() + QDir::separator() + hash + ".torrent";
if(file != newFile) {
// Delete file from torrentBackup directory in case it exists because
// QFile::copy() do not overwrite
QFile::remove(newFile);
// Copy it to torrentBackup directory
QFile::copy(file, newFile);
}
// Incremental download
if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".incremental")) {
}
// Incremental download
if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".incremental")) {
qDebug("Incremental download enabled for %s", t->name().c_str());
h.set_sequenced_download_threshold(1);
}
if((resumed || !addInPause) && !QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".paused")) {
h.set_sequential_download(true);
}
if((resumed || !addInPause) && !QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".paused")) {
// Start torrent because it was added in paused state
h.resume();
}
if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".finished")) {
}
if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".finished")) {
finishedTorrents << hash;
if(!resumed && queueingEnabled) {
uploadQueue->append(hash);
saveTorrentPriority(hash, uploadQueue->size()-1);
updateUploadQueue();
uploadQueue->append(hash);
saveTorrentPriority(hash, uploadQueue->size()-1);
updateUploadQueue();
}
}else{
}else{
unfinishedTorrents << hash;
if(!resumed && queueingEnabled) {
downloadQueue->append(hash);
saveTorrentPriority(hash, downloadQueue->size()-1);
updateDownloadQueue();
downloadQueue->append(hash);
saveTorrentPriority(hash, downloadQueue->size()-1);
updateDownloadQueue();
}
}
// If download from url, remove temp file
if(!from_url.isNull()) QFile::remove(file);
// Delete from scan dir to avoid trying to download it again
if(fromScanDir) {
}
// If download from url, remove temp file
if(!from_url.isNull()) QFile::remove(file);
// Delete from scan dir to avoid trying to download it again
if(fromScanDir) {
QFile::remove(file);
}
// Send torrent addition signal
if(!from_url.isNull()) {
}
// Send torrent addition signal
if(!from_url.isNull()) {
emit addedTorrent(h);
if(fastResume)
addConsoleMessage(tr("'%1' resumed. (fast resume)", "'/home/y/xxx.torrent' was resumed. (fast resume)").arg(from_url));
addConsoleMessage(tr("'%1' resumed. (fast resume)", "'/home/y/xxx.torrent' was resumed. (fast resume)").arg(from_url));
else
addConsoleMessage(tr("'%1' added to download list.", "'/home/y/xxx.torrent' was added to download list.").arg(from_url));
}else{
addConsoleMessage(tr("'%1' added to download list.", "'/home/y/xxx.torrent' was added to download list.").arg(from_url));
}else{
emit addedTorrent(h);
if(fastResume)
addConsoleMessage(tr("'%1' resumed. (fast resume)", "'/home/y/xxx.torrent' was resumed. (fast resume)").arg(file));
addConsoleMessage(tr("'%1' resumed. (fast resume)", "'/home/y/xxx.torrent' was resumed. (fast resume)").arg(file));
else
addConsoleMessage(tr("'%1' added to download list.", "'/home/y/xxx.torrent' was added to download list.").arg(file));
}
}catch (invalid_encoding& e) { // Raised by bdecode()
std::cerr << "Could not decode file, reason: " << e.what() << '\n';
// Display warning to tell user we can't decode the torrent file
if(!from_url.isNull()) {
addConsoleMessage(tr("Unable to decode torrent file: '%1'", "e.g: Unable to decode torrent file: '/home/y/xxx.torrent'").arg(from_url), QString::fromUtf8("red"));
//emit invalidTorrent(from_url);
QFile::remove(file);
}else{
addConsoleMessage(tr("Unable to decode torrent file: '%1'", "e.g: Unable to decode torrent file: '/home/y/xxx.torrent'").arg(file), QString::fromUtf8("red"));
//emit invalidTorrent(file);
}
addConsoleMessage(tr("This file is either corrupted or this isn't a torrent."),QString::fromUtf8("red"));
if(fromScanDir) {
// Remove .corrupt file in case it already exists
QFile::remove(file+".corrupt");
//Rename file extension so that it won't display error message more than once
QFile::rename(file,file+".corrupt");
}
}
catch (invalid_torrent_file&) { // Raised by torrent_info constructor
// Display warning to tell user we can't decode the torrent file
if(!from_url.isNull()) {
addConsoleMessage(tr("Unable to decode torrent file: '%1'", "e.g: Unable to decode torrent file: '/home/y/xxx.torrent'").arg(from_url), QString::fromUtf8("red"));
//emit invalidTorrent(from_url);
qDebug("File path is: %s", file.toUtf8().data());
QFile::remove(file);
}else{
addConsoleMessage(tr("Unable to decode torrent file: '%1'", "e.g: Unable to decode torrent file: '/home/y/xxx.torrent'").arg(file), QString::fromUtf8("red"));
//emit invalidTorrent(file);
}
if(fromScanDir) {
// Remove .corrupt file in case it already exists
QFile::remove(file+".corrupt");
//Rename file extension so that it won't display error message more than once
QFile::rename(file,file+".corrupt");
}
}
catch (std::exception& e) {
std::cerr << "Could not decode file, reason: " << e.what() << '\n';
// Display warning to tell user we can't decode the torrent file
if(!from_url.isNull()) {
addConsoleMessage(tr("Unable to decode torrent file: '%1'", "e.g: Unable to decode torrent file: '/home/y/xxx.torrent'").arg(from_url), QString::fromUtf8("red"));
//emit invalidTorrent(from_url);
QFile::remove(file);
}else{
addConsoleMessage(tr("Unable to decode torrent file: '%1'", "e.g: Unable to decode torrent file: '/home/y/xxx.torrent'").arg(file), QString::fromUtf8("red"));
//emit invalidTorrent(file);
}
if(fromScanDir) {
// Remove .corrupt file in case it already exists
QFile::remove(file+".corrupt");
//Rename file extension so that it won't display error message more than once
QFile::rename(file,file+".corrupt");
}
addConsoleMessage(tr("'%1' added to download list.", "'/home/y/xxx.torrent' was added to download list.").arg(file));
}
}
@ -1502,11 +1440,7 @@ void bittorrent::saveFastResumeAndRatioData(QString hash) { @@ -1502,11 +1440,7 @@ void bittorrent::saveFastResumeAndRatioData(QString hash) {
// Remove old .fastresume data in case it exists
QFile::remove(torrentBackup.path()+QDir::separator()+hash + ".fastresume");
// Write fast resume data
entry resumeData = h.write_resume_data();
file = hash + ".fastresume";
boost::filesystem::ofstream out(fs::path(torrentBackup.path().toUtf8().data()) / file.toUtf8().data(), std::ios_base::binary);
out.unsetf(std::ios_base::skipws);
bencode(std::ostream_iterator<char>(out), resumeData);
h.save_resume_data();
}
// Save ratio data
saveDownloadUploadForTorrent(hash);
@ -1762,9 +1696,21 @@ void bittorrent::readAlerts() { @@ -1762,9 +1696,21 @@ void bittorrent::readAlerts() {
emit finishedTorrent(h);
}
}
else if (save_resume_data_alert* p = dynamic_cast<save_resume_data_alert*>(a.get())) {
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
QTorrentHandle h(p->handle);
QString file = torrentBackup.path()+QDir::separator()+h.hash()+".torrent";
TORRENT_ASSERT(p->resume_data);
if (p->resume_data)
{
boost::filesystem::ofstream out(fs::path(torrentBackup.path().toUtf8().data()) / file.toUtf8().data(), std::ios_base::binary);
out.unsetf(std::ios_base::skipws);
bencode(std::ostream_iterator<char>(out), *p->resume_data);
}
}
else if (file_error_alert* p = dynamic_cast<file_error_alert*>(a.get())) {
QTorrentHandle h(p->handle);
qDebug("File Error: %s", p->msg().c_str());
qDebug("File Error: %s", p->message().c_str());
if(h.is_valid())
emit fullDiskError(h);
}
@ -1773,7 +1719,7 @@ void bittorrent::readAlerts() { @@ -1773,7 +1719,7 @@ void bittorrent::readAlerts() {
addConsoleMessage(tr("Couldn't listen on any of the given ports."), QString::fromUtf8("red"));
//emit portListeningFailure();
}
else if (tracker_alert* p = dynamic_cast<tracker_alert*>(a.get())) {
else if (tracker_error_alert* p = dynamic_cast<tracker_error_alert*>(a.get())) {
// Level: fatal
QTorrentHandle h(p->handle);
if(h.is_valid()){
@ -1783,7 +1729,7 @@ void bittorrent::readAlerts() { @@ -1783,7 +1729,7 @@ void bittorrent::readAlerts() {
qDebug("Received a tracker error for %s", p->url.c_str());
QHash<QString, QString> errors = trackersErrors.value(hash, QHash<QString, QString>());
// p->url requires at least libtorrent v0.13.1
errors[misc::toQString(p->url)] = QString::fromUtf8(a->msg().c_str());
errors[misc::toQString(p->url)] = QString::fromUtf8(a->message().c_str());
trackersErrors[hash] = errors;
} else {
emit trackerAuthenticationRequired(h);
@ -1802,12 +1748,12 @@ void bittorrent::readAlerts() { @@ -1802,12 +1748,12 @@ void bittorrent::readAlerts() {
}
}
else if (portmap_error_alert* p = dynamic_cast<portmap_error_alert*>(a.get())) {
addConsoleMessage(tr("UPnP/NAT-PMP: Port mapping failure, message: %1").arg(QString(p->msg().c_str())), QColor("red"));
addConsoleMessage(tr("UPnP/NAT-PMP: Port mapping failure, message: %1").arg(QString(p->message().c_str())), QColor("red"));
//emit UPnPError(QString(p->msg().c_str()));
}
else if (portmap_alert* p = dynamic_cast<portmap_alert*>(a.get())) {
qDebug("UPnP Success, msg: %s", p->msg().c_str());
addConsoleMessage(tr("UPnP/NAT-PMP: Port mapping successful, message: %1").arg(QString(p->msg().c_str())), QColor("blue"));
qDebug("UPnP Success, msg: %s", p->message().c_str());
addConsoleMessage(tr("UPnP/NAT-PMP: Port mapping successful, message: %1").arg(QString(p->message().c_str())), QColor("blue"));
//emit UPnPSuccess(QString(p->msg().c_str()));
}
else if (peer_blocked_alert* p = dynamic_cast<peer_blocked_alert*>(a.get())) {
@ -1821,13 +1767,13 @@ void bittorrent::readAlerts() { @@ -1821,13 +1767,13 @@ void bittorrent::readAlerts() {
else if (fastresume_rejected_alert* p = dynamic_cast<fastresume_rejected_alert*>(a.get())) {
QTorrentHandle h(p->handle);
if(h.is_valid()){
qDebug("/!\\ Fast resume failed for %s, reason: %s", h.name().toUtf8().data(), p->msg().c_str());
qDebug("/!\\ Fast resume failed for %s, reason: %s", h.name().toUtf8().data(), p->message().c_str());
addConsoleMessage(tr("Fast resume data was rejected for torrent %1, checking again...").arg(h.name()), QString::fromUtf8("red"));
//emit fastResumeDataRejected(h.name());
}
}
else if (url_seed_alert* p = dynamic_cast<url_seed_alert*>(a.get())) {
addConsoleMessage(tr("Url seed lookup failed for url: %1, message: %2").arg(QString::fromUtf8(p->url.c_str())).arg(QString::fromUtf8(p->msg().c_str())), QString::fromUtf8("red"));
addConsoleMessage(tr("Url seed lookup failed for url: %1, message: %2").arg(QString::fromUtf8(p->url.c_str())).arg(QString::fromUtf8(p->message().c_str())), QString::fromUtf8("red"));
//emit urlSeedProblem(QString::fromUtf8(p->url.c_str()), QString::fromUtf8(p->msg().c_str()));
}
else if (torrent_checked_alert* p = dynamic_cast<torrent_checked_alert*>(a.get())) {
@ -1853,72 +1799,6 @@ QHash<QString, QString> bittorrent::getTrackersErrors(QString hash) const{ @@ -1853,72 +1799,6 @@ QHash<QString, QString> bittorrent::getTrackersErrors(QString hash) const{
return trackersErrors.value(hash, QHash<QString, QString>());
}
// Reload a torrent with full allocation mode
void bittorrent::reloadTorrent(const QTorrentHandle &h, bool full_alloc) {
qDebug("** Reloading a torrent");
if(!h.is_valid()) {
qDebug("/!\\ Error: Invalid handle");
return;
}
QDir torrentBackup(misc::qBittorrentPath() + "BT_backup");
fs::path saveDir = h.save_path_boost();
QString fileName = h.name();
QString hash = h.hash();
boost::intrusive_ptr<torrent_info> t(new torrent_info(h.get_torrent_info()));
qDebug("Reloading torrent: %s", fileName.toUtf8().data());
entry resumeData;
// Checking if torrentBackup Dir exists
// create it if it is not
if(! torrentBackup.exists()) {
torrentBackup.mkpath(torrentBackup.path());
}
// Extracting resume data
if (h.has_metadata()) {
// get fast resume data
resumeData = h.write_resume_data();
}
// Remove torrent
s->remove_torrent(h.get_torrent_handle());
// Add torrent again to session
unsigned int timeout = 0;
while(h.is_valid() && timeout < 6) {
qDebug("Waiting for the torrent to be removed...");
SleeperThread::msleep(1000);
++timeout;
}
QTorrentHandle new_h;
if(full_alloc) {
new_h = s->add_torrent(t, saveDir, resumeData, storage_mode_allocate);
qDebug("Using full allocation mode");
} else {
new_h = s->add_torrent(t, saveDir, resumeData, storage_mode_sparse);
qDebug("Using sparse mode");
}
// Connections limit per torrent
new_h.set_max_connections(maxConnecsPerTorrent);
// Uploads limit per torrent
new_h.set_max_uploads(maxUploadsPerTorrent);
// Load filtered Files
loadFilesPriorities(new_h);
// Load speed limit from hard drive
loadTorrentSpeedLimits(hash);
// Load custom url seeds
loadWebSeeds(hash);
// Load ratio data
loadDownloadUploadForTorrent(hash);
// Pause torrent if it was paused last time
if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".paused")) {
new_h.pause();
}
// Incremental download
if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".incremental")) {
qDebug("Incremental download enabled for %s", fileName.toUtf8().data());
new_h.set_sequenced_download_threshold(1);
}
}
int bittorrent::getListenPort() const{
return s->listen_port();
}

1
src/bittorrent.h

@ -180,7 +180,6 @@ class bittorrent : public QObject { @@ -180,7 +180,6 @@ class bittorrent : public QObject {
void enableNATPMP(bool b);
void enableLSD(bool b);
bool enableDHT(bool b);
void reloadTorrent(const QTorrentHandle &h, bool full_alloc);
void setTimerScanInterval(int secs);
void setMaxActiveDownloads(int val);
void setMaxActiveTorrents(int val);

120
src/createtorrent_imp.cpp

@ -26,6 +26,7 @@ @@ -26,6 +26,7 @@
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/bind.hpp>
#include <libtorrent/entry.hpp>
#include <libtorrent/bencode.hpp>
@ -34,6 +35,7 @@ @@ -34,6 +35,7 @@
#include <libtorrent/storage.hpp>
#include <libtorrent/hasher.hpp>
#include <libtorrent/file_pool.hpp>
#include <libtorrent/create_torrent.hpp>
#include "createtorrent_imp.h"
#include "misc.h"
@ -41,13 +43,23 @@ @@ -41,13 +43,23 @@
using namespace libtorrent;
using namespace boost::filesystem;
// do not include files and folders whose
// name starts with a .
bool file_filter(boost::filesystem::path const& filename)
{
if (filename.leaf()[0] == '.') return false;
std::cerr << filename << std::endl;
return true;
}
createtorrent::createtorrent(QWidget *parent): QDialog(parent){
setupUi(this);
setAttribute(Qt::WA_DeleteOnClose);
creatorThread = new torrentCreatorThread();
connect(creatorThread, SIGNAL(creationSuccess(QString, const char*, QString)), this, SLOT(handleCreationSuccess(QString, const char*, QString)));
creatorThread = new torrentCreatorThread(this);
connect(creatorThread, SIGNAL(creationSuccess(QString, const char*)), this, SLOT(handleCreationSuccess(QString, const char*)));
connect(creatorThread, SIGNAL(creationFailure(QString)), this, SLOT(handleCreationFailure(QString)));
connect(creatorThread, SIGNAL(updateProgress(int)), this, SLOT(updateProgressBar(int)));
path::default_name_check(no_check);
show();
}
@ -126,31 +138,6 @@ void createtorrent::on_addURLSeed_button_clicked(){ @@ -126,31 +138,6 @@ void createtorrent::on_addURLSeed_button_clicked(){
}
}
// Subfunction to add files to a torrent_info structure
// Written by Arvid Norberg (libtorrent Author)
void add_files(torrent_info& t, path const& p, path const& l){
using boost::filesystem::path;
using boost::filesystem::directory_iterator;
#if BOOST_VERSION < 103600
std::string const& leaf = l.leaf();
#else
std::string const& leaf = l.filename();
#endif
if (leaf == ".." || leaf == ".") return;
path f(p / l);
if (is_directory(f)) {
for (directory_iterator i(f), end; i != end; ++i)
#if BOOST_VERSION < 103600
add_files(t, p, l / i->leaf());
#else
add_files(t, p, l / i->filename());
#endif
} else {
qDebug("Adding %s", l.string().c_str());
t.add_file(l, file_size(f));
}
}
QStringList createtorrent::allItems(QListWidget *list){
QStringList res;
unsigned int nbItems = list->count();
@ -191,17 +178,25 @@ void createtorrent::handleCreationFailure(QString msg) { @@ -191,17 +178,25 @@ void createtorrent::handleCreationFailure(QString msg) {
hide();
}
void createtorrent::handleCreationSuccess(QString path, const char* branch_path, QString hash) {
if(checkStartSeeding->isChecked()) {
// Create save path file
QFile savepath_file(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".savepath"));
savepath_file.open(QIODevice::WriteOnly | QIODevice::Text);
savepath_file.write(branch_path);
savepath_file.close();
emit torrent_to_seed(path);
}
QMessageBox::information(0, tr("Torrent creation"), tr("Torrent was created successfully:")+" "+path);
hide();
void createtorrent::handleCreationSuccess(QString path, const char* branch_path) {
if(checkStartSeeding->isChecked()) {
// Create save path file
boost::intrusive_ptr<torrent_info> t;
try {
t = new torrent_info(path.toUtf8().data());
} catch(std::exception&) {
QMessageBox::critical(0, tr("Torrent creation"), tr("Created torrent file is invalid. It won't be added to download list."));
return;
}
QString hash = misc::toQString(t->info_hash());
QFile savepath_file(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".savepath"));
savepath_file.open(QIODevice::WriteOnly | QIODevice::Text);
savepath_file.write(branch_path);
savepath_file.close();
emit torrent_to_seed(path);
}
QMessageBox::information(0, tr("Torrent creation"), tr("Torrent was created successfully:")+" "+path);
hide();
}
void createtorrent::updateProgressBar(int progress) {
@ -224,58 +219,47 @@ void torrentCreatorThread::create(QString _input_path, QString _save_path, QStri @@ -224,58 +219,47 @@ void torrentCreatorThread::create(QString _input_path, QString _save_path, QStri
start();
}
void sendProgressUpdateSignal(int i, int num, QDialog *parent){
((createtorrent*)parent)->updateProgressBar((int)(i*100./(float)num));
}
void torrentCreatorThread::run() {
emit updateProgress(0);
char const* creator_str = "qBittorrent "VERSION;
try {
boost::intrusive_ptr<torrent_info> t(new torrent_info);
ofstream out(complete(path((const char*)save_path.toUtf8())), std::ios_base::binary);
// Adding files to the torrent
file_storage fs;
file_pool fp;
path full_path = complete(path(input_path.toUtf8().data()));
#if BOOST_VERSION < 103600
add_files(*t, full_path.branch_path(), full_path.leaf());
#else
add_files(*t, full_path.branch_path(), full_path.filename());
#endif
// Adding files to the torrent
add_files(fs, full_path, file_filter);
if(abort) return;
// Set piece size
t->set_piece_size(piece_size);
create_torrent t(fs, piece_size);
// Add url seeds
QString seed;
foreach(seed, url_seeds){
t->add_url_seed(seed.toUtf8().data());
t.add_url_seed(seed.toUtf8().data());
}
for(int i=0; i<trackers.size(); ++i){
t->add_tracker(trackers.at(i).toUtf8().data());
t.add_tracker(trackers.at(i).toUtf8().data());
}
if(abort) return;
// calculate the hash for all pieces
file_pool fp;
boost::scoped_ptr<storage_interface> st(default_storage_constructor(t, full_path.branch_path(), fp));
int num = t->num_pieces();
std::vector<char> buf(piece_size);
for (int i = 0; i < num; ++i) {
st->read(&buf[0], i, 0, t->piece_size(i));
hasher h(&buf[0], t->piece_size(i));
t->set_hash(i, h.final());
emit updateProgress((int)(i*100./(float)num));
if(abort) return;
}
set_piece_hashes(t, full_path.branch_path(), boost::bind(&sendProgressUpdateSignal, _1, t.num_pieces(), parent));
// Set qBittorrent as creator and add user comment to
// torrent_info structure
t->set_creator(creator_str);
t->set_comment((const char*)comment.toUtf8());
t.set_creator(creator_str);
t.set_comment((const char*)comment.toUtf8());
// Is private ?
if(is_private){
t->set_priv(true);
t.set_priv(true);
}
if(abort) return;
// create the torrent and print it to out
entry e = t->create_torrent();
libtorrent::bencode(std::ostream_iterator<char>(out), e);
out.flush();
ofstream out(complete(path((const char*)save_path.toUtf8())), std::ios_base::binary);
bencode(std::ostream_iterator<char>(out), t.generate());
emit updateProgress(100);
emit creationSuccess(save_path, full_path.branch_path().string().c_str(), misc::toQString(t->info_hash()));
emit creationSuccess(save_path, full_path.branch_path().string().c_str());
}
catch (std::exception& e){
emit creationFailure(QString::fromUtf8(e.what()));

13
src/createtorrent_imp.h

@ -37,9 +37,12 @@ class torrentCreatorThread : public QThread { @@ -37,9 +37,12 @@ class torrentCreatorThread : public QThread {
bool is_private;
int piece_size;
bool abort;
QDialog *parent;
public:
torrentCreatorThread() {}
torrentCreatorThread(QDialog *_parent) {
parent = _parent;
}
~torrentCreatorThread() {
abort = true;
wait();
@ -51,7 +54,7 @@ class torrentCreatorThread : public QThread { @@ -51,7 +54,7 @@ class torrentCreatorThread : public QThread {
signals:
void creationFailure(QString msg);
void creationSuccess(QString path, const char* branch_path, QString hash);
void creationSuccess(QString path, const char* branch_path);
void updateProgress(int progress);
};
@ -70,6 +73,9 @@ class createtorrent : public QDialog, private Ui::createTorrentDialog{ @@ -70,6 +73,9 @@ class createtorrent : public QDialog, private Ui::createTorrentDialog{
signals:
void torrent_to_seed(QString path);
public slots:
void updateProgressBar(int progress);
protected slots:
void on_createButton_clicked();
void on_addFile_button_clicked();
@ -79,8 +85,7 @@ class createtorrent : public QDialog, private Ui::createTorrentDialog{ @@ -79,8 +85,7 @@ class createtorrent : public QDialog, private Ui::createTorrentDialog{
void on_addURLSeed_button_clicked();
void on_removeURLSeed_button_clicked();
void handleCreationFailure(QString msg);
void handleCreationSuccess(QString path, const char* branch_path, QString hash);
void updateProgressBar(int progress);
void handleCreationSuccess(QString path, const char* branch_path);
};
#endif

128
src/deleteThread.h

@ -1,128 +0,0 @@ @@ -1,128 +0,0 @@
/*
* Bittorrent Client using Qt4 and libtorrent.
* Copyright (C) 2006 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contact : chris@qbittorrent.org
*/
#ifndef DELETETHREAD_H
#define DELETETHREAD_H
#include <QThread>
#include <QMutex>
#include <QWaitCondition>
#include <QMutexLocker>
#include <QPair>
#include "arborescence.h"
class subDeleteThread : public QThread {
Q_OBJECT
private:
QString save_path;
arborescence *arb;
public:
subDeleteThread(QObject *parent, QString saveDir, arborescence *_arb) : QThread(parent), save_path(saveDir) {
arb = _arb;
}
~subDeleteThread(){
wait();
qDebug("subDeleteThread successfuly deleted");
}
signals:
// For subthreads
void deletionSuccessST(subDeleteThread* st);
//void deletionFailureST(subDeleteThread* st);
protected:
void run(){
/*if(arb->removeFromFS(save_path))
emit deletionSuccessST(this);
else
emit deletionFailureST(this);*/
arb->removeFromFS(save_path);
delete arb;
emit deletionSuccessST(this);
}
};
class deleteThread : public QThread {
Q_OBJECT
private:
QList<QPair<QString, arborescence*> > torrents_list;
QMutex mutex;
QWaitCondition condition;
bool abort;
QList<subDeleteThread*> subThreads;
public:
deleteThread(QObject* parent) : QThread(parent), abort(false){}
~deleteThread(){
mutex.lock();
abort = true;
condition.wakeOne();
mutex.unlock();
qDeleteAll(subThreads);
wait();
}
void deleteTorrent(QString saveDir, arborescence *arb){
qDebug("deleteThread called");
QMutexLocker locker(&mutex);
torrents_list << QPair<QString, arborescence*>(saveDir, arb);
if(!isRunning()){
start();
}else{
condition.wakeOne();
}
}
protected:
void run(){
forever{
if(abort)
return;
mutex.lock();
if(!torrents_list.empty()){
QPair<QString, arborescence *> torrent = torrents_list.takeFirst();
mutex.unlock();
subDeleteThread *st = new subDeleteThread(0, torrent.first, torrent.second);
subThreads << st;
connect(st, SIGNAL(deletionSuccessST(subDeleteThread*)), this, SLOT(deleteSubThread(subDeleteThread*)));
//connect(st, SIGNAL(deletionFailureST(subDeleteThread*)), this, SLOT(deleteSubThread(subDeleteThread*)));
st->start();
}else{
condition.wait(&mutex);
mutex.unlock();
}
}
}
protected slots:
void deleteSubThread(subDeleteThread* st){
int index = subThreads.indexOf(st);
Q_ASSERT(index != -1);
subThreads.removeAt(index);
delete st;
}
};
#endif

25
src/downloadingTorrents.cpp

@ -529,31 +529,6 @@ void DownloadingTorrents::updateDlList() { @@ -529,31 +529,6 @@ void DownloadingTorrents::updateDlList() {
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
}
break;
case torrent_status::connecting_to_tracker:
if(h.download_payload_rate() > 0) {
// Display "Downloading" status when connecting if download speed > 0
if(!downloadList->isColumnHidden(ETA)) {
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)BTSession->getETA(hash)));
}
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/downloading.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("green"));
}else{
if(!downloadList->isColumnHidden(ETA)) {
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
}
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/connecting.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("grey"));
}
if(!downloadList->isColumnHidden(PROGRESS)) {
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
}
if(!downloadList->isColumnHidden(DLSPEED)) {
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)h.download_payload_rate()));
}
if(!downloadList->isColumnHidden(UPSPEED)) {
DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)h.upload_payload_rate()));
}
break;
case torrent_status::downloading:
case torrent_status::downloading_metadata:
if(h.download_payload_rate() > 0) {

12
src/eventmanager.cpp

@ -66,12 +66,6 @@ void EventManager::addedTorrent(QTorrentHandle& h) @@ -66,12 +66,6 @@ void EventManager::addedTorrent(QTorrentHandle& h)
case torrent_status::queued_for_checking:
event["state"] = QVariant("checking");
break;
case torrent_status::connecting_to_tracker:
if(h.download_payload_rate() > 0)
event["state"] = QVariant("downloading");
else
event["state"] = QVariant("connecting");
break;
case torrent_status::downloading:
case torrent_status::downloading_metadata:
if(h.download_payload_rate() > 0)
@ -113,12 +107,6 @@ void EventManager::modifiedTorrent(QTorrentHandle h) @@ -113,12 +107,6 @@ void EventManager::modifiedTorrent(QTorrentHandle h)
case torrent_status::queued_for_checking:
event["state"] = QVariant("checking");
break;
case torrent_status::connecting_to_tracker:
if(h.download_payload_rate() > 0)
event["state"] = QVariant("downloading");
else
event["state"] = QVariant("connecting");
break;
case torrent_status::downloading:
case torrent_status::downloading_metadata:
if(h.download_payload_rate() > 0)

1
src/icons.qrc

@ -76,7 +76,6 @@ @@ -76,7 +76,6 @@
<file>Icons/flags/united_kingdom.png</file>
<file>Icons/skin/add.png</file>
<file>Icons/skin/connected.png</file>
<file>Icons/skin/connecting.png</file>
<file>Icons/skin/decrease.png</file>
<file>Icons/skin/delete.png</file>
<file>Icons/skin/delete_all.png</file>

4
src/previewSelect.h

@ -90,7 +90,7 @@ class previewSelect: public QDialog, private Ui::preview { @@ -90,7 +90,7 @@ class previewSelect: public QDialog, private Ui::preview {
previewList->setItemDelegate(listDelegate);
previewList->header()->resizeSection(0, 200);
// Fill list in
std::vector<float> fp;
std::vector<size_type> fp;
h.file_progress(fp);
unsigned int nbFiles = h.num_files();
for(unsigned int i=0; i<nbFiles; ++i){
@ -101,7 +101,7 @@ class previewSelect: public QDialog, private Ui::preview { @@ -101,7 +101,7 @@ class previewSelect: public QDialog, private Ui::preview {
previewListModel->insertRow(row);
previewListModel->setData(previewListModel->index(row, NAME), QVariant(fileName));
previewListModel->setData(previewListModel->index(row, SIZE), QVariant((qlonglong)h.filesize_at(i)));
previewListModel->setData(previewListModel->index(row, PROGRESS), QVariant((double)fp[i]));
previewListModel->setData(previewListModel->index(row, PROGRESS), QVariant((double)fp[i]/h.filesize_at(i)));
indexes << i;
}
}

6
src/properties_imp.cpp

@ -102,7 +102,7 @@ properties::properties(QWidget *parent, bittorrent *BTSession, QTorrentHandle &h @@ -102,7 +102,7 @@ properties::properties(QWidget *parent, bittorrent *BTSession, QTorrentHandle &h
}
}
shareRatio->setText(QString(QByteArray::number(ratio, 'f', 1)));
std::vector<float> fp;
std::vector<size_type> fp;
h.file_progress(fp);
int *prioritiesTab = loadPiecesPriorities();
// List files in torrent
@ -669,11 +669,11 @@ void properties::on_incrementalDownload_stateChanged(int){ @@ -669,11 +669,11 @@ void properties::on_incrementalDownload_stateChanged(int){
QFile incremental_file(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".incremental"));
incremental_file.open(QIODevice::WriteOnly | QIODevice::Text);
incremental_file.close();
h.set_sequenced_download_threshold(1);
h.set_sequential_download(true);
}
}else{
QFile::remove(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".incremental");
h.set_sequenced_download_threshold(100); // Disabled
h.set_sequential_download(false);
}
}

12
src/qtorrenthandle.cpp

@ -64,7 +64,7 @@ float QTorrentHandle::progress() const { @@ -64,7 +64,7 @@ float QTorrentHandle::progress() const {
return progress;
}
const std::vector<bool>* QTorrentHandle::pieces() const {
bitfield QTorrentHandle::pieces() const {
Q_ASSERT(h.is_valid());
return h.status().pieces;
}
@ -185,9 +185,9 @@ bool QTorrentHandle::has_metadata() const { @@ -185,9 +185,9 @@ bool QTorrentHandle::has_metadata() const {
return h.has_metadata();
}
entry QTorrentHandle::write_resume_data() const {
void QTorrentHandle::save_resume_data() const {
Q_ASSERT(h.is_valid());
return h.write_resume_data();
return h.save_resume_data();
}
QString QTorrentHandle::file_at(unsigned int index) const {
@ -227,7 +227,7 @@ size_type QTorrentHandle::total_failed_bytes() const { @@ -227,7 +227,7 @@ size_type QTorrentHandle::total_failed_bytes() const {
return h.status().total_failed_bytes;
}
void QTorrentHandle::file_progress(std::vector<float>& fp) {
void QTorrentHandle::file_progress(std::vector<size_type>& fp) {
Q_ASSERT(h.is_valid());
return h.file_progress(fp);
}
@ -330,9 +330,9 @@ void QTorrentHandle::force_reannounce() { @@ -330,9 +330,9 @@ void QTorrentHandle::force_reannounce() {
h.force_reannounce();
}
void QTorrentHandle::set_sequenced_download_threshold(int val) {
void QTorrentHandle::set_sequential_download(bool b) {
Q_ASSERT(h.is_valid());
h.set_sequenced_download_threshold(val);
h.set_sequential_download(b);
}
void QTorrentHandle::set_tracker_login(QString username, QString password) {

8
src/qtorrenthandle.h

@ -54,7 +54,7 @@ class QTorrentHandle { @@ -54,7 +54,7 @@ class QTorrentHandle {
QString hash() const;
QString name() const;
float progress() const;
const std::vector<bool>* pieces() const;
bitfield pieces() const;
void get_download_queue(std::vector<partial_piece_info>& queue) const;
QString current_tracker() const;
bool is_valid() const;
@ -76,7 +76,7 @@ class QTorrentHandle { @@ -76,7 +76,7 @@ class QTorrentHandle {
int upload_limit() const;
int num_files() const;
bool has_metadata() const;
entry write_resume_data() const;
void save_resume_data() const;
QString file_at(unsigned int index) const;
size_type filesize_at(unsigned int index) const;
std::vector<announce_entry> const& trackers() const;
@ -84,7 +84,7 @@ class QTorrentHandle { @@ -84,7 +84,7 @@ class QTorrentHandle {
QString creator() const;
QString comment() const;
size_type total_failed_bytes() const;
void file_progress(std::vector<float>& fp);
void file_progress(std::vector<size_type>& fp);
size_type total_payload_download();
size_type total_payload_upload();
QStringList files_path() const;
@ -107,7 +107,7 @@ class QTorrentHandle { @@ -107,7 +107,7 @@ class QTorrentHandle {
void set_ratio(float ratio) const;
void replace_trackers(std::vector<announce_entry> const&) const;
void force_reannounce();
void set_sequenced_download_threshold(int val);
void set_sequential_download(bool);
void set_tracker_login(QString username, QString password);
//

6
src/realprogressbarthread.cpp

@ -65,9 +65,9 @@ void RealProgressBarThread::run(){ @@ -65,9 +65,9 @@ void RealProgressBarThread::run(){
size_type total_size = thandle.total_size();
size_type piece_length = thandle.piece_length();
int num_pieces = thandle.num_pieces();
const std::vector<bool>* pieces = thandle.pieces();
bitfield pieces = thandle.pieces();
//pieces not returned
if (pieces == 0)
if (pieces.empty())
{
qDebug("pieces vector not returned");
return;
@ -97,7 +97,7 @@ void RealProgressBarThread::run(){ @@ -97,7 +97,7 @@ void RealProgressBarThread::run(){
}
qreal start = i * fraction;
qreal end = start + fraction;
if((*pieces)[i])
if(pieces[i])
mark(start, end);
}
if (success)

2
src/src.pro

@ -146,7 +146,7 @@ HEADERS += GUI.h misc.h options_imp.h about_imp.h \ @@ -146,7 +146,7 @@ HEADERS += GUI.h misc.h options_imp.h about_imp.h \
PropListDelegate.h previewSelect.h \
PreviewListDelegate.h trackerLogin.h \
downloadThread.h downloadFromURLImp.h \
torrentAddition.h deleteThread.h \
torrentAddition.h \
bittorrent.h searchEngine.h \
rss.h rss_imp.h FinishedTorrents.h \
allocationDlg.h FinishedListDelegate.h \

91
src/torrentAddition.h

@ -95,26 +95,32 @@ class torrentAdditionDialog : public QDialog, private Ui_addTorrentDialog{ @@ -95,26 +95,32 @@ class torrentAdditionDialog : public QDialog, private Ui_addTorrentDialog{
}
void showLoad(QString filePath, bool fromScanDir=false, QString from_url=QString::null){
this->filePath = filePath;
this->fromScanDir = fromScanDir;
this->from_url = from_url;
std::ifstream in(filePath.toUtf8().data(), std::ios_base::binary);
in.unsetf(std::ios_base::skipws);
try{
// Decode torrent file
entry e = bdecode(std::istream_iterator<char>(in), std::istream_iterator<char>());
this->filePath = filePath;
this->fromScanDir = fromScanDir;
this->from_url = from_url;
// Getting torrent file informations
torrent_info t(e);
nbFiles = t.num_files();
boost::intrusive_ptr<torrent_info> t;
try {
t = new torrent_info(filePath.toUtf8().data());
} catch(std::exception&) {
if(!from_url.isNull()){
BTSession->addConsoleMessage(tr("Unable to decode torrent file:")+QString::fromUtf8(" '")+from_url+QString::fromUtf8("'"), QString::fromUtf8("red"));
QFile::remove(filePath);
}else{
BTSession->addConsoleMessage(tr("Unable to decode torrent file:")+QString::fromUtf8(" '")+filePath+QString::fromUtf8("'"), QString::fromUtf8("red"));
}
close();
}
nbFiles = t->num_files();
// Setting file name
fileName = misc::toQString(t.name());
hash = misc::toQString(t.info_hash());
fileName = misc::toQString(t->name());
hash = misc::toQString(t->info_hash());
// Use left() to remove .old extension
QString newFileName;
if(fileName.endsWith(QString::fromUtf8(".old"))){
newFileName = fileName.left(fileName.size()-4);
newFileName = fileName.left(fileName.size()-4);
}else{
newFileName = fileName;
newFileName = fileName;
}
fileNameLbl->setText(QString::fromUtf8("<center><b>")+newFileName+QString::fromUtf8("</b></center>"));
// List files in torrent
@ -123,62 +129,7 @@ class torrentAdditionDialog : public QDialog, private Ui_addTorrentDialog{ @@ -123,62 +129,7 @@ class torrentAdditionDialog : public QDialog, private Ui_addTorrentDialog{
delete arb;
connect(PropListModel, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(updatePriorities(QStandardItem*)));
torrentContentList->expandAll();
}
catch (invalid_torrent_file&){ // Raised by torrent_info constructor
// Display warning to tell user we can't decode the torrent file
if(!from_url.isNull()){
BTSession->addConsoleMessage(tr("Unable to decode torrent file:")+QString::fromUtf8(" '")+from_url+QString::fromUtf8("'"), QString::fromUtf8("red"));
QFile::remove(filePath);
}else{
BTSession->addConsoleMessage(tr("Unable to decode torrent file:")+QString::fromUtf8(" '")+filePath+QString::fromUtf8("'"), QString::fromUtf8("red"));
}
BTSession->addConsoleMessage(tr("This file is either corrupted or this isn't a torrent."), QString::fromUtf8("red"));
if(fromScanDir){
// Remove .corrupt file in case it already exists
QFile::remove(filePath+QString::fromUtf8(".corrupt"));
//Rename file extension so that it won't display error message more than once
QFile::rename(filePath,filePath+QString::fromUtf8(".corrupt"));
}
close();
}
catch(invalid_encoding& e){
std::cerr << "Could not decode file, reason: " << e.what() << '\n';
// Display warning to tell user we can't decode the torrent file
if(!from_url.isNull()){
BTSession->addConsoleMessage(tr("Unable to decode torrent file:")+QString::fromUtf8(" '")+from_url+QString::fromUtf8("'"), QString::fromUtf8("red"));
QFile::remove(filePath);
}else{
BTSession->addConsoleMessage(tr("Unable to decode torrent file:")+QString::fromUtf8(" '")+filePath+QString::fromUtf8("'"), QString::fromUtf8("red"));
}
qDebug("path is %s", filePath.toUtf8().data());
BTSession->addConsoleMessage(tr("This file is either corrupted or this isn't a torrent."), QString::fromUtf8("red"));
if(fromScanDir){
// Remove .corrupt file in case it already exists
QFile::remove(filePath+QString::fromUtf8(".corrupt"));
//Rename file extension so that it won't display error message more than once
QFile::rename(filePath,filePath+QString::fromUtf8(".corrupt"));
}
close();
}
catch(std::exception& e){
std::cerr << "Could not decode file, reason: " << e.what() << '\n';
if(!from_url.isNull()){
BTSession->addConsoleMessage(tr("Unable to decode torrent file:")+QString::fromUtf8(" '")+from_url+QString::fromUtf8("'"), QString::fromUtf8("red"));
QFile::remove(filePath);
}else{
BTSession->addConsoleMessage(tr("Unable to decode torrent file:")+QString::fromUtf8(" '")+filePath+QString::fromUtf8("'"), QString::fromUtf8("red"));
}
qDebug("path is %s", filePath.toUtf8().data());
BTSession->addConsoleMessage(tr("This file is either corrupted or this isn't a torrent."), QString::fromUtf8("red"));
if(fromScanDir){
// Remove .corrupt file in case it already exists
QFile::remove(filePath+QString::fromUtf8(".corrupt"));
//Rename file extension so that it won't display error message more than once
QFile::rename(filePath,filePath+QString::fromUtf8(".corrupt"));
}
close();
}
show();
show();
}
void addFilesToTree(torrent_file *root, QStandardItem *parent) {

2
src/webui/scripts/client.js

@ -44,8 +44,6 @@ window.addEvent('domready', function(){ @@ -44,8 +44,6 @@ window.addEvent('domready', function(){
return '<img src="images/time.png"/>';
case 'downloading':
return '<img src="images/skin/downloading.png"/>';
case 'connecting':
return '<img src="images/skin/connecting.png"/>';
case 'stalled':
return '<img src="images/skin/stalled.png"/>';
case 'queued':

Loading…
Cancel
Save