From 0e4ef42ddf147f369ceed25bf8a82d353bb1d396 Mon Sep 17 00:00:00 2001 From: "Vladimir Golovnev (Glassez)" Date: Wed, 25 Feb 2015 12:48:40 +0300 Subject: [PATCH] Fix indentation size in qtlibtorrent/* files. --- src/core/qtlibtorrent/alertdispatcher.cpp | 114 +- src/core/qtlibtorrent/alertdispatcher.h | 38 +- src/core/qtlibtorrent/bandwidthscheduler.h | 106 +- src/core/qtlibtorrent/filterparserthread.cpp | 602 +- src/core/qtlibtorrent/filterparserthread.h | 36 +- src/core/qtlibtorrent/qbtsession.cpp | 4824 ++++++++--------- src/core/qtlibtorrent/qbtsession.h | 488 +- src/core/qtlibtorrent/qtorrenthandle.cpp | 8 +- src/core/qtlibtorrent/shutdownconfirm.cpp | 116 +- src/core/qtlibtorrent/shutdownconfirm.h | 26 +- src/core/qtlibtorrent/torrentmodel.cpp | 872 +-- src/core/qtlibtorrent/torrentmodel.h | 112 +- src/core/qtlibtorrent/torrentspeedmonitor.cpp | 154 +- src/core/qtlibtorrent/torrentspeedmonitor.h | 18 +- src/core/qtlibtorrent/torrentstatistics.cpp | 126 +- src/core/qtlibtorrent/torrentstatistics.h | 38 +- src/core/qtlibtorrent/trackerinfos.h | 34 +- 17 files changed, 3856 insertions(+), 3856 deletions(-) diff --git a/src/core/qtlibtorrent/alertdispatcher.cpp b/src/core/qtlibtorrent/alertdispatcher.cpp index 1ef90885c..cf5618019 100644 --- a/src/core/qtlibtorrent/alertdispatcher.cpp +++ b/src/core/qtlibtorrent/alertdispatcher.cpp @@ -37,99 +37,99 @@ const size_t DEFAULT_ALERTS_CAPACITY = 32; struct QAlertDispatcher::Tag { - Tag(QAlertDispatcher* dispatcher); + Tag(QAlertDispatcher* dispatcher); - QAlertDispatcher* dispatcher; - QMutex alerts_mutex; + QAlertDispatcher* dispatcher; + QMutex alerts_mutex; }; QAlertDispatcher::Tag::Tag(QAlertDispatcher* dispatcher) - : dispatcher(dispatcher) + : dispatcher(dispatcher) {} QAlertDispatcher::QAlertDispatcher(libtorrent::session *session, QObject* parent) - : QObject(parent) - , m_session(session) - , current_tag(new Tag(this)) - , event_posted(false) + : QObject(parent) + , m_session(session) + , current_tag(new Tag(this)) + , event_posted(false) { - alerts.reserve(DEFAULT_ALERTS_CAPACITY); - m_session->set_alert_dispatch(boost::bind(&QAlertDispatcher::dispatch, current_tag, _1)); + alerts.reserve(DEFAULT_ALERTS_CAPACITY); + m_session->set_alert_dispatch(boost::bind(&QAlertDispatcher::dispatch, current_tag, _1)); } QAlertDispatcher::~QAlertDispatcher() { - // When QAlertDispatcher is destoyed, libtorrent still can call - // QAlertDispatcher::dispatch a few times after destruction. This is - // handled by passing a "tag". A tag is a object that references QAlertDispatch. - // Tag could be invalidated. So on destruction QAlertDispatcher invalidates a tag - // and then unsubscribes from alerts. When QAlertDispatcher::dispatch is called - // with invalid tag it simply discard an alert. - - { - QMutexLocker lock(¤t_tag->alerts_mutex); - current_tag->dispatcher = 0; - current_tag.clear(); - } - - typedef boost::function)> dispatch_function_t; - m_session->set_alert_dispatch(dispatch_function_t()); + // When QAlertDispatcher is destoyed, libtorrent still can call + // QAlertDispatcher::dispatch a few times after destruction. This is + // handled by passing a "tag". A tag is a object that references QAlertDispatch. + // Tag could be invalidated. So on destruction QAlertDispatcher invalidates a tag + // and then unsubscribes from alerts. When QAlertDispatcher::dispatch is called + // with invalid tag it simply discard an alert. + + { + QMutexLocker lock(¤t_tag->alerts_mutex); + current_tag->dispatcher = 0; + current_tag.clear(); + } + + typedef boost::function)> dispatch_function_t; + m_session->set_alert_dispatch(dispatch_function_t()); } void QAlertDispatcher::getPendingAlertsNoWait(std::vector& out) { - Q_ASSERT(out.empty()); - out.reserve(DEFAULT_ALERTS_CAPACITY); + Q_ASSERT(out.empty()); + out.reserve(DEFAULT_ALERTS_CAPACITY); - QMutexLocker lock(¤t_tag->alerts_mutex); - alerts.swap(out); - event_posted = false; + QMutexLocker lock(¤t_tag->alerts_mutex); + alerts.swap(out); + event_posted = false; } void QAlertDispatcher::getPendingAlerts(std::vector& out, unsigned long time) { - Q_ASSERT(out.empty()); - out.reserve(DEFAULT_ALERTS_CAPACITY); + Q_ASSERT(out.empty()); + out.reserve(DEFAULT_ALERTS_CAPACITY); - QMutexLocker lock(¤t_tag->alerts_mutex); + QMutexLocker lock(¤t_tag->alerts_mutex); - while (alerts.empty()) - alerts_condvar.wait(¤t_tag->alerts_mutex, time); + while (alerts.empty()) + alerts_condvar.wait(¤t_tag->alerts_mutex, time); - alerts.swap(out); - event_posted = false; + alerts.swap(out); + event_posted = false; } void QAlertDispatcher::dispatch(QSharedPointer tag, std::auto_ptr alert_ptr) { - QMutexLocker lock(&(tag->alerts_mutex)); - QAlertDispatcher* that = tag->dispatcher; - if (!that) - return; + QMutexLocker lock(&(tag->alerts_mutex)); + QAlertDispatcher* that = tag->dispatcher; + if (!that) + return; - bool was_empty = that->alerts.empty(); + bool was_empty = that->alerts.empty(); - that->alerts.push_back(alert_ptr.get()); - alert_ptr.release(); + that->alerts.push_back(alert_ptr.get()); + alert_ptr.release(); - if (was_empty) - that->alerts_condvar.wakeAll(); + if (was_empty) + that->alerts_condvar.wakeAll(); - that->enqueueToMainThread(); + that->enqueueToMainThread(); - Q_ASSERT(that->current_tag == tag); + Q_ASSERT(that->current_tag == tag); } void QAlertDispatcher::enqueueToMainThread() { - if (!event_posted) { - event_posted = true; - QMetaObject::invokeMethod(this, "deliverSignal", Qt::QueuedConnection); - } + if (!event_posted) { + event_posted = true; + QMetaObject::invokeMethod(this, "deliverSignal", Qt::QueuedConnection); + } } void QAlertDispatcher::deliverSignal() { - emit alertsReceived(); + emit alertsReceived(); - QMutexLocker lock(¤t_tag->alerts_mutex); - event_posted = false; + QMutexLocker lock(¤t_tag->alerts_mutex); + event_posted = false; - if (!alerts.empty()) - enqueueToMainThread(); + if (!alerts.empty()) + enqueueToMainThread(); } diff --git a/src/core/qtlibtorrent/alertdispatcher.h b/src/core/qtlibtorrent/alertdispatcher.h index 5ebaf9bc1..e77f22474 100644 --- a/src/core/qtlibtorrent/alertdispatcher.h +++ b/src/core/qtlibtorrent/alertdispatcher.h @@ -41,40 +41,40 @@ #include namespace libtorrent { - class session; - class alert; +class session; +class alert; } class QAlertDispatcher : public QObject { - Q_OBJECT - Q_DISABLE_COPY(QAlertDispatcher) + Q_OBJECT + Q_DISABLE_COPY(QAlertDispatcher) - struct Tag; + struct Tag; public: - QAlertDispatcher(libtorrent::session *session, QObject* parent); - ~QAlertDispatcher(); + QAlertDispatcher(libtorrent::session *session, QObject* parent); + ~QAlertDispatcher(); - void getPendingAlertsNoWait(std::vector&); - void getPendingAlerts(std::vector&, unsigned long time = ULONG_MAX); + void getPendingAlertsNoWait(std::vector&); + void getPendingAlerts(std::vector&, unsigned long time = ULONG_MAX); signals: - void alertsReceived(); + void alertsReceived(); private: - static void dispatch(QSharedPointer, - std::auto_ptr); - void enqueueToMainThread(); + static void dispatch(QSharedPointer, + std::auto_ptr); + void enqueueToMainThread(); private slots: - void deliverSignal(); + void deliverSignal(); private: - libtorrent::session *m_session; - QWaitCondition alerts_condvar; - std::vector alerts; - QSharedPointer current_tag; - bool event_posted; + libtorrent::session *m_session; + QWaitCondition alerts_condvar; + std::vector alerts; + QSharedPointer current_tag; + bool event_posted; }; #endif // ALERTDISPATCHER_H diff --git a/src/core/qtlibtorrent/bandwidthscheduler.h b/src/core/qtlibtorrent/bandwidthscheduler.h index fe9f1b5cb..318f8e767 100644 --- a/src/core/qtlibtorrent/bandwidthscheduler.h +++ b/src/core/qtlibtorrent/bandwidthscheduler.h @@ -9,71 +9,71 @@ class BandwidthScheduler: public QTimer { - Q_OBJECT + Q_OBJECT public: - BandwidthScheduler(QObject *parent): QTimer(parent) { - Q_ASSERT(Preferences::instance()->isSchedulerEnabled()); - // Signal shot, we call start() again manually - setSingleShot(true); - // Connect Signals/Slots - connect(this, SIGNAL(timeout()), this, SLOT(start())); - } + BandwidthScheduler(QObject *parent): QTimer(parent) { + Q_ASSERT(Preferences::instance()->isSchedulerEnabled()); + // Signal shot, we call start() again manually + setSingleShot(true); + // Connect Signals/Slots + connect(this, SIGNAL(timeout()), this, SLOT(start())); + } public slots: - void start() { - const Preferences* const pref = Preferences::instance(); - Q_ASSERT(pref->isSchedulerEnabled()); - bool alt_bw_enabled = pref->isAltBandwidthEnabled(); + void start() { + const Preferences* const pref = Preferences::instance(); + Q_ASSERT(pref->isSchedulerEnabled()); + bool alt_bw_enabled = pref->isAltBandwidthEnabled(); - QTime start = pref->getSchedulerStartTime(); - QTime end = pref->getSchedulerEndTime(); - QTime now = QTime::currentTime(); - int sched_days = pref->getSchedulerDays(); - int day = QDateTime::currentDateTime().toLocalTime().date().dayOfWeek(); - bool new_mode = false; - bool reverse = false; + QTime start = pref->getSchedulerStartTime(); + QTime end = pref->getSchedulerEndTime(); + QTime now = QTime::currentTime(); + int sched_days = pref->getSchedulerDays(); + int day = QDateTime::currentDateTime().toLocalTime().date().dayOfWeek(); + bool new_mode = false; + bool reverse = false; - if (start > end) { - QTime temp = start; - start = end; - end = temp; - reverse = true; - } + if (start > end) { + QTime temp = start; + start = end; + end = temp; + reverse = true; + } - if (start <= now && end >= now) { - switch(sched_days) { - case EVERY_DAY: - new_mode = true; - break; - case WEEK_ENDS: - if (day == 6 || day == 7) - new_mode = true; - break; - case WEEK_DAYS: - if (day != 6 && day != 7) - new_mode = true; - break; - default: - if (day == sched_days - 2) - new_mode = true; - break; - } - } + if (start <= now && end >= now) { + switch(sched_days) { + case EVERY_DAY: + new_mode = true; + break; + case WEEK_ENDS: + if (day == 6 || day == 7) + new_mode = true; + break; + case WEEK_DAYS: + if (day != 6 && day != 7) + new_mode = true; + break; + default: + if (day == sched_days - 2) + new_mode = true; + break; + } + } - if (reverse) - new_mode = !new_mode; + if (reverse) + new_mode = !new_mode; - if (new_mode != alt_bw_enabled) - emit switchToAlternativeMode(new_mode); + if (new_mode != alt_bw_enabled) + emit switchToAlternativeMode(new_mode); - // Timeout regularly to accomodate for external system clock changes - // eg from the user or from a timesync utility - QTimer::start(1500); - } + // Timeout regularly to accomodate for external system clock changes + // eg from the user or from a timesync utility + QTimer::start(1500); + } signals: - void switchToAlternativeMode(bool alternative); + void switchToAlternativeMode(bool alternative); }; #endif // BANDWIDTHSCHEDULER_H diff --git a/src/core/qtlibtorrent/filterparserthread.cpp b/src/core/qtlibtorrent/filterparserthread.cpp index ea9a8dc6d..41749b61f 100644 --- a/src/core/qtlibtorrent/filterparserthread.cpp +++ b/src/core/qtlibtorrent/filterparserthread.cpp @@ -41,290 +41,290 @@ FilterParserThread::FilterParserThread(QObject* parent, libtorrent::session *s) } FilterParserThread::~FilterParserThread() { - abort = true; - wait(); + abort = true; + wait(); } // Parser for eMule ip filter in DAT format int FilterParserThread::parseDATFilterFile(QString filePath, libtorrent::ip_filter& filter) { - int ruleCount = 0; - QFile file(filePath); - if (file.exists()) { - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - std::cerr << "I/O Error: Could not open ip filer file in read mode." << std::endl; - return ruleCount; - } - unsigned int nbLine = 0; - while (!file.atEnd() && !abort) { - ++nbLine; - QByteArray line = file.readLine(); - // Ignoring empty lines - line = line.trimmed(); - if (line.isEmpty()) continue; - // Ignoring commented lines - if (line.startsWith('#') || line.startsWith("//")) continue; + int ruleCount = 0; + QFile file(filePath); + if (file.exists()) { + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + std::cerr << "I/O Error: Could not open ip filer file in read mode." << std::endl; + return ruleCount; + } + unsigned int nbLine = 0; + while (!file.atEnd() && !abort) { + ++nbLine; + QByteArray line = file.readLine(); + // Ignoring empty lines + line = line.trimmed(); + if (line.isEmpty()) continue; + // Ignoring commented lines + if (line.startsWith('#') || line.startsWith("//")) continue; - // Line should be splitted by commas - QList partsList = line.split(','); - const uint nbElem = partsList.size(); + // Line should be splitted by commas + QList partsList = line.split(','); + const uint nbElem = partsList.size(); - // IP Range should be splitted by a dash - QList IPs = partsList.first().split('-'); - if (IPs.size() != 2) { - qDebug("Ipfilter.dat: line %d is malformed.", nbLine); - qDebug("Line was %s", line.constData()); - continue; - } + // IP Range should be splitted by a dash + QList IPs = partsList.first().split('-'); + if (IPs.size() != 2) { + qDebug("Ipfilter.dat: line %d is malformed.", nbLine); + qDebug("Line was %s", line.constData()); + continue; + } - boost::system::error_code ec; - const QString strStartIP = cleanupIPAddress(IPs.at(0)); - if (strStartIP.isEmpty()) { - qDebug("Ipfilter.dat: line %d is malformed.", nbLine); - qDebug("Start IP of the range is malformated: %s", qPrintable(strStartIP)); - continue; - } - libtorrent::address startAddr = libtorrent::address::from_string(qPrintable(strStartIP), ec); - if (ec) { - qDebug("Ipfilter.dat: line %d is malformed.", nbLine); - qDebug("Start IP of the range is malformated: %s", qPrintable(strStartIP)); - continue; - } - const QString strEndIP = cleanupIPAddress(IPs.at(1)); - if (strEndIP.isEmpty()) { - qDebug("Ipfilter.dat: line %d is malformed.", nbLine); - qDebug("End IP of the range is malformated: %s", qPrintable(strEndIP)); - continue; - } - libtorrent::address endAddr = libtorrent::address::from_string(qPrintable(strEndIP), ec); - if (ec) { - qDebug("Ipfilter.dat: line %d is malformed.", nbLine); - qDebug("End IP of the range is malformated: %s", qPrintable(strEndIP)); - continue; - } - if (startAddr.is_v4() != endAddr.is_v4()) { - qDebug("Ipfilter.dat: line %d is malformed.", nbLine); - qDebug("One IP is IPv4 and the other is IPv6!"); - continue; - } + boost::system::error_code ec; + const QString strStartIP = cleanupIPAddress(IPs.at(0)); + if (strStartIP.isEmpty()) { + qDebug("Ipfilter.dat: line %d is malformed.", nbLine); + qDebug("Start IP of the range is malformated: %s", qPrintable(strStartIP)); + continue; + } + libtorrent::address startAddr = libtorrent::address::from_string(qPrintable(strStartIP), ec); + if (ec) { + qDebug("Ipfilter.dat: line %d is malformed.", nbLine); + qDebug("Start IP of the range is malformated: %s", qPrintable(strStartIP)); + continue; + } + const QString strEndIP = cleanupIPAddress(IPs.at(1)); + if (strEndIP.isEmpty()) { + qDebug("Ipfilter.dat: line %d is malformed.", nbLine); + qDebug("End IP of the range is malformated: %s", qPrintable(strEndIP)); + continue; + } + libtorrent::address endAddr = libtorrent::address::from_string(qPrintable(strEndIP), ec); + if (ec) { + qDebug("Ipfilter.dat: line %d is malformed.", nbLine); + qDebug("End IP of the range is malformated: %s", qPrintable(strEndIP)); + continue; + } + if (startAddr.is_v4() != endAddr.is_v4()) { + qDebug("Ipfilter.dat: line %d is malformed.", nbLine); + qDebug("One IP is IPv4 and the other is IPv6!"); + continue; + } - // Check if there is an access value (apparently not mandatory) - int nbAccess = 0; - if (nbElem > 1) { - // There is possibly one - nbAccess = partsList.at(1).trimmed().toInt(); - } + // Check if there is an access value (apparently not mandatory) + int nbAccess = 0; + if (nbElem > 1) { + // There is possibly one + nbAccess = partsList.at(1).trimmed().toInt(); + } - if (nbAccess > 127) { - // Ignoring this rule because access value is too high - continue; - } - // Now Add to the filter - try { - filter.add_rule(startAddr, endAddr, libtorrent::ip_filter::blocked); - ++ruleCount; - }catch(exception) { - qDebug("Bad line in filter file, avoided crash..."); - } + if (nbAccess > 127) { + // Ignoring this rule because access value is too high + continue; + } + // Now Add to the filter + try { + filter.add_rule(startAddr, endAddr, libtorrent::ip_filter::blocked); + ++ruleCount; + }catch(exception) { + qDebug("Bad line in filter file, avoided crash..."); + } + } + file.close(); } - file.close(); - } - return ruleCount; + return ruleCount; } // Parser for PeerGuardian ip filter in p2p format int FilterParserThread::parseP2PFilterFile(QString filePath, libtorrent::ip_filter& filter) { - int ruleCount = 0; - QFile file(filePath); - if (file.exists()) { - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - std::cerr << "I/O Error: Could not open ip filer file in read mode." << std::endl; - return ruleCount; - } - unsigned int nbLine = 0; - while (!file.atEnd() && !abort) { - ++nbLine; - QByteArray line = file.readLine().trimmed(); - if (line.isEmpty()) continue; - // Ignoring commented lines - if (line.startsWith('#') || line.startsWith("//")) continue; - // Line is splitted by : - QList partsList = line.split(':'); - if (partsList.size() < 2) { - qDebug("p2p file: line %d is malformed.", nbLine); - continue; - } - // Get IP range - QList IPs = partsList.last().split('-'); - if (IPs.size() != 2) { - qDebug("p2p file: line %d is malformed.", nbLine); - qDebug("line was: %s", line.constData()); - continue; - } - boost::system::error_code ec; - QString strStartIP = cleanupIPAddress(IPs.at(0)); - if (strStartIP.isEmpty()) { - qDebug("p2p file: line %d is malformed.", nbLine); - qDebug("Start IP is invalid: %s", qPrintable(strStartIP)); - continue; - } - libtorrent::address startAddr = libtorrent::address::from_string(qPrintable(strStartIP), ec); - if (ec) { - qDebug("p2p file: line %d is malformed.", nbLine); - qDebug("Start IP is invalid: %s", qPrintable(strStartIP)); - continue; - } - QString strEndIP = cleanupIPAddress(IPs.at(1)); - if (strEndIP.isEmpty()) { - qDebug("p2p file: line %d is malformed.", nbLine); - qDebug("End IP is invalid: %s", qPrintable(strStartIP)); - continue; - } - libtorrent::address endAddr = libtorrent::address::from_string(qPrintable(strEndIP), ec); - if (ec) { - qDebug("p2p file: line %d is malformed.", nbLine); - qDebug("End IP is invalid: %s", qPrintable(strStartIP)); - continue; - } - if (startAddr.is_v4() != endAddr.is_v4()) { - qDebug("p2p file: line %d is malformed.", nbLine); - qDebug("Line was: %s", line.constData()); - continue; - } - try { - filter.add_rule(startAddr, endAddr, libtorrent::ip_filter::blocked); - ++ruleCount; - } catch(std::exception&) { - qDebug("p2p file: line %d is malformed.", nbLine); - qDebug("Line was: %s", line.constData()); - continue; - } + int ruleCount = 0; + QFile file(filePath); + if (file.exists()) { + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + std::cerr << "I/O Error: Could not open ip filer file in read mode." << std::endl; + return ruleCount; + } + unsigned int nbLine = 0; + while (!file.atEnd() && !abort) { + ++nbLine; + QByteArray line = file.readLine().trimmed(); + if (line.isEmpty()) continue; + // Ignoring commented lines + if (line.startsWith('#') || line.startsWith("//")) continue; + // Line is splitted by : + QList partsList = line.split(':'); + if (partsList.size() < 2) { + qDebug("p2p file: line %d is malformed.", nbLine); + continue; + } + // Get IP range + QList IPs = partsList.last().split('-'); + if (IPs.size() != 2) { + qDebug("p2p file: line %d is malformed.", nbLine); + qDebug("line was: %s", line.constData()); + continue; + } + boost::system::error_code ec; + QString strStartIP = cleanupIPAddress(IPs.at(0)); + if (strStartIP.isEmpty()) { + qDebug("p2p file: line %d is malformed.", nbLine); + qDebug("Start IP is invalid: %s", qPrintable(strStartIP)); + continue; + } + libtorrent::address startAddr = libtorrent::address::from_string(qPrintable(strStartIP), ec); + if (ec) { + qDebug("p2p file: line %d is malformed.", nbLine); + qDebug("Start IP is invalid: %s", qPrintable(strStartIP)); + continue; + } + QString strEndIP = cleanupIPAddress(IPs.at(1)); + if (strEndIP.isEmpty()) { + qDebug("p2p file: line %d is malformed.", nbLine); + qDebug("End IP is invalid: %s", qPrintable(strStartIP)); + continue; + } + libtorrent::address endAddr = libtorrent::address::from_string(qPrintable(strEndIP), ec); + if (ec) { + qDebug("p2p file: line %d is malformed.", nbLine); + qDebug("End IP is invalid: %s", qPrintable(strStartIP)); + continue; + } + if (startAddr.is_v4() != endAddr.is_v4()) { + qDebug("p2p file: line %d is malformed.", nbLine); + qDebug("Line was: %s", line.constData()); + continue; + } + try { + filter.add_rule(startAddr, endAddr, libtorrent::ip_filter::blocked); + ++ruleCount; + } catch(std::exception&) { + qDebug("p2p file: line %d is malformed.", nbLine); + qDebug("Line was: %s", line.constData()); + continue; + } + } + file.close(); } - file.close(); - } - return ruleCount; + return ruleCount; } int FilterParserThread::getlineInStream(QDataStream& stream, string& name, char delim) { - char c; - int total_read = 0; - int read; - do { - read = stream.readRawData(&c, 1); - total_read += read; - if (read > 0) { - if (c != delim) { - name += c; - } else { - // Delim found - return total_read; - } - } - } while(read > 0); - return total_read; + char c; + int total_read = 0; + int read; + do { + read = stream.readRawData(&c, 1); + total_read += read; + if (read > 0) { + if (c != delim) { + name += c; + } else { + // Delim found + return total_read; + } + } + } while(read > 0); + return total_read; } // Parser for PeerGuardian ip filter in p2p format int FilterParserThread::parseP2BFilterFile(QString filePath, libtorrent::ip_filter& filter) { - int ruleCount = 0; - QFile file(filePath); - if (file.exists()) { - if (!file.open(QIODevice::ReadOnly)) { - std::cerr << "I/O Error: Could not open ip filer file in read mode." << std::endl; - return ruleCount; - } - QDataStream stream(&file); - // Read header - char buf[7]; - unsigned char version; - if ( - !stream.readRawData(buf, sizeof(buf)) || - memcmp(buf, "\xFF\xFF\xFF\xFFP2B", 7) || - !stream.readRawData((char*)&version, sizeof(version)) - ) { - std::cerr << "Parsing Error: The filter file is not a valid PeerGuardian P2B file." << std::endl; - return ruleCount; - } - - if (version==1 || version==2) { - qDebug ("p2b version 1 or 2"); - unsigned int start, end; - - string name; - while(getlineInStream(stream, name, '\0') && !abort) { + int ruleCount = 0; + QFile file(filePath); + if (file.exists()) { + if (!file.open(QIODevice::ReadOnly)) { + std::cerr << "I/O Error: Could not open ip filer file in read mode." << std::endl; + return ruleCount; + } + QDataStream stream(&file); + // Read header + char buf[7]; + unsigned char version; if ( - !stream.readRawData((char*)&start, sizeof(start)) || - !stream.readRawData((char*)&end, sizeof(end)) + !stream.readRawData(buf, sizeof(buf)) || + memcmp(buf, "\xFF\xFF\xFF\xFFP2B", 7) || + !stream.readRawData((char*)&version, sizeof(version)) ) { - std::cerr << "Parsing Error: The filter file is not a valid PeerGuardian P2B file." << std::endl; - return ruleCount; + std::cerr << "Parsing Error: The filter file is not a valid PeerGuardian P2B file." << std::endl; + return ruleCount; } - // Network byte order to Host byte order - // asio address_v4 contructor expects it - // that way - libtorrent::address_v4 first(ntohl(start)); - libtorrent::address_v4 last(ntohl(end)); - // Apply to bittorrent session - try { - filter.add_rule(first, last, libtorrent::ip_filter::blocked); - ++ruleCount; - } catch(std::exception&) {} - } - } - else if (version==3) { - qDebug ("p2b version 3"); - unsigned int namecount; - if (!stream.readRawData((char*)&namecount, sizeof(namecount))) { - std::cerr << "Parsing Error: The filter file is not a valid PeerGuardian P2B file." << std::endl; - return ruleCount; - } - namecount=ntohl(namecount); - // Reading names although, we don't really care about them - for (unsigned int i=0; iget_ip_filter(); - foreach (const QString &ip, IPs) { - qDebug("Manual ban of peer %s", ip.toLocal8Bit().constData()); - boost::system::error_code ec; - libtorrent::address addr = libtorrent::address::from_string(ip.toLocal8Bit().constData(), ec); - Q_ASSERT(!ec); - if (!ec) - filter.add_rule(addr, addr, libtorrent::ip_filter::blocked); - } - s->set_ip_filter(filter); + // First, import current filter + libtorrent::ip_filter filter = s->get_ip_filter(); + foreach (const QString &ip, IPs) { + qDebug("Manual ban of peer %s", ip.toLocal8Bit().constData()); + boost::system::error_code ec; + libtorrent::address addr = libtorrent::address::from_string(ip.toLocal8Bit().constData(), ec); + Q_ASSERT(!ec); + if (!ec) + filter.add_rule(addr, addr, libtorrent::ip_filter::blocked); + } + s->set_ip_filter(filter); } QString FilterParserThread::cleanupIPAddress(QString _ip) { - QHostAddress ip(_ip.trimmed()); - if (ip.isNull()) { - return QString(); - } - return ip.toString(); + QHostAddress ip(_ip.trimmed()); + if (ip.isNull()) { + return QString(); + } + return ip.toString(); } void FilterParserThread::run() { - qDebug("Processing filter file"); - libtorrent::ip_filter filter = s->get_ip_filter(); - int ruleCount = 0; - if (filePath.endsWith(".p2p", Qt::CaseInsensitive)) { - // PeerGuardian p2p file - ruleCount = parseP2PFilterFile(filePath, filter); - } else { - if (filePath.endsWith(".p2b", Qt::CaseInsensitive)) { - // PeerGuardian p2b file - ruleCount = parseP2BFilterFile(filePath, filter); + qDebug("Processing filter file"); + libtorrent::ip_filter filter = s->get_ip_filter(); + int ruleCount = 0; + if (filePath.endsWith(".p2p", Qt::CaseInsensitive)) { + // PeerGuardian p2p file + ruleCount = parseP2PFilterFile(filePath, filter); } else { - // Default: eMule DAT format - ruleCount = parseDATFilterFile(filePath, filter); + if (filePath.endsWith(".p2b", Qt::CaseInsensitive)) { + // PeerGuardian p2b file + ruleCount = parseP2BFilterFile(filePath, filter); + } else { + // Default: eMule DAT format + ruleCount = parseDATFilterFile(filePath, filter); + } } - } - if (abort) - return; - try { - s->set_ip_filter(filter); - emit IPFilterParsed(ruleCount); - } catch(std::exception&) { - emit IPFilterError(); - } - qDebug("IP Filter thread: finished parsing, filter applied"); + if (abort) + return; + try { + s->set_ip_filter(filter); + emit IPFilterParsed(ruleCount); + } catch(std::exception&) { + emit IPFilterError(); + } + qDebug("IP Filter thread: finished parsing, filter applied"); } diff --git a/src/core/qtlibtorrent/filterparserthread.h b/src/core/qtlibtorrent/filterparserthread.h index 7d41acbf5..a95086540 100644 --- a/src/core/qtlibtorrent/filterparserthread.h +++ b/src/core/qtlibtorrent/filterparserthread.h @@ -36,8 +36,8 @@ #include namespace libtorrent { - class session; - struct ip_filter; +class session; +struct ip_filter; } using namespace std; @@ -52,31 +52,31 @@ using namespace std; // End of P2B stuff class FilterParserThread : public QThread { - Q_OBJECT + Q_OBJECT public: - FilterParserThread(QObject* parent, libtorrent::session *s); - ~FilterParserThread(); + FilterParserThread(QObject* parent, libtorrent::session *s); + ~FilterParserThread(); - int parseDATFilterFile(QString filePath, libtorrent::ip_filter& filter); - int parseP2PFilterFile(QString filePath, libtorrent::ip_filter& filter); - int getlineInStream(QDataStream& stream, string& name, char delim); - int parseP2BFilterFile(QString filePath, libtorrent::ip_filter& filter); - void processFilterFile(QString _filePath); - static void processFilterList(libtorrent::session *s, const QStringList& IPs); + int parseDATFilterFile(QString filePath, libtorrent::ip_filter& filter); + int parseP2PFilterFile(QString filePath, libtorrent::ip_filter& filter); + int getlineInStream(QDataStream& stream, string& name, char delim); + int parseP2BFilterFile(QString filePath, libtorrent::ip_filter& filter); + void processFilterFile(QString _filePath); + static void processFilterList(libtorrent::session *s, const QStringList& IPs); signals: - void IPFilterParsed(int ruleCount); - void IPFilterError(); + void IPFilterParsed(int ruleCount); + void IPFilterError(); protected: - QString cleanupIPAddress(QString _ip); - void run(); + QString cleanupIPAddress(QString _ip); + void run(); private: - libtorrent::session *s; - bool abort; - QString filePath; + libtorrent::session *s; + bool abort; + QString filePath; }; #endif diff --git a/src/core/qtlibtorrent/qbtsession.cpp b/src/core/qtlibtorrent/qbtsession.cpp index a8e6c1093..d281746d0 100644 --- a/src/core/qtlibtorrent/qbtsession.cpp +++ b/src/core/qtlibtorrent/qbtsession.cpp @@ -93,1129 +93,1129 @@ const int MAX_TRACKER_ERRORS = 2; /* Converts a QString hash into a libtorrent sha1_hash */ static libtorrent::sha1_hash QStringToSha1(const QString& s) { - QByteArray raw = s.toLatin1(); - Q_ASSERT(raw.size() == 40); - libtorrent::sha1_hash ret; - from_hex(raw.constData(), 40, (char*)&ret[0]); - return ret; + QByteArray raw = s.toLatin1(); + Q_ASSERT(raw.size() == 40); + libtorrent::sha1_hash ret; + from_hex(raw.constData(), 40, (char*)&ret[0]); + return ret; } // Main constructor QBtSession::QBtSession() - : m_scanFolders(ScanFoldersModel::instance(this)), - preAllocateAll(false), global_ratio_limit(-1), - LSDEnabled(false), - DHTEnabled(false), queueingEnabled(false), - m_torrentExportEnabled(false), - m_finishedTorrentExportEnabled(false) - #ifndef DISABLE_GUI - , geoipDBLoaded(false), resolve_countries(false) - #endif - , m_tracker(0), m_shutdownAct(NO_SHUTDOWN) - #if LIBTORRENT_VERSION_NUM < 10000 - , m_upnp(0), m_natpmp(0) - #endif - , m_alertDispatcher(0) + : m_scanFolders(ScanFoldersModel::instance(this)), + preAllocateAll(false), global_ratio_limit(-1), + LSDEnabled(false), + DHTEnabled(false), queueingEnabled(false), + m_torrentExportEnabled(false), + m_finishedTorrentExportEnabled(false) +#ifndef DISABLE_GUI + , geoipDBLoaded(false), resolve_countries(false) +#endif + , m_tracker(0), m_shutdownAct(NO_SHUTDOWN) +#if LIBTORRENT_VERSION_NUM < 10000 + , m_upnp(0), m_natpmp(0) +#endif + , m_alertDispatcher(0) { - BigRatioTimer = new QTimer(this); - BigRatioTimer->setInterval(10000); - connect(BigRatioTimer, SIGNAL(timeout()), SLOT(processBigRatios())); - Preferences* const pref = Preferences::instance(); - // Creating Bittorrent session - QList version; - version << VERSION_MAJOR; - version << VERSION_MINOR; - version << VERSION_BUGFIX; - version << VERSION_BUILD; - const QString peer_id = "qB"; - // Construct session - s = new session(fingerprint(peer_id.toLocal8Bit().constData(), version.at(0), version.at(1), version.at(2), version.at(3)), 0); - //std::cout << "Peer ID: " << fingerprint(peer_id.toLocal8Bit().constData(), version.at(0), version.at(1), version.at(2), version.at(3)).to_string() << std::endl; - Logger::instance()->addMessage("Peer ID: "+misc::toQString(fingerprint(peer_id.toLocal8Bit().constData(), version.at(0), version.at(1), version.at(2), version.at(3)).to_string())); - - // Set severity level of libtorrent session - 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 | alert::progress_notification | alert::stats_notification); - // Load previous state - loadSessionState(); - // Enabling plugins - //s->add_extension(&create_metadata_plugin); - s->add_extension(&create_ut_metadata_plugin); - if (pref->trackerExchangeEnabled()) - s->add_extension(&create_lt_trackers_plugin); - if (pref->isPeXEnabled()) { - PeXEnabled = true; - s->add_extension(&create_ut_pex_plugin); - } else { - PeXEnabled = false; - } - s->add_extension(&create_smart_ban_plugin); - m_alertDispatcher = new QAlertDispatcher(s, this); - connect(m_alertDispatcher, SIGNAL(alertsReceived()), SLOT(readAlerts())); - appendLabelToSavePath = pref->appendTorrentLabel(); - appendqBExtension = pref->useIncompleteFilesExtension(); - connect(m_scanFolders, SIGNAL(torrentsAdded(QStringList&)), SLOT(addTorrentsFromScanFolder(QStringList&))); - // Apply user settings to Bittorrent session - configureSession(); - connect(pref, SIGNAL(changed()), SLOT(configureSession())); - // Torrent speed monitor - m_speedMonitor = new TorrentSpeedMonitor(this); - m_torrentStatistics = new TorrentStatistics(this, this); - // To download from urls - downloader = new DownloadThread(this); - connect(downloader, SIGNAL(downloadFinished(QString, QString)), SLOT(processDownloadedFile(QString, QString))); - connect(downloader, SIGNAL(downloadFailure(QString, QString)), SLOT(handleDownloadFailure(QString, QString))); - connect(downloader, SIGNAL(magnetRedirect(QString, QString)), SLOT(handleMagnetRedirect(QString, QString))); - // Regular saving of fastresume data - connect(&resumeDataTimer, SIGNAL(timeout()), SLOT(saveTempFastResumeData())); - resumeDataTimer.start(pref->saveResumeDataInterval() * 60 * 1000); - qDebug("* BTSession constructed"); + BigRatioTimer = new QTimer(this); + BigRatioTimer->setInterval(10000); + connect(BigRatioTimer, SIGNAL(timeout()), SLOT(processBigRatios())); + Preferences* const pref = Preferences::instance(); + // Creating Bittorrent session + QList version; + version << VERSION_MAJOR; + version << VERSION_MINOR; + version << VERSION_BUGFIX; + version << VERSION_BUILD; + const QString peer_id = "qB"; + // Construct session + s = new session(fingerprint(peer_id.toLocal8Bit().constData(), version.at(0), version.at(1), version.at(2), version.at(3)), 0); + //std::cout << "Peer ID: " << fingerprint(peer_id.toLocal8Bit().constData(), version.at(0), version.at(1), version.at(2), version.at(3)).to_string() << std::endl; + Logger::instance()->addMessage("Peer ID: "+misc::toQString(fingerprint(peer_id.toLocal8Bit().constData(), version.at(0), version.at(1), version.at(2), version.at(3)).to_string())); + + // Set severity level of libtorrent session + 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 | alert::progress_notification | alert::stats_notification); + // Load previous state + loadSessionState(); + // Enabling plugins + //s->add_extension(&create_metadata_plugin); + s->add_extension(&create_ut_metadata_plugin); + if (pref->trackerExchangeEnabled()) + s->add_extension(&create_lt_trackers_plugin); + if (pref->isPeXEnabled()) { + PeXEnabled = true; + s->add_extension(&create_ut_pex_plugin); + } else { + PeXEnabled = false; + } + s->add_extension(&create_smart_ban_plugin); + m_alertDispatcher = new QAlertDispatcher(s, this); + connect(m_alertDispatcher, SIGNAL(alertsReceived()), SLOT(readAlerts())); + appendLabelToSavePath = pref->appendTorrentLabel(); + appendqBExtension = pref->useIncompleteFilesExtension(); + connect(m_scanFolders, SIGNAL(torrentsAdded(QStringList&)), SLOT(addTorrentsFromScanFolder(QStringList&))); + // Apply user settings to Bittorrent session + configureSession(); + connect(pref, SIGNAL(changed()), SLOT(configureSession())); + // Torrent speed monitor + m_speedMonitor = new TorrentSpeedMonitor(this); + m_torrentStatistics = new TorrentStatistics(this, this); + // To download from urls + downloader = new DownloadThread(this); + connect(downloader, SIGNAL(downloadFinished(QString, QString)), SLOT(processDownloadedFile(QString, QString))); + connect(downloader, SIGNAL(downloadFailure(QString, QString)), SLOT(handleDownloadFailure(QString, QString))); + connect(downloader, SIGNAL(magnetRedirect(QString, QString)), SLOT(handleMagnetRedirect(QString, QString))); + // Regular saving of fastresume data + connect(&resumeDataTimer, SIGNAL(timeout()), SLOT(saveTempFastResumeData())); + resumeDataTimer.start(pref->saveResumeDataInterval() * 60 * 1000); + qDebug("* BTSession constructed"); } // Main destructor QBtSession::~QBtSession() { - qDebug("BTSession destructor IN"); - delete m_speedMonitor; - qDebug("Deleted the torrent speed monitor"); - // Do some BT related saving - saveSessionState(); - saveFastResumeData(); - // Delete our objects - if (m_tracker) - delete m_tracker; - if (BigRatioTimer) - delete BigRatioTimer; - if (filterParser) - delete filterParser; - delete downloader; - if (bd_scheduler) - delete bd_scheduler; - delete m_alertDispatcher; - delete m_torrentStatistics; - qDebug("Deleting the session"); - delete s; - qDebug("BTSession destructor OUT"); + qDebug("BTSession destructor IN"); + delete m_speedMonitor; + qDebug("Deleted the torrent speed monitor"); + // Do some BT related saving + saveSessionState(); + saveFastResumeData(); + // Delete our objects + if (m_tracker) + delete m_tracker; + if (BigRatioTimer) + delete BigRatioTimer; + if (filterParser) + delete filterParser; + delete downloader; + if (bd_scheduler) + delete bd_scheduler; + delete m_alertDispatcher; + delete m_torrentStatistics; + qDebug("Deleting the session"); + delete s; + qDebug("BTSession destructor OUT"); #ifndef DISABLE_GUI - if (m_shutdownAct != NO_SHUTDOWN) { - qDebug() << "Sending computer shutdown/suspend/hibernate signal..."; - misc::shutdownComputer(m_shutdownAct); - } + if (m_shutdownAct != NO_SHUTDOWN) { + qDebug() << "Sending computer shutdown/suspend/hibernate signal..."; + misc::shutdownComputer(m_shutdownAct); + } #endif } void QBtSession::preAllocateAllFiles(bool b) { - const bool change = (preAllocateAll != b); - if (change) { - qDebug("PreAllocateAll changed, reloading all torrents!"); - preAllocateAll = b; - } + const bool change = (preAllocateAll != b); + if (change) { + qDebug("PreAllocateAll changed, reloading all torrents!"); + preAllocateAll = b; + } } void QBtSession::processBigRatios() { - qDebug("Process big ratios..."); - std::vector torrents = s->get_torrents(); - - std::vector::iterator torrentIT = torrents.begin(); - std::vector::iterator torrentITend = torrents.end(); - for ( ; torrentIT != torrentITend; ++torrentIT) { - const QTorrentHandle h(*torrentIT); - if (!h.is_valid()) continue; - if (h.is_seed()) { - const QString hash = h.hash(); - const qreal ratio = getRealRatio(h.status(torrent_handle::query_accurate_download_counters)); - qreal ratio_limit = TorrentPersistentData::instance()->getRatioLimit(hash); - if (ratio_limit == TorrentPersistentData::USE_GLOBAL_RATIO) - ratio_limit = global_ratio_limit; - if (ratio_limit == TorrentPersistentData::NO_RATIO_LIMIT) - continue; - qDebug("Ratio: %f (limit: %f)", ratio, ratio_limit); - Q_ASSERT(ratio_limit >= 0.f); - if (ratio <= MAX_RATIO && ratio >= ratio_limit) { - Logger* const logger = Logger::instance(); - if (high_ratio_action == REMOVE_ACTION) { - logger->addMessage(tr("%1 reached the maximum ratio you set.").arg(h.name())); - logger->addMessage(tr("Removing torrent %1...").arg(h.name())); - deleteTorrent(hash); - } else { - // Pause it - if (!h.is_paused()) { - logger->addMessage(tr("%1 reached the maximum ratio you set.").arg(h.name())); - logger->addMessage(tr("Pausing torrent %1...").arg(h.name())); - pauseTorrent(hash); - } + qDebug("Process big ratios..."); + std::vector torrents = s->get_torrents(); + + std::vector::iterator torrentIT = torrents.begin(); + std::vector::iterator torrentITend = torrents.end(); + for ( ; torrentIT != torrentITend; ++torrentIT) { + const QTorrentHandle h(*torrentIT); + if (!h.is_valid()) continue; + if (h.is_seed()) { + const QString hash = h.hash(); + const qreal ratio = getRealRatio(h.status(torrent_handle::query_accurate_download_counters)); + qreal ratio_limit = TorrentPersistentData::instance()->getRatioLimit(hash); + if (ratio_limit == TorrentPersistentData::USE_GLOBAL_RATIO) + ratio_limit = global_ratio_limit; + if (ratio_limit == TorrentPersistentData::NO_RATIO_LIMIT) + continue; + qDebug("Ratio: %f (limit: %f)", ratio, ratio_limit); + Q_ASSERT(ratio_limit >= 0.f); + if (ratio <= MAX_RATIO && ratio >= ratio_limit) { + Logger* const logger = Logger::instance(); + if (high_ratio_action == REMOVE_ACTION) { + logger->addMessage(tr("%1 reached the maximum ratio you set.").arg(h.name())); + logger->addMessage(tr("Removing torrent %1...").arg(h.name())); + deleteTorrent(hash); + } else { + // Pause it + if (!h.is_paused()) { + logger->addMessage(tr("%1 reached the maximum ratio you set.").arg(h.name())); + logger->addMessage(tr("Pausing torrent %1...").arg(h.name())); + pauseTorrent(hash); + } + } + //emit torrent_ratio_deleted(fileName); + } } - //emit torrent_ratio_deleted(fileName); - } } - } } void QBtSession::setDownloadLimit(QString hash, long val) { - QTorrentHandle h = getTorrentHandle(hash); - if (h.is_valid()) { - h.set_download_limit(val); - } + QTorrentHandle h = getTorrentHandle(hash); + if (h.is_valid()) { + h.set_download_limit(val); + } } void QBtSession::setUploadLimit(QString hash, long val) { - qDebug("Set upload limit rate to %ld", val); - QTorrentHandle h = getTorrentHandle(hash); - if (h.is_valid()) { - h.set_upload_limit(val); - } + qDebug("Set upload limit rate to %ld", val); + QTorrentHandle h = getTorrentHandle(hash); + if (h.is_valid()) { + h.set_upload_limit(val); + } } void QBtSession::handleDownloadFailure(QString url, QString reason) { - emit downloadFromUrlFailure(url, reason); - // Clean up - const QUrl qurl = QUrl::fromEncoded(url.toUtf8()); - url_skippingDlg.removeOne(qurl); - savepathLabel_fromurl.remove(qurl); + emit downloadFromUrlFailure(url, reason); + // Clean up + const QUrl qurl = QUrl::fromEncoded(url.toUtf8()); + url_skippingDlg.removeOne(qurl); + savepathLabel_fromurl.remove(qurl); #ifndef DISABLE_GUI - addpaused_fromurl.remove(qurl); + addpaused_fromurl.remove(qurl); #endif } void QBtSession::handleMagnetRedirect(const QString &url_new, const QString &url_old) { - if (url_skippingDlg.contains(url_old)) { - url_skippingDlg.removeOne(url_old); - QPair savePath_label; - if (savepathLabel_fromurl.contains(url_old)) { - savePath_label = savepathLabel_fromurl.take(url_old); - } + if (url_skippingDlg.contains(url_old)) { + url_skippingDlg.removeOne(url_old); + QPair savePath_label; + if (savepathLabel_fromurl.contains(url_old)) { + savePath_label = savepathLabel_fromurl.take(url_old); + } #ifndef DISABLE_GUI - RssDownloadRule::AddPausedState state = RssDownloadRule::USE_GLOBAL; - if (addpaused_fromurl.contains(url_old)) { - state = addpaused_fromurl.take(url_old); - } + RssDownloadRule::AddPausedState state = RssDownloadRule::USE_GLOBAL; + if (addpaused_fromurl.contains(url_old)) { + state = addpaused_fromurl.take(url_old); + } #endif - addMagnetSkipAddDlg(url_new, savePath_label.first, savePath_label.second, - #ifndef DISABLE_GUI - state, - #endif - url_old); - } - else - addMagnetInteractive(url_new); + addMagnetSkipAddDlg(url_new, savePath_label.first, savePath_label.second, +#ifndef DISABLE_GUI + state, +#endif + url_old); + } + else + addMagnetInteractive(url_new); } void QBtSession::setQueueingEnabled(bool enable) { - if (queueingEnabled != enable) { - qDebug("Queueing system is changing state..."); - queueingEnabled = enable; - } + if (queueingEnabled != enable) { + qDebug("Queueing system is changing state..."); + queueingEnabled = enable; + } } // Set BT session configuration void QBtSession::configureSession() { - qDebug("Configuring session"); - Preferences* const pref = Preferences::instance(); - - const unsigned short old_listenPort = getListenPort(); - const unsigned short new_listenPort = pref->getSessionPort(); - if (old_listenPort != new_listenPort) { - qDebug("Session port changes in program preferences: %d -> %d", old_listenPort, new_listenPort); - setListeningPort(new_listenPort); - } - - // Downloads - // * Save path - defaultSavePath = pref->getSavePath(); - if (pref->isTempPathEnabled()) { - setDefaultTempPath(pref->getTempPath()); - } else { - setDefaultTempPath(QString::null); - } - setAppendLabelToSavePath(pref->appendTorrentLabel()); - setAppendqBExtension(pref->useIncompleteFilesExtension()); - preAllocateAllFiles(pref->preAllocateAllFiles()); - // * Torrent export directory - const bool torrentExportEnabled = pref->isTorrentExportEnabled(); - if (m_torrentExportEnabled != torrentExportEnabled) { - m_torrentExportEnabled = torrentExportEnabled; - if (m_torrentExportEnabled) { - qDebug("Torrent export is enabled, exporting the current torrents"); - exportTorrentFiles(pref->getTorrentExportDir()); - } - } - // * Finished Torrent export directory - const bool finishedTorrentExportEnabled = pref->isFinishedTorrentExportEnabled(); - if (m_finishedTorrentExportEnabled != finishedTorrentExportEnabled) - m_finishedTorrentExportEnabled = finishedTorrentExportEnabled; - // Connection - // * Global download limit - const bool alternative_speeds = pref->isAltBandwidthEnabled(); - int down_limit; - if (alternative_speeds) - down_limit = pref->getAltGlobalDownloadLimit(); - else - down_limit = pref->getGlobalDownloadLimit(); - if (down_limit <= 0) { - // Download limit disabled - setDownloadRateLimit(-1); - } else { - // Enabled - setDownloadRateLimit(down_limit*1024); - } - int up_limit; - if (alternative_speeds) - up_limit = pref->getAltGlobalUploadLimit(); - else - up_limit = pref->getGlobalUploadLimit(); - // * Global Upload limit - if (up_limit <= 0) { - // Upload limit disabled - setUploadRateLimit(-1); - } else { - // Enabled - setUploadRateLimit(up_limit*1024); - } - if (pref->isSchedulerEnabled()) { - if (!bd_scheduler) { - bd_scheduler = new BandwidthScheduler(this); - connect(bd_scheduler, SIGNAL(switchToAlternativeMode(bool)), this, SLOT(useAlternativeSpeedsLimit(bool))); - } - bd_scheduler->start(); - } else { - delete bd_scheduler; - } -#ifndef DISABLE_GUI - // Resolve countries - qDebug("Loading country resolution settings"); - const bool new_resolv_countries = pref->resolvePeerCountries(); - if (resolve_countries != new_resolv_countries) { - qDebug("in country resolution settings"); - resolve_countries = new_resolv_countries; - if (resolve_countries && !geoipDBLoaded) { - qDebug("Loading geoip database"); - GeoIPManager::loadDatabase(s); - geoipDBLoaded = true; - } - // Update torrent handles - std::vector torrents = s->get_torrents(); + qDebug("Configuring session"); + Preferences* const pref = Preferences::instance(); - std::vector::iterator torrentIT = torrents.begin(); - std::vector::iterator torrentITend = torrents.end(); - for ( ; torrentIT != torrentITend; ++torrentIT) { - QTorrentHandle h = QTorrentHandle(*torrentIT); - if (h.is_valid()) - h.resolve_countries(resolve_countries); + const unsigned short old_listenPort = getListenPort(); + const unsigned short new_listenPort = pref->getSessionPort(); + if (old_listenPort != new_listenPort) { + qDebug("Session port changes in program preferences: %d -> %d", old_listenPort, new_listenPort); + setListeningPort(new_listenPort); } - } -#endif - // * UPnP / NAT-PMP - Logger* const logger = Logger::instance(); - if (pref->isUPnPEnabled()) { - enableUPnP(true); - logger->addMessage(tr("UPnP / NAT-PMP support [ON]"), Log::INFO); - } else { - enableUPnP(false); - logger->addMessage(tr("UPnP / NAT-PMP support [OFF]"), Log::INFO); - } - // * Session settings - session_settings sessionSettings = s->settings(); - sessionSettings.user_agent = "qBittorrent " VERSION; - //std::cout << "HTTP user agent is " << sessionSettings.user_agent << std::endl; - logger->addMessage(tr("HTTP user agent is %1").arg(misc::toQString(sessionSettings.user_agent))); - - sessionSettings.upnp_ignore_nonrouters = true; - sessionSettings.use_dht_as_fallback = false; - // Disable support for SSL torrents for now - sessionSettings.ssl_listen = 0; - // To prevent ISPs from blocking seeding - sessionSettings.lazy_bitfields = true; - // Speed up exit - sessionSettings.stop_tracker_timeout = 1; - //sessionSettings.announce_to_all_trackers = true; - sessionSettings.auto_scrape_interval = 1200; // 20 minutes - bool announce_to_all = pref->announceToAllTrackers(); - sessionSettings.announce_to_all_trackers = announce_to_all; - sessionSettings.announce_to_all_tiers = announce_to_all; - sessionSettings.auto_scrape_min_interval = 900; // 15 minutes - int cache_size = pref->diskCacheSize(); - sessionSettings.cache_size = cache_size ? cache_size * 64 : -1; - sessionSettings.cache_expiry = pref->diskCacheTTL(); - qDebug() << "Using a disk cache size of" << cache_size << "MiB"; - session_settings::io_buffer_mode_t mode = pref->osCache() ? session_settings::enable_os_cache : session_settings::disable_os_cache; - sessionSettings.disk_io_read_mode = mode; - sessionSettings.disk_io_write_mode = mode; - resumeDataTimer.setInterval(pref->saveResumeDataInterval() * 60 * 1000); - sessionSettings.anonymous_mode = pref->isAnonymousModeEnabled(); - if (sessionSettings.anonymous_mode) { - logger->addMessage(tr("Anonymous mode [ON]"), Log::INFO); - } else { - logger->addMessage(tr("Anonymous mode [OFF]"), Log::INFO); - } - // Queueing System - if (pref->isQueueingSystemEnabled()) { - int max_downloading = pref->getMaxActiveDownloads(); - int max_active = pref->getMaxActiveTorrents(); - if (max_downloading > -1) - sessionSettings.active_downloads = max_downloading + HiddenData::getDownloadingSize(); + + // Downloads + // * Save path + defaultSavePath = pref->getSavePath(); + if (pref->isTempPathEnabled()) { + setDefaultTempPath(pref->getTempPath()); + } else { + setDefaultTempPath(QString::null); + } + setAppendLabelToSavePath(pref->appendTorrentLabel()); + setAppendqBExtension(pref->useIncompleteFilesExtension()); + preAllocateAllFiles(pref->preAllocateAllFiles()); + // * Torrent export directory + const bool torrentExportEnabled = pref->isTorrentExportEnabled(); + if (m_torrentExportEnabled != torrentExportEnabled) { + m_torrentExportEnabled = torrentExportEnabled; + if (m_torrentExportEnabled) { + qDebug("Torrent export is enabled, exporting the current torrents"); + exportTorrentFiles(pref->getTorrentExportDir()); + } + } + // * Finished Torrent export directory + const bool finishedTorrentExportEnabled = pref->isFinishedTorrentExportEnabled(); + if (m_finishedTorrentExportEnabled != finishedTorrentExportEnabled) + m_finishedTorrentExportEnabled = finishedTorrentExportEnabled; + // Connection + // * Global download limit + const bool alternative_speeds = pref->isAltBandwidthEnabled(); + int down_limit; + if (alternative_speeds) + down_limit = pref->getAltGlobalDownloadLimit(); else - sessionSettings.active_downloads = max_downloading; - if (max_active > -1) { - int limit = max_active + HiddenData::getDownloadingSize(); - sessionSettings.active_limit = limit; - sessionSettings.active_tracker_limit = limit; - sessionSettings.active_dht_limit = limit; - sessionSettings.active_lsd_limit = limit; + down_limit = pref->getGlobalDownloadLimit(); + if (down_limit <= 0) { + // Download limit disabled + setDownloadRateLimit(-1); + } else { + // Enabled + setDownloadRateLimit(down_limit*1024); } - else { - sessionSettings.active_limit = max_active; - sessionSettings.active_tracker_limit = max_active; - sessionSettings.active_dht_limit = max_active; - sessionSettings.active_lsd_limit = max_active; - } - sessionSettings.active_seeds = pref->getMaxActiveUploads(); - sessionSettings.dont_count_slow_torrents = pref->ignoreSlowTorrentsForQueueing(); - setQueueingEnabled(true); - } else { - sessionSettings.active_downloads = -1; - sessionSettings.active_seeds = -1; - sessionSettings.active_limit = -1; - sessionSettings.active_tracker_limit = -1; - sessionSettings.active_dht_limit = -1; - sessionSettings.active_lsd_limit = -1; - setQueueingEnabled(false); - } - // Outgoing ports - sessionSettings.outgoing_ports = std::make_pair(pref->outgoingPortsMin(), pref->outgoingPortsMax()); - // Ignore limits on LAN - qDebug() << "Ignore limits on LAN" << pref->ignoreLimitsOnLAN(); - sessionSettings.ignore_limits_on_local_network = pref->ignoreLimitsOnLAN(); - // Include overhead in transfer limits - sessionSettings.rate_limit_ip_overhead = pref->includeOverheadInLimits(); - // IP address to announce to trackers - QString announce_ip = pref->getNetworkAddress(); - if (!announce_ip.isEmpty()) - sessionSettings.announce_ip = announce_ip.toStdString(); - // Super seeding - sessionSettings.strict_super_seeding = pref->isSuperSeedingEnabled(); - // * Max Half-open connections - sessionSettings.half_open_limit = pref->getMaxHalfOpenConnections(); - // * Max connections limit - sessionSettings.connections_limit = pref->getMaxConnecs(); - // * Global max upload slots - sessionSettings.unchoke_slots_limit = pref->getMaxUploads(); - // uTP - sessionSettings.enable_incoming_utp = pref->isuTPEnabled(); - sessionSettings.enable_outgoing_utp = pref->isuTPEnabled(); - // uTP rate limiting - sessionSettings.rate_limit_utp = pref->isuTPRateLimited(); - if (sessionSettings.rate_limit_utp) - sessionSettings.mixed_mode_algorithm = session_settings::prefer_tcp; - else - sessionSettings.mixed_mode_algorithm = session_settings::peer_proportional; - sessionSettings.connection_speed = 20; //default is 10 + int up_limit; + if (alternative_speeds) + up_limit = pref->getAltGlobalUploadLimit(); + else + up_limit = pref->getGlobalUploadLimit(); + // * Global Upload limit + if (up_limit <= 0) { + // Upload limit disabled + setUploadRateLimit(-1); + } else { + // Enabled + setUploadRateLimit(up_limit*1024); + } + if (pref->isSchedulerEnabled()) { + if (!bd_scheduler) { + bd_scheduler = new BandwidthScheduler(this); + connect(bd_scheduler, SIGNAL(switchToAlternativeMode(bool)), this, SLOT(useAlternativeSpeedsLimit(bool))); + } + bd_scheduler->start(); + } else { + delete bd_scheduler; + } +#ifndef DISABLE_GUI + // Resolve countries + qDebug("Loading country resolution settings"); + const bool new_resolv_countries = pref->resolvePeerCountries(); + if (resolve_countries != new_resolv_countries) { + qDebug("in country resolution settings"); + resolve_countries = new_resolv_countries; + if (resolve_countries && !geoipDBLoaded) { + qDebug("Loading geoip database"); + GeoIPManager::loadDatabase(s); + geoipDBLoaded = true; + } + // Update torrent handles + std::vector torrents = s->get_torrents(); + + std::vector::iterator torrentIT = torrents.begin(); + std::vector::iterator torrentITend = torrents.end(); + for ( ; torrentIT != torrentITend; ++torrentIT) { + QTorrentHandle h = QTorrentHandle(*torrentIT); + if (h.is_valid()) + h.resolve_countries(resolve_countries); + } + } +#endif + // * UPnP / NAT-PMP + Logger* const logger = Logger::instance(); + if (pref->isUPnPEnabled()) { + enableUPnP(true); + logger->addMessage(tr("UPnP / NAT-PMP support [ON]"), Log::INFO); + } else { + enableUPnP(false); + logger->addMessage(tr("UPnP / NAT-PMP support [OFF]"), Log::INFO); + } + // * Session settings + session_settings sessionSettings = s->settings(); + sessionSettings.user_agent = "qBittorrent " VERSION; + //std::cout << "HTTP user agent is " << sessionSettings.user_agent << std::endl; + logger->addMessage(tr("HTTP user agent is %1").arg(misc::toQString(sessionSettings.user_agent))); + + sessionSettings.upnp_ignore_nonrouters = true; + sessionSettings.use_dht_as_fallback = false; + // Disable support for SSL torrents for now + sessionSettings.ssl_listen = 0; + // To prevent ISPs from blocking seeding + sessionSettings.lazy_bitfields = true; + // Speed up exit + sessionSettings.stop_tracker_timeout = 1; + //sessionSettings.announce_to_all_trackers = true; + sessionSettings.auto_scrape_interval = 1200; // 20 minutes + bool announce_to_all = pref->announceToAllTrackers(); + sessionSettings.announce_to_all_trackers = announce_to_all; + sessionSettings.announce_to_all_tiers = announce_to_all; + sessionSettings.auto_scrape_min_interval = 900; // 15 minutes + int cache_size = pref->diskCacheSize(); + sessionSettings.cache_size = cache_size ? cache_size * 64 : -1; + sessionSettings.cache_expiry = pref->diskCacheTTL(); + qDebug() << "Using a disk cache size of" << cache_size << "MiB"; + session_settings::io_buffer_mode_t mode = pref->osCache() ? session_settings::enable_os_cache : session_settings::disable_os_cache; + sessionSettings.disk_io_read_mode = mode; + sessionSettings.disk_io_write_mode = mode; + resumeDataTimer.setInterval(pref->saveResumeDataInterval() * 60 * 1000); + sessionSettings.anonymous_mode = pref->isAnonymousModeEnabled(); + if (sessionSettings.anonymous_mode) { + logger->addMessage(tr("Anonymous mode [ON]"), Log::INFO); + } else { + logger->addMessage(tr("Anonymous mode [OFF]"), Log::INFO); + } + // Queueing System + if (pref->isQueueingSystemEnabled()) { + int max_downloading = pref->getMaxActiveDownloads(); + int max_active = pref->getMaxActiveTorrents(); + if (max_downloading > -1) + sessionSettings.active_downloads = max_downloading + HiddenData::getDownloadingSize(); + else + sessionSettings.active_downloads = max_downloading; + if (max_active > -1) { + int limit = max_active + HiddenData::getDownloadingSize(); + sessionSettings.active_limit = limit; + sessionSettings.active_tracker_limit = limit; + sessionSettings.active_dht_limit = limit; + sessionSettings.active_lsd_limit = limit; + } + else { + sessionSettings.active_limit = max_active; + sessionSettings.active_tracker_limit = max_active; + sessionSettings.active_dht_limit = max_active; + sessionSettings.active_lsd_limit = max_active; + } + sessionSettings.active_seeds = pref->getMaxActiveUploads(); + sessionSettings.dont_count_slow_torrents = pref->ignoreSlowTorrentsForQueueing(); + setQueueingEnabled(true); + } else { + sessionSettings.active_downloads = -1; + sessionSettings.active_seeds = -1; + sessionSettings.active_limit = -1; + sessionSettings.active_tracker_limit = -1; + sessionSettings.active_dht_limit = -1; + sessionSettings.active_lsd_limit = -1; + setQueueingEnabled(false); + } + // Outgoing ports + sessionSettings.outgoing_ports = std::make_pair(pref->outgoingPortsMin(), pref->outgoingPortsMax()); + // Ignore limits on LAN + qDebug() << "Ignore limits on LAN" << pref->ignoreLimitsOnLAN(); + sessionSettings.ignore_limits_on_local_network = pref->ignoreLimitsOnLAN(); + // Include overhead in transfer limits + sessionSettings.rate_limit_ip_overhead = pref->includeOverheadInLimits(); + // IP address to announce to trackers + QString announce_ip = pref->getNetworkAddress(); + if (!announce_ip.isEmpty()) + sessionSettings.announce_ip = announce_ip.toStdString(); + // Super seeding + sessionSettings.strict_super_seeding = pref->isSuperSeedingEnabled(); + // * Max Half-open connections + sessionSettings.half_open_limit = pref->getMaxHalfOpenConnections(); + // * Max connections limit + sessionSettings.connections_limit = pref->getMaxConnecs(); + // * Global max upload slots + sessionSettings.unchoke_slots_limit = pref->getMaxUploads(); + // uTP + sessionSettings.enable_incoming_utp = pref->isuTPEnabled(); + sessionSettings.enable_outgoing_utp = pref->isuTPEnabled(); + // uTP rate limiting + sessionSettings.rate_limit_utp = pref->isuTPRateLimited(); + if (sessionSettings.rate_limit_utp) + sessionSettings.mixed_mode_algorithm = session_settings::prefer_tcp; + else + sessionSettings.mixed_mode_algorithm = session_settings::peer_proportional; + sessionSettings.connection_speed = 20; //default is 10 #if LIBTORRENT_VERSION_NUM >= 10000 - if (pref->isProxyEnabled()) - sessionSettings.force_proxy = pref->getForceProxy(); - else - sessionSettings.force_proxy = false; + if (pref->isProxyEnabled()) + sessionSettings.force_proxy = pref->getForceProxy(); + else + sessionSettings.force_proxy = false; #endif - sessionSettings.no_connect_privileged_ports = false; - sessionSettings.seed_choking_algorithm = session_settings::fastest_upload; - qDebug() << "Settings SessionSettings"; - setSessionSettings(sessionSettings); - // Bittorrent - // * Max connections per torrent limit - setMaxConnectionsPerTorrent(pref->getMaxConnecsPerTorrent()); - // * Max uploads per torrent limit - setMaxUploadsPerTorrent(pref->getMaxUploadsPerTorrent()); - // * DHT - enableDHT(pref->isDHTEnabled()); - // * PeX - if (PeXEnabled) { - logger->addMessage(tr("PeX support [ON]"), Log::INFO); - } else { - logger->addMessage(tr("PeX support [OFF]"), Log::CRITICAL); - } - if (PeXEnabled != pref->isPeXEnabled()) { - logger->addMessage(tr("Restart is required to toggle PeX support"), Log::CRITICAL); - } - // * LSD - if (pref->isLSDEnabled()) { - enableLSD(true); - logger->addMessage(tr("Local Peer Discovery support [ON]"), Log::INFO); - } else { - enableLSD(false); - logger->addMessage(tr("Local Peer Discovery support [OFF]"), Log::INFO); - } - // * Encryption - const int encryptionState = pref->getEncryptionSetting(); - // The most secure, rc4 only so that all streams and encrypted - pe_settings encryptionSettings; - encryptionSettings.allowed_enc_level = pe_settings::rc4; - encryptionSettings.prefer_rc4 = true; - switch(encryptionState) { - case 0: //Enabled - encryptionSettings.out_enc_policy = pe_settings::enabled; - encryptionSettings.in_enc_policy = pe_settings::enabled; - logger->addMessage(tr("Encryption support [ON]"), Log::INFO); - break; - case 1: // Forced - encryptionSettings.out_enc_policy = pe_settings::forced; - encryptionSettings.in_enc_policy = pe_settings::forced; - logger->addMessage(tr("Encryption support [FORCED]"), Log::INFO); - break; - default: // Disabled - encryptionSettings.out_enc_policy = pe_settings::disabled; - encryptionSettings.in_enc_policy = pe_settings::disabled; - logger->addMessage(tr("Encryption support [OFF]"), Log::INFO); - } - applyEncryptionSettings(encryptionSettings); - // * Maximum ratio - high_ratio_action = pref->getMaxRatioAction(); - setGlobalMaxRatio(pref->getGlobalMaxRatio()); - updateRatioTimer(); - // Ip Filter - FilterParserThread::processFilterList(s, pref->bannedIPs()); - if (pref->isFilteringEnabled()) { - enableIPFilter(pref->getFilter()); - }else{ - disableIPFilter(); - } - // * Proxy settings - proxy_settings proxySettings; - if (pref->isProxyEnabled()) { - qDebug("Enabling P2P proxy"); - proxySettings.hostname = pref->getProxyIp().toStdString(); - qDebug("hostname is %s", proxySettings.hostname.c_str()); - proxySettings.port = pref->getProxyPort(); - qDebug("port is %d", proxySettings.port); - if (pref->isProxyAuthEnabled()) { - proxySettings.username = pref->getProxyUsername().toStdString(); - proxySettings.password = pref->getProxyPassword().toStdString(); - qDebug("username is %s", proxySettings.username.c_str()); - qDebug("password is %s", proxySettings.password.c_str()); - } - } - switch(pref->getProxyType()) { - case Proxy::HTTP: - qDebug("type: http"); - proxySettings.type = proxy_settings::http; - break; - case Proxy::HTTP_PW: - qDebug("type: http_pw"); - proxySettings.type = proxy_settings::http_pw; - break; - case Proxy::SOCKS4: - proxySettings.type = proxy_settings::socks4; - break; - case Proxy::SOCKS5: - qDebug("type: socks5"); - proxySettings.type = proxy_settings::socks5; - break; - case Proxy::SOCKS5_PW: - qDebug("type: socks5_pw"); - proxySettings.type = proxy_settings::socks5_pw; - break; - default: - proxySettings.type = proxy_settings::none; - } - setProxySettings(proxySettings); - // Tracker - if (pref->isTrackerEnabled()) { - if (!m_tracker) { - m_tracker = new QTracker(this); - } - if (m_tracker->start()) { - logger->addMessage(tr("Embedded Tracker [ON]"), Log::INFO); + sessionSettings.no_connect_privileged_ports = false; + sessionSettings.seed_choking_algorithm = session_settings::fastest_upload; + qDebug() << "Settings SessionSettings"; + setSessionSettings(sessionSettings); + // Bittorrent + // * Max connections per torrent limit + setMaxConnectionsPerTorrent(pref->getMaxConnecsPerTorrent()); + // * Max uploads per torrent limit + setMaxUploadsPerTorrent(pref->getMaxUploadsPerTorrent()); + // * DHT + enableDHT(pref->isDHTEnabled()); + // * PeX + if (PeXEnabled) { + logger->addMessage(tr("PeX support [ON]"), Log::INFO); } else { - logger->addMessage(tr("Failed to start the embedded tracker!"), Log::CRITICAL); + logger->addMessage(tr("PeX support [OFF]"), Log::CRITICAL); } - } else { - logger->addMessage(tr("Embedded Tracker [OFF]")); - if (m_tracker) - delete m_tracker; - } - // * Scan dirs - const QStringList scan_dirs = pref->getScanDirs(); - QList downloadInDirList = pref->getDownloadInScanDirs(); - while(scan_dirs.size() > downloadInDirList.size()) { - downloadInDirList << false; - } - int i = 0; - foreach (const QString &dir, scan_dirs) { - qDebug() << "Adding scan dir" << dir << downloadInDirList.at(i); - m_scanFolders->addPath(dir, downloadInDirList.at(i)); - ++i; - } - qDebug("Session configured"); + if (PeXEnabled != pref->isPeXEnabled()) { + logger->addMessage(tr("Restart is required to toggle PeX support"), Log::CRITICAL); + } + // * LSD + if (pref->isLSDEnabled()) { + enableLSD(true); + logger->addMessage(tr("Local Peer Discovery support [ON]"), Log::INFO); + } else { + enableLSD(false); + logger->addMessage(tr("Local Peer Discovery support [OFF]"), Log::INFO); + } + // * Encryption + const int encryptionState = pref->getEncryptionSetting(); + // The most secure, rc4 only so that all streams and encrypted + pe_settings encryptionSettings; + encryptionSettings.allowed_enc_level = pe_settings::rc4; + encryptionSettings.prefer_rc4 = true; + switch(encryptionState) { + case 0: //Enabled + encryptionSettings.out_enc_policy = pe_settings::enabled; + encryptionSettings.in_enc_policy = pe_settings::enabled; + logger->addMessage(tr("Encryption support [ON]"), Log::INFO); + break; + case 1: // Forced + encryptionSettings.out_enc_policy = pe_settings::forced; + encryptionSettings.in_enc_policy = pe_settings::forced; + logger->addMessage(tr("Encryption support [FORCED]"), Log::INFO); + break; + default: // Disabled + encryptionSettings.out_enc_policy = pe_settings::disabled; + encryptionSettings.in_enc_policy = pe_settings::disabled; + logger->addMessage(tr("Encryption support [OFF]"), Log::INFO); + } + applyEncryptionSettings(encryptionSettings); + // * Maximum ratio + high_ratio_action = pref->getMaxRatioAction(); + setGlobalMaxRatio(pref->getGlobalMaxRatio()); + updateRatioTimer(); + // Ip Filter + FilterParserThread::processFilterList(s, pref->bannedIPs()); + if (pref->isFilteringEnabled()) { + enableIPFilter(pref->getFilter()); + }else{ + disableIPFilter(); + } + // * Proxy settings + proxy_settings proxySettings; + if (pref->isProxyEnabled()) { + qDebug("Enabling P2P proxy"); + proxySettings.hostname = pref->getProxyIp().toStdString(); + qDebug("hostname is %s", proxySettings.hostname.c_str()); + proxySettings.port = pref->getProxyPort(); + qDebug("port is %d", proxySettings.port); + if (pref->isProxyAuthEnabled()) { + proxySettings.username = pref->getProxyUsername().toStdString(); + proxySettings.password = pref->getProxyPassword().toStdString(); + qDebug("username is %s", proxySettings.username.c_str()); + qDebug("password is %s", proxySettings.password.c_str()); + } + } + switch(pref->getProxyType()) { + case Proxy::HTTP: + qDebug("type: http"); + proxySettings.type = proxy_settings::http; + break; + case Proxy::HTTP_PW: + qDebug("type: http_pw"); + proxySettings.type = proxy_settings::http_pw; + break; + case Proxy::SOCKS4: + proxySettings.type = proxy_settings::socks4; + break; + case Proxy::SOCKS5: + qDebug("type: socks5"); + proxySettings.type = proxy_settings::socks5; + break; + case Proxy::SOCKS5_PW: + qDebug("type: socks5_pw"); + proxySettings.type = proxy_settings::socks5_pw; + break; + default: + proxySettings.type = proxy_settings::none; + } + setProxySettings(proxySettings); + // Tracker + if (pref->isTrackerEnabled()) { + if (!m_tracker) { + m_tracker = new QTracker(this); + } + if (m_tracker->start()) { + logger->addMessage(tr("Embedded Tracker [ON]"), Log::INFO); + } else { + logger->addMessage(tr("Failed to start the embedded tracker!"), Log::CRITICAL); + } + } else { + logger->addMessage(tr("Embedded Tracker [OFF]")); + if (m_tracker) + delete m_tracker; + } + // * Scan dirs + const QStringList scan_dirs = pref->getScanDirs(); + QList downloadInDirList = pref->getDownloadInScanDirs(); + while(scan_dirs.size() > downloadInDirList.size()) { + downloadInDirList << false; + } + int i = 0; + foreach (const QString &dir, scan_dirs) { + qDebug() << "Adding scan dir" << dir << downloadInDirList.at(i); + m_scanFolders->addPath(dir, downloadInDirList.at(i)); + ++i; + } + qDebug("Session configured"); } void QBtSession::useAlternativeSpeedsLimit(bool alternative) { - qDebug() << Q_FUNC_INFO << alternative; - // Save new state to remember it on startup - Preferences* const pref = Preferences::instance(); - // Stop the scheduler when the user has manually changed the bandwidth mode - if (!pref->isSchedulerEnabled()) - delete bd_scheduler; - pref->setAltBandwidthEnabled(alternative); - // Apply settings to the bittorrent session - int down_limit = alternative ? pref->getAltGlobalDownloadLimit() : pref->getGlobalDownloadLimit(); - if (down_limit <= 0) { - down_limit = -1; - } else { - down_limit *= 1024; - } - setDownloadRateLimit(down_limit); - // Upload rate - int up_limit = alternative ? pref->getAltGlobalUploadLimit() : pref->getGlobalUploadLimit(); - if (up_limit <= 0) { - up_limit = -1; - } else { - up_limit *= 1024; - } - setUploadRateLimit(up_limit); - // Notify - emit alternativeSpeedsModeChanged(alternative); + qDebug() << Q_FUNC_INFO << alternative; + // Save new state to remember it on startup + Preferences* const pref = Preferences::instance(); + // Stop the scheduler when the user has manually changed the bandwidth mode + if (!pref->isSchedulerEnabled()) + delete bd_scheduler; + pref->setAltBandwidthEnabled(alternative); + // Apply settings to the bittorrent session + int down_limit = alternative ? pref->getAltGlobalDownloadLimit() : pref->getGlobalDownloadLimit(); + if (down_limit <= 0) { + down_limit = -1; + } else { + down_limit *= 1024; + } + setDownloadRateLimit(down_limit); + // Upload rate + int up_limit = alternative ? pref->getAltGlobalUploadLimit() : pref->getGlobalUploadLimit(); + if (up_limit <= 0) { + up_limit = -1; + } else { + up_limit *= 1024; + } + setUploadRateLimit(up_limit); + // Notify + emit alternativeSpeedsModeChanged(alternative); } // Return the torrent handle, given its hash QTorrentHandle QBtSession::getTorrentHandle(const QString &hash) const { - return QTorrentHandle(s->find_torrent(QStringToSha1(hash))); + return QTorrentHandle(s->find_torrent(QStringToSha1(hash))); } bool QBtSession::hasActiveTorrents() const { - std::vector torrents = s->get_torrents(); + std::vector torrents = s->get_torrents(); - std::vector::iterator torrentIT = torrents.begin(); - std::vector::iterator torrentITend = torrents.end(); - for ( ; torrentIT != torrentITend; ++torrentIT) { - const QTorrentHandle h(*torrentIT); - if (h.is_valid() && !h.is_paused() && !h.is_queued()) - return true; - } - return false; + std::vector::iterator torrentIT = torrents.begin(); + std::vector::iterator torrentITend = torrents.end(); + for ( ; torrentIT != torrentITend; ++torrentIT) { + const QTorrentHandle h(*torrentIT); + if (h.is_valid() && !h.is_paused() && !h.is_queued()) + return true; + } + return false; } bool QBtSession::hasDownloadingTorrents() const { - std::vector torrents = s->get_torrents(); + std::vector torrents = s->get_torrents(); - std::vector::iterator torrentIT = torrents.begin(); - std::vector::iterator torrentITend = torrents.end(); - for ( ; torrentIT != torrentITend; ++torrentIT) { - if (torrentIT->is_valid()) { - try { - const torrent_status status = torrentIT->status(); - if (status.state != torrent_status::finished && status.state != torrent_status::seeding - && !(status.paused && !status.auto_managed)) - return true; - } catch(std::exception) {} + std::vector::iterator torrentIT = torrents.begin(); + std::vector::iterator torrentITend = torrents.end(); + for ( ; torrentIT != torrentITend; ++torrentIT) { + if (torrentIT->is_valid()) { + try { + const torrent_status status = torrentIT->status(); + if (status.state != torrent_status::finished && status.state != torrent_status::seeding + && !(status.paused && !status.auto_managed)) + return true; + } catch(std::exception) {} + } } - } - return false; + return false; } void QBtSession::banIP(QString ip) { - FilterParserThread::processFilterList(s, QStringList(ip)); - Preferences::instance()->banIP(ip); + FilterParserThread::processFilterList(s, QStringList(ip)); + Preferences::instance()->banIP(ip); } // Delete a torrent from the session, given its hash // permanent = true means that the torrent will be removed from the hard-drive too void QBtSession::deleteTorrent(const QString &hash, bool delete_local_files) { - qDebug("Deleting torrent with hash: %s", qPrintable(hash)); - const QTorrentHandle h = getTorrentHandle(hash); - if (!h.is_valid()) { - qDebug("/!\\ Error: Invalid handle"); - return; - } - emit torrentAboutToBeRemoved(h); - qDebug("h is valid, getting name or hash..."); - QString fileName; - if (h.has_metadata()) - fileName = h.name(); - else - fileName = h.hash(); - // Remove it from session - if (delete_local_files) { - if (h.has_metadata()) { - QDir save_dir(h.save_path()); - if (save_dir != QDir(defaultSavePath) && (defaultTempPath.isEmpty() || save_dir != QDir(defaultTempPath))) { - savePathsToRemove[hash] = save_dir.absolutePath(); - qDebug() << "Save path to remove (async): " << save_dir.absolutePath(); - } + qDebug("Deleting torrent with hash: %s", qPrintable(hash)); + const QTorrentHandle h = getTorrentHandle(hash); + if (!h.is_valid()) { + qDebug("/!\\ Error: Invalid handle"); + return; } - s->remove_torrent(h, session::delete_files); - } else { - QStringList uneeded_files; + emit torrentAboutToBeRemoved(h); + qDebug("h is valid, getting name or hash..."); + QString fileName; if (h.has_metadata()) - uneeded_files = h.absolute_files_path_uneeded(); - s->remove_torrent(h); - // Remove unneeded and incomplete files - foreach (const QString &uneeded_file, uneeded_files) { - qDebug("Removing uneeded file: %s", qPrintable(uneeded_file)); - fsutils::forceRemove(uneeded_file); - const QString parent_folder = fsutils::branchPath(uneeded_file); - qDebug("Attempt to remove parent folder (if empty): %s", qPrintable(parent_folder)); - QDir().rmpath(parent_folder); - } - } - // Remove it from torrent backup directory - QDir torrentBackup(fsutils::BTBackupLocation()); - QStringList filters; - filters << hash+".*"; - const QStringList files = torrentBackup.entryList(filters, QDir::Files, QDir::Unsorted); - foreach (const QString &file, files) { - fsutils::forceRemove(torrentBackup.absoluteFilePath(file)); - } - TorrentPersistentData::instance()->deletePersistentData(hash); - TorrentTempData::deleteTempData(hash); - HiddenData::deleteData(hash); - // Remove tracker errors - trackersInfos.remove(hash); - if (delete_local_files) - Logger::instance()->addMessage(tr("'%1' was removed from transfer list and hard disk.", "'xxx.avi' was removed...").arg(fileName)); - else - Logger::instance()->addMessage(tr("'%1' was removed from transfer list.", "'xxx.avi' was removed...").arg(fileName)); - qDebug("Torrent deleted."); + fileName = h.name(); + else + fileName = h.hash(); + // Remove it from session + if (delete_local_files) { + if (h.has_metadata()) { + QDir save_dir(h.save_path()); + if (save_dir != QDir(defaultSavePath) && (defaultTempPath.isEmpty() || save_dir != QDir(defaultTempPath))) { + savePathsToRemove[hash] = save_dir.absolutePath(); + qDebug() << "Save path to remove (async): " << save_dir.absolutePath(); + } + } + s->remove_torrent(h, session::delete_files); + } else { + QStringList uneeded_files; + if (h.has_metadata()) + uneeded_files = h.absolute_files_path_uneeded(); + s->remove_torrent(h); + // Remove unneeded and incomplete files + foreach (const QString &uneeded_file, uneeded_files) { + qDebug("Removing uneeded file: %s", qPrintable(uneeded_file)); + fsutils::forceRemove(uneeded_file); + const QString parent_folder = fsutils::branchPath(uneeded_file); + qDebug("Attempt to remove parent folder (if empty): %s", qPrintable(parent_folder)); + QDir().rmpath(parent_folder); + } + } + // Remove it from torrent backup directory + QDir torrentBackup(fsutils::BTBackupLocation()); + QStringList filters; + filters << hash+".*"; + const QStringList files = torrentBackup.entryList(filters, QDir::Files, QDir::Unsorted); + foreach (const QString &file, files) { + fsutils::forceRemove(torrentBackup.absoluteFilePath(file)); + } + TorrentPersistentData::instance()->deletePersistentData(hash); + TorrentTempData::deleteTempData(hash); + HiddenData::deleteData(hash); + // Remove tracker errors + trackersInfos.remove(hash); + if (delete_local_files) + Logger::instance()->addMessage(tr("'%1' was removed from transfer list and hard disk.", "'xxx.avi' was removed...").arg(fileName)); + else + Logger::instance()->addMessage(tr("'%1' was removed from transfer list.", "'xxx.avi' was removed...").arg(fileName)); + qDebug("Torrent deleted."); } void QBtSession::pauseAllTorrents() { - std::vector torrents = s->get_torrents(); + std::vector torrents = s->get_torrents(); - std::vector::iterator torrentIT = torrents.begin(); - std::vector::iterator torrentITend = torrents.end(); - for ( ; torrentIT != torrentITend; ++torrentIT) { - try { - QTorrentHandle h = QTorrentHandle(*torrentIT); - if (!h.is_paused()) { - h.pause(); - emit pausedTorrent(h); - } - } catch(invalid_handle&) {} - } + std::vector::iterator torrentIT = torrents.begin(); + std::vector::iterator torrentITend = torrents.end(); + for ( ; torrentIT != torrentITend; ++torrentIT) { + try { + QTorrentHandle h = QTorrentHandle(*torrentIT); + if (!h.is_paused()) { + h.pause(); + emit pausedTorrent(h); + } + } catch(invalid_handle&) {} + } } std::vector QBtSession::getTorrents() const { - return s->get_torrents(); + return s->get_torrents(); } void QBtSession::resumeAllTorrents() { - std::vector torrents = s->get_torrents(); + std::vector torrents = s->get_torrents(); - std::vector::iterator torrentIT = torrents.begin(); - std::vector::iterator torrentITend = torrents.end(); - for ( ; torrentIT != torrentITend; ++torrentIT) { - try { - QTorrentHandle h = QTorrentHandle(*torrentIT); - if (h.is_paused()) { - h.resume(); - emit resumedTorrent(h); - } - } catch(invalid_handle&) {} - } + std::vector::iterator torrentIT = torrents.begin(); + std::vector::iterator torrentITend = torrents.end(); + for ( ; torrentIT != torrentITend; ++torrentIT) { + try { + QTorrentHandle h = QTorrentHandle(*torrentIT); + if (h.is_paused()) { + h.resume(); + emit resumedTorrent(h); + } + } catch(invalid_handle&) {} + } } void QBtSession::pauseTorrent(const QString &hash) { - QTorrentHandle h = getTorrentHandle(hash); - if (!h.is_paused()) { - h.pause(); - emit pausedTorrent(h); - } + QTorrentHandle h = getTorrentHandle(hash); + if (!h.is_paused()) { + h.pause(); + emit pausedTorrent(h); + } } void QBtSession::resumeTorrent(const QString &hash) { - QTorrentHandle h = getTorrentHandle(hash); - if (h.is_paused()) { - h.resume(); - emit resumedTorrent(h); - } + QTorrentHandle h = getTorrentHandle(hash); + if (h.is_paused()) { + h.resume(); + emit resumedTorrent(h); + } } bool QBtSession::loadFastResumeData(const QString &hash, std::vector &buf) { - const QString fastresume_path = QDir(fsutils::BTBackupLocation()).absoluteFilePath(hash+QString(".fastresume")); - qDebug("Trying to load fastresume data: %s", qPrintable(fastresume_path)); - QFile fastresume_file(fastresume_path); - if (fastresume_file.size() <= 0) - return false; - if (!fastresume_file.open(QIODevice::ReadOnly)) - return false; - const QByteArray content = fastresume_file.readAll(); - const int content_size = content.size(); - Q_ASSERT(content_size > 0); - buf.resize(content_size); - memcpy(&buf[0], content.data(), content_size); - fastresume_file.close(); - return true; + const QString fastresume_path = QDir(fsutils::BTBackupLocation()).absoluteFilePath(hash+QString(".fastresume")); + qDebug("Trying to load fastresume data: %s", qPrintable(fastresume_path)); + QFile fastresume_file(fastresume_path); + if (fastresume_file.size() <= 0) + return false; + if (!fastresume_file.open(QIODevice::ReadOnly)) + return false; + const QByteArray content = fastresume_file.readAll(); + const int content_size = content.size(); + Q_ASSERT(content_size > 0); + buf.resize(content_size); + memcpy(&buf[0], content.data(), content_size); + fastresume_file.close(); + return true; } void QBtSession::loadTorrentSettings(QTorrentHandle& h) { - Preferences* const pref = Preferences::instance(); - // Connections limit per torrent - h.set_max_connections(pref->getMaxConnecsPerTorrent()); - // Uploads limit per torrent - h.set_max_uploads(pref->getMaxUploadsPerTorrent()); + Preferences* const pref = Preferences::instance(); + // Connections limit per torrent + h.set_max_connections(pref->getMaxConnecsPerTorrent()); + // Uploads limit per torrent + h.set_max_uploads(pref->getMaxUploadsPerTorrent()); #ifndef DISABLE_GUI - // Resolve countries - h.resolve_countries(resolve_countries); + // Resolve countries + h.resolve_countries(resolve_countries); #endif } QTorrentHandle QBtSession::addMagnetUri(QString magnet_uri, bool resumed, bool fromScanDir, const QString &filePath) { - Q_UNUSED(fromScanDir); - Q_UNUSED(filePath); - Preferences* const pref = Preferences::instance(); - Logger* const logger = Logger::instance(); - QTorrentHandle h; - add_torrent_params p; - libtorrent::error_code ec; - - libtorrent::parse_magnet_uri(magnet_uri.toUtf8().constData(), p, ec); - if (ec) { - logger->addMessage(tr("Couldn't parse this Magnet URI: '%1'").arg(magnet_uri)); - return h; - } - const QString hash(misc::toQString(p.info_hash)); - if (hash.isEmpty()) { - logger->addMessage(tr("'%1' is not a valid magnet URI.").arg(magnet_uri)); - return h; - } - const QDir torrentBackup(fsutils::BTBackupLocation()); - if (resumed) { - // Load metadata - const QString torrent_path = torrentBackup.absoluteFilePath(hash+".torrent"); - if (QFile::exists(torrent_path)) - return addTorrent(torrent_path, false, QString::null, true); - } - qDebug("Adding a magnet URI: %s", qPrintable(hash)); - Q_ASSERT(magnet_uri.startsWith("magnet:", Qt::CaseInsensitive)); - - // limit h_ex scope - { - // Check for duplicate torrent - QTorrentHandle h_ex = QTorrentHandle(s->find_torrent(p.info_hash)); - if (h_ex.is_valid()) { - qDebug("/!\\ Torrent is already in download list"); - logger->addMessage(tr("'%1' is already in download list.", "e.g: 'xxx.avi' is already in download list.").arg(magnet_uri)); - // Check if the torrent contains trackers or url seeds we don't know about - // and add them - mergeTorrents(h_ex, magnet_uri); - return h; - } - } - - initializeAddTorrentParams(hash, p); - - // Get save path - QString savePath; - if (!resumed && savepathLabel_fromurl.contains(magnet_uri)) { - QPair savePath_label = savepathLabel_fromurl.take(magnet_uri); - if(!savePath_label.first.isEmpty()) - savePath = savePath_label.first; - // Remember label - if(!savePath_label.second.isEmpty()) - TorrentTempData::setLabel(hash, savePath_label.second); - } - if (savePath.isEmpty()) - savePath = getSavePath(hash, false); - if (!defaultTempPath.isEmpty() && !TorrentPersistentData::instance()->isSeed(hash)) { - qDebug("addMagnetURI: Temp folder is enabled."); - QString torrent_tmp_path = defaultTempPath; - p.save_path = fsutils::toNativePath(torrent_tmp_path).toUtf8().constData(); - // Check if save path exists, creating it otherwise - if (!QDir(torrent_tmp_path).exists()) - QDir().mkpath(torrent_tmp_path); - qDebug("addTorrent: using save_path: %s", qPrintable(torrent_tmp_path)); - } else { - p.save_path = fsutils::toNativePath(savePath).toUtf8().constData(); - // Check if save path exists, creating it otherwise - if (!QDir(savePath).exists()) QDir().mkpath(savePath); - qDebug("addTorrent: using save_path: %s", qPrintable(savePath)); - } - - qDebug("Adding magnet URI: %s", qPrintable(magnet_uri)); - - // Adding torrent to Bittorrent session - try { - h = QTorrentHandle(s->add_torrent(p)); - }catch(std::exception &e) { - qDebug("Error: %s", e.what()); - } - // Check if it worked - if (!h.is_valid()) { - // No need to keep on, it failed. - qDebug("/!\\ Error: Invalid handle"); - return h; - } - Q_ASSERT(h.hash() == hash); - - loadTorrentSettings(h); - - // Load filtered files - bool add_paused = pref->addTorrentsInPause(); - if (!resumed) { - if (TorrentTempData::hasTempData(hash)) - add_paused = TorrentTempData::isAddPaused(hash); - loadTorrentTempData(h, savePath, true); - } - if (HiddenData::hasData(hash) && pref->isQueueingSystemEnabled()) { - //Internally increase the queue limits to ensure that the magnet is started - libtorrent::session_settings sessionSettings(s->settings()); - int max_downloading = pref->getMaxActiveDownloads(); - int max_active = pref->getMaxActiveTorrents(); - if (max_downloading > -1) - sessionSettings.active_downloads = max_downloading + HiddenData::getDownloadingSize(); - else - sessionSettings.active_downloads = max_downloading; - if (max_active > -1) - sessionSettings.active_limit = max_active + HiddenData::getDownloadingSize(); - else - sessionSettings.active_limit = max_active; - s->set_settings(sessionSettings); - h.queue_position_top(); - } - if (!add_paused || HiddenData::hasData(hash)) { - // Start torrent because it was added in paused state - h.resume(); - } - // Send torrent addition signal - logger->addMessage(tr("'%1' added to download list.", "'/home/y/xxx.torrent' was added to download list.").arg(magnet_uri)); - if (!HiddenData::hasData(hash)) - emit addedTorrent(h); + Q_UNUSED(fromScanDir); + Q_UNUSED(filePath); + Preferences* const pref = Preferences::instance(); + Logger* const logger = Logger::instance(); + QTorrentHandle h; + add_torrent_params p; + libtorrent::error_code ec; + + libtorrent::parse_magnet_uri(magnet_uri.toUtf8().constData(), p, ec); + if (ec) { + logger->addMessage(tr("Couldn't parse this Magnet URI: '%1'").arg(magnet_uri)); + return h; + } + const QString hash(misc::toQString(p.info_hash)); + if (hash.isEmpty()) { + logger->addMessage(tr("'%1' is not a valid magnet URI.").arg(magnet_uri)); + return h; + } + const QDir torrentBackup(fsutils::BTBackupLocation()); + if (resumed) { + // Load metadata + const QString torrent_path = torrentBackup.absoluteFilePath(hash+".torrent"); + if (QFile::exists(torrent_path)) + return addTorrent(torrent_path, false, QString::null, true); + } + qDebug("Adding a magnet URI: %s", qPrintable(hash)); + Q_ASSERT(magnet_uri.startsWith("magnet:", Qt::CaseInsensitive)); + + // limit h_ex scope + { + // Check for duplicate torrent + QTorrentHandle h_ex = QTorrentHandle(s->find_torrent(p.info_hash)); + if (h_ex.is_valid()) { + qDebug("/!\\ Torrent is already in download list"); + logger->addMessage(tr("'%1' is already in download list.", "e.g: 'xxx.avi' is already in download list.").arg(magnet_uri)); + // Check if the torrent contains trackers or url seeds we don't know about + // and add them + mergeTorrents(h_ex, magnet_uri); + return h; + } + } - return h; + initializeAddTorrentParams(hash, p); + + // Get save path + QString savePath; + if (!resumed && savepathLabel_fromurl.contains(magnet_uri)) { + QPair savePath_label = savepathLabel_fromurl.take(magnet_uri); + if(!savePath_label.first.isEmpty()) + savePath = savePath_label.first; + // Remember label + if(!savePath_label.second.isEmpty()) + TorrentTempData::setLabel(hash, savePath_label.second); + } + if (savePath.isEmpty()) + savePath = getSavePath(hash, false); + if (!defaultTempPath.isEmpty() && !TorrentPersistentData::instance()->isSeed(hash)) { + qDebug("addMagnetURI: Temp folder is enabled."); + QString torrent_tmp_path = defaultTempPath; + p.save_path = fsutils::toNativePath(torrent_tmp_path).toUtf8().constData(); + // Check if save path exists, creating it otherwise + if (!QDir(torrent_tmp_path).exists()) + QDir().mkpath(torrent_tmp_path); + qDebug("addTorrent: using save_path: %s", qPrintable(torrent_tmp_path)); + } else { + p.save_path = fsutils::toNativePath(savePath).toUtf8().constData(); + // Check if save path exists, creating it otherwise + if (!QDir(savePath).exists()) QDir().mkpath(savePath); + qDebug("addTorrent: using save_path: %s", qPrintable(savePath)); + } + + qDebug("Adding magnet URI: %s", qPrintable(magnet_uri)); + + // Adding torrent to Bittorrent session + try { + h = QTorrentHandle(s->add_torrent(p)); + }catch(std::exception &e) { + qDebug("Error: %s", e.what()); + } + // Check if it worked + if (!h.is_valid()) { + // No need to keep on, it failed. + qDebug("/!\\ Error: Invalid handle"); + return h; + } + Q_ASSERT(h.hash() == hash); + + loadTorrentSettings(h); + + // Load filtered files + bool add_paused = pref->addTorrentsInPause(); + if (!resumed) { + if (TorrentTempData::hasTempData(hash)) + add_paused = TorrentTempData::isAddPaused(hash); + loadTorrentTempData(h, savePath, true); + } + if (HiddenData::hasData(hash) && pref->isQueueingSystemEnabled()) { + //Internally increase the queue limits to ensure that the magnet is started + libtorrent::session_settings sessionSettings(s->settings()); + int max_downloading = pref->getMaxActiveDownloads(); + int max_active = pref->getMaxActiveTorrents(); + if (max_downloading > -1) + sessionSettings.active_downloads = max_downloading + HiddenData::getDownloadingSize(); + else + sessionSettings.active_downloads = max_downloading; + if (max_active > -1) + sessionSettings.active_limit = max_active + HiddenData::getDownloadingSize(); + else + sessionSettings.active_limit = max_active; + s->set_settings(sessionSettings); + h.queue_position_top(); + } + if (!add_paused || HiddenData::hasData(hash)) { + // Start torrent because it was added in paused state + h.resume(); + } + // Send torrent addition signal + logger->addMessage(tr("'%1' added to download list.", "'/home/y/xxx.torrent' was added to download list.").arg(magnet_uri)); + if (!HiddenData::hasData(hash)) + emit addedTorrent(h); + + return h; } // Add a torrent to the Bittorrent session QTorrentHandle QBtSession::addTorrent(QString path, bool fromScanDir, QString from_url, bool resumed, bool imported) { - QTorrentHandle h; - Preferences* const pref = Preferences::instance(); - Logger* const logger = Logger::instance(); + QTorrentHandle h; + Preferences* const pref = Preferences::instance(); + Logger* const logger = Logger::instance(); - // Check if BT_backup directory exists - const QDir torrentBackup(fsutils::BTBackupLocation()); - if (!torrentBackup.exists()) { - // If temporary file, remove it - if (!from_url.isNull() || fromScanDir) - fsutils::forceRemove(path); - return h; - } + // Check if BT_backup directory exists + const QDir torrentBackup(fsutils::BTBackupLocation()); + if (!torrentBackup.exists()) { + // If temporary file, remove it + if (!from_url.isNull() || fromScanDir) + fsutils::forceRemove(path); + return h; + } - // Fix the input path if necessary - path = fsutils::fromNativePath(path); + // Fix the input path if necessary + path = fsutils::fromNativePath(path); #ifdef Q_OS_WIN - // Windows hack - if (!path.endsWith(".torrent")) - if (QFile::rename(path, path+".torrent")) path += ".torrent"; + // Windows hack + if (!path.endsWith(".torrent")) + if (QFile::rename(path, path+".torrent")) path += ".torrent"; #endif - if (path.startsWith("file:", Qt::CaseInsensitive)) - path = QUrl::fromEncoded(path.toLocal8Bit()).toLocalFile(); - if (path.isEmpty()) return h; - - Q_ASSERT(!misc::isUrl(path)); - - qDebug("Adding %s to download list", qPrintable(path)); - boost::intrusive_ptr t; - try { - qDebug() << "Loading torrent at" << path; - // Getting torrent file informations - std::vector buffer; - lazy_entry entry; - libtorrent::error_code ec; - misc::loadBencodedFile(path, buffer, entry, ec); - t = new torrent_info(entry); - if (!t->is_valid()) - throw std::exception(); - } catch(std::exception& e) { - if (!from_url.isNull()) { - logger->addMessage(tr("Unable to decode torrent file: '%1'", "e.g: Unable to decode torrent file: '/home/y/xxx.torrent'").arg(from_url), Log::CRITICAL); - logger->addMessage(misc::toQStringU(e.what()), Log::CRITICAL); - //emit invalidTorrent(from_url); - fsutils::forceRemove(path); - }else{ - logger->addMessage(tr("Unable to decode torrent file: '%1'", "e.g: Unable to decode torrent file: '/home/y/xxx.torrent'").arg(fsutils::toNativePath(path)), Log::CRITICAL); - //emit invalidTorrent(path); - } - logger->addMessage(tr("This file is either corrupted or this isn't a torrent."), Log::CRITICAL); - if (fromScanDir) { - // Remove file - fsutils::forceRemove(path); - } - return h; - } + if (path.startsWith("file:", Qt::CaseInsensitive)) + path = QUrl::fromEncoded(path.toLocal8Bit()).toLocalFile(); + if (path.isEmpty()) return h; - const QString hash = misc::toQString(t->info_hash()); + Q_ASSERT(!misc::isUrl(path)); - qDebug(" -> Hash: %s", qPrintable(hash)); - qDebug(" -> Name: %s", t->name().c_str()); - - // Check for duplicate - if (s->find_torrent(t->info_hash()).is_valid()) { - qDebug("/!\\ Torrent is already in download list"); - // Update info Bar - if (!from_url.isNull()) { - logger->addMessage(tr("'%1' is already in download list.", "e.g: 'xxx.avi' is already in download list.").arg(from_url)); - }else{ - logger->addMessage(tr("'%1' is already in download list.", "e.g: 'xxx.avi' is already in download list.").arg(fsutils::toNativePath(path))); + qDebug("Adding %s to download list", qPrintable(path)); + boost::intrusive_ptr t; + try { + qDebug() << "Loading torrent at" << path; + // Getting torrent file informations + std::vector buffer; + lazy_entry entry; + libtorrent::error_code ec; + misc::loadBencodedFile(path, buffer, entry, ec); + t = new torrent_info(entry); + if (!t->is_valid()) + throw std::exception(); + } catch(std::exception& e) { + if (!from_url.isNull()) { + logger->addMessage(tr("Unable to decode torrent file: '%1'", "e.g: Unable to decode torrent file: '/home/y/xxx.torrent'").arg(from_url), Log::CRITICAL); + logger->addMessage(misc::toQStringU(e.what()), Log::CRITICAL); + //emit invalidTorrent(from_url); + fsutils::forceRemove(path); + }else{ + logger->addMessage(tr("Unable to decode torrent file: '%1'", "e.g: Unable to decode torrent file: '/home/y/xxx.torrent'").arg(fsutils::toNativePath(path)), Log::CRITICAL); + //emit invalidTorrent(path); + } + logger->addMessage(tr("This file is either corrupted or this isn't a torrent."), Log::CRITICAL); + if (fromScanDir) { + // Remove file + fsutils::forceRemove(path); + } + return h; } - // Check if the torrent contains trackers or url seeds we don't know about - // and add them - QTorrentHandle h_ex = getTorrentHandle(hash); - mergeTorrents(h_ex, t); - // Delete file if temporary - if (!from_url.isNull() || fromScanDir) - fsutils::forceRemove(path); - return h; - } + const QString hash = misc::toQString(t->info_hash()); - // Check number of files - if (t->num_files() < 1) { - logger->addMessage(tr("Error: The torrent %1 does not contain any file.").arg(misc::toQStringU(t->name()))); - // Delete file if temporary - if (!from_url.isNull() || fromScanDir) - fsutils::forceRemove(path); - return h; - } - - // Actually add the torrent - add_torrent_params p; - initializeAddTorrentParams(hash, p); - p.ti = t; - - // Get fast resume data if existing - bool fastResume = false; - std::vector buf; // Needs to stay in the function scope - if (resumed) { - if (loadFastResumeData(hash, buf)) { - fastResume = true; + qDebug(" -> Hash: %s", qPrintable(hash)); + qDebug(" -> Name: %s", t->name().c_str()); + + // Check for duplicate + if (s->find_torrent(t->info_hash()).is_valid()) { + qDebug("/!\\ Torrent is already in download list"); + // Update info Bar + if (!from_url.isNull()) { + logger->addMessage(tr("'%1' is already in download list.", "e.g: 'xxx.avi' is already in download list.").arg(from_url)); + }else{ + logger->addMessage(tr("'%1' is already in download list.", "e.g: 'xxx.avi' is already in download list.").arg(fsutils::toNativePath(path))); + } + // Check if the torrent contains trackers or url seeds we don't know about + // and add them + QTorrentHandle h_ex = getTorrentHandle(hash); + mergeTorrents(h_ex, t); + + // Delete file if temporary + if (!from_url.isNull() || fromScanDir) + fsutils::forceRemove(path); + return h; + } + + // Check number of files + if (t->num_files() < 1) { + logger->addMessage(tr("Error: The torrent %1 does not contain any file.").arg(misc::toQStringU(t->name()))); + // Delete file if temporary + if (!from_url.isNull() || fromScanDir) + fsutils::forceRemove(path); + return h; + } + + // Actually add the torrent + add_torrent_params p; + initializeAddTorrentParams(hash, p); + p.ti = t; + + // Get fast resume data if existing + bool fastResume = false; + std::vector buf; // Needs to stay in the function scope + if (resumed) { + if (loadFastResumeData(hash, buf)) { + fastResume = true; #if LIBTORRENT_VERSION_NUM < 10000 - p.resume_data = &buf; + p.resume_data = &buf; #else - p.resume_data = buf; + p.resume_data = buf; #endif - qDebug("Successfully loaded fast resume data"); + qDebug("Successfully loaded fast resume data"); + } + } + + recoverPersistentData(hash, buf); + QString savePath; + if (!from_url.isEmpty() && savepathLabel_fromurl.contains(QUrl::fromEncoded(from_url.toUtf8()))) { + // Enforcing the save path defined before URL download (from RSS for example) + QPair savePath_label = savepathLabel_fromurl.take(QUrl::fromEncoded(from_url.toUtf8())); + if (savePath_label.first.isEmpty()) + savePath = getSavePath(hash, fromScanDir, path); + else + savePath = savePath_label.first; + // Remember label + TorrentTempData::setLabel(hash, savePath_label.second); + } else { + savePath = getSavePath(hash, fromScanDir, path, imported); + } + if (!imported && !defaultTempPath.isEmpty() && !TorrentPersistentData::instance()->isSeed(hash)) { + qDebug("addTorrent::Temp folder is enabled."); + QString torrent_tmp_path = defaultTempPath; + p.save_path = fsutils::toNativePath(torrent_tmp_path).toUtf8().constData(); + // Check if save path exists, creating it otherwise + if (!QDir(torrent_tmp_path).exists()) QDir().mkpath(torrent_tmp_path); + qDebug("addTorrent: using save_path: %s", qPrintable(torrent_tmp_path)); + } else { + p.save_path = fsutils::toNativePath(savePath).toUtf8().constData(); + // Check if save path exists, creating it otherwise + if (!QDir(savePath).exists()) QDir().mkpath(savePath); + qDebug("addTorrent: using save_path: %s", qPrintable(savePath)); + } + + // Adding torrent to Bittorrent session + try { + h = QTorrentHandle(s->add_torrent(p)); + }catch(std::exception &e) { + qDebug("Error: %s", e.what()); + } + // Check if it worked + if (!h.is_valid()) { + qDebug("/!\\ Error: Invalid handle"); + // If temporary file, remove it + if (!from_url.isNull() || fromScanDir) + fsutils::forceRemove(path); + return h; + } + + loadTorrentSettings(h); + + bool add_paused = pref->addTorrentsInPause(); + if (!resumed) { + qDebug("This is a NEW torrent (first time)..."); + if (TorrentTempData::hasTempData(hash)) + add_paused = TorrentTempData::isAddPaused(hash); + + loadTorrentTempData(h, savePath, false); + + // Append .!qB to incomplete files + if (appendqBExtension) + appendqBextensionToTorrent(h, true); + + // Backup torrent file + const QString newFile = torrentBackup.absoluteFilePath(hash + ".torrent"); + if (path != newFile) + QFile::copy(path, newFile); + // Copy the torrent file to the export folder + if (m_torrentExportEnabled) + exportTorrentFile(h); + } + + if (!fastResume && !add_paused) { + // Start torrent because it was added in paused state + h.resume(); } - } - recoverPersistentData(hash, buf); - QString savePath; - if (!from_url.isEmpty() && savepathLabel_fromurl.contains(QUrl::fromEncoded(from_url.toUtf8()))) { - // Enforcing the save path defined before URL download (from RSS for example) - QPair savePath_label = savepathLabel_fromurl.take(QUrl::fromEncoded(from_url.toUtf8())); - if (savePath_label.first.isEmpty()) - savePath = getSavePath(hash, fromScanDir, path); - else - savePath = savePath_label.first; - // Remember label - TorrentTempData::setLabel(hash, savePath_label.second); - } else { - savePath = getSavePath(hash, fromScanDir, path, imported); - } - if (!imported && !defaultTempPath.isEmpty() && !TorrentPersistentData::instance()->isSeed(hash)) { - qDebug("addTorrent::Temp folder is enabled."); - QString torrent_tmp_path = defaultTempPath; - p.save_path = fsutils::toNativePath(torrent_tmp_path).toUtf8().constData(); - // Check if save path exists, creating it otherwise - if (!QDir(torrent_tmp_path).exists()) QDir().mkpath(torrent_tmp_path); - qDebug("addTorrent: using save_path: %s", qPrintable(torrent_tmp_path)); - } else { - p.save_path = fsutils::toNativePath(savePath).toUtf8().constData(); - // Check if save path exists, creating it otherwise - if (!QDir(savePath).exists()) QDir().mkpath(savePath); - qDebug("addTorrent: using save_path: %s", qPrintable(savePath)); - } - - // Adding torrent to Bittorrent session - try { - h = QTorrentHandle(s->add_torrent(p)); - }catch(std::exception &e) { - qDebug("Error: %s", e.what()); - } - // Check if it worked - if (!h.is_valid()) { - qDebug("/!\\ Error: Invalid handle"); // If temporary file, remove it if (!from_url.isNull() || fromScanDir) - fsutils::forceRemove(path); - return h; - } - - loadTorrentSettings(h); - - bool add_paused = pref->addTorrentsInPause(); - if (!resumed) { - qDebug("This is a NEW torrent (first time)..."); - if (TorrentTempData::hasTempData(hash)) - add_paused = TorrentTempData::isAddPaused(hash); - - loadTorrentTempData(h, savePath, false); - - // Append .!qB to incomplete files - if (appendqBExtension) - appendqBextensionToTorrent(h, true); - - // Backup torrent file - const QString newFile = torrentBackup.absoluteFilePath(hash + ".torrent"); - if (path != newFile) - QFile::copy(path, newFile); - // Copy the torrent file to the export folder - if (m_torrentExportEnabled) - exportTorrentFile(h); - } - - if (!fastResume && !add_paused) { - // Start torrent because it was added in paused state - h.resume(); - } - - // If temporary file, remove it - if (!from_url.isNull() || fromScanDir) - fsutils::forceRemove(path); - - // Display console message - if (!from_url.isNull()) { - if (fastResume) - logger->addMessage(tr("'%1' resumed. (fast resume)", "'/home/y/xxx.torrent' was resumed. (fast resume)").arg(from_url)); - else - logger->addMessage(tr("'%1' added to download list.", "'/home/y/xxx.torrent' was added to download list.").arg(from_url)); - }else{ - if (fastResume) - logger->addMessage(tr("'%1' resumed. (fast resume)", "'/home/y/xxx.torrent' was resumed. (fast resume)").arg(fsutils::toNativePath(path))); - else - logger->addMessage(tr("'%1' added to download list.", "'/home/y/xxx.torrent' was added to download list.").arg(fsutils::toNativePath(path))); - } + fsutils::forceRemove(path); + + // Display console message + if (!from_url.isNull()) { + if (fastResume) + logger->addMessage(tr("'%1' resumed. (fast resume)", "'/home/y/xxx.torrent' was resumed. (fast resume)").arg(from_url)); + else + logger->addMessage(tr("'%1' added to download list.", "'/home/y/xxx.torrent' was added to download list.").arg(from_url)); + }else{ + if (fastResume) + logger->addMessage(tr("'%1' resumed. (fast resume)", "'/home/y/xxx.torrent' was resumed. (fast resume)").arg(fsutils::toNativePath(path))); + else + logger->addMessage(tr("'%1' added to download list.", "'/home/y/xxx.torrent' was added to download list.").arg(fsutils::toNativePath(path))); + } - // Send torrent addition signal - emit addedTorrent(h); - return h; + // Send torrent addition signal + emit addedTorrent(h); + return h; } void QBtSession::exportTorrentFile(const QTorrentHandle& h, TorrentExportFolder folder) { - Q_ASSERT((folder == RegularTorrentExportFolder && m_torrentExportEnabled) || - (folder == FinishedTorrentExportFolder && m_finishedTorrentExportEnabled)); - QString torrent_path = QDir(fsutils::BTBackupLocation()).absoluteFilePath(h.hash()+".torrent"); - QDir exportPath(folder == RegularTorrentExportFolder ? Preferences::instance()->getTorrentExportDir() : Preferences::instance()->getFinishedTorrentExportDir()); - if (exportPath.exists() || exportPath.mkpath(exportPath.absolutePath())) { - QString new_torrent_path = exportPath.absoluteFilePath(h.name()+".torrent"); - if (QFile::exists(new_torrent_path) && fsutils::sameFiles(torrent_path, new_torrent_path)) { - // Append hash to torrent name to make it unique - new_torrent_path = exportPath.absoluteFilePath(h.name()+"-"+h.hash()+".torrent"); + Q_ASSERT((folder == RegularTorrentExportFolder && m_torrentExportEnabled) || + (folder == FinishedTorrentExportFolder && m_finishedTorrentExportEnabled)); + QString torrent_path = QDir(fsutils::BTBackupLocation()).absoluteFilePath(h.hash()+".torrent"); + QDir exportPath(folder == RegularTorrentExportFolder ? Preferences::instance()->getTorrentExportDir() : Preferences::instance()->getFinishedTorrentExportDir()); + if (exportPath.exists() || exportPath.mkpath(exportPath.absolutePath())) { + QString new_torrent_path = exportPath.absoluteFilePath(h.name()+".torrent"); + if (QFile::exists(new_torrent_path) && fsutils::sameFiles(torrent_path, new_torrent_path)) { + // Append hash to torrent name to make it unique + new_torrent_path = exportPath.absoluteFilePath(h.name()+"-"+h.hash()+".torrent"); + } + QFile::copy(torrent_path, new_torrent_path); } - QFile::copy(torrent_path, new_torrent_path); - } } void QBtSession::initializeAddTorrentParams(const QString &hash, add_torrent_params &p) { - // Seeding mode - // Skip checking and directly start seeding (new in libtorrent v0.15) - if (TorrentTempData::isSeedingMode(hash)) - p.flags |= add_torrent_params::flag_seed_mode; - else - p.flags &= ~add_torrent_params::flag_seed_mode; - - // Preallocation mode - if (preAllocateAll) - p.storage_mode = storage_mode_allocate; - else - p.storage_mode = storage_mode_sparse; - - // Priorities -/*if (TorrentTempData::hasTempData(hash)) { + // Seeding mode + // Skip checking and directly start seeding (new in libtorrent v0.15) + if (TorrentTempData::isSeedingMode(hash)) + p.flags |= add_torrent_params::flag_seed_mode; + else + p.flags &= ~add_torrent_params::flag_seed_mode; + + // Preallocation mode + if (preAllocateAll) + p.storage_mode = storage_mode_allocate; + else + p.storage_mode = storage_mode_sparse; + + // Priorities + /*if (TorrentTempData::hasTempData(hash)) { std::vector fp; TorrentTempData::getFilesPriority(hash, fp); if (!fp.empty()) { @@ -1227,463 +1227,463 @@ void QBtSession::initializeAddTorrentParams(const QString &hash, add_torrent_par } }*/ - // Start in pause - p.flags |= add_torrent_params::flag_paused; - p.flags &= ~add_torrent_params::flag_duplicate_is_error; // Already checked - p.flags &= ~add_torrent_params::flag_auto_managed; // Because it is added in paused state + // Start in pause + p.flags |= add_torrent_params::flag_paused; + p.flags &= ~add_torrent_params::flag_duplicate_is_error; // Already checked + p.flags &= ~add_torrent_params::flag_auto_managed; // Because it is added in paused state } void QBtSession::loadTorrentTempData(QTorrentHandle &h, QString savePath, bool magnet) { - qDebug("loadTorrentTempdata() - ENTER"); - const QString hash = h.hash(); - // Sequential download - if (TorrentTempData::hasTempData(hash)) { - // sequential download - h.set_sequential_download(TorrentTempData::isSequential(hash)); - - // The following is useless for newly added magnet - if (!magnet) { - // Files priorities - vector fp; - TorrentTempData::getFilesPriority(hash, fp); - h.prioritize_files(fp); - - // Prioritize first/last piece - h.prioritize_first_last_piece(TorrentTempData::isSequential(hash)); - - // Update file names - const QStringList files_path = TorrentTempData::getFilesPath(hash); - bool force_recheck = false; - QDir base_dir(h.save_path()); - if (files_path.size() == h.num_files()) { - for (int i=0; i fp; + TorrentTempData::getFilesPriority(hash, fp); + h.prioritize_files(fp); + + // Prioritize first/last piece + h.prioritize_first_last_piece(TorrentTempData::isSequential(hash)); + + // Update file names + const QStringList files_path = TorrentTempData::getFilesPath(hash); + bool force_recheck = false; + QDir base_dir(h.save_path()); + if (files_path.size() == h.num_files()) { + for (int i=0; isaveTorrentPersistentData(h, QString::null, magnet); - else - TorrentPersistentData::instance()->saveTorrentPersistentData(h, fsutils::fromNativePath(savePath), magnet); + // Save persistent data for new torrent + qDebug("Saving torrent persistant data"); + if (defaultTempPath.isEmpty()) + TorrentPersistentData::instance()->saveTorrentPersistentData(h, QString::null, magnet); + else + TorrentPersistentData::instance()->saveTorrentPersistentData(h, fsutils::fromNativePath(savePath), magnet); } void QBtSession::mergeTorrents(QTorrentHandle& h_ex, const QString& magnet_uri) { - QList new_trackers = misc::magnetUriToTrackers(magnet_uri); - bool trackers_added = false; - foreach (const QUrl& new_tracker, new_trackers) { - bool found = false; - std::vector existing_trackers = h_ex.trackers(); - foreach (const announce_entry& existing_tracker, existing_trackers) { - if (new_tracker == QUrl(existing_tracker.url.c_str())) { - found = true; - break; - } - } + QList new_trackers = misc::magnetUriToTrackers(magnet_uri); + bool trackers_added = false; + foreach (const QUrl& new_tracker, new_trackers) { + bool found = false; + std::vector existing_trackers = h_ex.trackers(); + foreach (const announce_entry& existing_tracker, existing_trackers) { + if (new_tracker == QUrl(existing_tracker.url.c_str())) { + found = true; + break; + } + } - if (!found) { - h_ex.add_tracker(announce_entry(new_tracker.toString().toStdString())); - trackers_added = true; + if (!found) { + h_ex.add_tracker(announce_entry(new_tracker.toString().toStdString())); + trackers_added = true; + } } - } - if (trackers_added) - Logger::instance()->addMessage(tr("Note: new trackers were added to the existing torrent.")); + if (trackers_added) + Logger::instance()->addMessage(tr("Note: new trackers were added to the existing torrent.")); } void QBtSession::mergeTorrents(QTorrentHandle &h_ex, boost::intrusive_ptr t) { - // Check if the torrent contains trackers or url seeds we don't know about - // and add them - if (!h_ex.is_valid()) return; - std::vector existing_trackers = h_ex.trackers(); - std::vector new_trackers = t->trackers(); - bool trackers_added = false; - foreach (const announce_entry& new_tracker, new_trackers) { - std::string new_tracker_url = new_tracker.url; - // Check if existing torrent has this tracker - bool found = false; - foreach (const announce_entry& existing_tracker, existing_trackers) { - if (QUrl(new_tracker_url.c_str()) == QUrl(existing_tracker.url.c_str())) { - found = true; - break; - } - } + // Check if the torrent contains trackers or url seeds we don't know about + // and add them + if (!h_ex.is_valid()) return; + std::vector existing_trackers = h_ex.trackers(); + std::vector new_trackers = t->trackers(); + bool trackers_added = false; + foreach (const announce_entry& new_tracker, new_trackers) { + std::string new_tracker_url = new_tracker.url; + // Check if existing torrent has this tracker + bool found = false; + foreach (const announce_entry& existing_tracker, existing_trackers) { + if (QUrl(new_tracker_url.c_str()) == QUrl(existing_tracker.url.c_str())) { + found = true; + break; + } + } - if (!found) { - h_ex.add_tracker(announce_entry(new_tracker_url)); - trackers_added = true; + if (!found) { + h_ex.add_tracker(announce_entry(new_tracker_url)); + trackers_added = true; + } } - } - - Logger* const logger = Logger::instance(); - if (trackers_added) - logger->addMessage(tr("Note: new trackers were added to the existing torrent.")); - - bool urlseeds_added = false; - const QStringList old_urlseeds = h_ex.url_seeds(); - std::vector new_urlseeds = t->web_seeds(); - std::vector::iterator it = new_urlseeds.begin(); - std::vector::iterator itend = new_urlseeds.end(); - for ( ; it != itend; ++it) { - const QString new_url = misc::toQString(it->url.c_str()); - if (!old_urlseeds.contains(new_url)) { - urlseeds_added = true; - h_ex.add_url_seed(new_url); + Logger* const logger = Logger::instance(); + if (trackers_added) + logger->addMessage(tr("Note: new trackers were added to the existing torrent.")); + + bool urlseeds_added = false; + const QStringList old_urlseeds = h_ex.url_seeds(); + std::vector new_urlseeds = t->web_seeds(); + + std::vector::iterator it = new_urlseeds.begin(); + std::vector::iterator itend = new_urlseeds.end(); + for ( ; it != itend; ++it) { + const QString new_url = misc::toQString(it->url.c_str()); + if (!old_urlseeds.contains(new_url)) { + urlseeds_added = true; + h_ex.add_url_seed(new_url); + } } - } - if (urlseeds_added) - logger->addMessage(tr("Note: new URL seeds were added to the existing torrent.")); + if (urlseeds_added) + logger->addMessage(tr("Note: new URL seeds were added to the existing torrent.")); } void QBtSession::exportTorrentFiles(QString path) { - Q_ASSERT(m_torrentExportEnabled); - QDir exportDir(path); - if (!exportDir.exists()) { - if (!exportDir.mkpath(exportDir.absolutePath())) { - std::cerr << "Error: Could not create torrent export directory: " << qPrintable(exportDir.absolutePath()) << std::endl; - return; - } - } - QDir torrentBackup(fsutils::BTBackupLocation()); - std::vector handles = s->get_torrents(); - - std::vector::iterator itr=handles.begin(); - std::vector::iterator itrend=handles.end(); - for ( ; itr != itrend; ++itr) { - const QTorrentHandle h(*itr); - if (!h.is_valid()) { - std::cerr << "Torrent Export: torrent is invalid, skipping..." << std::endl; - continue; - } - const QString src_path(torrentBackup.absoluteFilePath(h.hash()+".torrent")); - if (QFile::exists(src_path)) { - QString dst_path = exportDir.absoluteFilePath(h.name()+".torrent"); - if (QFile::exists(dst_path)) { - if (!fsutils::sameFiles(src_path, dst_path)) { - dst_path = exportDir.absoluteFilePath(h.name()+"-"+h.hash()+".torrent"); + Q_ASSERT(m_torrentExportEnabled); + QDir exportDir(path); + if (!exportDir.exists()) { + if (!exportDir.mkpath(exportDir.absolutePath())) { + std::cerr << "Error: Could not create torrent export directory: " << qPrintable(exportDir.absolutePath()) << std::endl; + return; + } + } + QDir torrentBackup(fsutils::BTBackupLocation()); + std::vector handles = s->get_torrents(); + + std::vector::iterator itr=handles.begin(); + std::vector::iterator itrend=handles.end(); + for ( ; itr != itrend; ++itr) { + const QTorrentHandle h(*itr); + if (!h.is_valid()) { + std::cerr << "Torrent Export: torrent is invalid, skipping..." << std::endl; + continue; + } + const QString src_path(torrentBackup.absoluteFilePath(h.hash()+".torrent")); + if (QFile::exists(src_path)) { + QString dst_path = exportDir.absoluteFilePath(h.name()+".torrent"); + if (QFile::exists(dst_path)) { + if (!fsutils::sameFiles(src_path, dst_path)) { + dst_path = exportDir.absoluteFilePath(h.name()+"-"+h.hash()+".torrent"); + } else { + qDebug("Torrent Export: Destination file exists, skipping..."); + continue; + } + } + qDebug("Export Torrent: %s -> %s", qPrintable(src_path), qPrintable(dst_path)); + QFile::copy(src_path, dst_path); } else { - qDebug("Torrent Export: Destination file exists, skipping..."); - continue; + std::cerr << "Error: could not export torrent "<< qPrintable(h.hash()) << ", maybe it has not metadata yet." < %s", qPrintable(src_path), qPrintable(dst_path)); - QFile::copy(src_path, dst_path); - } else { - std::cerr << "Error: could not export torrent "<< qPrintable(h.hash()) << ", maybe it has not metadata yet." < handles = s->get_torrents(); - - std::vector::const_iterator it = handles.begin(); - std::vector::const_iterator itend = handles.end(); - for ( ; it != itend; ++it) { - if (!it->is_valid()) - continue; - try { - it->set_max_connections(max); - } catch(std::exception) {} - } + qDebug() << Q_FUNC_INFO << max; + // Apply this to all session torrents + std::vector handles = s->get_torrents(); + + std::vector::const_iterator it = handles.begin(); + std::vector::const_iterator itend = handles.end(); + for ( ; it != itend; ++it) { + if (!it->is_valid()) + continue; + try { + it->set_max_connections(max); + } catch(std::exception) {} + } } void QBtSession::setMaxUploadsPerTorrent(int max) { - qDebug() << Q_FUNC_INFO << max; - // Apply this to all session torrents - std::vector handles = s->get_torrents(); - - std::vector::const_iterator it = handles.begin(); - std::vector::const_iterator itend = handles.end(); - for ( ; it != itend; ++it) { - if (!it->is_valid()) - continue; - try { - it->set_max_uploads(max); - } catch(std::exception) {} - } + qDebug() << Q_FUNC_INFO << max; + // Apply this to all session torrents + std::vector handles = s->get_torrents(); + + std::vector::const_iterator it = handles.begin(); + std::vector::const_iterator itend = handles.end(); + for ( ; it != itend; ++it) { + if (!it->is_valid()) + continue; + try { + it->set_max_uploads(max); + } catch(std::exception) {} + } } void QBtSession::enableUPnP(bool b) { - Preferences* const pref = Preferences::instance(); - if (b) { - qDebug("Enabling UPnP / NAT-PMP"); + Preferences* const pref = Preferences::instance(); + if (b) { + qDebug("Enabling UPnP / NAT-PMP"); #if LIBTORRENT_VERSION_NUM < 10000 - m_upnp = s->start_upnp(); - m_natpmp = s->start_natpmp(); + m_upnp = s->start_upnp(); + m_natpmp = s->start_natpmp(); #else - s->start_upnp(); - s->start_natpmp(); + s->start_upnp(); + s->start_natpmp(); #endif - // TODO: Remove dependency from WebUI - // Use UPnP/NAT-PMP for Web UI too - if (pref->isWebUiEnabled() && pref->useUPnPForWebUIPort()) { - const qint16 port = pref->getWebUiPort(); + // TODO: Remove dependency from WebUI + // Use UPnP/NAT-PMP for Web UI too + if (pref->isWebUiEnabled() && pref->useUPnPForWebUIPort()) { + const qint16 port = pref->getWebUiPort(); #if LIBTORRENT_VERSION_NUM < 10000 - m_upnp->add_mapping(upnp::tcp, port, port); - m_natpmp->add_mapping(natpmp::tcp, port, port); + m_upnp->add_mapping(upnp::tcp, port, port); + m_natpmp->add_mapping(natpmp::tcp, port, port); #else - s->add_port_mapping(session::tcp, port, port); + s->add_port_mapping(session::tcp, port, port); #endif - } - } else { - qDebug("Disabling UPnP / NAT-PMP"); - s->stop_upnp(); - s->stop_natpmp(); + } + } else { + qDebug("Disabling UPnP / NAT-PMP"); + s->stop_upnp(); + s->stop_natpmp(); #if LIBTORRENT_VERSION_NUM < 10000 - m_upnp = 0; - m_natpmp = 0; + m_upnp = 0; + m_natpmp = 0; #endif - } + } } void QBtSession::enableLSD(bool b) { - if (b) { - if (!LSDEnabled) { - qDebug("Enabling Local Peer Discovery"); - s->start_lsd(); - LSDEnabled = true; - } - } else { - if (LSDEnabled) { - qDebug("Disabling Local Peer Discovery"); - s->stop_lsd(); - LSDEnabled = false; + if (b) { + if (!LSDEnabled) { + qDebug("Enabling Local Peer Discovery"); + s->start_lsd(); + LSDEnabled = true; + } + } else { + if (LSDEnabled) { + qDebug("Disabling Local Peer Discovery"); + s->stop_lsd(); + LSDEnabled = false; + } } - } } void QBtSession::loadSessionState() { - const QString state_path = fsutils::cacheLocation()+"/"+QString::fromUtf8("ses_state"); - if (!QFile::exists(state_path)) return; - if (QFile(state_path).size() == 0) { - // Remove empty invalid state file - fsutils::forceRemove(state_path); - return; - } - std::vector in; - lazy_entry e; - libtorrent::error_code ec; - misc::loadBencodedFile(state_path, in, e, ec); - if (!ec) - s->load_state(e); + const QString state_path = fsutils::cacheLocation()+"/"+QString::fromUtf8("ses_state"); + if (!QFile::exists(state_path)) return; + if (QFile(state_path).size() == 0) { + // Remove empty invalid state file + fsutils::forceRemove(state_path); + return; + } + std::vector in; + lazy_entry e; + libtorrent::error_code ec; + misc::loadBencodedFile(state_path, in, e, ec); + if (!ec) + s->load_state(e); } void QBtSession::saveSessionState() { - qDebug("Saving session state to disk..."); - const QString state_path = fsutils::cacheLocation()+"/"+QString::fromUtf8("ses_state"); - entry session_state; - s->save_state(session_state); - vector out; - bencode(back_inserter(out), session_state); - QFile session_file(state_path); - if (!out.empty() && session_file.open(QIODevice::WriteOnly)) { - session_file.write(&out[0], out.size()); - session_file.close(); - } + qDebug("Saving session state to disk..."); + const QString state_path = fsutils::cacheLocation()+"/"+QString::fromUtf8("ses_state"); + entry session_state; + s->save_state(session_state); + vector out; + bencode(back_inserter(out), session_state); + QFile session_file(state_path); + if (!out.empty() && session_file.open(QIODevice::WriteOnly)) { + session_file.write(&out[0], out.size()); + session_file.close(); + } } // Enable DHT void QBtSession::enableDHT(bool b) { - Logger* const logger = Logger::instance(); - if (b) { - if (!DHTEnabled) { - try { - qDebug() << "Starting DHT..."; - Q_ASSERT(!s->is_dht_running()); - s->start_dht(); - s->add_dht_router(std::make_pair(std::string("router.bittorrent.com"), 6881)); - s->add_dht_router(std::make_pair(std::string("router.utorrent.com"), 6881)); - s->add_dht_router(std::make_pair(std::string("dht.transmissionbt.com"), 6881)); - s->add_dht_router(std::make_pair(std::string("dht.aelitis.com"), 6881)); // Vuze - DHTEnabled = true; - logger->addMessage(tr("DHT support [ON]"), Log::INFO); - qDebug("DHT enabled"); - } - catch(std::exception &e) { - qDebug("Could not enable DHT, reason: %s", e.what()); - logger->addMessage(tr("DHT support [OFF]. Reason: %1").arg(misc::toQStringU(e.what())), Log::CRITICAL); - } + Logger* const logger = Logger::instance(); + if (b) { + if (!DHTEnabled) { + try { + qDebug() << "Starting DHT..."; + Q_ASSERT(!s->is_dht_running()); + s->start_dht(); + s->add_dht_router(std::make_pair(std::string("router.bittorrent.com"), 6881)); + s->add_dht_router(std::make_pair(std::string("router.utorrent.com"), 6881)); + s->add_dht_router(std::make_pair(std::string("dht.transmissionbt.com"), 6881)); + s->add_dht_router(std::make_pair(std::string("dht.aelitis.com"), 6881)); // Vuze + DHTEnabled = true; + logger->addMessage(tr("DHT support [ON]"), Log::INFO); + qDebug("DHT enabled"); + } + catch(std::exception &e) { + qDebug("Could not enable DHT, reason: %s", e.what()); + logger->addMessage(tr("DHT support [OFF]. Reason: %1").arg(misc::toQStringU(e.what())), Log::CRITICAL); + } + } } - } - else { - if (DHTEnabled) { - DHTEnabled = false; - s->stop_dht(); - logger->addMessage(tr("DHT support [OFF]"), Log::INFO); - qDebug("DHT disabled"); + else { + if (DHTEnabled) { + DHTEnabled = false; + s->stop_dht(); + logger->addMessage(tr("DHT support [OFF]"), Log::INFO); + qDebug("DHT disabled"); + } } - } } qreal QBtSession::getRealRatio(const libtorrent::torrent_status &status) const { - libtorrent::size_type all_time_upload = status.all_time_upload; - libtorrent::size_type all_time_download = status.all_time_download; - libtorrent::size_type total_done = status.total_done; - - if (all_time_download < total_done) { - // We have more data on disk than we downloaded - // either because the user imported the file - // or because of crash the download histroy was lost. - // Otherwise will get weird ratios - // eg when downloaded 1KB and uploaded 700MB of a - // 700MB torrent. - all_time_download = total_done; - } - - if (all_time_download == 0) { - if (all_time_upload == 0) - return 0.0; - return MAX_RATIO+1; - } - - qreal ratio = all_time_upload / (float) all_time_download; - Q_ASSERT(ratio >= 0.); - if (ratio > MAX_RATIO) - ratio = MAX_RATIO; - return ratio; + libtorrent::size_type all_time_upload = status.all_time_upload; + libtorrent::size_type all_time_download = status.all_time_download; + libtorrent::size_type total_done = status.total_done; + + if (all_time_download < total_done) { + // We have more data on disk than we downloaded + // either because the user imported the file + // or because of crash the download histroy was lost. + // Otherwise will get weird ratios + // eg when downloaded 1KB and uploaded 700MB of a + // 700MB torrent. + all_time_download = total_done; + } + + if (all_time_download == 0) { + if (all_time_upload == 0) + return 0.0; + return MAX_RATIO+1; + } + + qreal ratio = all_time_upload / (float) all_time_download; + Q_ASSERT(ratio >= 0.); + if (ratio > MAX_RATIO) + ratio = MAX_RATIO; + return ratio; } // Called periodically void QBtSession::saveTempFastResumeData() { - std::vector torrents = s->get_torrents(); + std::vector torrents = s->get_torrents(); - std::vector::iterator torrentIT = torrents.begin(); - std::vector::iterator torrentITend = torrents.end(); - for ( ; torrentIT != torrentITend; ++torrentIT) { - QTorrentHandle h = QTorrentHandle(*torrentIT); - try { - if (!h.is_valid() || !h.has_metadata() /*|| h.is_seed() || h.is_paused()*/) continue; - if (!h.need_save_resume_data()) continue; - if (h.state() == torrent_status::checking_files || h.state() == torrent_status::queued_for_checking || h.has_error() - || TorrentPersistentData::instance()->getHasMissingFiles(h.hash())) continue; - qDebug("Saving fastresume data for %s", qPrintable(h.name())); - h.save_resume_data(); - }catch(std::exception &e) {} - } + std::vector::iterator torrentIT = torrents.begin(); + std::vector::iterator torrentITend = torrents.end(); + for ( ; torrentIT != torrentITend; ++torrentIT) { + QTorrentHandle h = QTorrentHandle(*torrentIT); + try { + if (!h.is_valid() || !h.has_metadata() /*|| h.is_seed() || h.is_paused()*/) continue; + if (!h.need_save_resume_data()) continue; + if (h.state() == torrent_status::checking_files || h.state() == torrent_status::queued_for_checking || h.has_error() + || TorrentPersistentData::instance()->getHasMissingFiles(h.hash())) continue; + qDebug("Saving fastresume data for %s", qPrintable(h.name())); + h.save_resume_data(); + }catch(std::exception &e) {} + } } // Only save fast resume data for unfinished and unpaused torrents (Optimization) // Called on exit void QBtSession::saveFastResumeData() { - qDebug("Saving fast resume data..."); - // Stop listening for alerts - resumeDataTimer.stop(); - int num_resume_data = 0; - // Pause session - s->pause(); - std::vector torrents = s->get_torrents(); - - std::vector::iterator torrentIT = torrents.begin(); - std::vector::iterator torrentITend = torrents.end(); - for ( ; torrentIT != torrentITend; ++torrentIT) { - QTorrentHandle h = QTorrentHandle(*torrentIT); - if (!h.is_valid()) - continue; - try { - if (isQueueingEnabled()) - TorrentPersistentData::instance()->savePriority(h); - if (!h.has_metadata()) - continue; - // Actually with should save fast resume data for paused files too - //if (h.is_paused()) continue; - if (h.state() == torrent_status::checking_files || h.state() == torrent_status::queued_for_checking || h.has_error()) continue; - if (TorrentPersistentData::instance()->getHasMissingFiles(h.hash())) { - TorrentPersistentData::instance()->setHasMissingFiles(h.hash(), false); - continue; - } - h.save_resume_data(); - ++num_resume_data; - } catch(libtorrent::invalid_handle&) {} - } - while (num_resume_data > 0) { - std::vector alerts; - m_alertDispatcher->getPendingAlerts(alerts, 30*1000); - if (alerts.empty()) { - std::cerr << " aborting with " << num_resume_data << " outstanding " - "torrents to save resume data for" << std::endl; - break; - } - - for (std::vector::const_iterator i = alerts.begin(), end = alerts.end(); i != end; ++i) - { - alert const* a = *i; - // Saving fastresume data can fail - save_resume_data_failed_alert const* rda = dynamic_cast(a); - if (rda) { - --num_resume_data; + qDebug("Saving fast resume data..."); + // Stop listening for alerts + resumeDataTimer.stop(); + int num_resume_data = 0; + // Pause session + s->pause(); + std::vector torrents = s->get_torrents(); + + std::vector::iterator torrentIT = torrents.begin(); + std::vector::iterator torrentITend = torrents.end(); + for ( ; torrentIT != torrentITend; ++torrentIT) { + QTorrentHandle h = QTorrentHandle(*torrentIT); + if (!h.is_valid()) + continue; try { - // Remove torrent from session - if (rda->handle.is_valid()) - s->remove_torrent(rda->handle); - }catch(libtorrent::libtorrent_exception) {} - delete a; - continue; - } - save_resume_data_alert const* rd = dynamic_cast(a); - if (!rd) { - delete a; - continue; - } - // Saving fast resume data was successful - --num_resume_data; - if (!rd->resume_data) { - delete a; - continue; - } - QDir torrentBackup(fsutils::BTBackupLocation()); - const QTorrentHandle h(rd->handle); - if (!h.is_valid()) { - delete a; - continue; - } - try { - // Remove old fastresume file if it exists - backupPersistentData(h.hash(), rd->resume_data); - vector out; - bencode(back_inserter(out), *rd->resume_data); - const QString filepath = torrentBackup.absoluteFilePath(h.hash()+".fastresume"); - QFile resume_file(filepath); - if (resume_file.exists()) - fsutils::forceRemove(filepath); - if (!out.empty() && resume_file.open(QIODevice::WriteOnly)) { - resume_file.write(&out[0], out.size()); - resume_file.close(); + if (isQueueingEnabled()) + TorrentPersistentData::instance()->savePriority(h); + if (!h.has_metadata()) + continue; + // Actually with should save fast resume data for paused files too + //if (h.is_paused()) continue; + if (h.state() == torrent_status::checking_files || h.state() == torrent_status::queued_for_checking || h.has_error()) continue; + if (TorrentPersistentData::instance()->getHasMissingFiles(h.hash())) { + TorrentPersistentData::instance()->setHasMissingFiles(h.hash(), false); + continue; + } + h.save_resume_data(); + ++num_resume_data; + } catch(libtorrent::invalid_handle&) {} + } + while (num_resume_data > 0) { + std::vector alerts; + m_alertDispatcher->getPendingAlerts(alerts, 30*1000); + if (alerts.empty()) { + std::cerr << " aborting with " << num_resume_data << " outstanding " + "torrents to save resume data for" << std::endl; + break; } - // Remove torrent from session - s->remove_torrent(rd->handle); - } catch(libtorrent::invalid_handle&) {} - delete a; + for (std::vector::const_iterator i = alerts.begin(), end = alerts.end(); i != end; ++i) + { + alert const* a = *i; + // Saving fastresume data can fail + save_resume_data_failed_alert const* rda = dynamic_cast(a); + if (rda) { + --num_resume_data; + try { + // Remove torrent from session + if (rda->handle.is_valid()) + s->remove_torrent(rda->handle); + }catch(libtorrent::libtorrent_exception) {} + delete a; + continue; + } + save_resume_data_alert const* rd = dynamic_cast(a); + if (!rd) { + delete a; + continue; + } + // Saving fast resume data was successful + --num_resume_data; + if (!rd->resume_data) { + delete a; + continue; + } + QDir torrentBackup(fsutils::BTBackupLocation()); + const QTorrentHandle h(rd->handle); + if (!h.is_valid()) { + delete a; + continue; + } + try { + // Remove old fastresume file if it exists + backupPersistentData(h.hash(), rd->resume_data); + vector out; + bencode(back_inserter(out), *rd->resume_data); + const QString filepath = torrentBackup.absoluteFilePath(h.hash()+".fastresume"); + QFile resume_file(filepath); + if (resume_file.exists()) + fsutils::forceRemove(filepath); + if (!out.empty() && resume_file.open(QIODevice::WriteOnly)) { + resume_file.write(&out[0], out.size()); + resume_file.close(); + } + // Remove torrent from session + s->remove_torrent(rd->handle); + } catch(libtorrent::invalid_handle&) {} + + delete a; + } } - } } bool QBtSession::isFilePreviewPossible(const QString &hash) const { - // See if there are supported files in the torrent - const QTorrentHandle h = getTorrentHandle(hash); - if (!h.is_valid() || !h.has_metadata()) { + // See if there are supported files in the torrent + const QTorrentHandle h = getTorrentHandle(hash); + if (!h.is_valid() || !h.has_metadata()) { + return false; + } + const unsigned int nbFiles = h.num_files(); + for (unsigned int i=0; i torrents = s->get_torrents(); - - std::vector::iterator torrentIT = torrents.begin(); - std::vector::iterator torrentITend = torrents.end(); - for ( ; torrentIT != torrentITend; ++torrentIT) { - QTorrentHandle h = QTorrentHandle(*torrentIT); - if (!h.is_valid()) continue; - h.move_storage(getSavePath(h.hash())); - } - } else { - qDebug("Enabling default temp path..."); - // Moving all downloading torrents to temporary save path - std::vector torrents = s->get_torrents(); - - std::vector::iterator torrentIT = torrents.begin(); - std::vector::iterator torrentITend = torrents.end(); - for ( ; torrentIT != torrentITend; ++torrentIT) { - QTorrentHandle h = QTorrentHandle(*torrentIT); - if (!h.is_valid()) continue; - if (!h.is_seed()) { - qDebug("Moving torrent to its temp save path: %s", qPrintable(temppath)); - h.move_storage(temppath); - } + if (QDir(defaultTempPath) == QDir(temppath)) + return; + + if (temppath.isEmpty()) { + // Disabling temp dir + // Moving all torrents to their destination folder + std::vector torrents = s->get_torrents(); + + std::vector::iterator torrentIT = torrents.begin(); + std::vector::iterator torrentITend = torrents.end(); + for ( ; torrentIT != torrentITend; ++torrentIT) { + QTorrentHandle h = QTorrentHandle(*torrentIT); + if (!h.is_valid()) continue; + h.move_storage(getSavePath(h.hash())); + } + } else { + qDebug("Enabling default temp path..."); + // Moving all downloading torrents to temporary save path + std::vector torrents = s->get_torrents(); + + std::vector::iterator torrentIT = torrents.begin(); + std::vector::iterator torrentITend = torrents.end(); + for ( ; torrentIT != torrentITend; ++torrentIT) { + QTorrentHandle h = QTorrentHandle(*torrentIT); + if (!h.is_valid()) continue; + if (!h.is_seed()) { + qDebug("Moving torrent to its temp save path: %s", qPrintable(temppath)); + h.move_storage(temppath); + } + } } - } - defaultTempPath = fsutils::fromNativePath(temppath); + defaultTempPath = fsutils::fromNativePath(temppath); } void QBtSession::appendqBextensionToTorrent(const QTorrentHandle &h, bool append) { - if (!h.is_valid() || !h.has_metadata()) return; - std::vector fp; - h.file_progress(fp); - for (int i=0; i 0 && (fp[i]/(double)file_size) < 1.) { - const QString name = h.filepath_at(i); - if (!name.endsWith(".!qB")) { - const QString new_name = name+".!qB"; - qDebug("Renaming %s to %s", qPrintable(name), qPrintable(new_name)); - h.rename_file(i, new_name); + if (!h.is_valid() || !h.has_metadata()) return; + std::vector fp; + h.file_progress(fp); + for (int i=0; i 0 && (fp[i]/(double)file_size) < 1.) { + const QString name = h.filepath_at(i); + if (!name.endsWith(".!qB")) { + const QString new_name = name+".!qB"; + qDebug("Renaming %s to %s", qPrintable(name), qPrintable(new_name)); + h.rename_file(i, new_name); + } + } + } else { + QString name = h.filepath_at(i); + if (name.endsWith(".!qB")) { + const QString old_name = name; + name.chop(4); + qDebug("Renaming %s to %s", qPrintable(old_name), qPrintable(name)); + h.rename_file(i, name); + } } - } - } else { - QString name = h.filepath_at(i); - if (name.endsWith(".!qB")) { - const QString old_name = name; - name.chop(4); - qDebug("Renaming %s to %s", qPrintable(old_name), qPrintable(name)); - h.rename_file(i, name); - } } - } } void QBtSession::changeLabelInTorrentSavePath(const QTorrentHandle &h, QString old_label, QString new_label) { - if (!h.is_valid()) return; - if (!appendLabelToSavePath) return; - QString old_save_path = fsutils::fromNativePath(TorrentPersistentData::instance()->getSavePath(h.hash())); - if (!old_save_path.startsWith(defaultSavePath)) return; - QString new_save_path = fsutils::updateLabelInSavePath(defaultSavePath, old_save_path, old_label, new_label); - if (new_save_path != old_save_path) { - // Move storage - qDebug("Moving storage to %s", qPrintable(new_save_path)); - QDir().mkpath(new_save_path); - h.move_storage(new_save_path); - } + if (!h.is_valid()) return; + if (!appendLabelToSavePath) return; + QString old_save_path = fsutils::fromNativePath(TorrentPersistentData::instance()->getSavePath(h.hash())); + if (!old_save_path.startsWith(defaultSavePath)) return; + QString new_save_path = fsutils::updateLabelInSavePath(defaultSavePath, old_save_path, old_label, new_label); + if (new_save_path != old_save_path) { + // Move storage + qDebug("Moving storage to %s", qPrintable(new_save_path)); + QDir().mkpath(new_save_path); + h.move_storage(new_save_path); + } } void QBtSession::appendLabelToTorrentSavePath(const QTorrentHandle& h) { - if (!h.is_valid()) return; - const TorrentPersistentData* const TorPersistent = TorrentPersistentData::instance(); - const QString label = TorPersistent->getLabel(h.hash()); - if (label.isEmpty()) return; - // Current save path - QString old_save_path = fsutils::fromNativePath(TorPersistent->getSavePath(h.hash())); - QString new_save_path = fsutils::updateLabelInSavePath(defaultSavePath, old_save_path, "", label); - if (old_save_path != new_save_path) { - // Move storage - QDir().mkpath(new_save_path); - h.move_storage(new_save_path); - } + if (!h.is_valid()) return; + const TorrentPersistentData* const TorPersistent = TorrentPersistentData::instance(); + const QString label = TorPersistent->getLabel(h.hash()); + if (label.isEmpty()) return; + // Current save path + QString old_save_path = fsutils::fromNativePath(TorPersistent->getSavePath(h.hash())); + QString new_save_path = fsutils::updateLabelInSavePath(defaultSavePath, old_save_path, "", label); + if (old_save_path != new_save_path) { + // Move storage + QDir().mkpath(new_save_path); + h.move_storage(new_save_path); + } } void QBtSession::setAppendLabelToSavePath(bool append) { - if (appendLabelToSavePath != append) { - appendLabelToSavePath = !appendLabelToSavePath; - if (appendLabelToSavePath) { - // Move torrents storage to sub folder with label name - std::vector torrents = s->get_torrents(); - - std::vector::iterator torrentIT = torrents.begin(); - std::vector::iterator torrentITend = torrents.end(); - for ( ; torrentIT != torrentITend; ++torrentIT) { - QTorrentHandle h = QTorrentHandle(*torrentIT); - appendLabelToTorrentSavePath(h); - } + if (appendLabelToSavePath != append) { + appendLabelToSavePath = !appendLabelToSavePath; + if (appendLabelToSavePath) { + // Move torrents storage to sub folder with label name + std::vector torrents = s->get_torrents(); + + std::vector::iterator torrentIT = torrents.begin(); + std::vector::iterator torrentITend = torrents.end(); + for ( ; torrentIT != torrentITend; ++torrentIT) { + QTorrentHandle h = QTorrentHandle(*torrentIT); + appendLabelToTorrentSavePath(h); + } + } } - } } void QBtSession::setAppendqBExtension(bool append) { - if (appendqBExtension != append) { - appendqBExtension = !appendqBExtension; - // append or remove .!qB extension for incomplete files - std::vector torrents = s->get_torrents(); - - std::vector::iterator torrentIT = torrents.begin(); - std::vector::iterator torrentITend = torrents.end(); - for ( ; torrentIT != torrentITend; ++torrentIT) { - QTorrentHandle h = QTorrentHandle(*torrentIT); - appendqBextensionToTorrent(h, appendqBExtension); + if (appendqBExtension != append) { + appendqBExtension = !appendqBExtension; + // append or remove .!qB extension for incomplete files + std::vector torrents = s->get_torrents(); + + std::vector::iterator torrentIT = torrents.begin(); + std::vector::iterator torrentITend = torrents.end(); + for ( ; torrentIT != torrentITend; ++torrentIT) { + QTorrentHandle h = QTorrentHandle(*torrentIT); + appendqBextensionToTorrent(h, appendqBExtension); + } } - } } // Set the ports range in which is chosen the port the Bittorrent // session will listen to void QBtSession::setListeningPort(int port) { - qDebug() << Q_FUNC_INFO << port; - Preferences* const pref = Preferences::instance(); - Logger* const logger = Logger::instance(); - std::pair ports(port, port); - libtorrent::error_code ec; - const QString iface_name = pref->getNetworkInterface(); - const bool listen_ipv6 = pref->getListenIPv6(); - if (iface_name.isEmpty()) { - logger->addMessage(tr("qBittorrent is trying to listen on any interface port: %1", "e.g: qBittorrent is trying to listen on any interface port: TCP/6881").arg(QString::number(port)), Log::INFO); - if (listen_ipv6) - s->listen_on(ports, ec, "::", session::listen_no_system_port); - else - s->listen_on(ports, ec, "0.0.0.0", session::listen_no_system_port); - - if (ec) - logger->addMessage(tr("qBittorrent failed to listen on any interface port: %1. Reason: %2", "e.g: qBittorrent failed to listen on any interface port: TCP/6881. Reason: no such interface" ).arg(QString::number(port)).arg(misc::toQStringU(ec.message())), Log::CRITICAL); - - return; - } - // Attempt to listen on provided interface - const QNetworkInterface network_iface = QNetworkInterface::interfaceFromName(iface_name); - if (!network_iface.isValid()) { - qDebug("Invalid network interface: %s", qPrintable(iface_name)); - logger->addMessage(tr("The network interface defined is invalid: %1").arg(iface_name), Log::CRITICAL); - return; - } - QString ip; - qDebug("This network interface has %d IP addresses", network_iface.addressEntries().size()); - foreach (const QNetworkAddressEntry &entry, network_iface.addressEntries()) { - if ((!listen_ipv6 && (entry.ip().protocol() == QAbstractSocket::IPv6Protocol)) - || (listen_ipv6 && (entry.ip().protocol() == QAbstractSocket::IPv4Protocol))) - continue; - qDebug("Trying to listen on IP %s (%s)", qPrintable(entry.ip().toString()), qPrintable(iface_name)); - s->listen_on(ports, ec, entry.ip().toString().toLatin1().constData(), session::listen_no_system_port); - if (!ec) { - ip = entry.ip().toString(); - logger->addMessage(tr("qBittorrent is trying to listen on interface %1 port: %2", "e.g: qBittorrent is trying to listen on interface 192.168.0.1 port: TCP/6881").arg(ip).arg(QString::number(port)), Log::INFO); - return; - } - } - logger->addMessage(tr("qBittorrent didn't find an %1 local address to listen on", "qBittorrent didn't find an IPv4 local address to listen on").arg(listen_ipv6 ? "IPv6" : "IPv4"), Log::CRITICAL); + qDebug() << Q_FUNC_INFO << port; + Preferences* const pref = Preferences::instance(); + Logger* const logger = Logger::instance(); + std::pair ports(port, port); + libtorrent::error_code ec; + const QString iface_name = pref->getNetworkInterface(); + const bool listen_ipv6 = pref->getListenIPv6(); + if (iface_name.isEmpty()) { + logger->addMessage(tr("qBittorrent is trying to listen on any interface port: %1", "e.g: qBittorrent is trying to listen on any interface port: TCP/6881").arg(QString::number(port)), Log::INFO); + if (listen_ipv6) + s->listen_on(ports, ec, "::", session::listen_no_system_port); + else + s->listen_on(ports, ec, "0.0.0.0", session::listen_no_system_port); + + if (ec) + logger->addMessage(tr("qBittorrent failed to listen on any interface port: %1. Reason: %2", "e.g: qBittorrent failed to listen on any interface port: TCP/6881. Reason: no such interface" ).arg(QString::number(port)).arg(misc::toQStringU(ec.message())), Log::CRITICAL); + + return; + } + // Attempt to listen on provided interface + const QNetworkInterface network_iface = QNetworkInterface::interfaceFromName(iface_name); + if (!network_iface.isValid()) { + qDebug("Invalid network interface: %s", qPrintable(iface_name)); + logger->addMessage(tr("The network interface defined is invalid: %1").arg(iface_name), Log::CRITICAL); + return; + } + QString ip; + qDebug("This network interface has %d IP addresses", network_iface.addressEntries().size()); + foreach (const QNetworkAddressEntry &entry, network_iface.addressEntries()) { + if ((!listen_ipv6 && (entry.ip().protocol() == QAbstractSocket::IPv6Protocol)) + || (listen_ipv6 && (entry.ip().protocol() == QAbstractSocket::IPv4Protocol))) + continue; + qDebug("Trying to listen on IP %s (%s)", qPrintable(entry.ip().toString()), qPrintable(iface_name)); + s->listen_on(ports, ec, entry.ip().toString().toLatin1().constData(), session::listen_no_system_port); + if (!ec) { + ip = entry.ip().toString(); + logger->addMessage(tr("qBittorrent is trying to listen on interface %1 port: %2", "e.g: qBittorrent is trying to listen on interface 192.168.0.1 port: TCP/6881").arg(ip).arg(QString::number(port)), Log::INFO); + return; + } + } + logger->addMessage(tr("qBittorrent didn't find an %1 local address to listen on", "qBittorrent didn't find an IPv4 local address to listen on").arg(listen_ipv6 ? "IPv6" : "IPv4"), Log::CRITICAL); } // Set download rate limit // -1 to disable void QBtSession::setDownloadRateLimit(long rate) { - qDebug() << Q_FUNC_INFO << rate; - Q_ASSERT(rate == -1 || rate >= 0); - session_settings settings = s->settings(); - settings.download_rate_limit = rate; - s->set_settings(settings); + qDebug() << Q_FUNC_INFO << rate; + Q_ASSERT(rate == -1 || rate >= 0); + session_settings settings = s->settings(); + settings.download_rate_limit = rate; + s->set_settings(settings); } // Set upload rate limit // -1 to disable void QBtSession::setUploadRateLimit(long rate) { - qDebug() << Q_FUNC_INFO << rate; - Q_ASSERT(rate == -1 || rate >= 0); - session_settings settings = s->settings(); - settings.upload_rate_limit = rate; - s->set_settings(settings); + qDebug() << Q_FUNC_INFO << rate; + Q_ASSERT(rate == -1 || rate >= 0); + session_settings settings = s->settings(); + settings.upload_rate_limit = rate; + s->set_settings(settings); } // Torrents will a ratio superior to the given value will // be automatically deleted void QBtSession::setGlobalMaxRatio(qreal ratio) { - if (ratio < 0) ratio = -1.; - if (global_ratio_limit != ratio) { - global_ratio_limit = ratio; - qDebug("* Set global deleteRatio to %.1f", global_ratio_limit); - updateRatioTimer(); - } + if (ratio < 0) ratio = -1.; + if (global_ratio_limit != ratio) { + global_ratio_limit = ratio; + qDebug("* Set global deleteRatio to %.1f", global_ratio_limit); + updateRatioTimer(); + } } void QBtSession::setMaxRatioPerTorrent(const QString &hash, qreal ratio) { - if (ratio < 0) - ratio = -1; - if (ratio > MAX_RATIO) - ratio = MAX_RATIO; - qDebug("* Set individual max ratio for torrent %s to %.1f.", - qPrintable(hash), ratio); - TorrentPersistentData::instance()->setRatioLimit(hash, ratio); - updateRatioTimer(); + if (ratio < 0) + ratio = -1; + if (ratio > MAX_RATIO) + ratio = MAX_RATIO; + qDebug("* Set individual max ratio for torrent %s to %.1f.", + qPrintable(hash), ratio); + TorrentPersistentData::instance()->setRatioLimit(hash, ratio); + updateRatioTimer(); } void QBtSession::removeRatioPerTorrent(const QString &hash) { - qDebug("* Remove individual max ratio for torrent %s.", qPrintable(hash)); - TorrentPersistentData::instance()->setRatioLimit(hash, TorrentPersistentData::USE_GLOBAL_RATIO); - updateRatioTimer(); + qDebug("* Remove individual max ratio for torrent %s.", qPrintable(hash)); + TorrentPersistentData::instance()->setRatioLimit(hash, TorrentPersistentData::USE_GLOBAL_RATIO); + updateRatioTimer(); } qreal QBtSession::getMaxRatioPerTorrent(const QString &hash, bool *usesGlobalRatio) const { - qreal ratio_limit = TorrentPersistentData::instance()->getRatioLimit(hash); - if (ratio_limit == TorrentPersistentData::USE_GLOBAL_RATIO) { - ratio_limit = global_ratio_limit; - if (usesGlobalRatio) - *usesGlobalRatio = true; - } else { - if (usesGlobalRatio) - *usesGlobalRatio = false; - } - return ratio_limit; + qreal ratio_limit = TorrentPersistentData::instance()->getRatioLimit(hash); + if (ratio_limit == TorrentPersistentData::USE_GLOBAL_RATIO) { + ratio_limit = global_ratio_limit; + if (usesGlobalRatio) + *usesGlobalRatio = true; + } else { + if (usesGlobalRatio) + *usesGlobalRatio = false; + } + return ratio_limit; } void QBtSession::updateRatioTimer() { - if (global_ratio_limit == -1 && !TorrentPersistentData::instance()->hasPerTorrentRatioLimit()) { - if (BigRatioTimer->isActive()) - BigRatioTimer->stop(); - } else if (!BigRatioTimer->isActive()) { - BigRatioTimer->start(); - } + if (global_ratio_limit == -1 && !TorrentPersistentData::instance()->hasPerTorrentRatioLimit()) { + if (BigRatioTimer->isActive()) + BigRatioTimer->stop(); + } else if (!BigRatioTimer->isActive()) { + BigRatioTimer->start(); + } } // Enable IP Filtering void QBtSession::enableIPFilter(const QString &filter_path, bool force) { - qDebug("Enabling IPFiler"); - if (!filterParser) { - filterParser = new FilterParserThread(this, s); - connect(filterParser.data(), SIGNAL(IPFilterParsed(int)), SLOT(handleIPFilterParsed(int))); - connect(filterParser.data(), SIGNAL(IPFilterError()), SLOT(handleIPFilterError())); - } - if (filterPath.isEmpty() || filterPath != fsutils::fromNativePath(filter_path) || force) { - filterPath = fsutils::fromNativePath(filter_path); - filterParser->processFilterFile(fsutils::fromNativePath(filter_path)); - } + qDebug("Enabling IPFiler"); + if (!filterParser) { + filterParser = new FilterParserThread(this, s); + connect(filterParser.data(), SIGNAL(IPFilterParsed(int)), SLOT(handleIPFilterParsed(int))); + connect(filterParser.data(), SIGNAL(IPFilterError()), SLOT(handleIPFilterError())); + } + if (filterPath.isEmpty() || filterPath != fsutils::fromNativePath(filter_path) || force) { + filterPath = fsutils::fromNativePath(filter_path); + filterParser->processFilterFile(fsutils::fromNativePath(filter_path)); + } } // Disable IP Filtering void QBtSession::disableIPFilter() { - qDebug("Disabling IPFilter"); - s->set_ip_filter(ip_filter()); - if (filterParser) { - disconnect(filterParser.data(), 0, this, 0); - delete filterParser; - } - filterPath = ""; + qDebug("Disabling IPFilter"); + s->set_ip_filter(ip_filter()); + if (filterParser) { + disconnect(filterParser.data(), 0, this, 0); + delete filterParser; + } + filterPath = ""; } void QBtSession::recursiveTorrentDownload(const QTorrentHandle &h) @@ -2017,536 +2017,536 @@ void QBtSession::recursiveTorrentDownload(const QTorrentHandle &h) } void QBtSession::autoRunExternalProgram(const QTorrentHandle &h) { - if (!h.is_valid()) return; - QString program = Preferences::instance()->getAutoRunProgram().trimmed(); - if (program.isEmpty()) return; - // Replace %f by torrent path - QString torrent_path; - if (h.num_files() == 1) - torrent_path = h.firstFileSavePath(); - else - torrent_path = h.save_path(); - program.replace("%f", torrent_path); - // Replace %n by torrent name - program.replace("%n", h.name()); - QProcess::startDetached(program); + if (!h.is_valid()) return; + QString program = Preferences::instance()->getAutoRunProgram().trimmed(); + if (program.isEmpty()) return; + // Replace %f by torrent path + QString torrent_path; + if (h.num_files() == 1) + torrent_path = h.firstFileSavePath(); + else + torrent_path = h.save_path(); + program.replace("%f", torrent_path); + // Replace %n by torrent name + program.replace("%n", h.name()); + QProcess::startDetached(program); } void QBtSession::sendNotificationEmail(const QTorrentHandle &h) { - libtorrent::torrent_status status = h.status(torrent_handle::query_accurate_download_counters); - // Prepare mail content - QString content = tr("Torrent name: %1").arg(h.name()) + "\n"; - content += tr("Torrent size: %1").arg(misc::friendlyUnit(status.total_wanted)) + "\n"; - content += tr("Save path: %1").arg(TorrentPersistentData::instance()->getSavePath(h.hash())) + "\n\n"; - content += tr("The torrent was downloaded in %1.", "The torrent was downloaded in 1 hour and 20 seconds").arg(misc::userFriendlyDuration(status.active_time)) + "\n\n\n"; - content += tr("Thank you for using qBittorrent.") + "\n"; - // Send the notification email - Smtp *sender = new Smtp(this); - sender->sendMail("notification@qbittorrent.org", Preferences::instance()->getMailNotificationEmail(), tr("[qBittorrent] %1 has finished downloading").arg(h.name()), content); + libtorrent::torrent_status status = h.status(torrent_handle::query_accurate_download_counters); + // Prepare mail content + QString content = tr("Torrent name: %1").arg(h.name()) + "\n"; + content += tr("Torrent size: %1").arg(misc::friendlyUnit(status.total_wanted)) + "\n"; + content += tr("Save path: %1").arg(TorrentPersistentData::instance()->getSavePath(h.hash())) + "\n\n"; + content += tr("The torrent was downloaded in %1.", "The torrent was downloaded in 1 hour and 20 seconds").arg(misc::userFriendlyDuration(status.active_time)) + "\n\n\n"; + content += tr("Thank you for using qBittorrent.") + "\n"; + // Send the notification email + Smtp *sender = new Smtp(this); + sender->sendMail("notification@qbittorrent.org", Preferences::instance()->getMailNotificationEmail(), tr("[qBittorrent] %1 has finished downloading").arg(h.name()), content); } // Read alerts sent by the Bittorrent session void QBtSession::readAlerts() { - typedef std::vector alerts_t; - alerts_t alerts; - m_alertDispatcher->getPendingAlertsNoWait(alerts); + typedef std::vector alerts_t; + alerts_t alerts; + m_alertDispatcher->getPendingAlertsNoWait(alerts); - for (alerts_t::const_iterator i = alerts.begin(), end = alerts.end(); i != end; ++i) { - handleAlert(*i); - delete *i; - } + for (alerts_t::const_iterator i = alerts.begin(), end = alerts.end(); i != end; ++i) { + handleAlert(*i); + delete *i; + } } void QBtSession::handleAlert(libtorrent::alert* a) { - try { - switch (a->type()) { - case torrent_finished_alert::alert_type: - handleTorrentFinishedAlert(static_cast(a)); - break; - case save_resume_data_alert::alert_type: - handleSaveResumeDataAlert(static_cast(a)); - break; - case file_renamed_alert::alert_type: - handleFileRenamedAlert(static_cast(a)); - break; - case torrent_deleted_alert::alert_type: - handleTorrentDeletedAlert(static_cast(a)); - break; - case storage_moved_alert::alert_type: - handleStorageMovedAlert(static_cast(a)); - break; - case storage_moved_failed_alert::alert_type: - handleStorageMovedFailedAlert(static_cast(a)); - break; - case metadata_received_alert::alert_type: - handleMetadataReceivedAlert(static_cast(a)); - break; - case file_error_alert::alert_type: - handleFileErrorAlert(static_cast(a)); - break; - case file_completed_alert::alert_type: - handleFileCompletedAlert(static_cast(a)); - break; - case torrent_paused_alert::alert_type: - handleTorrentPausedAlert(static_cast(a)); - break; - case tracker_error_alert::alert_type: - handleTrackerErrorAlert(static_cast(a)); - break; - case tracker_reply_alert::alert_type: - handleTrackerReplyAlert(static_cast(a)); - break; - case tracker_warning_alert::alert_type: - handleTrackerWarningAlert(static_cast(a)); - break; - case portmap_error_alert::alert_type: - handlePortmapWarningAlert(static_cast(a)); - break; - case portmap_alert::alert_type: - handlePortmapAlert(static_cast(a)); - break; - case peer_blocked_alert::alert_type: - handlePeerBlockedAlert(static_cast(a)); - break; - case peer_ban_alert::alert_type: - handlePeerBanAlert(static_cast(a)); - break; - case fastresume_rejected_alert::alert_type: - handleFastResumeRejectedAlert(static_cast(a)); - break; - case url_seed_alert::alert_type: - handleUrlSeedAlert(static_cast(a)); - break; - case listen_succeeded_alert::alert_type: - handleListenSucceededAlert(static_cast(a)); - break; - case listen_failed_alert::alert_type: - handleListenFailedAlert(static_cast(a)); - break; - case torrent_checked_alert::alert_type: - handleTorrentCheckedAlert(static_cast(a)); - break; - case external_ip_alert::alert_type: - handleExternalIPAlert(static_cast(a)); - break; - case state_update_alert::alert_type: - handleStateUpdateAlert(static_cast(a)); - break; - case stats_alert::alert_type: - handleStatsAlert(static_cast(a)); - break; - } - } catch (const std::exception& e) { - qWarning() << "Caught exception in readAlerts(): " << misc::toQStringU(e.what()); - } + try { + switch (a->type()) { + case torrent_finished_alert::alert_type: + handleTorrentFinishedAlert(static_cast(a)); + break; + case save_resume_data_alert::alert_type: + handleSaveResumeDataAlert(static_cast(a)); + break; + case file_renamed_alert::alert_type: + handleFileRenamedAlert(static_cast(a)); + break; + case torrent_deleted_alert::alert_type: + handleTorrentDeletedAlert(static_cast(a)); + break; + case storage_moved_alert::alert_type: + handleStorageMovedAlert(static_cast(a)); + break; + case storage_moved_failed_alert::alert_type: + handleStorageMovedFailedAlert(static_cast(a)); + break; + case metadata_received_alert::alert_type: + handleMetadataReceivedAlert(static_cast(a)); + break; + case file_error_alert::alert_type: + handleFileErrorAlert(static_cast(a)); + break; + case file_completed_alert::alert_type: + handleFileCompletedAlert(static_cast(a)); + break; + case torrent_paused_alert::alert_type: + handleTorrentPausedAlert(static_cast(a)); + break; + case tracker_error_alert::alert_type: + handleTrackerErrorAlert(static_cast(a)); + break; + case tracker_reply_alert::alert_type: + handleTrackerReplyAlert(static_cast(a)); + break; + case tracker_warning_alert::alert_type: + handleTrackerWarningAlert(static_cast(a)); + break; + case portmap_error_alert::alert_type: + handlePortmapWarningAlert(static_cast(a)); + break; + case portmap_alert::alert_type: + handlePortmapAlert(static_cast(a)); + break; + case peer_blocked_alert::alert_type: + handlePeerBlockedAlert(static_cast(a)); + break; + case peer_ban_alert::alert_type: + handlePeerBanAlert(static_cast(a)); + break; + case fastresume_rejected_alert::alert_type: + handleFastResumeRejectedAlert(static_cast(a)); + break; + case url_seed_alert::alert_type: + handleUrlSeedAlert(static_cast(a)); + break; + case listen_succeeded_alert::alert_type: + handleListenSucceededAlert(static_cast(a)); + break; + case listen_failed_alert::alert_type: + handleListenFailedAlert(static_cast(a)); + break; + case torrent_checked_alert::alert_type: + handleTorrentCheckedAlert(static_cast(a)); + break; + case external_ip_alert::alert_type: + handleExternalIPAlert(static_cast(a)); + break; + case state_update_alert::alert_type: + handleStateUpdateAlert(static_cast(a)); + break; + case stats_alert::alert_type: + handleStatsAlert(static_cast(a)); + break; + } + } catch (const std::exception& e) { + qWarning() << "Caught exception in readAlerts(): " << misc::toQStringU(e.what()); + } } void QBtSession::handleTorrentFinishedAlert(libtorrent::torrent_finished_alert* p) { - QTorrentHandle h(p->handle); - if (h.is_valid()) { - const QString hash = h.hash(); - qDebug("Got a torrent finished alert for %s", qPrintable(h.name())); - // Remove .!qB extension if necessary - if (appendqBExtension) - appendqBextensionToTorrent(h, false); - - TorrentPersistentData* const TorPersistent = TorrentPersistentData::instance(); - const bool was_already_seeded = TorPersistent->isSeed(hash); - qDebug("Was already seeded: %d", was_already_seeded); - if (!was_already_seeded) { - h.save_resume_data(); - qDebug("Checking if the torrent contains torrent files to download"); - // Check if there are torrent files inside - for (int i=0; i buffer; - lazy_entry entry; - libtorrent::error_code ec; - misc::loadBencodedFile(torrent_fullpath, buffer, entry, ec); - boost::intrusive_ptr t = new torrent_info(entry); - if (t->is_valid()) { - qDebug("emitting recursiveTorrentDownloadPossible()"); - emit recursiveTorrentDownloadPossible(h); - break; - } - } - catch(std::exception&) { - qDebug("Caught error loading torrent"); - Logger::instance()->addMessage(tr("Unable to decode %1 torrent file.").arg(fsutils::toNativePath(torrent_fullpath)), Log::CRITICAL); - } - } - } - // Move to download directory if necessary - if (!defaultTempPath.isEmpty()) { - // Check if directory is different - const QDir current_dir(h.save_path()); - const QDir save_dir(getSavePath(hash)); - if (current_dir != save_dir) { - qDebug("Moving torrent from the temp folder"); - h.move_storage(save_dir.absolutePath()); - } - } - // Remember finished state - qDebug("Saving seed status"); - TorPersistent->saveSeedStatus(h); - // Recheck if the user asked to - Preferences* const pref = Preferences::instance(); - if (pref->recheckTorrentsOnCompletion()) { - h.force_recheck(); - } - qDebug("Emitting finishedTorrent() signal"); - emit finishedTorrent(h); - qDebug("Received finished alert for %s", qPrintable(h.name())); + QTorrentHandle h(p->handle); + if (h.is_valid()) { + const QString hash = h.hash(); + qDebug("Got a torrent finished alert for %s", qPrintable(h.name())); + // Remove .!qB extension if necessary + if (appendqBExtension) + appendqBextensionToTorrent(h, false); + + TorrentPersistentData* const TorPersistent = TorrentPersistentData::instance(); + const bool was_already_seeded = TorPersistent->isSeed(hash); + qDebug("Was already seeded: %d", was_already_seeded); + if (!was_already_seeded) { + h.save_resume_data(); + qDebug("Checking if the torrent contains torrent files to download"); + // Check if there are torrent files inside + for (int i=0; i buffer; + lazy_entry entry; + libtorrent::error_code ec; + misc::loadBencodedFile(torrent_fullpath, buffer, entry, ec); + boost::intrusive_ptr t = new torrent_info(entry); + if (t->is_valid()) { + qDebug("emitting recursiveTorrentDownloadPossible()"); + emit recursiveTorrentDownloadPossible(h); + break; + } + } + catch(std::exception&) { + qDebug("Caught error loading torrent"); + Logger::instance()->addMessage(tr("Unable to decode %1 torrent file.").arg(fsutils::toNativePath(torrent_fullpath)), Log::CRITICAL); + } + } + } + // Move to download directory if necessary + if (!defaultTempPath.isEmpty()) { + // Check if directory is different + const QDir current_dir(h.save_path()); + const QDir save_dir(getSavePath(hash)); + if (current_dir != save_dir) { + qDebug("Moving torrent from the temp folder"); + h.move_storage(save_dir.absolutePath()); + } + } + // Remember finished state + qDebug("Saving seed status"); + TorPersistent->saveSeedStatus(h); + // Recheck if the user asked to + Preferences* const pref = Preferences::instance(); + if (pref->recheckTorrentsOnCompletion()) { + h.force_recheck(); + } + qDebug("Emitting finishedTorrent() signal"); + emit finishedTorrent(h); + qDebug("Received finished alert for %s", qPrintable(h.name())); #ifndef DISABLE_GUI - bool will_shutdown = (pref->shutdownWhenDownloadsComplete() || - pref->shutdownqBTWhenDownloadsComplete() || - pref->suspendWhenDownloadsComplete() || - pref->hibernateWhenDownloadsComplete()) - && !hasDownloadingTorrents(); + bool will_shutdown = (pref->shutdownWhenDownloadsComplete() || + pref->shutdownqBTWhenDownloadsComplete() || + pref->suspendWhenDownloadsComplete() || + pref->hibernateWhenDownloadsComplete()) + && !hasDownloadingTorrents(); #else - bool will_shutdown = false; + bool will_shutdown = false; #endif - // AutoRun program - if (pref->isAutoRunEnabled()) - autoRunExternalProgram(h); - // Move .torrent file to another folder - if (pref->isFinishedTorrentExportEnabled()) - exportTorrentFile(h, FinishedTorrentExportFolder); - // Mail notification - if (pref->isMailNotificationEnabled()) - sendNotificationEmail(h); + // AutoRun program + if (pref->isAutoRunEnabled()) + autoRunExternalProgram(h); + // Move .torrent file to another folder + if (pref->isFinishedTorrentExportEnabled()) + exportTorrentFile(h, FinishedTorrentExportFolder); + // Mail notification + if (pref->isMailNotificationEnabled()) + sendNotificationEmail(h); #ifndef DISABLE_GUI - // Auto-Shutdown - if (will_shutdown) { - bool suspend = pref->suspendWhenDownloadsComplete(); - bool hibernate = pref->hibernateWhenDownloadsComplete(); - bool shutdown = pref->shutdownWhenDownloadsComplete(); - // Confirm shutdown - shutDownAction action = NO_SHUTDOWN; - - if (suspend) - action = SUSPEND_COMPUTER; - else if (hibernate) - action = HIBERNATE_COMPUTER; - else if (shutdown) - action = SHUTDOWN_COMPUTER; - if (!ShutdownConfirmDlg::askForConfirmation(action)) - return; - - // Actually shut down - if (suspend || hibernate || shutdown) { - qDebug("Preparing for auto-shutdown because all downloads are complete!"); - // Disabling it for next time - pref->setShutdownWhenDownloadsComplete(false); - pref->setSuspendWhenDownloadsComplete(false); - pref->setHibernateWhenDownloadsComplete(false); - // Make sure preferences are synced before exiting - m_shutdownAct = action; - } - qDebug("Exiting the application"); - qApp->exit(); - return; - } + // Auto-Shutdown + if (will_shutdown) { + bool suspend = pref->suspendWhenDownloadsComplete(); + bool hibernate = pref->hibernateWhenDownloadsComplete(); + bool shutdown = pref->shutdownWhenDownloadsComplete(); + // Confirm shutdown + shutDownAction action = NO_SHUTDOWN; + + if (suspend) + action = SUSPEND_COMPUTER; + else if (hibernate) + action = HIBERNATE_COMPUTER; + else if (shutdown) + action = SHUTDOWN_COMPUTER; + if (!ShutdownConfirmDlg::askForConfirmation(action)) + return; + + // Actually shut down + if (suspend || hibernate || shutdown) { + qDebug("Preparing for auto-shutdown because all downloads are complete!"); + // Disabling it for next time + pref->setShutdownWhenDownloadsComplete(false); + pref->setSuspendWhenDownloadsComplete(false); + pref->setHibernateWhenDownloadsComplete(false); + // Make sure preferences are synced before exiting + m_shutdownAct = action; + } + qDebug("Exiting the application"); + qApp->exit(); + return; + } #endif // DISABLE_GUI + } } - } } void QBtSession::handleSaveResumeDataAlert(libtorrent::save_resume_data_alert* p) { - const QDir torrentBackup(fsutils::BTBackupLocation()); - const QTorrentHandle h(p->handle); - if (h.is_valid() && p->resume_data) { - const QString filepath = torrentBackup.absoluteFilePath(h.hash()+".fastresume"); - QFile resume_file(filepath); - if (resume_file.exists()) - fsutils::forceRemove(filepath); - qDebug("Saving fastresume data in %s", qPrintable(filepath)); - backupPersistentData(h.hash(), p->resume_data); - vector out; - bencode(back_inserter(out), *p->resume_data); - if (!out.empty() && resume_file.open(QIODevice::WriteOnly)) { - resume_file.write(&out[0], out.size()); - resume_file.close(); + const QDir torrentBackup(fsutils::BTBackupLocation()); + const QTorrentHandle h(p->handle); + if (h.is_valid() && p->resume_data) { + const QString filepath = torrentBackup.absoluteFilePath(h.hash()+".fastresume"); + QFile resume_file(filepath); + if (resume_file.exists()) + fsutils::forceRemove(filepath); + qDebug("Saving fastresume data in %s", qPrintable(filepath)); + backupPersistentData(h.hash(), p->resume_data); + vector out; + bencode(back_inserter(out), *p->resume_data); + if (!out.empty() && resume_file.open(QIODevice::WriteOnly)) { + resume_file.write(&out[0], out.size()); + resume_file.close(); + } } - } } void QBtSession::handleFileRenamedAlert(libtorrent::file_renamed_alert* p) { - QTorrentHandle h(p->handle); - if (h.is_valid()) { - if (h.num_files() > 1) { - // Check if folders were renamed - QStringList old_path_parts = h.orig_filepath_at(p->index).split("/"); - old_path_parts.removeLast(); - QString old_path = old_path_parts.join("/"); - QStringList new_path_parts = fsutils::fromNativePath(misc::toQStringU(p->name)).split("/"); - new_path_parts.removeLast(); - if (!new_path_parts.isEmpty() && old_path != new_path_parts.join("/")) { - qDebug("Old_path(%s) != new_path(%s)", qPrintable(old_path), qPrintable(new_path_parts.join("/"))); - old_path = h.save_path()+"/"+old_path; - qDebug("Detected folder renaming, attempt to delete old folder: %s", qPrintable(old_path)); - QDir().rmpath(old_path); - } - } else { - // Single-file torrent - // Renaming a file corresponds to changing the save path - emit savePathChanged(h); + QTorrentHandle h(p->handle); + if (h.is_valid()) { + if (h.num_files() > 1) { + // Check if folders were renamed + QStringList old_path_parts = h.orig_filepath_at(p->index).split("/"); + old_path_parts.removeLast(); + QString old_path = old_path_parts.join("/"); + QStringList new_path_parts = fsutils::fromNativePath(misc::toQStringU(p->name)).split("/"); + new_path_parts.removeLast(); + if (!new_path_parts.isEmpty() && old_path != new_path_parts.join("/")) { + qDebug("Old_path(%s) != new_path(%s)", qPrintable(old_path), qPrintable(new_path_parts.join("/"))); + old_path = h.save_path()+"/"+old_path; + qDebug("Detected folder renaming, attempt to delete old folder: %s", qPrintable(old_path)); + QDir().rmpath(old_path); + } + } else { + // Single-file torrent + // Renaming a file corresponds to changing the save path + emit savePathChanged(h); + } } - } } void QBtSession::handleTorrentDeletedAlert(libtorrent::torrent_deleted_alert* p) { - qDebug("A torrent was deleted from the hard disk, attempting to remove the root folder too..."); - QString hash = misc::toQString(p->info_hash); - if (!hash.isEmpty()) { - if (savePathsToRemove.contains(hash)) { - const QString dirpath = savePathsToRemove.take(hash); - qDebug() << "Removing save path: " << dirpath << "..."; - bool ok = fsutils::smartRemoveEmptyFolderTree(dirpath); - Q_UNUSED(ok); - qDebug() << "Folder was removed: " << ok; - } - } else { - // Fallback - qDebug() << "hash is empty, use fallback to remove save path"; - foreach (const QString& key, savePathsToRemove.keys()) { - // Attempt to delete - if (QDir().rmdir(savePathsToRemove[key])) { - savePathsToRemove.remove(key); - } + qDebug("A torrent was deleted from the hard disk, attempting to remove the root folder too..."); + QString hash = misc::toQString(p->info_hash); + if (!hash.isEmpty()) { + if (savePathsToRemove.contains(hash)) { + const QString dirpath = savePathsToRemove.take(hash); + qDebug() << "Removing save path: " << dirpath << "..."; + bool ok = fsutils::smartRemoveEmptyFolderTree(dirpath); + Q_UNUSED(ok); + qDebug() << "Folder was removed: " << ok; + } + } else { + // Fallback + qDebug() << "hash is empty, use fallback to remove save path"; + foreach (const QString& key, savePathsToRemove.keys()) { + // Attempt to delete + if (QDir().rmdir(savePathsToRemove[key])) { + savePathsToRemove.remove(key); + } + } } - } } void QBtSession::handleStorageMovedAlert(libtorrent::storage_moved_alert* p) { - QTorrentHandle h(p->handle); - if (!h.is_valid()) { - qWarning("invalid handle received in storage_moved_alert"); - return; - } - - QString hash = h.hash(); - - if (!TorrentTempData::isMoveInProgress(hash)) { - qWarning("unexpected storage_moved_alert received"); - return; - } - - QString new_save_path = fsutils::fromNativePath(misc::toQStringU(p->path.c_str())); - if (new_save_path != fsutils::fromNativePath(TorrentTempData::getNewPath(hash))) { - qWarning("new path received in handleStorageMovedAlert() doesn't match a path in a queue"); - return; - } - - QString oldPath = fsutils::fromNativePath(TorrentTempData::getOldPath(hash)); - - qDebug("Torrent is successfully moved from %s to %s", qPrintable(oldPath), qPrintable(new_save_path)); - - // Attempt to remove old folder if empty - QDir old_save_dir(oldPath); - if (old_save_dir != QDir(defaultSavePath) && old_save_dir != QDir(defaultTempPath)) { - qDebug("Attempting to remove %s", qPrintable(oldPath)); - QDir().rmpath(oldPath); - } - if (defaultTempPath.isEmpty() || !new_save_path.startsWith(defaultTempPath)) { - qDebug("Storage has been moved, updating save path to %s", qPrintable(new_save_path)); - TorrentPersistentData::instance()->saveSavePath(h.hash(), new_save_path); - } - emit savePathChanged(h); - //h.force_recheck(); - - QString queued = TorrentTempData::getQueuedPath(hash); - if (!queued.isEmpty()) { - TorrentTempData::finishMove(hash); - h.move_storage(queued); - } - else { - TorrentTempData::finishMove(hash); - } + QTorrentHandle h(p->handle); + if (!h.is_valid()) { + qWarning("invalid handle received in storage_moved_alert"); + return; + } + + QString hash = h.hash(); + + if (!TorrentTempData::isMoveInProgress(hash)) { + qWarning("unexpected storage_moved_alert received"); + return; + } + + QString new_save_path = fsutils::fromNativePath(misc::toQStringU(p->path.c_str())); + if (new_save_path != fsutils::fromNativePath(TorrentTempData::getNewPath(hash))) { + qWarning("new path received in handleStorageMovedAlert() doesn't match a path in a queue"); + return; + } + + QString oldPath = fsutils::fromNativePath(TorrentTempData::getOldPath(hash)); + + qDebug("Torrent is successfully moved from %s to %s", qPrintable(oldPath), qPrintable(new_save_path)); + + // Attempt to remove old folder if empty + QDir old_save_dir(oldPath); + if (old_save_dir != QDir(defaultSavePath) && old_save_dir != QDir(defaultTempPath)) { + qDebug("Attempting to remove %s", qPrintable(oldPath)); + QDir().rmpath(oldPath); + } + if (defaultTempPath.isEmpty() || !new_save_path.startsWith(defaultTempPath)) { + qDebug("Storage has been moved, updating save path to %s", qPrintable(new_save_path)); + TorrentPersistentData::instance()->saveSavePath(h.hash(), new_save_path); + } + emit savePathChanged(h); + //h.force_recheck(); + + QString queued = TorrentTempData::getQueuedPath(hash); + if (!queued.isEmpty()) { + TorrentTempData::finishMove(hash); + h.move_storage(queued); + } + else { + TorrentTempData::finishMove(hash); + } } void QBtSession::handleStorageMovedFailedAlert(libtorrent::storage_moved_failed_alert* p) { - QTorrentHandle h(p->handle); - if (!h.is_valid()) { - qWarning("invalid handle received in storage_moved_failed_alert"); - return; - } + QTorrentHandle h(p->handle); + if (!h.is_valid()) { + qWarning("invalid handle received in storage_moved_failed_alert"); + return; + } - QString hash = h.hash(); + QString hash = h.hash(); - if (!TorrentTempData::isMoveInProgress(hash)) { - qWarning("unexpected storage_moved_alert received"); - return; - } + if (!TorrentTempData::isMoveInProgress(hash)) { + qWarning("unexpected storage_moved_alert received"); + return; + } - Logger* const logger = Logger::instance(); - logger->addMessage(tr("Could not move torrent: '%1'. Reason: %2").arg(h.name()).arg(misc::toQStringU(p->message())), Log::CRITICAL); + Logger* const logger = Logger::instance(); + logger->addMessage(tr("Could not move torrent: '%1'. Reason: %2").arg(h.name()).arg(misc::toQStringU(p->message())), Log::CRITICAL); - QString queued = TorrentTempData::getQueuedPath(hash); - if (!queued.isEmpty()) { - TorrentTempData::finishMove(hash); - logger->addMessage(tr("Attempting to move torrent: '%1' to path: '%2'.").arg(h.name()).arg(fsutils::toNativePath(queued))); - h.move_storage(queued); - } - else { - TorrentTempData::finishMove(hash); - } + QString queued = TorrentTempData::getQueuedPath(hash); + if (!queued.isEmpty()) { + TorrentTempData::finishMove(hash); + logger->addMessage(tr("Attempting to move torrent: '%1' to path: '%2'.").arg(h.name()).arg(fsutils::toNativePath(queued))); + h.move_storage(queued); + } + else { + TorrentTempData::finishMove(hash); + } } void QBtSession::handleMetadataReceivedAlert(libtorrent::metadata_received_alert* p) { - QTorrentHandle h(p->handle); - Preferences* const pref = Preferences::instance(); - if (h.is_valid()) { - QString hash(h.hash()); - if (HiddenData::hasData(hash)) { - HiddenData::gotMetadata(hash); - if (pref->isQueueingSystemEnabled()) { - //Internally decrease the queue limits to ensure that that other queued items aren't started - libtorrent::session_settings sessionSettings(s->settings()); - int max_downloading = pref->getMaxActiveDownloads(); - int max_active = pref->getMaxActiveTorrents(); - if (max_downloading > -1) - sessionSettings.active_downloads = max_downloading + HiddenData::getDownloadingSize(); - else - sessionSettings.active_downloads = max_downloading; - if (max_active > -1) - sessionSettings.active_limit = max_active + HiddenData::getDownloadingSize(); + QTorrentHandle h(p->handle); + Preferences* const pref = Preferences::instance(); + if (h.is_valid()) { + QString hash(h.hash()); + if (HiddenData::hasData(hash)) { + HiddenData::gotMetadata(hash); + if (pref->isQueueingSystemEnabled()) { + //Internally decrease the queue limits to ensure that that other queued items aren't started + libtorrent::session_settings sessionSettings(s->settings()); + int max_downloading = pref->getMaxActiveDownloads(); + int max_active = pref->getMaxActiveTorrents(); + if (max_downloading > -1) + sessionSettings.active_downloads = max_downloading + HiddenData::getDownloadingSize(); + else + sessionSettings.active_downloads = max_downloading; + if (max_active > -1) + sessionSettings.active_limit = max_active + HiddenData::getDownloadingSize(); + else + sessionSettings.active_limit = max_active; + s->set_settings(sessionSettings); + } + h.pause(); + } + qDebug("Received metadata for %s", qPrintable(h.hash())); + // Save metadata + const QDir torrentBackup(fsutils::BTBackupLocation()); + if (!QFile::exists(torrentBackup.absoluteFilePath(h.hash()+QString(".torrent")))) + h.save_torrent_file(torrentBackup.absoluteFilePath(h.hash()+QString(".torrent"))); + // Copy the torrent file to the export folder + if (m_torrentExportEnabled) + exportTorrentFile(h); + // Append .!qB to incomplete files + if (appendqBExtension) + appendqBextensionToTorrent(h, true); + + if (!HiddenData::hasData(hash)) + emit metadataReceived(h); else - sessionSettings.active_limit = max_active; - s->set_settings(sessionSettings); - } - h.pause(); - } - qDebug("Received metadata for %s", qPrintable(h.hash())); - // Save metadata - const QDir torrentBackup(fsutils::BTBackupLocation()); - if (!QFile::exists(torrentBackup.absoluteFilePath(h.hash()+QString(".torrent")))) - h.save_torrent_file(torrentBackup.absoluteFilePath(h.hash()+QString(".torrent"))); - // Copy the torrent file to the export folder - if (m_torrentExportEnabled) - exportTorrentFile(h); - // Append .!qB to incomplete files - if (appendqBExtension) - appendqBextensionToTorrent(h, true); - - if (!HiddenData::hasData(hash)) - emit metadataReceived(h); - else - emit metadataReceivedHidden(h); + emit metadataReceivedHidden(h); - if (h.is_paused() && !HiddenData::hasData(hash)) { - // XXX: Unfortunately libtorrent-rasterbar does not send a torrent_paused_alert - // and the torrent can be paused when metadata is received - emit pausedTorrent(h); + if (h.is_paused() && !HiddenData::hasData(hash)) { + // XXX: Unfortunately libtorrent-rasterbar does not send a torrent_paused_alert + // and the torrent can be paused when metadata is received + emit pausedTorrent(h); + } } - } } void QBtSession::handleFileErrorAlert(libtorrent::file_error_alert* p) { - QTorrentHandle h(p->handle); - if (h.is_valid()) { - h.pause(); - std::cerr << "File Error: " << p->message().c_str() << std::endl; - Logger* const logger = Logger::instance(); - logger->addMessage(tr("An I/O error occurred, '%1' paused.").arg(h.name())); - logger->addMessage(tr("Reason: %1").arg(misc::toQStringU(p->message()))); + QTorrentHandle h(p->handle); if (h.is_valid()) { - emit fullDiskError(h, misc::toQStringU(p->message())); - //h.pause(); - emit pausedTorrent(h); + h.pause(); + std::cerr << "File Error: " << p->message().c_str() << std::endl; + Logger* const logger = Logger::instance(); + logger->addMessage(tr("An I/O error occurred, '%1' paused.").arg(h.name())); + logger->addMessage(tr("Reason: %1").arg(misc::toQStringU(p->message()))); + if (h.is_valid()) { + emit fullDiskError(h, misc::toQStringU(p->message())); + //h.pause(); + emit pausedTorrent(h); + } } - } } void QBtSession::handleFileCompletedAlert(libtorrent::file_completed_alert* p) { - QTorrentHandle h(p->handle); - qDebug("A file completed download in torrent %s", qPrintable(h.name())); - if (appendqBExtension) { - qDebug("appendqBTExtension is true"); - QString name = h.filepath_at(p->index); - if (name.endsWith(".!qB")) { - const QString old_name = name; - name.chop(4); - qDebug("Renaming %s to %s", qPrintable(old_name), qPrintable(name)); - h.rename_file(p->index, name); + QTorrentHandle h(p->handle); + qDebug("A file completed download in torrent %s", qPrintable(h.name())); + if (appendqBExtension) { + qDebug("appendqBTExtension is true"); + QString name = h.filepath_at(p->index); + if (name.endsWith(".!qB")) { + const QString old_name = name; + name.chop(4); + qDebug("Renaming %s to %s", qPrintable(old_name), qPrintable(name)); + h.rename_file(p->index, name); + } } - } } void QBtSession::handleTorrentPausedAlert(libtorrent::torrent_paused_alert* p) { - if (p->handle.is_valid()) { - QTorrentHandle h(p->handle); - if (!HiddenData::hasData(h.hash())) { - if (!h.has_error() && !TorrentPersistentData::instance()->getHasMissingFiles(h.hash())) - h.save_resume_data(); - emit pausedTorrent(h); + if (p->handle.is_valid()) { + QTorrentHandle h(p->handle); + if (!HiddenData::hasData(h.hash())) { + if (!h.has_error() && !TorrentPersistentData::instance()->getHasMissingFiles(h.hash())) + h.save_resume_data(); + emit pausedTorrent(h); + } } - } } void QBtSession::handleTrackerErrorAlert(libtorrent::tracker_error_alert* p) { - // Level: fatal - QTorrentHandle h(p->handle); - if (h.is_valid()) { - // Authentication - if (p->status_code != 401) { - qDebug("Received a tracker error for %s: %s", p->url.c_str(), p->msg.c_str()); - const QString tracker_url = misc::toQString(p->url); - QHash trackers_data = trackersInfos.value(h.hash(), QHash()); - TrackerInfos data = trackers_data.value(tracker_url, TrackerInfos(tracker_url)); - data.last_message = misc::toQStringU(p->msg); - trackers_data.insert(tracker_url, data); - trackersInfos[h.hash()] = trackers_data; - } else { - emit trackerAuthenticationRequired(h); + // Level: fatal + QTorrentHandle h(p->handle); + if (h.is_valid()) { + // Authentication + if (p->status_code != 401) { + qDebug("Received a tracker error for %s: %s", p->url.c_str(), p->msg.c_str()); + const QString tracker_url = misc::toQString(p->url); + QHash trackers_data = trackersInfos.value(h.hash(), QHash()); + TrackerInfos data = trackers_data.value(tracker_url, TrackerInfos(tracker_url)); + data.last_message = misc::toQStringU(p->msg); + trackers_data.insert(tracker_url, data); + trackersInfos[h.hash()] = trackers_data; + } else { + emit trackerAuthenticationRequired(h); + } } - } } void QBtSession::handleTrackerReplyAlert(libtorrent::tracker_reply_alert* p) { - const QTorrentHandle h(p->handle); - if (h.is_valid()) { - qDebug("Received a tracker reply from %s (Num_peers=%d)", p->url.c_str(), p->num_peers); - // Connection was successful now. Remove possible old errors - QHash trackers_data = trackersInfos.value(h.hash(), QHash()); - const QString tracker_url = misc::toQString(p->url); - TrackerInfos data = trackers_data.value(tracker_url, TrackerInfos(tracker_url)); - data.last_message = ""; // Reset error/warning message - data.num_peers = p->num_peers; - trackers_data.insert(tracker_url, data); - trackersInfos[h.hash()] = trackers_data; - } + const QTorrentHandle h(p->handle); + if (h.is_valid()) { + qDebug("Received a tracker reply from %s (Num_peers=%d)", p->url.c_str(), p->num_peers); + // Connection was successful now. Remove possible old errors + QHash trackers_data = trackersInfos.value(h.hash(), QHash()); + const QString tracker_url = misc::toQString(p->url); + TrackerInfos data = trackers_data.value(tracker_url, TrackerInfos(tracker_url)); + data.last_message = ""; // Reset error/warning message + data.num_peers = p->num_peers; + trackers_data.insert(tracker_url, data); + trackersInfos[h.hash()] = trackers_data; + } } void QBtSession::handleTrackerWarningAlert(libtorrent::tracker_warning_alert* p) { - const QTorrentHandle h(p->handle); - if (h.is_valid()) { - // Connection was successful now but there is a warning message - QHash trackers_data = trackersInfos.value(h.hash(), QHash()); - const QString tracker_url = misc::toQString(p->url); - TrackerInfos data = trackers_data.value(tracker_url, TrackerInfos(tracker_url)); - data.last_message = misc::toQStringU(p->msg); // Store warning message - trackers_data.insert(tracker_url, data); - trackersInfos[h.hash()] = trackers_data; - qDebug("Received a tracker warning from %s: %s", p->url.c_str(), p->msg.c_str()); - } + const QTorrentHandle h(p->handle); + if (h.is_valid()) { + // Connection was successful now but there is a warning message + QHash trackers_data = trackersInfos.value(h.hash(), QHash()); + const QString tracker_url = misc::toQString(p->url); + TrackerInfos data = trackers_data.value(tracker_url, TrackerInfos(tracker_url)); + data.last_message = misc::toQStringU(p->msg); // Store warning message + trackers_data.insert(tracker_url, data); + trackersInfos[h.hash()] = trackers_data; + qDebug("Received a tracker warning from %s: %s", p->url.c_str(), p->msg.c_str()); + } } void QBtSession::handlePortmapWarningAlert(libtorrent::portmap_error_alert* p) { - Logger::instance()->addMessage(tr("UPnP/NAT-PMP: Port mapping failure, message: %1").arg(misc::toQStringU(p->message())), Log::CRITICAL); + Logger::instance()->addMessage(tr("UPnP/NAT-PMP: Port mapping failure, message: %1").arg(misc::toQStringU(p->message())), Log::CRITICAL); } void QBtSession::handlePortmapAlert(libtorrent::portmap_alert* p) { - qDebug("UPnP Success, msg: %s", p->message().c_str()); - Logger::instance()->addMessage(tr("UPnP/NAT-PMP: Port mapping successful, message: %1").arg(misc::toQStringU(p->message())), Log::INFO); + qDebug("UPnP Success, msg: %s", p->message().c_str()); + Logger::instance()->addMessage(tr("UPnP/NAT-PMP: Port mapping successful, message: %1").arg(misc::toQStringU(p->message())), Log::INFO); } void QBtSession::handlePeerBlockedAlert(libtorrent::peer_blocked_alert* p) @@ -2585,229 +2585,229 @@ void QBtSession::handlePeerBlockedAlert(libtorrent::peer_blocked_alert* p) } void QBtSession::handlePeerBanAlert(libtorrent::peer_ban_alert* p) { - boost::system::error_code ec; - string ip = p->ip.address().to_string(ec); - if (!ec) - Logger::instance()->addPeer(QString::fromLatin1(ip.c_str()), false); + boost::system::error_code ec; + string ip = p->ip.address().to_string(ec); + if (!ec) + Logger::instance()->addPeer(QString::fromLatin1(ip.c_str()), false); } void QBtSession::handleFastResumeRejectedAlert(libtorrent::fastresume_rejected_alert* p) { - Logger* const logger = Logger::instance(); - QTorrentHandle h(p->handle); - if (h.is_valid()) { - qDebug("/!\\ Fast resume failed for %s, reason: %s", qPrintable(h.name()), p->message().c_str()); - if (p->error.value() == errors::mismatching_file_size) { - // Mismatching file size (files were probably moved) - const QString hash = h.hash(); - logger->addMessage(tr("File sizes mismatch for torrent %1, pausing it.").arg(h.name()), Log::CRITICAL); - TorrentPersistentData::instance()->setHasMissingFiles(h.hash(), true); - pauseTorrent(hash); - } else { - logger->addMessage(tr("Fast resume data was rejected for torrent %1, checking again...").arg(h.name()), Log::CRITICAL); - logger->addMessage(tr("Reason: %1").arg(misc::toQStringU(p->message()))); + Logger* const logger = Logger::instance(); + QTorrentHandle h(p->handle); + if (h.is_valid()) { + qDebug("/!\\ Fast resume failed for %s, reason: %s", qPrintable(h.name()), p->message().c_str()); + if (p->error.value() == errors::mismatching_file_size) { + // Mismatching file size (files were probably moved) + const QString hash = h.hash(); + logger->addMessage(tr("File sizes mismatch for torrent %1, pausing it.").arg(h.name()), Log::CRITICAL); + TorrentPersistentData::instance()->setHasMissingFiles(h.hash(), true); + pauseTorrent(hash); + } else { + logger->addMessage(tr("Fast resume data was rejected for torrent %1, checking again...").arg(h.name()), Log::CRITICAL); + logger->addMessage(tr("Reason: %1").arg(misc::toQStringU(p->message()))); + } } - } } void QBtSession::handleUrlSeedAlert(libtorrent::url_seed_alert* p) { - Logger::instance()->addMessage(tr("Url seed lookup failed for url: %1, message: %2").arg(misc::toQString(p->url)).arg(misc::toQStringU(p->message())), Log::CRITICAL); + Logger::instance()->addMessage(tr("Url seed lookup failed for url: %1, message: %2").arg(misc::toQString(p->url)).arg(misc::toQStringU(p->message())), Log::CRITICAL); } void QBtSession::handleListenSucceededAlert(libtorrent::listen_succeeded_alert *p) { - boost::system::error_code ec; - QString proto = "TCP"; + boost::system::error_code ec; + QString proto = "TCP"; #if LIBTORRENT_VERSION_NUM >= 10000 - if (p->sock_type == listen_succeeded_alert::udp) - proto = "UDP"; - else if (p->sock_type == listen_succeeded_alert::tcp) - proto = "TCP"; - else if (p->sock_type == listen_succeeded_alert::tcp_ssl) - proto = "TCP_SSL"; + if (p->sock_type == listen_succeeded_alert::udp) + proto = "UDP"; + else if (p->sock_type == listen_succeeded_alert::tcp) + proto = "TCP"; + else if (p->sock_type == listen_succeeded_alert::tcp_ssl) + proto = "TCP_SSL"; #endif - qDebug() << "Successfully listening on " << proto << p->endpoint.address().to_string(ec).c_str() << "/" << p->endpoint.port(); - Logger::instance()->addMessage(tr("qBittorrent is successfully listening on interface %1 port: %2/%3", "e.g: qBittorrent is successfully listening on interface 192.168.0.1 port: TCP/6881").arg(p->endpoint.address().to_string(ec).c_str()).arg(proto).arg(QString::number(p->endpoint.port())), Log::INFO); - // Force reannounce on all torrents because some trackers blacklist some ports - std::vector torrents = s->get_torrents(); + qDebug() << "Successfully listening on " << proto << p->endpoint.address().to_string(ec).c_str() << "/" << p->endpoint.port(); + Logger::instance()->addMessage(tr("qBittorrent is successfully listening on interface %1 port: %2/%3", "e.g: qBittorrent is successfully listening on interface 192.168.0.1 port: TCP/6881").arg(p->endpoint.address().to_string(ec).c_str()).arg(proto).arg(QString::number(p->endpoint.port())), Log::INFO); + // Force reannounce on all torrents because some trackers blacklist some ports + std::vector torrents = s->get_torrents(); - std::vector::iterator it = torrents.begin(); - std::vector::iterator itend = torrents.end(); - for ( ; it != itend; ++it) { - it->force_reannounce(); - } + std::vector::iterator it = torrents.begin(); + std::vector::iterator itend = torrents.end(); + for ( ; it != itend; ++it) { + it->force_reannounce(); + } } void QBtSession::handleListenFailedAlert(libtorrent::listen_failed_alert *p) { - boost::system::error_code ec; - QString proto = "TCP"; + boost::system::error_code ec; + QString proto = "TCP"; #if LIBTORRENT_VERSION_NUM >= 10000 - if (p->sock_type == listen_failed_alert::udp) - proto = "UDP"; - else if (p->sock_type == listen_failed_alert::tcp) - proto = "TCP"; - else if (p->sock_type == listen_failed_alert::tcp_ssl) - proto = "TCP_SSL"; - else if (p->sock_type == listen_failed_alert::i2p) - proto = "I2P"; - else if (p->sock_type == listen_failed_alert::socks5) - proto = "SOCKS5"; + if (p->sock_type == listen_failed_alert::udp) + proto = "UDP"; + else if (p->sock_type == listen_failed_alert::tcp) + proto = "TCP"; + else if (p->sock_type == listen_failed_alert::tcp_ssl) + proto = "TCP_SSL"; + else if (p->sock_type == listen_failed_alert::i2p) + proto = "I2P"; + else if (p->sock_type == listen_failed_alert::socks5) + proto = "SOCKS5"; #endif - qDebug() << "Failed listening on " << proto << p->endpoint.address().to_string(ec).c_str() << "/" << p->endpoint.port(); - Logger::instance()->addMessage(tr("qBittorrent failed listening on interface %1 port: %2/%3. Reason: %4", "e.g: qBittorrent failed listening on interface 192.168.0.1 port: TCP/6881. Reason: already in use").arg(p->endpoint.address().to_string(ec).c_str()).arg(proto).arg(QString::number(p->endpoint.port())).arg(misc::toQStringU(p->error.message())), Log::CRITICAL); + qDebug() << "Failed listening on " << proto << p->endpoint.address().to_string(ec).c_str() << "/" << p->endpoint.port(); + Logger::instance()->addMessage(tr("qBittorrent failed listening on interface %1 port: %2/%3. Reason: %4", "e.g: qBittorrent failed listening on interface 192.168.0.1 port: TCP/6881. Reason: already in use").arg(p->endpoint.address().to_string(ec).c_str()).arg(proto).arg(QString::number(p->endpoint.port())).arg(misc::toQStringU(p->error.message())), Log::CRITICAL); } void QBtSession::handleTorrentCheckedAlert(libtorrent::torrent_checked_alert* p) { - QTorrentHandle h(p->handle); - if (h.is_valid()) { - const QString hash = h.hash(); - qDebug("%s have just finished checking", qPrintable(hash)); - // Save seed status - TorrentPersistentData::instance()->saveSeedStatus(h); - // Move to temp directory if necessary - if (!h.is_seed() && !defaultTempPath.isEmpty()) { - // Check if directory is different - const QDir current_dir(h.save_path()); - const QDir save_dir(getSavePath(h.hash())); - if (current_dir == save_dir) { - qDebug("Moving the torrent to the temp directory..."); - QString torrent_tmp_path = defaultTempPath; - h.move_storage(torrent_tmp_path); - } - } - emit torrentFinishedChecking(h); - if (torrentsToPausedAfterChecking.contains(hash)) { - torrentsToPausedAfterChecking.removeOne(hash); - h.pause(); - emit pausedTorrent(h); + QTorrentHandle h(p->handle); + if (h.is_valid()) { + const QString hash = h.hash(); + qDebug("%s have just finished checking", qPrintable(hash)); + // Save seed status + TorrentPersistentData::instance()->saveSeedStatus(h); + // Move to temp directory if necessary + if (!h.is_seed() && !defaultTempPath.isEmpty()) { + // Check if directory is different + const QDir current_dir(h.save_path()); + const QDir save_dir(getSavePath(h.hash())); + if (current_dir == save_dir) { + qDebug("Moving the torrent to the temp directory..."); + QString torrent_tmp_path = defaultTempPath; + h.move_storage(torrent_tmp_path); + } + } + emit torrentFinishedChecking(h); + if (torrentsToPausedAfterChecking.contains(hash)) { + torrentsToPausedAfterChecking.removeOne(hash); + h.pause(); + emit pausedTorrent(h); + } } - } } void QBtSession::handleExternalIPAlert(libtorrent::external_ip_alert *p) { - boost::system::error_code ec; - Logger::instance()->addMessage(tr("External IP: %1", "e.g. External IP: 192.168.0.1").arg(p->external_address.to_string(ec).c_str()), Log::INFO); + boost::system::error_code ec; + Logger::instance()->addMessage(tr("External IP: %1", "e.g. External IP: 192.168.0.1").arg(p->external_address.to_string(ec).c_str()), Log::INFO); } void QBtSession::handleStateUpdateAlert(libtorrent::state_update_alert *p) { - emit stateUpdate(p->status); + emit stateUpdate(p->status); } void QBtSession::handleStatsAlert(libtorrent::stats_alert *p) { - emit statsReceived(*p); + emit statsReceived(*p); } void QBtSession::recheckTorrent(const QString &hash) { - QTorrentHandle h = getTorrentHandle(hash); - if (h.is_valid() && h.has_metadata()) { - if (h.is_paused()) { - if (!torrentsToPausedAfterChecking.contains(h.hash())) { - torrentsToPausedAfterChecking << h.hash(); - h.resume(); - } + QTorrentHandle h = getTorrentHandle(hash); + if (h.is_valid() && h.has_metadata()) { + if (h.is_paused()) { + if (!torrentsToPausedAfterChecking.contains(h.hash())) { + torrentsToPausedAfterChecking << h.hash(); + h.resume(); + } + } + h.force_recheck(); } - h.force_recheck(); - } } QHash QBtSession::getTrackersInfo(const QString &hash) const { - return trackersInfos.value(hash, QHash()); + return trackersInfos.value(hash, QHash()); } int QBtSession::getListenPort() const { - qDebug() << Q_FUNC_INFO << s->listen_port(); - return s->listen_port(); + qDebug() << Q_FUNC_INFO << s->listen_port(); + return s->listen_port(); } session_status QBtSession::getSessionStatus() const { - return s->status(); + return s->status(); } void QBtSession::applyEncryptionSettings(pe_settings se) { - qDebug("Applying encryption settings"); - s->set_pe_settings(se); + qDebug("Applying encryption settings"); + s->set_pe_settings(se); } // Set Proxy void QBtSession::setProxySettings(proxy_settings proxySettings) { - qDebug() << Q_FUNC_INFO; - - proxySettings.proxy_peer_connections = Preferences::instance()->proxyPeerConnections(); - s->set_proxy(proxySettings); - - // Define environment variable - QString proxy_str; - switch(proxySettings.type) { - case proxy_settings::http_pw: - proxy_str = "http://"+misc::toQString(proxySettings.username)+":"+misc::toQString(proxySettings.password)+"@"+misc::toQString(proxySettings.hostname)+":"+QString::number(proxySettings.port); - break; - case proxy_settings::http: - proxy_str = "http://"+misc::toQString(proxySettings.hostname)+":"+QString::number(proxySettings.port); - break; - case proxy_settings::socks5: - proxy_str = misc::toQString(proxySettings.hostname)+":"+QString::number(proxySettings.port); - break; - case proxy_settings::socks5_pw: - proxy_str = misc::toQString(proxySettings.username)+":"+misc::toQString(proxySettings.password)+"@"+misc::toQString(proxySettings.hostname)+":"+QString::number(proxySettings.port); - break; - default: - qDebug("Disabling HTTP communications proxy"); - qputenv("http_proxy", QByteArray()); - qputenv("sock_proxy", QByteArray()); - return; - } - // We need this for urllib in search engine plugins - qDebug("HTTP communications proxy string: %s", qPrintable(proxy_str)); - if (proxySettings.type == proxy_settings::socks5 || proxySettings.type == proxy_settings::socks5_pw) - qputenv("sock_proxy", proxy_str.toLocal8Bit()); - else - qputenv("http_proxy", proxy_str.toLocal8Bit()); + qDebug() << Q_FUNC_INFO; + + proxySettings.proxy_peer_connections = Preferences::instance()->proxyPeerConnections(); + s->set_proxy(proxySettings); + + // Define environment variable + QString proxy_str; + switch(proxySettings.type) { + case proxy_settings::http_pw: + proxy_str = "http://"+misc::toQString(proxySettings.username)+":"+misc::toQString(proxySettings.password)+"@"+misc::toQString(proxySettings.hostname)+":"+QString::number(proxySettings.port); + break; + case proxy_settings::http: + proxy_str = "http://"+misc::toQString(proxySettings.hostname)+":"+QString::number(proxySettings.port); + break; + case proxy_settings::socks5: + proxy_str = misc::toQString(proxySettings.hostname)+":"+QString::number(proxySettings.port); + break; + case proxy_settings::socks5_pw: + proxy_str = misc::toQString(proxySettings.username)+":"+misc::toQString(proxySettings.password)+"@"+misc::toQString(proxySettings.hostname)+":"+QString::number(proxySettings.port); + break; + default: + qDebug("Disabling HTTP communications proxy"); + qputenv("http_proxy", QByteArray()); + qputenv("sock_proxy", QByteArray()); + return; + } + // We need this for urllib in search engine plugins + qDebug("HTTP communications proxy string: %s", qPrintable(proxy_str)); + if (proxySettings.type == proxy_settings::socks5 || proxySettings.type == proxy_settings::socks5_pw) + qputenv("sock_proxy", proxy_str.toLocal8Bit()); + else + qputenv("http_proxy", proxy_str.toLocal8Bit()); } // Set BT session settings (user_agent) void QBtSession::setSessionSettings(const session_settings &sessionSettings) { - qDebug("Set session settings"); - s->set_settings(sessionSettings); + qDebug("Set session settings"); + s->set_settings(sessionSettings); } QString QBtSession::getSavePath(const QString &hash, bool fromScanDir, QString filePath, bool imported) { - QString savePath; - if (TorrentTempData::hasTempData(hash)) { - savePath = fsutils::fromNativePath(TorrentTempData::getSavePath(hash)); - if (savePath.isEmpty()) { - savePath = defaultSavePath; - } - if (!imported && appendLabelToSavePath) { - qDebug("appendLabelToSavePath is true"); - const QString label = TorrentTempData::getLabel(hash); - if (!label.isEmpty()) { - savePath = fsutils::updateLabelInSavePath(defaultSavePath, savePath, "", label); - } - } - qDebug("getSavePath, got save_path from temp data: %s", qPrintable(savePath)); - } else { - savePath = fsutils::fromNativePath(TorrentPersistentData::instance()->getSavePath(hash)); - qDebug("SavePath got from persistant data is %s", qPrintable(savePath)); - if (savePath.isEmpty()) { - if (fromScanDir && m_scanFolders->downloadInTorrentFolder(filePath)) { - savePath = QFileInfo(filePath).dir().path(); - } else { - savePath = defaultSavePath; - } - } - if (!fromScanDir && appendLabelToSavePath) { - const QString label = TorrentPersistentData::instance()->getLabel(hash); - if (!label.isEmpty()) { - qDebug("Torrent label is %s", qPrintable(label)); - savePath = fsutils::updateLabelInSavePath(defaultSavePath, savePath, "", label); - } + QString savePath; + if (TorrentTempData::hasTempData(hash)) { + savePath = fsutils::fromNativePath(TorrentTempData::getSavePath(hash)); + if (savePath.isEmpty()) { + savePath = defaultSavePath; + } + if (!imported && appendLabelToSavePath) { + qDebug("appendLabelToSavePath is true"); + const QString label = TorrentTempData::getLabel(hash); + if (!label.isEmpty()) { + savePath = fsutils::updateLabelInSavePath(defaultSavePath, savePath, "", label); + } + } + qDebug("getSavePath, got save_path from temp data: %s", qPrintable(savePath)); + } else { + savePath = fsutils::fromNativePath(TorrentPersistentData::instance()->getSavePath(hash)); + qDebug("SavePath got from persistant data is %s", qPrintable(savePath)); + if (savePath.isEmpty()) { + if (fromScanDir && m_scanFolders->downloadInTorrentFolder(filePath)) { + savePath = QFileInfo(filePath).dir().path(); + } else { + savePath = defaultSavePath; + } + } + if (!fromScanDir && appendLabelToSavePath) { + const QString label = TorrentPersistentData::instance()->getLabel(hash); + if (!label.isEmpty()) { + qDebug("Torrent label is %s", qPrintable(label)); + savePath = fsutils::updateLabelInSavePath(defaultSavePath, savePath, "", label); + } + } + qDebug("getSavePath, got save_path from persistent data: %s", qPrintable(savePath)); } - qDebug("getSavePath, got save_path from persistent data: %s", qPrintable(savePath)); - } - // Clean path - savePath = fsutils::expandPathAbs(savePath); - if (!savePath.endsWith("/")) - savePath += "/"; - return savePath; + // Clean path + savePath = fsutils::expandPathAbs(savePath); + if (!savePath.endsWith("/")) + savePath += "/"; + return savePath; } // Take an url string to a torrent file, @@ -2815,328 +2815,328 @@ QString QBtSession::getSavePath(const QString &hash, bool fromScanDir, QString f // add it to download list void QBtSession::downloadFromUrl(const QString &url, const QList& cookies) { - Logger::instance()->addMessage(tr("Downloading '%1', please wait...", "e.g: Downloading 'xxx.torrent', please wait...").arg(url)); - // Launch downloader thread - downloader->downloadTorrentUrl(url, cookies); + Logger::instance()->addMessage(tr("Downloading '%1', please wait...", "e.g: Downloading 'xxx.torrent', please wait...").arg(url)); + // Launch downloader thread + downloader->downloadTorrentUrl(url, cookies); } void QBtSession::downloadFromURLList(const QStringList& urls) { - foreach (const QString &url, urls) { - downloadFromUrl(url); - } + foreach (const QString &url, urls) { + downloadFromUrl(url); + } } void QBtSession::addMagnetInteractive(const QString& uri) { - emit newMagnetLink(uri); + emit newMagnetLink(uri); } #ifndef DISABLE_GUI - void QBtSession::addMagnetSkipAddDlg(const QString& uri, const QString& save_path, const QString& label, - const RssDownloadRule::AddPausedState &aps, const QString &uri_old) { +void QBtSession::addMagnetSkipAddDlg(const QString& uri, const QString& save_path, const QString& label, + const RssDownloadRule::AddPausedState &aps, const QString &uri_old) { #else - void QBtSession::addMagnetSkipAddDlg(const QString& uri, const QString& save_path, const QString& label, const QString &uri_old) { +void QBtSession::addMagnetSkipAddDlg(const QString& uri, const QString& save_path, const QString& label, const QString &uri_old) { #endif - if (!save_path.isEmpty() || !label.isEmpty()) - savepathLabel_fromurl[uri] = qMakePair(fsutils::fromNativePath(save_path), label); + if (!save_path.isEmpty() || !label.isEmpty()) + savepathLabel_fromurl[uri] = qMakePair(fsutils::fromNativePath(save_path), label); #ifndef DISABLE_GUI - QString hash = misc::magnetUriToHash(uri); - switch (aps) { - case RssDownloadRule::ALWAYS_PAUSED: - TorrentTempData::setAddPaused(hash, true); - break; - case RssDownloadRule::NEVER_PAUSED: - TorrentTempData::setAddPaused(hash, false); - break; - case RssDownloadRule::USE_GLOBAL: - default:; - // Use global preferences - } + QString hash = misc::magnetUriToHash(uri); + switch (aps) { + case RssDownloadRule::ALWAYS_PAUSED: + TorrentTempData::setAddPaused(hash, true); + break; + case RssDownloadRule::NEVER_PAUSED: + TorrentTempData::setAddPaused(hash, false); + break; + case RssDownloadRule::USE_GLOBAL: + default:; + // Use global preferences + } #endif - addMagnetUri(uri, false); - emit newDownloadedTorrentFromRss(uri_old.isEmpty() ? uri : uri_old); + addMagnetUri(uri, false); + emit newDownloadedTorrentFromRss(uri_old.isEmpty() ? uri : uri_old); } #ifndef DISABLE_GUI - void QBtSession::downloadUrlAndSkipDialog(QString url, QString save_path, QString label, - const QList& cookies, const RssDownloadRule::AddPausedState &aps) { +void QBtSession::downloadUrlAndSkipDialog(QString url, QString save_path, QString label, + const QList& cookies, const RssDownloadRule::AddPausedState &aps) { #else - void QBtSession::downloadUrlAndSkipDialog(QString url, QString save_path, QString label, const QList& cookies) { +void QBtSession::downloadUrlAndSkipDialog(QString url, QString save_path, QString label, const QList& cookies) { #endif - //emit aboutToDownloadFromUrl(url); - const QUrl qurl = QUrl::fromEncoded(url.toUtf8()); - if (!save_path.isEmpty() || !label.isEmpty()) - savepathLabel_fromurl[qurl] = qMakePair(fsutils::fromNativePath(save_path), label); + //emit aboutToDownloadFromUrl(url); + const QUrl qurl = QUrl::fromEncoded(url.toUtf8()); + if (!save_path.isEmpty() || !label.isEmpty()) + savepathLabel_fromurl[qurl] = qMakePair(fsutils::fromNativePath(save_path), label); #ifndef DISABLE_GUI - if (aps != RssDownloadRule::USE_GLOBAL) - addpaused_fromurl[qurl] = aps; + if (aps != RssDownloadRule::USE_GLOBAL) + addpaused_fromurl[qurl] = aps; #endif - url_skippingDlg << qurl; - // Launch downloader thread - downloader->downloadTorrentUrl(url, cookies); + url_skippingDlg << qurl; + // Launch downloader thread + downloader->downloadTorrentUrl(url, cookies); } // Add to Bittorrent session the downloaded torrent file void QBtSession::processDownloadedFile(QString url, QString file_path) { - const int index = url_skippingDlg.indexOf(QUrl::fromEncoded(url.toUtf8())); - if (index < 0) { - // Add file to torrent download list - file_path = fsutils::fromNativePath(file_path); + const int index = url_skippingDlg.indexOf(QUrl::fromEncoded(url.toUtf8())); + if (index < 0) { + // Add file to torrent download list + file_path = fsutils::fromNativePath(file_path); #ifdef Q_OS_WIN - // Windows hack - if (!file_path.endsWith(".torrent", Qt::CaseInsensitive)) { - Q_ASSERT(QFile::exists(file_path)); - qDebug("Torrent name does not end with .torrent, from %s", qPrintable(file_path)); - if (QFile::rename(file_path, file_path+".torrent")) { - file_path += ".torrent"; - } else { - qDebug("Failed to rename torrent file!"); - } - } - qDebug("Downloading torrent at path: %s", qPrintable(file_path)); + // Windows hack + if (!file_path.endsWith(".torrent", Qt::CaseInsensitive)) { + Q_ASSERT(QFile::exists(file_path)); + qDebug("Torrent name does not end with .torrent, from %s", qPrintable(file_path)); + if (QFile::rename(file_path, file_path+".torrent")) { + file_path += ".torrent"; + } else { + qDebug("Failed to rename torrent file!"); + } + } + qDebug("Downloading torrent at path: %s", qPrintable(file_path)); #endif - emit newDownloadedTorrent(file_path, url); - } else { - url_skippingDlg.removeAt(index); + emit newDownloadedTorrent(file_path, url); + } else { + url_skippingDlg.removeAt(index); #ifndef DISABLE_GUI - libtorrent::error_code ec; - // Get hash - libtorrent::torrent_info ti(file_path.toStdString(), ec); - QString hash; - - if (!ec) { - hash = misc::toQString(ti.info_hash()); - RssDownloadRule::AddPausedState aps = addpaused_fromurl[url]; - addpaused_fromurl.remove(url); - switch (aps) { - case RssDownloadRule::ALWAYS_PAUSED: - TorrentTempData::setAddPaused(hash, true); - break; - case RssDownloadRule::NEVER_PAUSED: - TorrentTempData::setAddPaused(hash, false); - break; - case RssDownloadRule::USE_GLOBAL: - default:; - // Use global preferences - } - } + libtorrent::error_code ec; + // Get hash + libtorrent::torrent_info ti(file_path.toStdString(), ec); + QString hash; + + if (!ec) { + hash = misc::toQString(ti.info_hash()); + RssDownloadRule::AddPausedState aps = addpaused_fromurl[url]; + addpaused_fromurl.remove(url); + switch (aps) { + case RssDownloadRule::ALWAYS_PAUSED: + TorrentTempData::setAddPaused(hash, true); + break; + case RssDownloadRule::NEVER_PAUSED: + TorrentTempData::setAddPaused(hash, false); + break; + case RssDownloadRule::USE_GLOBAL: + default:; + // Use global preferences + } + } #endif - addTorrent(file_path, false, url, false); - emit newDownloadedTorrentFromRss(url); - } + addTorrent(file_path, false, url, false); + emit newDownloadedTorrentFromRss(url); + } } // Return current download rate for the BT // session. Payload means that it only take into // account "useful" part of the rate qreal QBtSession::getPayloadDownloadRate() const { - return s->status().payload_download_rate; + return s->status().payload_download_rate; } // Return current upload rate for the BT // session. Payload means that it only take into // account "useful" part of the rate qreal QBtSession::getPayloadUploadRate() const { - return s->status().payload_upload_rate; + return s->status().payload_upload_rate; } // Will fast resume torrents in // backup directory void QBtSession::startUpTorrents() { - qDebug("Resuming unfinished torrents"); - const QDir torrentBackup(fsutils::BTBackupLocation()); - const TorrentPersistentData* const TorPersistent = TorrentPersistentData::instance(); - const QStringList known_torrents = TorPersistent->knownTorrents(); - - // Safety measure because some people reported torrent loss since - // we switch the v1.5 way of resuming torrents on startup - QStringList filters; - filters << "*.torrent"; - const QStringList torrents_on_hd = torrentBackup.entryList(filters, QDir::Files, QDir::Unsorted); - foreach (QString hash, torrents_on_hd) { - hash.chop(8); // remove trailing .torrent - if (!known_torrents.contains(hash)) { - qDebug("found torrent with hash: %s on hard disk", qPrintable(hash)); - std::cerr << "ERROR Detected!!! Adding back torrent " << qPrintable(hash) << " which got lost for some reason." << std::endl; - addTorrent(torrentBackup.path()+"/"+hash+".torrent", false, QString(), true); - } - } - // End of safety measure - - qDebug("Starting up torrents"); - if (isQueueingEnabled()) { - priority_queue, vector >, std::greater > > torrent_queue; - foreach (const QString &hash, known_torrents) { - const int prio = TorPersistent->getPriority(hash); - torrent_queue.push(qMakePair(prio, hash)); - } - qDebug("Priority_queue size: %ld", (long)torrent_queue.size()); - // Resume downloads - while(!torrent_queue.empty()) { - const QString hash = torrent_queue.top().second; - torrent_queue.pop(); - qDebug("Starting up torrent %s", qPrintable(hash)); - if (TorPersistent->isMagnet(hash)) { - addMagnetUri(TorPersistent->getMagnetUri(hash), true); - } else { - addTorrent(torrentBackup.path()+"/"+hash+".torrent", false, QString(), true); - } + qDebug("Resuming unfinished torrents"); + const QDir torrentBackup(fsutils::BTBackupLocation()); + const TorrentPersistentData* const TorPersistent = TorrentPersistentData::instance(); + const QStringList known_torrents = TorPersistent->knownTorrents(); + + // Safety measure because some people reported torrent loss since + // we switch the v1.5 way of resuming torrents on startup + QStringList filters; + filters << "*.torrent"; + const QStringList torrents_on_hd = torrentBackup.entryList(filters, QDir::Files, QDir::Unsorted); + foreach (QString hash, torrents_on_hd) { + hash.chop(8); // remove trailing .torrent + if (!known_torrents.contains(hash)) { + qDebug("found torrent with hash: %s on hard disk", qPrintable(hash)); + std::cerr << "ERROR Detected!!! Adding back torrent " << qPrintable(hash) << " which got lost for some reason." << std::endl; + addTorrent(torrentBackup.path()+"/"+hash+".torrent", false, QString(), true); + } } - } else { - // Resume downloads - foreach (const QString &hash, known_torrents) { - qDebug("Starting up torrent %s", qPrintable(hash)); - if (TorPersistent->isMagnet(hash)) - addMagnetUri(TorPersistent->getMagnetUri(hash), true); - else - addTorrent(torrentBackup.path()+"/"+hash+".torrent", false, QString(), true); + // End of safety measure + + qDebug("Starting up torrents"); + if (isQueueingEnabled()) { + priority_queue, vector >, std::greater > > torrent_queue; + foreach (const QString &hash, known_torrents) { + const int prio = TorPersistent->getPriority(hash); + torrent_queue.push(qMakePair(prio, hash)); + } + qDebug("Priority_queue size: %ld", (long)torrent_queue.size()); + // Resume downloads + while(!torrent_queue.empty()) { + const QString hash = torrent_queue.top().second; + torrent_queue.pop(); + qDebug("Starting up torrent %s", qPrintable(hash)); + if (TorPersistent->isMagnet(hash)) { + addMagnetUri(TorPersistent->getMagnetUri(hash), true); + } else { + addTorrent(torrentBackup.path()+"/"+hash+".torrent", false, QString(), true); + } + } + } else { + // Resume downloads + foreach (const QString &hash, known_torrents) { + qDebug("Starting up torrent %s", qPrintable(hash)); + if (TorPersistent->isMagnet(hash)) + addMagnetUri(TorPersistent->getMagnetUri(hash), true); + else + addTorrent(torrentBackup.path()+"/"+hash+".torrent", false, QString(), true); + } } - } - qDebug("Unfinished torrents resumed"); + qDebug("Unfinished torrents resumed"); } QBtSession * QBtSession::instance() { - if (!m_instance) { - m_instance = new QBtSession; - } - return m_instance; + if (!m_instance) { + m_instance = new QBtSession; + } + return m_instance; } void QBtSession::drop() { - if (m_instance) { - delete m_instance; - m_instance = 0; - } + if (m_instance) { + delete m_instance; + m_instance = 0; + } } qlonglong QBtSession::getETA(const QString &hash, const libtorrent::torrent_status &status) const { - return m_speedMonitor->getETA(hash, status); + return m_speedMonitor->getETA(hash, status); } quint64 QBtSession::getAlltimeDL() const { - return m_torrentStatistics->getAlltimeDL(); + return m_torrentStatistics->getAlltimeDL(); } quint64 QBtSession::getAlltimeUL() const { - return m_torrentStatistics->getAlltimeUL(); + return m_torrentStatistics->getAlltimeUL(); } void QBtSession::postTorrentUpdate() { - s->post_torrent_updates(); + s->post_torrent_updates(); } void QBtSession::handleIPFilterParsed(int ruleCount) { - Logger::instance()->addMessage(tr("Successfully parsed the provided IP filter: %1 rules were applied.", "%1 is a number").arg(ruleCount)); - emit ipFilterParsed(false, ruleCount); + Logger::instance()->addMessage(tr("Successfully parsed the provided IP filter: %1 rules were applied.", "%1 is a number").arg(ruleCount)); + emit ipFilterParsed(false, ruleCount); } void QBtSession::handleIPFilterError() { - Logger::instance()->addMessage(tr("Error: Failed to parse the provided IP filter."), Log::CRITICAL); - emit ipFilterParsed(true, 0); + Logger::instance()->addMessage(tr("Error: Failed to parse the provided IP filter."), Log::CRITICAL); + emit ipFilterParsed(true, 0); } void QBtSession::recoverPersistentData(const QString &hash, const std::vector &buf) { - TorrentPersistentData* const TorPersistent = TorrentPersistentData::instance(); - if (TorPersistent->isKnownTorrent(hash) || TorrentTempData::hasTempData(hash) || buf.empty()) - return; + TorrentPersistentData* const TorPersistent = TorrentPersistentData::instance(); + if (TorPersistent->isKnownTorrent(hash) || TorrentTempData::hasTempData(hash) || buf.empty()) + return; - libtorrent::lazy_entry fast; - libtorrent::error_code ec; + libtorrent::lazy_entry fast; + libtorrent::error_code ec; - libtorrent::lazy_bdecode(&(buf.front()), &(buf.back()), fast, ec); - if (fast.type() != libtorrent::lazy_entry::dict_t && !ec) - return; + libtorrent::lazy_bdecode(&(buf.front()), &(buf.back()), fast, ec); + if (fast.type() != libtorrent::lazy_entry::dict_t && !ec) + return; - QString savePath = fsutils::fromNativePath(QString::fromUtf8(fast.dict_find_string_value("qBt-savePath").c_str())); - qreal ratioLimit = QString::fromUtf8(fast.dict_find_string_value("qBt-ratioLimit").c_str()).toDouble(); - QDateTime addedDate = QDateTime::fromTime_t(fast.dict_find_int_value("added_time")); - QString label = QString::fromUtf8(fast.dict_find_string_value("qBt-label").c_str()); - int priority = fast.dict_find_int_value("qBt-queuePosition"); - bool seedStatus = fast.dict_find_int_value("qBt-seedStatus"); + QString savePath = fsutils::fromNativePath(QString::fromUtf8(fast.dict_find_string_value("qBt-savePath").c_str())); + qreal ratioLimit = QString::fromUtf8(fast.dict_find_string_value("qBt-ratioLimit").c_str()).toDouble(); + QDateTime addedDate = QDateTime::fromTime_t(fast.dict_find_int_value("added_time")); + QString label = QString::fromUtf8(fast.dict_find_string_value("qBt-label").c_str()); + int priority = fast.dict_find_int_value("qBt-queuePosition"); + bool seedStatus = fast.dict_find_int_value("qBt-seedStatus"); - TorPersistent->saveSavePath(hash, savePath); - TorPersistent->setRatioLimit(hash, ratioLimit); - TorPersistent->setAddedDate(hash, addedDate); - TorPersistent->saveLabel(hash, label); - TorPersistent->savePriority(hash, priority); - TorPersistent->saveSeedStatus(hash, seedStatus); + TorPersistent->saveSavePath(hash, savePath); + TorPersistent->setRatioLimit(hash, ratioLimit); + TorPersistent->setAddedDate(hash, addedDate); + TorPersistent->saveLabel(hash, label); + TorPersistent->savePriority(hash, priority); + TorPersistent->saveSeedStatus(hash, seedStatus); } void QBtSession::backupPersistentData(const QString &hash, boost::shared_ptr data) { - const TorrentPersistentData* const TorPersistent = TorrentPersistentData::instance(); - (*data)["qBt-savePath"] = fsutils::fromNativePath(TorPersistent->getSavePath(hash)).toUtf8().constData(); - (*data)["qBt-ratioLimit"] = QString::number(TorPersistent->getRatioLimit(hash)).toUtf8().constData(); - (*data)["qBt-label"] = TorPersistent->getLabel(hash).toUtf8().constData(); - (*data)["qBt-queuePosition"] = TorPersistent->getPriority(hash); - (*data)["qBt-seedStatus"] = (int)TorPersistent->isSeed(hash); + const TorrentPersistentData* const TorPersistent = TorrentPersistentData::instance(); + (*data)["qBt-savePath"] = fsutils::fromNativePath(TorPersistent->getSavePath(hash)).toUtf8().constData(); + (*data)["qBt-ratioLimit"] = QString::number(TorPersistent->getRatioLimit(hash)).toUtf8().constData(); + (*data)["qBt-label"] = TorPersistent->getLabel(hash).toUtf8().constData(); + (*data)["qBt-queuePosition"] = TorPersistent->getPriority(hash); + (*data)["qBt-seedStatus"] = (int)TorPersistent->isSeed(hash); } void QBtSession::unhideMagnet(const QString &hash) { - Preferences* const pref = Preferences::instance(); - HiddenData::deleteData(hash); - QString save_path = getSavePath(hash, false); //appends label if necessary - QTorrentHandle h(getTorrentHandle(hash)); + Preferences* const pref = Preferences::instance(); + HiddenData::deleteData(hash); + QString save_path = getSavePath(hash, false); //appends label if necessary + QTorrentHandle h(getTorrentHandle(hash)); - if (!h.is_valid()) { - if (pref->isQueueingSystemEnabled()) { - //Internally decrease the queue limits to ensure that other queued items aren't started - libtorrent::session_settings sessionSettings(s->settings()); - int max_downloading = pref->getMaxActiveDownloads(); - int max_active = pref->getMaxActiveTorrents(); - if (max_downloading > -1) - sessionSettings.active_downloads = max_downloading + HiddenData::getDownloadingSize(); - else - sessionSettings.active_downloads = max_downloading; - if (max_active > -1) - sessionSettings.active_limit = max_active + HiddenData::getDownloadingSize(); - else - sessionSettings.active_limit = max_active; - s->set_settings(sessionSettings); - } - TorrentTempData::deleteTempData(hash); - return; - } + if (!h.is_valid()) { + if (pref->isQueueingSystemEnabled()) { + //Internally decrease the queue limits to ensure that other queued items aren't started + libtorrent::session_settings sessionSettings(s->settings()); + int max_downloading = pref->getMaxActiveDownloads(); + int max_active = pref->getMaxActiveTorrents(); + if (max_downloading > -1) + sessionSettings.active_downloads = max_downloading + HiddenData::getDownloadingSize(); + else + sessionSettings.active_downloads = max_downloading; + if (max_active > -1) + sessionSettings.active_limit = max_active + HiddenData::getDownloadingSize(); + else + sessionSettings.active_limit = max_active; + s->set_settings(sessionSettings); + } + TorrentTempData::deleteTempData(hash); + return; + } + + bool add_paused = pref->addTorrentsInPause(); + if (TorrentTempData::hasTempData(hash)) { + add_paused = TorrentTempData::isAddPaused(hash); + } + + if (!h.has_metadata()) { + if (pref->isQueueingSystemEnabled()) { + //Internally decrease the queue limits to ensure that other queued items aren't started + libtorrent::session_settings sessionSettings(s->settings()); + int max_downloading = pref->getMaxActiveDownloads(); + int max_active = pref->getMaxActiveTorrents(); + if (max_downloading > -1) + sessionSettings.active_downloads = max_downloading + HiddenData::getDownloadingSize(); + else + sessionSettings.active_downloads = max_downloading; + if (max_active > -1) + sessionSettings.active_limit = max_active + HiddenData::getDownloadingSize(); + else + sessionSettings.active_limit = max_active; + s->set_settings(sessionSettings); + } + if (add_paused) + h.pause(); + } - bool add_paused = pref->addTorrentsInPause(); - if (TorrentTempData::hasTempData(hash)) { - add_paused = TorrentTempData::isAddPaused(hash); - } + h.queue_position_bottom(); + loadTorrentTempData(h, h.save_path(), !h.has_metadata()); //TempData are deleted by a call to TorrentPersistentData::instance()->saveTorrentPersistentData() + if (!add_paused) + h.resume(); + h.move_storage(save_path); - if (!h.has_metadata()) { - if (pref->isQueueingSystemEnabled()) { - //Internally decrease the queue limits to ensure that other queued items aren't started - libtorrent::session_settings sessionSettings(s->settings()); - int max_downloading = pref->getMaxActiveDownloads(); - int max_active = pref->getMaxActiveTorrents(); - if (max_downloading > -1) - sessionSettings.active_downloads = max_downloading + HiddenData::getDownloadingSize(); - else - sessionSettings.active_downloads = max_downloading; - if (max_active > -1) - sessionSettings.active_limit = max_active + HiddenData::getDownloadingSize(); - else - sessionSettings.active_limit = max_active; - s->set_settings(sessionSettings); - } - if (add_paused) - h.pause(); - } - - h.queue_position_bottom(); - loadTorrentTempData(h, h.save_path(), !h.has_metadata()); //TempData are deleted by a call to TorrentPersistentData::instance()->saveTorrentPersistentData() - if (!add_paused) - h.resume(); - h.move_storage(save_path); - - emit addedTorrent(h); + emit addedTorrent(h); } diff --git a/src/core/qtlibtorrent/qbtsession.h b/src/core/qtlibtorrent/qbtsession.h index 3edbe6a38..63a1ec4ea 100644 --- a/src/core/qtlibtorrent/qbtsession.h +++ b/src/core/qtlibtorrent/qbtsession.h @@ -49,42 +49,42 @@ #endif namespace libtorrent { - struct add_torrent_params; - struct pe_settings; - struct proxy_settings; - class session; - struct session_status; +struct add_torrent_params; +struct pe_settings; +struct proxy_settings; +class session; +struct session_status; - class alert; - struct torrent_finished_alert; - struct save_resume_data_alert; - struct file_renamed_alert; - struct torrent_deleted_alert; - struct storage_moved_alert; - struct storage_moved_failed_alert; - struct metadata_received_alert; - struct file_error_alert; - struct file_completed_alert; - struct torrent_paused_alert; - struct tracker_error_alert; - struct tracker_reply_alert; - struct tracker_warning_alert; - struct portmap_error_alert; - struct portmap_alert; - struct peer_blocked_alert; - struct peer_ban_alert; - struct fastresume_rejected_alert; - struct url_seed_alert; - struct listen_succeeded_alert; - struct listen_failed_alert; - struct torrent_checked_alert; - struct external_ip_alert; - struct state_update_alert; - struct stats_alert; +class alert; +struct torrent_finished_alert; +struct save_resume_data_alert; +struct file_renamed_alert; +struct torrent_deleted_alert; +struct storage_moved_alert; +struct storage_moved_failed_alert; +struct metadata_received_alert; +struct file_error_alert; +struct file_completed_alert; +struct torrent_paused_alert; +struct tracker_error_alert; +struct tracker_reply_alert; +struct tracker_warning_alert; +struct portmap_error_alert; +struct portmap_alert; +struct peer_blocked_alert; +struct peer_ban_alert; +struct fastresume_rejected_alert; +struct url_seed_alert; +struct listen_succeeded_alert; +struct listen_failed_alert; +struct torrent_checked_alert; +struct external_ip_alert; +struct state_update_alert; +struct stats_alert; #if LIBTORRENT_VERSION_NUM < 10000 - class upnp; - class natpmp; +class upnp; +class natpmp; #endif } @@ -97,250 +97,250 @@ class TorrentStatistics; class QAlertDispatcher; enum TorrentExportFolder { - RegularTorrentExportFolder, - FinishedTorrentExportFolder + RegularTorrentExportFolder, + FinishedTorrentExportFolder }; class QTracker; class QBtSession : public QObject { - Q_OBJECT - Q_DISABLE_COPY(QBtSession) + Q_OBJECT + Q_DISABLE_COPY(QBtSession) public: - static const qreal MAX_RATIO; + static const qreal MAX_RATIO; private: - explicit QBtSession(); - static QBtSession* m_instance; + explicit QBtSession(); + static QBtSession* m_instance; public: - static QBtSession* instance(); - static void drop(); - ~QBtSession(); - QTorrentHandle getTorrentHandle(const QString &hash) const; - std::vector getTorrents() const; - bool isFilePreviewPossible(const QString& hash) const; - qreal getPayloadDownloadRate() const; - qreal getPayloadUploadRate() const; - libtorrent::session_status getSessionStatus() const; - int getListenPort() const; - qreal getRealRatio(const libtorrent::torrent_status &status) const; - QHash getTrackersInfo(const QString &hash) const; - bool hasActiveTorrents() const; - bool hasDownloadingTorrents() const; - //int getMaximumActiveDownloads() const; - //int getMaximumActiveTorrents() const; - inline libtorrent::session* getSession() const { return s; } - inline bool useTemporaryFolder() const { return !defaultTempPath.isEmpty(); } - inline QString getDefaultSavePath() const { return defaultSavePath; } - inline ScanFoldersModel* getScanFoldersModel() const { return m_scanFolders; } - inline bool isDHTEnabled() const { return DHTEnabled; } - inline bool isLSDEnabled() const { return LSDEnabled; } - inline bool isPexEnabled() const { return PeXEnabled; } - inline bool isQueueingEnabled() const { return queueingEnabled; } - quint64 getAlltimeDL() const; - quint64 getAlltimeUL() const; - void postTorrentUpdate(); + static QBtSession* instance(); + static void drop(); + ~QBtSession(); + QTorrentHandle getTorrentHandle(const QString &hash) const; + std::vector getTorrents() const; + bool isFilePreviewPossible(const QString& hash) const; + qreal getPayloadDownloadRate() const; + qreal getPayloadUploadRate() const; + libtorrent::session_status getSessionStatus() const; + int getListenPort() const; + qreal getRealRatio(const libtorrent::torrent_status &status) const; + QHash getTrackersInfo(const QString &hash) const; + bool hasActiveTorrents() const; + bool hasDownloadingTorrents() const; + //int getMaximumActiveDownloads() const; + //int getMaximumActiveTorrents() const; + inline libtorrent::session* getSession() const { return s; } + inline bool useTemporaryFolder() const { return !defaultTempPath.isEmpty(); } + inline QString getDefaultSavePath() const { return defaultSavePath; } + inline ScanFoldersModel* getScanFoldersModel() const { return m_scanFolders; } + inline bool isDHTEnabled() const { return DHTEnabled; } + inline bool isLSDEnabled() const { return LSDEnabled; } + inline bool isPexEnabled() const { return PeXEnabled; } + inline bool isQueueingEnabled() const { return queueingEnabled; } + quint64 getAlltimeDL() const; + quint64 getAlltimeUL() const; + void postTorrentUpdate(); public slots: - QTorrentHandle addTorrent(QString path, bool fromScanDir = false, QString from_url = QString(), bool resumed = false, bool imported = false); - QTorrentHandle addMagnetUri(QString magnet_uri, bool resumed=false, bool fromScanDir=false, const QString &filePath=QString()); - void loadSessionState(); - void saveSessionState(); - void downloadFromUrl(const QString &url, const QList& cookies = QList()); - void deleteTorrent(const QString &hash, bool delete_local_files = false); - void startUpTorrents(); - void recheckTorrent(const QString &hash); - void useAlternativeSpeedsLimit(bool alternative); - qlonglong getETA(const QString& hash, const libtorrent::torrent_status &status) const; - /* Needed by Web UI */ - void pauseAllTorrents(); - void pauseTorrent(const QString &hash); - void resumeTorrent(const QString &hash); - void resumeAllTorrents(); - /* End Web UI */ - void preAllocateAllFiles(bool b); - void saveFastResumeData(); - void enableIPFilter(const QString &filter_path, bool force=false); - void disableIPFilter(); - void setQueueingEnabled(bool enable); - void handleDownloadFailure(QString url, QString reason); - void handleMagnetRedirect(const QString &url_new, const QString &url_old); + QTorrentHandle addTorrent(QString path, bool fromScanDir = false, QString from_url = QString(), bool resumed = false, bool imported = false); + QTorrentHandle addMagnetUri(QString magnet_uri, bool resumed=false, bool fromScanDir=false, const QString &filePath=QString()); + void loadSessionState(); + void saveSessionState(); + void downloadFromUrl(const QString &url, const QList& cookies = QList()); + void deleteTorrent(const QString &hash, bool delete_local_files = false); + void startUpTorrents(); + void recheckTorrent(const QString &hash); + void useAlternativeSpeedsLimit(bool alternative); + qlonglong getETA(const QString& hash, const libtorrent::torrent_status &status) const; + /* Needed by Web UI */ + void pauseAllTorrents(); + void pauseTorrent(const QString &hash); + void resumeTorrent(const QString &hash); + void resumeAllTorrents(); + /* End Web UI */ + void preAllocateAllFiles(bool b); + void saveFastResumeData(); + void enableIPFilter(const QString &filter_path, bool force=false); + void disableIPFilter(); + void setQueueingEnabled(bool enable); + void handleDownloadFailure(QString url, QString reason); + void handleMagnetRedirect(const QString &url_new, const QString &url_old); #ifndef DISABLE_GUI - void downloadUrlAndSkipDialog(QString url, QString save_path=QString(), QString label=QString(), - const QList& cookies = QList(), - const RssDownloadRule::AddPausedState &aps = RssDownloadRule::USE_GLOBAL); + void downloadUrlAndSkipDialog(QString url, QString save_path=QString(), QString label=QString(), + const QList& cookies = QList(), + const RssDownloadRule::AddPausedState &aps = RssDownloadRule::USE_GLOBAL); #else - void downloadUrlAndSkipDialog(QString url, QString save_path=QString(), QString label=QString(), - const QList& cookies = QList()); + void downloadUrlAndSkipDialog(QString url, QString save_path=QString(), QString label=QString(), + const QList& cookies = QList()); #endif - // Session configuration - Setters - void setListeningPort(int port); - void setMaxConnectionsPerTorrent(int max); - void setMaxUploadsPerTorrent(int max); - void setDownloadRateLimit(long rate); - void setUploadRateLimit(long rate); - void setGlobalMaxRatio(qreal ratio); - qreal getGlobalMaxRatio() const { return global_ratio_limit; } - void setMaxRatioPerTorrent(const QString &hash, qreal ratio); - qreal getMaxRatioPerTorrent(const QString &hash, bool *usesGlobalRatio) const; - void removeRatioPerTorrent(const QString &hash); - void setDefaultSavePath(const QString &savepath); - void setDefaultTempPath(const QString &temppath); - void setAppendLabelToSavePath(bool append); - void appendLabelToTorrentSavePath(const QTorrentHandle &h); - void changeLabelInTorrentSavePath(const QTorrentHandle &h, QString old_label, QString new_label); - void appendqBextensionToTorrent(const QTorrentHandle &h, bool append); - void setAppendqBExtension(bool append); - void setDownloadLimit(QString hash, long val); - void setUploadLimit(QString hash, long val); - void enableUPnP(bool b); - void enableLSD(bool b); - void enableDHT(bool b); - void processDownloadedFile(QString, QString); + // Session configuration - Setters + void setListeningPort(int port); + void setMaxConnectionsPerTorrent(int max); + void setMaxUploadsPerTorrent(int max); + void setDownloadRateLimit(long rate); + void setUploadRateLimit(long rate); + void setGlobalMaxRatio(qreal ratio); + qreal getGlobalMaxRatio() const { return global_ratio_limit; } + void setMaxRatioPerTorrent(const QString &hash, qreal ratio); + qreal getMaxRatioPerTorrent(const QString &hash, bool *usesGlobalRatio) const; + void removeRatioPerTorrent(const QString &hash); + void setDefaultSavePath(const QString &savepath); + void setDefaultTempPath(const QString &temppath); + void setAppendLabelToSavePath(bool append); + void appendLabelToTorrentSavePath(const QTorrentHandle &h); + void changeLabelInTorrentSavePath(const QTorrentHandle &h, QString old_label, QString new_label); + void appendqBextensionToTorrent(const QTorrentHandle &h, bool append); + void setAppendqBExtension(bool append); + void setDownloadLimit(QString hash, long val); + void setUploadLimit(QString hash, long val); + void enableUPnP(bool b); + void enableLSD(bool b); + void enableDHT(bool b); + void processDownloadedFile(QString, QString); #ifndef DISABLE_GUI - void addMagnetSkipAddDlg(const QString& uri, const QString& save_path = QString(), const QString& label = QString(), - const RssDownloadRule::AddPausedState &aps = RssDownloadRule::USE_GLOBAL, const QString &uri_old = QString()); + void addMagnetSkipAddDlg(const QString& uri, const QString& save_path = QString(), const QString& label = QString(), + const RssDownloadRule::AddPausedState &aps = RssDownloadRule::USE_GLOBAL, const QString &uri_old = QString()); #else - void addMagnetSkipAddDlg(const QString& uri, const QString& save_path = QString(), const QString& label = QString(), const QString &uri_old = QString()); + void addMagnetSkipAddDlg(const QString& uri, const QString& save_path = QString(), const QString& label = QString(), const QString &uri_old = QString()); #endif - void addMagnetInteractive(const QString& uri); - void downloadFromURLList(const QStringList& urls); - void banIP(QString ip); - void recursiveTorrentDownload(const QTorrentHandle &h); - void unhideMagnet(const QString &hash); + void addMagnetInteractive(const QString& uri); + void downloadFromURLList(const QStringList& urls); + void banIP(QString ip); + void recursiveTorrentDownload(const QTorrentHandle &h); + void unhideMagnet(const QString &hash); private: - void applyEncryptionSettings(libtorrent::pe_settings se); - void setProxySettings(libtorrent::proxy_settings proxySettings); - void setSessionSettings(const libtorrent::session_settings &sessionSettings); - QString getSavePath(const QString &hash, bool fromScanDir = false, QString filePath = QString::null, bool imported = false); - bool loadFastResumeData(const QString &hash, std::vector &buf); - void loadTorrentSettings(QTorrentHandle &h); - void loadTorrentTempData(QTorrentHandle &h, QString savePath, bool magnet); - void initializeAddTorrentParams(const QString &hash, libtorrent::add_torrent_params &p); - void updateRatioTimer(); - void recoverPersistentData(const QString &hash, const std::vector &buf); - void backupPersistentData(const QString &hash, boost::shared_ptr data); - void handleAlert(libtorrent::alert* a); - void handleTorrentFinishedAlert(libtorrent::torrent_finished_alert* p); - void handleSaveResumeDataAlert(libtorrent::save_resume_data_alert* p); - void handleFileRenamedAlert(libtorrent::file_renamed_alert* p); - void handleTorrentDeletedAlert(libtorrent::torrent_deleted_alert* p); - void handleStorageMovedAlert(libtorrent::storage_moved_alert* p); - void handleStorageMovedFailedAlert(libtorrent::storage_moved_failed_alert* p); - void handleMetadataReceivedAlert(libtorrent::metadata_received_alert* p); - void handleFileErrorAlert(libtorrent::file_error_alert* p); - void handleFileCompletedAlert(libtorrent::file_completed_alert* p); - void handleTorrentPausedAlert(libtorrent::torrent_paused_alert* p); - void handleTrackerErrorAlert(libtorrent::tracker_error_alert* p); - void handleTrackerReplyAlert(libtorrent::tracker_reply_alert* p); - void handleTrackerWarningAlert(libtorrent::tracker_warning_alert* p); - void handlePortmapWarningAlert(libtorrent::portmap_error_alert* p); - void handlePortmapAlert(libtorrent::portmap_alert* p); - void handlePeerBlockedAlert(libtorrent::peer_blocked_alert* p); - void handlePeerBanAlert(libtorrent::peer_ban_alert* p); - void handleFastResumeRejectedAlert(libtorrent::fastresume_rejected_alert* p); - void handleUrlSeedAlert(libtorrent::url_seed_alert* p); - void handleListenSucceededAlert(libtorrent::listen_succeeded_alert *p); - void handleListenFailedAlert(libtorrent::listen_failed_alert *p); - void handleTorrentCheckedAlert(libtorrent::torrent_checked_alert* p); - void handleExternalIPAlert(libtorrent::external_ip_alert *p); - void handleStateUpdateAlert(libtorrent::state_update_alert *p); - void handleStatsAlert(libtorrent::stats_alert *p); + void applyEncryptionSettings(libtorrent::pe_settings se); + void setProxySettings(libtorrent::proxy_settings proxySettings); + void setSessionSettings(const libtorrent::session_settings &sessionSettings); + QString getSavePath(const QString &hash, bool fromScanDir = false, QString filePath = QString::null, bool imported = false); + bool loadFastResumeData(const QString &hash, std::vector &buf); + void loadTorrentSettings(QTorrentHandle &h); + void loadTorrentTempData(QTorrentHandle &h, QString savePath, bool magnet); + void initializeAddTorrentParams(const QString &hash, libtorrent::add_torrent_params &p); + void updateRatioTimer(); + void recoverPersistentData(const QString &hash, const std::vector &buf); + void backupPersistentData(const QString &hash, boost::shared_ptr data); + void handleAlert(libtorrent::alert* a); + void handleTorrentFinishedAlert(libtorrent::torrent_finished_alert* p); + void handleSaveResumeDataAlert(libtorrent::save_resume_data_alert* p); + void handleFileRenamedAlert(libtorrent::file_renamed_alert* p); + void handleTorrentDeletedAlert(libtorrent::torrent_deleted_alert* p); + void handleStorageMovedAlert(libtorrent::storage_moved_alert* p); + void handleStorageMovedFailedAlert(libtorrent::storage_moved_failed_alert* p); + void handleMetadataReceivedAlert(libtorrent::metadata_received_alert* p); + void handleFileErrorAlert(libtorrent::file_error_alert* p); + void handleFileCompletedAlert(libtorrent::file_completed_alert* p); + void handleTorrentPausedAlert(libtorrent::torrent_paused_alert* p); + void handleTrackerErrorAlert(libtorrent::tracker_error_alert* p); + void handleTrackerReplyAlert(libtorrent::tracker_reply_alert* p); + void handleTrackerWarningAlert(libtorrent::tracker_warning_alert* p); + void handlePortmapWarningAlert(libtorrent::portmap_error_alert* p); + void handlePortmapAlert(libtorrent::portmap_alert* p); + void handlePeerBlockedAlert(libtorrent::peer_blocked_alert* p); + void handlePeerBanAlert(libtorrent::peer_ban_alert* p); + void handleFastResumeRejectedAlert(libtorrent::fastresume_rejected_alert* p); + void handleUrlSeedAlert(libtorrent::url_seed_alert* p); + void handleListenSucceededAlert(libtorrent::listen_succeeded_alert *p); + void handleListenFailedAlert(libtorrent::listen_failed_alert *p); + void handleTorrentCheckedAlert(libtorrent::torrent_checked_alert* p); + void handleExternalIPAlert(libtorrent::external_ip_alert *p); + void handleStateUpdateAlert(libtorrent::state_update_alert *p); + void handleStatsAlert(libtorrent::stats_alert *p); private slots: - void addTorrentsFromScanFolder(QStringList&); - void readAlerts(); - void processBigRatios(); - void exportTorrentFiles(QString path); - void saveTempFastResumeData(); - void sendNotificationEmail(const QTorrentHandle &h); - void autoRunExternalProgram(const QTorrentHandle &h); - void mergeTorrents(QTorrentHandle& h_ex, boost::intrusive_ptr t); - void mergeTorrents(QTorrentHandle& h_ex, const QString& magnet_uri); - void exportTorrentFile(const QTorrentHandle &h, TorrentExportFolder folder = RegularTorrentExportFolder); - void handleIPFilterParsed(int ruleCount); - void handleIPFilterError(); - void configureSession(); + void addTorrentsFromScanFolder(QStringList&); + void readAlerts(); + void processBigRatios(); + void exportTorrentFiles(QString path); + void saveTempFastResumeData(); + void sendNotificationEmail(const QTorrentHandle &h); + void autoRunExternalProgram(const QTorrentHandle &h); + void mergeTorrents(QTorrentHandle& h_ex, boost::intrusive_ptr t); + void mergeTorrents(QTorrentHandle& h_ex, const QString& magnet_uri); + void exportTorrentFile(const QTorrentHandle &h, TorrentExportFolder folder = RegularTorrentExportFolder); + void handleIPFilterParsed(int ruleCount); + void handleIPFilterError(); + void configureSession(); signals: - void addedTorrent(const QTorrentHandle& h); - void torrentAboutToBeRemoved(const QTorrentHandle &h); - void pausedTorrent(const QTorrentHandle& h); - void resumedTorrent(const QTorrentHandle& h); - void finishedTorrent(const QTorrentHandle& h); - void fullDiskError(const QTorrentHandle& h, QString msg); - void trackerError(const QString &hash, QString time, QString msg); - void trackerAuthenticationRequired(const QTorrentHandle& h); - void newDownloadedTorrent(QString path, QString url); - void newDownloadedTorrentFromRss(QString url); - void newMagnetLink(const QString& link); - void updateFileSize(const QString &hash); - void downloadFromUrlFailure(QString url, QString reason); - void torrentFinishedChecking(const QTorrentHandle& h); - void metadataReceived(const QTorrentHandle &h); - void savePathChanged(const QTorrentHandle &h); - void alternativeSpeedsModeChanged(bool alternative); - void recursiveTorrentDownloadPossible(const QTorrentHandle &h); - void ipFilterParsed(bool error, int ruleCount); - void metadataReceivedHidden(const QTorrentHandle &h); - void stateUpdate(const std::vector &statuses); - void statsReceived(const libtorrent::stats_alert&); + void addedTorrent(const QTorrentHandle& h); + void torrentAboutToBeRemoved(const QTorrentHandle &h); + void pausedTorrent(const QTorrentHandle& h); + void resumedTorrent(const QTorrentHandle& h); + void finishedTorrent(const QTorrentHandle& h); + void fullDiskError(const QTorrentHandle& h, QString msg); + void trackerError(const QString &hash, QString time, QString msg); + void trackerAuthenticationRequired(const QTorrentHandle& h); + void newDownloadedTorrent(QString path, QString url); + void newDownloadedTorrentFromRss(QString url); + void newMagnetLink(const QString& link); + void updateFileSize(const QString &hash); + void downloadFromUrlFailure(QString url, QString reason); + void torrentFinishedChecking(const QTorrentHandle& h); + void metadataReceived(const QTorrentHandle &h); + void savePathChanged(const QTorrentHandle &h); + void alternativeSpeedsModeChanged(bool alternative); + void recursiveTorrentDownloadPossible(const QTorrentHandle &h); + void ipFilterParsed(bool error, int ruleCount); + void metadataReceivedHidden(const QTorrentHandle &h); + void stateUpdate(const std::vector &statuses); + void statsReceived(const libtorrent::stats_alert&); private: - // Bittorrent - libtorrent::session *s; - QPointer bd_scheduler; - QMap > savepathLabel_fromurl; // Use QMap for compatibility with Qt < 4.7: qHash(QUrl) + // Bittorrent + libtorrent::session *s; + QPointer bd_scheduler; + QMap > savepathLabel_fromurl; // Use QMap for compatibility with Qt < 4.7: qHash(QUrl) #ifndef DISABLE_GUI - QMap addpaused_fromurl; + QMap addpaused_fromurl; #endif - QHash > trackersInfos; - QHash savePathsToRemove; - QStringList torrentsToPausedAfterChecking; - QTimer resumeDataTimer; - // Ratio - QPointer BigRatioTimer; - // HTTP - DownloadThread* downloader; - // File System - ScanFoldersModel *m_scanFolders; - // Settings - bool preAllocateAll; - qreal global_ratio_limit; - int high_ratio_action; - bool LSDEnabled; - bool DHTEnabled; - bool PeXEnabled; - bool queueingEnabled; - bool appendLabelToSavePath; - bool m_torrentExportEnabled; - bool m_finishedTorrentExportEnabled; - bool appendqBExtension; - QString defaultSavePath; - QString defaultTempPath; - // IP filtering - QPointer filterParser; - QString filterPath; - QList url_skippingDlg; - // GeoIP + QHash > trackersInfos; + QHash savePathsToRemove; + QStringList torrentsToPausedAfterChecking; + QTimer resumeDataTimer; + // Ratio + QPointer BigRatioTimer; + // HTTP + DownloadThread* downloader; + // File System + ScanFoldersModel *m_scanFolders; + // Settings + bool preAllocateAll; + qreal global_ratio_limit; + int high_ratio_action; + bool LSDEnabled; + bool DHTEnabled; + bool PeXEnabled; + bool queueingEnabled; + bool appendLabelToSavePath; + bool m_torrentExportEnabled; + bool m_finishedTorrentExportEnabled; + bool appendqBExtension; + QString defaultSavePath; + QString defaultTempPath; + // IP filtering + QPointer filterParser; + QString filterPath; + QList url_skippingDlg; + // GeoIP #ifndef DISABLE_GUI - bool geoipDBLoaded; - bool resolve_countries; + bool geoipDBLoaded; + bool resolve_countries; #endif - // Tracker - QPointer m_tracker; - TorrentSpeedMonitor *m_speedMonitor; - shutDownAction m_shutdownAct; - // Port forwarding + // Tracker + QPointer m_tracker; + TorrentSpeedMonitor *m_speedMonitor; + shutDownAction m_shutdownAct; + // Port forwarding #if LIBTORRENT_VERSION_NUM < 10000 - libtorrent::upnp *m_upnp; - libtorrent::natpmp *m_natpmp; + libtorrent::upnp *m_upnp; + libtorrent::natpmp *m_natpmp; #endif - QAlertDispatcher* m_alertDispatcher; - TorrentStatistics* m_torrentStatistics; + QAlertDispatcher* m_alertDispatcher; + TorrentStatistics* m_torrentStatistics; }; #endif diff --git a/src/core/qtlibtorrent/qtorrenthandle.cpp b/src/core/qtlibtorrent/qtorrenthandle.cpp index a30dadfc4..4680e76ca 100644 --- a/src/core/qtlibtorrent/qtorrenthandle.cpp +++ b/src/core/qtlibtorrent/qtorrenthandle.cpp @@ -182,7 +182,7 @@ bool QTorrentHandle::first_last_piece_first() const QPair extremities = get_file_extremity_pieces(*t, index); return (torrent_handle::piece_priority(extremities.first) == 7) - && (torrent_handle::piece_priority(extremities.second) == 7); + && (torrent_handle::piece_priority(extremities.second) == 7); } QString QTorrentHandle::save_path() const @@ -512,7 +512,7 @@ void QTorrentHandle::pause() const torrent_handle::auto_managed(false); torrent_handle::pause(); if (!TorrentPersistentData::instance()->getHasMissingFiles(this->hash())) - torrent_handle::save_resume_data(); + torrent_handle::save_resume_data(); } void QTorrentHandle::resume() const @@ -770,13 +770,13 @@ bool QTorrentHandle::is_queued(const libtorrent::torrent_status &status) bool QTorrentHandle::is_seed(const libtorrent::torrent_status &status) { return status.state == torrent_status::finished - || status.state == torrent_status::seeding; + || status.state == torrent_status::seeding; } bool QTorrentHandle::is_checking(const libtorrent::torrent_status &status) { return status.state == torrent_status::checking_files - || status.state == torrent_status::checking_resume_data; + || status.state == torrent_status::checking_resume_data; } bool QTorrentHandle::has_error(const libtorrent::torrent_status &status) diff --git a/src/core/qtlibtorrent/shutdownconfirm.cpp b/src/core/qtlibtorrent/shutdownconfirm.cpp index 07520dc49..c10d2ed24 100644 --- a/src/core/qtlibtorrent/shutdownconfirm.cpp +++ b/src/core/qtlibtorrent/shutdownconfirm.cpp @@ -35,80 +35,80 @@ #include ShutdownConfirmDlg::ShutdownConfirmDlg(const shutDownAction &action): exit_now(NULL), timeout(15), action0(action) { - // Title and button - if (action0 == NO_SHUTDOWN) { - setWindowTitle(tr("Exit confirmation")); - exit_now = addButton(tr("Exit now"), QMessageBox::AcceptRole); - } - else { - setWindowTitle(tr("Shutdown confirmation")); - exit_now = addButton(tr("Shutdown now"), QMessageBox::AcceptRole); - } - // Cancel Button - addButton(QMessageBox::Cancel); - // Text - updateText(); - // Icon - setIcon(QMessageBox::Warning); - // Always on top - setWindowFlags(windowFlags()|Qt::WindowStaysOnTopHint); - // Set 'Cancel' as default button. - setDefaultButton(QMessageBox::Cancel); - timer.setInterval(1000); // 1sec - connect(&timer, SIGNAL(timeout()), this, SLOT(updateSeconds())); - show(); - // Move to center - move(misc::screenCenter(this)); + // Title and button + if (action0 == NO_SHUTDOWN) { + setWindowTitle(tr("Exit confirmation")); + exit_now = addButton(tr("Exit now"), QMessageBox::AcceptRole); + } + else { + setWindowTitle(tr("Shutdown confirmation")); + exit_now = addButton(tr("Shutdown now"), QMessageBox::AcceptRole); + } + // Cancel Button + addButton(QMessageBox::Cancel); + // Text + updateText(); + // Icon + setIcon(QMessageBox::Warning); + // Always on top + setWindowFlags(windowFlags()|Qt::WindowStaysOnTopHint); + // Set 'Cancel' as default button. + setDefaultButton(QMessageBox::Cancel); + timer.setInterval(1000); // 1sec + connect(&timer, SIGNAL(timeout()), this, SLOT(updateSeconds())); + show(); + // Move to center + move(misc::screenCenter(this)); } void ShutdownConfirmDlg::showEvent(QShowEvent *event) { - QMessageBox::showEvent(event); - timer.start(); + QMessageBox::showEvent(event); + timer.start(); } bool ShutdownConfirmDlg::askForConfirmation(const shutDownAction &action) { - ShutdownConfirmDlg dlg(action); - dlg.exec(); - return dlg.shutdown(); + ShutdownConfirmDlg dlg(action); + dlg.exec(); + return dlg.shutdown(); } void ShutdownConfirmDlg::updateSeconds() { - --timeout; - updateText(); - if (timeout == 0) { - timer.stop(); - accept(); - } + --timeout; + updateText(); + if (timeout == 0) { + timer.stop(); + accept(); + } } bool ShutdownConfirmDlg::shutdown() const { - // This is necessary because result() in the case of QMessageBox - // returns a type of StandardButton, but since we use a custom button - // it will return 0 instead, even though we set the 'accept' role on it. - if (result() != QDialog::Accepted) - return (clickedButton() == exit_now); - else - return true; + // This is necessary because result() in the case of QMessageBox + // returns a type of StandardButton, but since we use a custom button + // it will return 0 instead, even though we set the 'accept' role on it. + if (result() != QDialog::Accepted) + return (clickedButton() == exit_now); + else + return true; } void ShutdownConfirmDlg::updateText() { - QString text; + QString text; - switch (action0) { - case NO_SHUTDOWN: - text = tr("qBittorrent will now exit unless you cancel within the next %1 seconds.").arg(QString::number(timeout)); - break; - case SHUTDOWN_COMPUTER: - text = tr("The computer will now be switched off unless you cancel within the next %1 seconds.").arg(QString::number(timeout)); - break; - case SUSPEND_COMPUTER: - text = tr("The computer will now go to sleep mode unless you cancel within the next %1 seconds.").arg(QString::number(timeout)); - break; - case HIBERNATE_COMPUTER: - text = tr("The computer will now go to hibernation mode unless you cancel within the next %1 seconds.").arg(QString::number(timeout)); - break; - } + switch (action0) { + case NO_SHUTDOWN: + text = tr("qBittorrent will now exit unless you cancel within the next %1 seconds.").arg(QString::number(timeout)); + break; + case SHUTDOWN_COMPUTER: + text = tr("The computer will now be switched off unless you cancel within the next %1 seconds.").arg(QString::number(timeout)); + break; + case SUSPEND_COMPUTER: + text = tr("The computer will now go to sleep mode unless you cancel within the next %1 seconds.").arg(QString::number(timeout)); + break; + case HIBERNATE_COMPUTER: + text = tr("The computer will now go to hibernation mode unless you cancel within the next %1 seconds.").arg(QString::number(timeout)); + break; + } - setText(text); + setText(text); } diff --git a/src/core/qtlibtorrent/shutdownconfirm.h b/src/core/qtlibtorrent/shutdownconfirm.h index 77278ebf0..983e37092 100644 --- a/src/core/qtlibtorrent/shutdownconfirm.h +++ b/src/core/qtlibtorrent/shutdownconfirm.h @@ -36,29 +36,29 @@ #include "misc.h" class ShutdownConfirmDlg : public QMessageBox { - Q_OBJECT + Q_OBJECT public: - ShutdownConfirmDlg(const shutDownAction &action); - bool shutdown() const; + ShutdownConfirmDlg(const shutDownAction &action); + bool shutdown() const; - static bool askForConfirmation(const shutDownAction &action); + static bool askForConfirmation(const shutDownAction &action); protected: - void showEvent(QShowEvent *event); + void showEvent(QShowEvent *event); private slots: - void updateSeconds(); + void updateSeconds(); private: - // Methods - void updateText(); + // Methods + void updateText(); - // Vars - QAbstractButton *exit_now; - QTimer timer; - int timeout; - shutDownAction action0; + // Vars + QAbstractButton *exit_now; + QTimer timer; + int timeout; + shutDownAction action0; }; #endif // SHUTDOWNCONFIRM_H diff --git a/src/core/qtlibtorrent/torrentmodel.cpp b/src/core/qtlibtorrent/torrentmodel.cpp index 25973828a..43c9a28f9 100644 --- a/src/core/qtlibtorrent/torrentmodel.cpp +++ b/src/core/qtlibtorrent/torrentmodel.cpp @@ -43,601 +43,601 @@ namespace { QIcon get_paused_icon() { static QIcon cached = QIcon(":/icons/skin/paused.png"); return cached; - } +} QIcon get_queued_icon() { static QIcon cached = QIcon(":/icons/skin/queued.png"); return cached; - } +} QIcon get_downloading_icon() { static QIcon cached = QIcon(":/icons/skin/downloading.png"); return cached; - } +} QIcon get_stalled_downloading_icon() { static QIcon cached = QIcon(":/icons/skin/stalledDL.png"); return cached; - } +} QIcon get_uploading_icon() { static QIcon cached = QIcon(":/icons/skin/uploading.png"); return cached; - } +} QIcon get_stalled_uploading_icon() { static QIcon cached = QIcon(":/icons/skin/stalledUP.png"); return cached; - } +} QIcon get_checking_icon() { static QIcon cached = QIcon(":/icons/skin/checking.png"); return cached; - } +} QIcon get_error_icon() { static QIcon cached = QIcon(":/icons/skin/error.png"); return cached; - } +} } TorrentModelItem::TorrentModelItem(const QTorrentHandle &h) - : m_torrent(h) - , m_lastStatus(h.status(torrent_handle::query_accurate_download_counters)) - , m_addedTime(TorrentPersistentData::instance()->getAddedDate(h.hash())) - , m_label(TorrentPersistentData::instance()->getLabel(h.hash())) - , m_name(TorrentPersistentData::instance()->getName(h.hash())) - , m_hash(h.hash()) + : m_torrent(h) + , m_lastStatus(h.status(torrent_handle::query_accurate_download_counters)) + , m_addedTime(TorrentPersistentData::instance()->getAddedDate(h.hash())) + , m_label(TorrentPersistentData::instance()->getLabel(h.hash())) + , m_name(TorrentPersistentData::instance()->getName(h.hash())) + , m_hash(h.hash()) { - if (m_name.isEmpty()) - m_name = h.name(); + if (m_name.isEmpty()) + m_name = h.name(); } void TorrentModelItem::refreshStatus(libtorrent::torrent_status const& status) { - m_lastStatus = status; + m_lastStatus = status; } TorrentModelItem::State TorrentModelItem::state() const { - try { - // Pause or Queued - if (m_torrent.is_paused(m_lastStatus)) { - if (TorrentPersistentData::instance()->getHasMissingFiles(misc::toQString(m_lastStatus.info_hash))) - return STATE_PAUSED_MISSING; - else - return m_torrent.is_seed(m_lastStatus) ? STATE_PAUSED_UP : STATE_PAUSED_DL; - } - - if (m_torrent.is_queued(m_lastStatus) - && m_lastStatus.state != torrent_status::queued_for_checking - && m_lastStatus.state != torrent_status::checking_resume_data - && m_lastStatus.state != torrent_status::checking_files) - return m_torrent.is_seed(m_lastStatus) ? STATE_QUEUED_UP : STATE_QUEUED_DL; - - // Other states - switch(m_lastStatus.state) { - case torrent_status::allocating: - return STATE_ALLOCATING; - case torrent_status::downloading_metadata: - return STATE_DOWNLOADING_META; - case torrent_status::downloading: - return m_lastStatus.download_payload_rate > 0 ? STATE_DOWNLOADING : STATE_STALLED_DL; - case torrent_status::finished: - case torrent_status::seeding: - return m_lastStatus.upload_payload_rate > 0 ? STATE_SEEDING : STATE_STALLED_UP; - case torrent_status::queued_for_checking: - return STATE_QUEUED_CHECK; - case torrent_status::checking_resume_data: - return STATE_QUEUED_FASTCHECK; - case torrent_status::checking_files: - return m_torrent.is_seed(m_lastStatus) ? STATE_CHECKING_UP : STATE_CHECKING_DL; - default: - return STATE_INVALID; + try { + // Pause or Queued + if (m_torrent.is_paused(m_lastStatus)) { + if (TorrentPersistentData::instance()->getHasMissingFiles(misc::toQString(m_lastStatus.info_hash))) + return STATE_PAUSED_MISSING; + else + return m_torrent.is_seed(m_lastStatus) ? STATE_PAUSED_UP : STATE_PAUSED_DL; + } + + if (m_torrent.is_queued(m_lastStatus) + && m_lastStatus.state != torrent_status::queued_for_checking + && m_lastStatus.state != torrent_status::checking_resume_data + && m_lastStatus.state != torrent_status::checking_files) + return m_torrent.is_seed(m_lastStatus) ? STATE_QUEUED_UP : STATE_QUEUED_DL; + + // Other states + switch(m_lastStatus.state) { + case torrent_status::allocating: + return STATE_ALLOCATING; + case torrent_status::downloading_metadata: + return STATE_DOWNLOADING_META; + case torrent_status::downloading: + return m_lastStatus.download_payload_rate > 0 ? STATE_DOWNLOADING : STATE_STALLED_DL; + case torrent_status::finished: + case torrent_status::seeding: + return m_lastStatus.upload_payload_rate > 0 ? STATE_SEEDING : STATE_STALLED_UP; + case torrent_status::queued_for_checking: + return STATE_QUEUED_CHECK; + case torrent_status::checking_resume_data: + return STATE_QUEUED_FASTCHECK; + case torrent_status::checking_files: + return m_torrent.is_seed(m_lastStatus) ? STATE_CHECKING_UP : STATE_CHECKING_DL; + default: + return STATE_INVALID; + } + } catch(invalid_handle&) { + return STATE_INVALID; } - } catch(invalid_handle&) { - return STATE_INVALID; - } } QIcon TorrentModelItem::getIconByState(State state) { - switch (state) { - case STATE_DOWNLOADING: - case STATE_DOWNLOADING_META: - return get_downloading_icon(); - case STATE_ALLOCATING: - case STATE_STALLED_DL: - return get_stalled_downloading_icon(); - case STATE_STALLED_UP: - return get_stalled_uploading_icon(); - case STATE_SEEDING: - return get_uploading_icon(); - case STATE_PAUSED_DL: - case STATE_PAUSED_UP: - return get_paused_icon(); - case STATE_QUEUED_DL: - case STATE_QUEUED_UP: - return get_queued_icon(); - case STATE_CHECKING_UP: - case STATE_CHECKING_DL: - case STATE_QUEUED_CHECK: - case STATE_QUEUED_FASTCHECK: - return get_checking_icon(); - case STATE_INVALID: - case STATE_PAUSED_MISSING: - return get_error_icon(); - default: - Q_ASSERT(false); - return get_error_icon(); - } + switch (state) { + case STATE_DOWNLOADING: + case STATE_DOWNLOADING_META: + return get_downloading_icon(); + case STATE_ALLOCATING: + case STATE_STALLED_DL: + return get_stalled_downloading_icon(); + case STATE_STALLED_UP: + return get_stalled_uploading_icon(); + case STATE_SEEDING: + return get_uploading_icon(); + case STATE_PAUSED_DL: + case STATE_PAUSED_UP: + return get_paused_icon(); + case STATE_QUEUED_DL: + case STATE_QUEUED_UP: + return get_queued_icon(); + case STATE_CHECKING_UP: + case STATE_CHECKING_DL: + case STATE_QUEUED_CHECK: + case STATE_QUEUED_FASTCHECK: + return get_checking_icon(); + case STATE_INVALID: + case STATE_PAUSED_MISSING: + return get_error_icon(); + default: + Q_ASSERT(false); + return get_error_icon(); + } } QColor TorrentModelItem::getColorByState(State state) { - switch (state) { - case STATE_DOWNLOADING: - case STATE_DOWNLOADING_META: - return QColor(0, 128, 0); // green - case STATE_ALLOCATING: - case STATE_STALLED_DL: - case STATE_STALLED_UP: - return QColor(128, 128, 128); // grey - case STATE_SEEDING: - return QColor(255, 165, 0); // orange - case STATE_PAUSED_DL: - case STATE_PAUSED_UP: - case STATE_PAUSED_MISSING: - return QColor(255, 0, 0); // red - case STATE_QUEUED_DL: - case STATE_QUEUED_UP: - case STATE_CHECKING_UP: - case STATE_CHECKING_DL: - case STATE_QUEUED_CHECK: - case STATE_QUEUED_FASTCHECK: - return QColor(128, 128, 128); // grey - case STATE_INVALID: - return QColor(255, 0, 0); // red - default: - Q_ASSERT(false); - return QColor(255, 0, 0); // red - } + switch (state) { + case STATE_DOWNLOADING: + case STATE_DOWNLOADING_META: + return QColor(0, 128, 0); // green + case STATE_ALLOCATING: + case STATE_STALLED_DL: + case STATE_STALLED_UP: + return QColor(128, 128, 128); // grey + case STATE_SEEDING: + return QColor(255, 165, 0); // orange + case STATE_PAUSED_DL: + case STATE_PAUSED_UP: + case STATE_PAUSED_MISSING: + return QColor(255, 0, 0); // red + case STATE_QUEUED_DL: + case STATE_QUEUED_UP: + case STATE_CHECKING_UP: + case STATE_CHECKING_DL: + case STATE_QUEUED_CHECK: + case STATE_QUEUED_FASTCHECK: + return QColor(128, 128, 128); // grey + case STATE_INVALID: + return QColor(255, 0, 0); // red + default: + Q_ASSERT(false); + return QColor(255, 0, 0); // red + } } bool TorrentModelItem::setData(int column, const QVariant &value, int role) { - qDebug() << Q_FUNC_INFO << column << value; - if (role != Qt::DisplayRole) return false; - // Label, seed date and Name columns can be edited - switch(column) { - case TR_NAME: - m_name = value.toString(); - TorrentPersistentData::instance()->saveName(m_torrent.hash(), m_name); - return true; - case TR_LABEL: { - QString new_label = value.toString(); - if (m_label != new_label) { - QString old_label = m_label; - m_label = new_label; - TorrentPersistentData::instance()->saveLabel(m_torrent.hash(), new_label); - emit labelChanged(old_label, new_label); + qDebug() << Q_FUNC_INFO << column << value; + if (role != Qt::DisplayRole) return false; + // Label, seed date and Name columns can be edited + switch(column) { + case TR_NAME: + m_name = value.toString(); + TorrentPersistentData::instance()->saveName(m_torrent.hash(), m_name); + return true; + case TR_LABEL: { + QString new_label = value.toString(); + if (m_label != new_label) { + QString old_label = m_label; + m_label = new_label; + TorrentPersistentData::instance()->saveLabel(m_torrent.hash(), new_label); + emit labelChanged(old_label, new_label); + } + return true; + } + default: + break; } - return true; - } - default: - break; - } - return false; + return false; } QVariant TorrentModelItem::data(int column, int role) const { - if (role == Qt::DecorationRole && column == TR_NAME) { - return getIconByState(state()); - } - if (role == Qt::ForegroundRole) { - return getColorByState(state()); - } - if (role != Qt::DisplayRole && role != Qt::UserRole) return QVariant(); - switch(column) { - case TR_NAME: - return m_name.isEmpty() ? m_torrent.name() : m_name; - case TR_PRIORITY: { - int pos = m_torrent.queue_position(m_lastStatus); - if (pos > -1) - return pos - HiddenData::getSize(); - else - return pos; - } - case TR_SIZE: - return m_lastStatus.has_metadata ? static_cast(m_lastStatus.total_wanted) : -1; - case TR_PROGRESS: - return m_torrent.progress(m_lastStatus); - case TR_STATUS: - return state(); - case TR_SEEDS: { - return (role == Qt::DisplayRole) ? m_lastStatus.num_seeds : m_lastStatus.num_complete; - } - case TR_PEERS: { - return (role == Qt::DisplayRole) ? (m_lastStatus.num_peers-m_lastStatus.num_seeds) : m_lastStatus.num_incomplete; - } - case TR_DLSPEED: - return m_lastStatus.download_payload_rate; - case TR_UPSPEED: - return m_lastStatus.upload_payload_rate; - case TR_ETA: { - // XXX: Is this correct? - if (m_torrent.is_paused(m_lastStatus) || m_torrent.is_queued(m_lastStatus)) return MAX_ETA; - return QBtSession::instance()->getETA(m_hash, m_lastStatus); - } - case TR_RATIO: - return QBtSession::instance()->getRealRatio(m_lastStatus); - case TR_LABEL: - return m_label; - case TR_ADD_DATE: - return m_addedTime; - case TR_SEED_DATE: - return m_lastStatus.completed_time ? QDateTime::fromTime_t(m_lastStatus.completed_time) : QDateTime(); - case TR_TRACKER: - return misc::toQString(m_lastStatus.current_tracker); - case TR_DLLIMIT: - return m_torrent.download_limit(); - case TR_UPLIMIT: - return m_torrent.upload_limit(); - case TR_AMOUNT_DOWNLOADED: - return static_cast(m_lastStatus.all_time_download); - case TR_AMOUNT_UPLOADED: - return static_cast(m_lastStatus.all_time_upload); - case TR_AMOUNT_LEFT: - return static_cast(m_lastStatus.total_wanted - m_lastStatus.total_wanted_done); - case TR_TIME_ELAPSED: - return (role == Qt::DisplayRole) ? m_lastStatus.active_time : m_lastStatus.seeding_time; - case TR_SAVE_PATH: - return fsutils::toNativePath(m_torrent.save_path_parsed()); - case TR_COMPLETED: - return static_cast(m_lastStatus.total_wanted_done); - case TR_RATIO_LIMIT: { - QString hash = misc::toQString(m_lastStatus.info_hash); - return QBtSession::instance()->getMaxRatioPerTorrent(hash, NULL); - } - case TR_SEEN_COMPLETE_DATE: - return m_lastStatus.last_seen_complete ? QDateTime::fromTime_t(m_lastStatus.last_seen_complete) : QDateTime(); - case TR_LAST_ACTIVITY: - if (m_torrent.is_paused(m_lastStatus) || m_torrent.is_checking(m_lastStatus)) - return -1; - if (m_lastStatus.time_since_upload < m_lastStatus.time_since_download) - return m_lastStatus.time_since_upload; - else - return m_lastStatus.time_since_download; - case TR_TOTAL_SIZE: - return m_lastStatus.has_metadata ? static_cast(m_torrent.total_size()) : -1; - default: - return QVariant(); - } + if (role == Qt::DecorationRole && column == TR_NAME) { + return getIconByState(state()); + } + if (role == Qt::ForegroundRole) { + return getColorByState(state()); + } + if (role != Qt::DisplayRole && role != Qt::UserRole) return QVariant(); + switch(column) { + case TR_NAME: + return m_name.isEmpty() ? m_torrent.name() : m_name; + case TR_PRIORITY: { + int pos = m_torrent.queue_position(m_lastStatus); + if (pos > -1) + return pos - HiddenData::getSize(); + else + return pos; + } + case TR_SIZE: + return m_lastStatus.has_metadata ? static_cast(m_lastStatus.total_wanted) : -1; + case TR_PROGRESS: + return m_torrent.progress(m_lastStatus); + case TR_STATUS: + return state(); + case TR_SEEDS: { + return (role == Qt::DisplayRole) ? m_lastStatus.num_seeds : m_lastStatus.num_complete; + } + case TR_PEERS: { + return (role == Qt::DisplayRole) ? (m_lastStatus.num_peers-m_lastStatus.num_seeds) : m_lastStatus.num_incomplete; + } + case TR_DLSPEED: + return m_lastStatus.download_payload_rate; + case TR_UPSPEED: + return m_lastStatus.upload_payload_rate; + case TR_ETA: { + // XXX: Is this correct? + if (m_torrent.is_paused(m_lastStatus) || m_torrent.is_queued(m_lastStatus)) return MAX_ETA; + return QBtSession::instance()->getETA(m_hash, m_lastStatus); + } + case TR_RATIO: + return QBtSession::instance()->getRealRatio(m_lastStatus); + case TR_LABEL: + return m_label; + case TR_ADD_DATE: + return m_addedTime; + case TR_SEED_DATE: + return m_lastStatus.completed_time ? QDateTime::fromTime_t(m_lastStatus.completed_time) : QDateTime(); + case TR_TRACKER: + return misc::toQString(m_lastStatus.current_tracker); + case TR_DLLIMIT: + return m_torrent.download_limit(); + case TR_UPLIMIT: + return m_torrent.upload_limit(); + case TR_AMOUNT_DOWNLOADED: + return static_cast(m_lastStatus.all_time_download); + case TR_AMOUNT_UPLOADED: + return static_cast(m_lastStatus.all_time_upload); + case TR_AMOUNT_LEFT: + return static_cast(m_lastStatus.total_wanted - m_lastStatus.total_wanted_done); + case TR_TIME_ELAPSED: + return (role == Qt::DisplayRole) ? m_lastStatus.active_time : m_lastStatus.seeding_time; + case TR_SAVE_PATH: + return fsutils::toNativePath(m_torrent.save_path_parsed()); + case TR_COMPLETED: + return static_cast(m_lastStatus.total_wanted_done); + case TR_RATIO_LIMIT: { + QString hash = misc::toQString(m_lastStatus.info_hash); + return QBtSession::instance()->getMaxRatioPerTorrent(hash, NULL); + } + case TR_SEEN_COMPLETE_DATE: + return m_lastStatus.last_seen_complete ? QDateTime::fromTime_t(m_lastStatus.last_seen_complete) : QDateTime(); + case TR_LAST_ACTIVITY: + if (m_torrent.is_paused(m_lastStatus) || m_torrent.is_checking(m_lastStatus)) + return -1; + if (m_lastStatus.time_since_upload < m_lastStatus.time_since_download) + return m_lastStatus.time_since_upload; + else + return m_lastStatus.time_since_download; + case TR_TOTAL_SIZE: + return m_lastStatus.has_metadata ? static_cast(m_torrent.total_size()) : -1; + default: + return QVariant(); + } } // TORRENT MODEL TorrentModel::TorrentModel(QObject *parent) : - QAbstractListModel(parent), m_refreshInterval(2000) + QAbstractListModel(parent), m_refreshInterval(2000) { } void TorrentModel::populate() { - // Load the torrents - std::vector torrents = QBtSession::instance()->getSession()->get_torrents(); - - std::vector::const_iterator it = torrents.begin(); - std::vector::const_iterator itend = torrents.end(); - for ( ; it != itend; ++it) { - const QTorrentHandle h(*it); - if (HiddenData::hasData(h.hash())) - continue; - addTorrent(h); - } - // Refresh timer - connect(&m_refreshTimer, SIGNAL(timeout()), SLOT(forceModelRefresh())); - m_refreshTimer.start(m_refreshInterval); - // Listen for torrent changes - connect(QBtSession::instance(), SIGNAL(addedTorrent(QTorrentHandle)), SLOT(addTorrent(QTorrentHandle))); - connect(QBtSession::instance(), SIGNAL(torrentAboutToBeRemoved(QTorrentHandle)), SLOT(handleTorrentAboutToBeRemoved(QTorrentHandle))); - connect(QBtSession::instance(), SIGNAL(finishedTorrent(QTorrentHandle)), SLOT(handleFinishedTorrent(QTorrentHandle))); - connect(QBtSession::instance(), SIGNAL(metadataReceived(QTorrentHandle)), SLOT(handleTorrentUpdate(QTorrentHandle))); - connect(QBtSession::instance(), SIGNAL(resumedTorrent(QTorrentHandle)), SLOT(handleTorrentUpdate(QTorrentHandle))); - connect(QBtSession::instance(), SIGNAL(pausedTorrent(QTorrentHandle)), SLOT(handleTorrentUpdate(QTorrentHandle))); - connect(QBtSession::instance(), SIGNAL(torrentFinishedChecking(QTorrentHandle)), SLOT(handleTorrentUpdate(QTorrentHandle))); - connect(QBtSession::instance(), SIGNAL(stateUpdate(std::vector)), SLOT(stateUpdated(std::vector))); + // Load the torrents + std::vector torrents = QBtSession::instance()->getSession()->get_torrents(); + + std::vector::const_iterator it = torrents.begin(); + std::vector::const_iterator itend = torrents.end(); + for ( ; it != itend; ++it) { + const QTorrentHandle h(*it); + if (HiddenData::hasData(h.hash())) + continue; + addTorrent(h); + } + // Refresh timer + connect(&m_refreshTimer, SIGNAL(timeout()), SLOT(forceModelRefresh())); + m_refreshTimer.start(m_refreshInterval); + // Listen for torrent changes + connect(QBtSession::instance(), SIGNAL(addedTorrent(QTorrentHandle)), SLOT(addTorrent(QTorrentHandle))); + connect(QBtSession::instance(), SIGNAL(torrentAboutToBeRemoved(QTorrentHandle)), SLOT(handleTorrentAboutToBeRemoved(QTorrentHandle))); + connect(QBtSession::instance(), SIGNAL(finishedTorrent(QTorrentHandle)), SLOT(handleFinishedTorrent(QTorrentHandle))); + connect(QBtSession::instance(), SIGNAL(metadataReceived(QTorrentHandle)), SLOT(handleTorrentUpdate(QTorrentHandle))); + connect(QBtSession::instance(), SIGNAL(resumedTorrent(QTorrentHandle)), SLOT(handleTorrentUpdate(QTorrentHandle))); + connect(QBtSession::instance(), SIGNAL(pausedTorrent(QTorrentHandle)), SLOT(handleTorrentUpdate(QTorrentHandle))); + connect(QBtSession::instance(), SIGNAL(torrentFinishedChecking(QTorrentHandle)), SLOT(handleTorrentUpdate(QTorrentHandle))); + connect(QBtSession::instance(), SIGNAL(stateUpdate(std::vector)), SLOT(stateUpdated(std::vector))); } TorrentModel::~TorrentModel() { - qDebug() << Q_FUNC_INFO << "ENTER"; - qDeleteAll(m_torrents); - m_torrents.clear(); - qDebug() << Q_FUNC_INFO << "EXIT"; + qDebug() << Q_FUNC_INFO << "ENTER"; + qDeleteAll(m_torrents); + m_torrents.clear(); + qDebug() << Q_FUNC_INFO << "EXIT"; } QVariant TorrentModel::headerData(int section, Qt::Orientation orientation, int role) const { - if (orientation == Qt::Horizontal) { - if (role == Qt::DisplayRole) { - switch(section) { - case TorrentModelItem::TR_NAME: return tr("Name", "i.e: torrent name"); - case TorrentModelItem::TR_PRIORITY: return "#"; - case TorrentModelItem::TR_SIZE: return tr("Size", "i.e: torrent size"); - case TorrentModelItem::TR_PROGRESS: return tr("Done", "% Done"); - case TorrentModelItem::TR_STATUS: return tr("Status", "Torrent status (e.g. downloading, seeding, paused)"); - case TorrentModelItem::TR_SEEDS: return tr("Seeds", "i.e. full sources (often untranslated)"); - case TorrentModelItem::TR_PEERS: return tr("Peers", "i.e. partial sources (often untranslated)"); - case TorrentModelItem::TR_DLSPEED: return tr("Down Speed", "i.e: Download speed"); - case TorrentModelItem::TR_UPSPEED: return tr("Up Speed", "i.e: Upload speed"); - case TorrentModelItem::TR_RATIO: return tr("Ratio", "Share ratio"); - case TorrentModelItem::TR_ETA: return tr("ETA", "i.e: Estimated Time of Arrival / Time left"); - case TorrentModelItem::TR_LABEL: return tr("Label"); - case TorrentModelItem::TR_ADD_DATE: return tr("Added On", "Torrent was added to transfer list on 01/01/2010 08:00"); - case TorrentModelItem::TR_SEED_DATE: return tr("Completed On", "Torrent was completed on 01/01/2010 08:00"); - case TorrentModelItem::TR_TRACKER: return tr("Tracker"); - case TorrentModelItem::TR_DLLIMIT: return tr("Down Limit", "i.e: Download limit"); - case TorrentModelItem::TR_UPLIMIT: return tr("Up Limit", "i.e: Upload limit"); - case TorrentModelItem::TR_AMOUNT_DOWNLOADED: return tr("Downloaded", "Amount of data downloaded (e.g. in MB)"); - case TorrentModelItem::TR_AMOUNT_UPLOADED: return tr("Uploaded", "Amount of data uploaded (e.g. in MB)"); - case TorrentModelItem::TR_AMOUNT_LEFT: return tr("Remaining", "Amount of data left to download (e.g. in MB)"); - case TorrentModelItem::TR_TIME_ELAPSED: return tr("Time Active", "Time (duration) the torrent is active (not paused)"); - case TorrentModelItem::TR_SAVE_PATH: return tr("Save path", "Torrent save path"); - case TorrentModelItem::TR_COMPLETED: return tr("Completed", "Amount of data completed (e.g. in MB)"); - case TorrentModelItem::TR_RATIO_LIMIT: return tr("Ratio Limit", "Upload share ratio limit"); - case TorrentModelItem::TR_SEEN_COMPLETE_DATE: return tr("Last Seen Complete", "Indicates the time when the torrent was last seen complete/whole"); - case TorrentModelItem::TR_LAST_ACTIVITY: return tr("Last Activity", "Time passed since a chunk was downloaded/uploaded"); - case TorrentModelItem::TR_TOTAL_SIZE: return tr("Total Size", "i.e. Size including unwanted data"); - default: - return QVariant(); - } - } - else if (role == Qt::TextAlignmentRole) { - switch(section) { - case TorrentModelItem::TR_AMOUNT_DOWNLOADED: - case TorrentModelItem::TR_AMOUNT_UPLOADED: - case TorrentModelItem::TR_AMOUNT_LEFT: - case TorrentModelItem::TR_COMPLETED: - case TorrentModelItem::TR_SIZE: - case TorrentModelItem::TR_TOTAL_SIZE: - case TorrentModelItem::TR_ETA: - case TorrentModelItem::TR_SEEDS: - case TorrentModelItem::TR_PEERS: - case TorrentModelItem::TR_UPSPEED: - case TorrentModelItem::TR_DLSPEED: - case TorrentModelItem::TR_UPLIMIT: - case TorrentModelItem::TR_DLLIMIT: - case TorrentModelItem::TR_RATIO_LIMIT: - case TorrentModelItem::TR_RATIO: - case TorrentModelItem::TR_PRIORITY: - case TorrentModelItem::TR_LAST_ACTIVITY: - return QVariant(Qt::AlignRight | Qt::AlignVCenter); - default: - return QAbstractListModel::headerData(section, orientation, role); - } + if (orientation == Qt::Horizontal) { + if (role == Qt::DisplayRole) { + switch(section) { + case TorrentModelItem::TR_NAME: return tr("Name", "i.e: torrent name"); + case TorrentModelItem::TR_PRIORITY: return "#"; + case TorrentModelItem::TR_SIZE: return tr("Size", "i.e: torrent size"); + case TorrentModelItem::TR_PROGRESS: return tr("Done", "% Done"); + case TorrentModelItem::TR_STATUS: return tr("Status", "Torrent status (e.g. downloading, seeding, paused)"); + case TorrentModelItem::TR_SEEDS: return tr("Seeds", "i.e. full sources (often untranslated)"); + case TorrentModelItem::TR_PEERS: return tr("Peers", "i.e. partial sources (often untranslated)"); + case TorrentModelItem::TR_DLSPEED: return tr("Down Speed", "i.e: Download speed"); + case TorrentModelItem::TR_UPSPEED: return tr("Up Speed", "i.e: Upload speed"); + case TorrentModelItem::TR_RATIO: return tr("Ratio", "Share ratio"); + case TorrentModelItem::TR_ETA: return tr("ETA", "i.e: Estimated Time of Arrival / Time left"); + case TorrentModelItem::TR_LABEL: return tr("Label"); + case TorrentModelItem::TR_ADD_DATE: return tr("Added On", "Torrent was added to transfer list on 01/01/2010 08:00"); + case TorrentModelItem::TR_SEED_DATE: return tr("Completed On", "Torrent was completed on 01/01/2010 08:00"); + case TorrentModelItem::TR_TRACKER: return tr("Tracker"); + case TorrentModelItem::TR_DLLIMIT: return tr("Down Limit", "i.e: Download limit"); + case TorrentModelItem::TR_UPLIMIT: return tr("Up Limit", "i.e: Upload limit"); + case TorrentModelItem::TR_AMOUNT_DOWNLOADED: return tr("Downloaded", "Amount of data downloaded (e.g. in MB)"); + case TorrentModelItem::TR_AMOUNT_UPLOADED: return tr("Uploaded", "Amount of data uploaded (e.g. in MB)"); + case TorrentModelItem::TR_AMOUNT_LEFT: return tr("Remaining", "Amount of data left to download (e.g. in MB)"); + case TorrentModelItem::TR_TIME_ELAPSED: return tr("Time Active", "Time (duration) the torrent is active (not paused)"); + case TorrentModelItem::TR_SAVE_PATH: return tr("Save path", "Torrent save path"); + case TorrentModelItem::TR_COMPLETED: return tr("Completed", "Amount of data completed (e.g. in MB)"); + case TorrentModelItem::TR_RATIO_LIMIT: return tr("Ratio Limit", "Upload share ratio limit"); + case TorrentModelItem::TR_SEEN_COMPLETE_DATE: return tr("Last Seen Complete", "Indicates the time when the torrent was last seen complete/whole"); + case TorrentModelItem::TR_LAST_ACTIVITY: return tr("Last Activity", "Time passed since a chunk was downloaded/uploaded"); + case TorrentModelItem::TR_TOTAL_SIZE: return tr("Total Size", "i.e. Size including unwanted data"); + default: + return QVariant(); + } + } + else if (role == Qt::TextAlignmentRole) { + switch(section) { + case TorrentModelItem::TR_AMOUNT_DOWNLOADED: + case TorrentModelItem::TR_AMOUNT_UPLOADED: + case TorrentModelItem::TR_AMOUNT_LEFT: + case TorrentModelItem::TR_COMPLETED: + case TorrentModelItem::TR_SIZE: + case TorrentModelItem::TR_TOTAL_SIZE: + case TorrentModelItem::TR_ETA: + case TorrentModelItem::TR_SEEDS: + case TorrentModelItem::TR_PEERS: + case TorrentModelItem::TR_UPSPEED: + case TorrentModelItem::TR_DLSPEED: + case TorrentModelItem::TR_UPLIMIT: + case TorrentModelItem::TR_DLLIMIT: + case TorrentModelItem::TR_RATIO_LIMIT: + case TorrentModelItem::TR_RATIO: + case TorrentModelItem::TR_PRIORITY: + case TorrentModelItem::TR_LAST_ACTIVITY: + return QVariant(Qt::AlignRight | Qt::AlignVCenter); + default: + return QAbstractListModel::headerData(section, orientation, role); + } + } } - } - return QVariant(); + return QVariant(); } QVariant TorrentModel::data(const QModelIndex &index, int role) const { - if (!index.isValid()) return QVariant(); - try { - if (index.row() >= 0 && index.row() < rowCount() && index.column() >= 0 && index.column() < columnCount()) - return m_torrents[index.row()]->data(index.column(), role); - } catch(invalid_handle&) {} - return QVariant(); + if (!index.isValid()) return QVariant(); + try { + if (index.row() >= 0 && index.row() < rowCount() && index.column() >= 0 && index.column() < columnCount()) + return m_torrents[index.row()]->data(index.column(), role); + } catch(invalid_handle&) {} + return QVariant(); } bool TorrentModel::setData(const QModelIndex &index, const QVariant &value, int role) { - qDebug() << Q_FUNC_INFO << value; - if (!index.isValid() || role != Qt::DisplayRole) return false; - qDebug("Index is valid and role is DisplayRole"); - try { - if (index.row() >= 0 && index.row() < rowCount() && index.column() >= 0 && index.column() < columnCount()) { - bool change = m_torrents[index.row()]->setData(index.column(), value, role); - if (change) - notifyTorrentChanged(index.row()); - return change; - } - } catch(invalid_handle&) {} - return false; + qDebug() << Q_FUNC_INFO << value; + if (!index.isValid() || role != Qt::DisplayRole) return false; + qDebug("Index is valid and role is DisplayRole"); + try { + if (index.row() >= 0 && index.row() < rowCount() && index.column() >= 0 && index.column() < columnCount()) { + bool change = m_torrents[index.row()]->setData(index.column(), value, role); + if (change) + notifyTorrentChanged(index.row()); + return change; + } + } catch(invalid_handle&) {} + return false; } int TorrentModel::torrentRow(const QString &hash) const { - int row = 0; + int row = 0; - QList::const_iterator it = m_torrents.constBegin(); - QList::const_iterator itend = m_torrents.constEnd(); - for ( ; it != itend; ++it) { - if ((*it)->hash() == hash) return row; - ++row; - } - return -1; + QList::const_iterator it = m_torrents.constBegin(); + QList::const_iterator itend = m_torrents.constEnd(); + for ( ; it != itend; ++it) { + if ((*it)->hash() == hash) return row; + ++row; + } + return -1; } void TorrentModel::addTorrent(const QTorrentHandle &h) { - if (torrentRow(h.hash()) < 0) { - beginInsertTorrent(m_torrents.size()); - TorrentModelItem *item = new TorrentModelItem(h); - connect(item, SIGNAL(labelChanged(QString,QString)), SLOT(handleTorrentLabelChange(QString,QString))); - m_torrents << item; - emit torrentAdded(item); - endInsertTorrent(); - } + if (torrentRow(h.hash()) < 0) { + beginInsertTorrent(m_torrents.size()); + TorrentModelItem *item = new TorrentModelItem(h); + connect(item, SIGNAL(labelChanged(QString,QString)), SLOT(handleTorrentLabelChange(QString,QString))); + m_torrents << item; + emit torrentAdded(item); + endInsertTorrent(); + } } void TorrentModel::beginInsertTorrent(int row) { - beginInsertRows(QModelIndex(), row, row); + beginInsertRows(QModelIndex(), row, row); } void TorrentModel::endInsertTorrent() { - endInsertRows(); + endInsertRows(); } void TorrentModel::beginRemoveTorrent(int row) { - beginRemoveRows(QModelIndex(), row, row); + beginRemoveRows(QModelIndex(), row, row); } void TorrentModel::endRemoveTorrent() { - endRemoveRows(); + endRemoveRows(); } void TorrentModel::handleTorrentUpdate(const QTorrentHandle &h) { - const int row = torrentRow(h.hash()); - if (row >= 0) { - m_torrents[row]->refreshStatus(h.status(torrent_handle::query_accurate_download_counters)); - notifyTorrentChanged(row); - } + const int row = torrentRow(h.hash()); + if (row >= 0) { + m_torrents[row]->refreshStatus(h.status(torrent_handle::query_accurate_download_counters)); + notifyTorrentChanged(row); + } } void TorrentModel::handleFinishedTorrent(const QTorrentHandle& h) { - const int row = torrentRow(h.hash()); - if (row < 0) - return; + const int row = torrentRow(h.hash()); + if (row < 0) + return; - // Update completion date - m_torrents[row]->refreshStatus(h.status(torrent_handle::query_accurate_download_counters)); - notifyTorrentChanged(row); + // Update completion date + m_torrents[row]->refreshStatus(h.status(torrent_handle::query_accurate_download_counters)); + notifyTorrentChanged(row); } void TorrentModel::notifyTorrentChanged(int row) { - emit dataChanged(index(row, 0), index(row, columnCount()-1)); + emit dataChanged(index(row, 0), index(row, columnCount()-1)); } void TorrentModel::setRefreshInterval(int refreshInterval) { - if (m_refreshInterval != refreshInterval) { - m_refreshInterval = refreshInterval; - m_refreshTimer.stop(); - m_refreshTimer.start(m_refreshInterval); - } + if (m_refreshInterval != refreshInterval) { + m_refreshInterval = refreshInterval; + m_refreshTimer.stop(); + m_refreshTimer.start(m_refreshInterval); + } } void TorrentModel::forceModelRefresh() { - QBtSession::instance()->postTorrentUpdate(); + QBtSession::instance()->postTorrentUpdate(); } TorrentStatusReport TorrentModel::getTorrentStatusReport() const { - TorrentStatusReport report; - - QList::const_iterator it = m_torrents.constBegin(); - QList::const_iterator itend = m_torrents.constEnd(); - for ( ; it != itend; ++it) { - switch((*it)->state()) { - case TorrentModelItem::STATE_DOWNLOADING: - ++report.nb_active; - ++report.nb_downloading; - break; - case TorrentModelItem::STATE_DOWNLOADING_META: - ++report.nb_downloading; - break; - case TorrentModelItem::STATE_PAUSED_DL: - ++report.nb_paused; - case TorrentModelItem::STATE_STALLED_DL: - case TorrentModelItem::STATE_CHECKING_DL: - case TorrentModelItem::STATE_QUEUED_DL: { - ++report.nb_inactive; - ++report.nb_downloading; - break; - } - case TorrentModelItem::STATE_SEEDING: - ++report.nb_active; - ++report.nb_seeding; - break; - case TorrentModelItem::STATE_PAUSED_UP: - case TorrentModelItem::STATE_PAUSED_MISSING: - ++report.nb_paused; - case TorrentModelItem::STATE_STALLED_UP: - case TorrentModelItem::STATE_CHECKING_UP: - case TorrentModelItem::STATE_QUEUED_UP: { - ++report.nb_seeding; - ++report.nb_inactive; - break; + TorrentStatusReport report; + + QList::const_iterator it = m_torrents.constBegin(); + QList::const_iterator itend = m_torrents.constEnd(); + for ( ; it != itend; ++it) { + switch((*it)->state()) { + case TorrentModelItem::STATE_DOWNLOADING: + ++report.nb_active; + ++report.nb_downloading; + break; + case TorrentModelItem::STATE_DOWNLOADING_META: + ++report.nb_downloading; + break; + case TorrentModelItem::STATE_PAUSED_DL: + ++report.nb_paused; + case TorrentModelItem::STATE_STALLED_DL: + case TorrentModelItem::STATE_CHECKING_DL: + case TorrentModelItem::STATE_QUEUED_DL: { + ++report.nb_inactive; + ++report.nb_downloading; + break; + } + case TorrentModelItem::STATE_SEEDING: + ++report.nb_active; + ++report.nb_seeding; + break; + case TorrentModelItem::STATE_PAUSED_UP: + case TorrentModelItem::STATE_PAUSED_MISSING: + ++report.nb_paused; + case TorrentModelItem::STATE_STALLED_UP: + case TorrentModelItem::STATE_CHECKING_UP: + case TorrentModelItem::STATE_QUEUED_UP: { + ++report.nb_seeding; + ++report.nb_inactive; + break; + } + default: + break; + } } - default: - break; - } - } - return report; + return report; } Qt::ItemFlags TorrentModel::flags(const QModelIndex &index) const { - if (!index.isValid()) - return 0; - // Explicitely mark as editable - return QAbstractListModel::flags(index) | Qt::ItemIsEditable; + if (!index.isValid()) + return 0; + // Explicitely mark as editable + return QAbstractListModel::flags(index) | Qt::ItemIsEditable; } void TorrentModel::handleTorrentLabelChange(QString previous, QString current) { - emit torrentChangedLabel(static_cast(sender()), previous, current); + emit torrentChangedLabel(static_cast(sender()), previous, current); } QString TorrentModel::torrentHash(int row) const { - if (row >= 0 && row < rowCount()) - return m_torrents.at(row)->hash(); - return QString(); + if (row >= 0 && row < rowCount()) + return m_torrents.at(row)->hash(); + return QString(); } void TorrentModel::handleTorrentAboutToBeRemoved(const QTorrentHandle &h) { - const int row = torrentRow(h.hash()); - qDebug() << Q_FUNC_INFO << row; - if (row >= 0) { - emit torrentAboutToBeRemoved(m_torrents.at(row)); + const int row = torrentRow(h.hash()); + qDebug() << Q_FUNC_INFO << row; + if (row >= 0) { + emit torrentAboutToBeRemoved(m_torrents.at(row)); - beginRemoveTorrent(row); - delete m_torrents[row]; - m_torrents.removeAt(row); - endRemoveTorrent(); - } + beginRemoveTorrent(row); + delete m_torrents[row]; + m_torrents.removeAt(row); + endRemoveTorrent(); + } } void TorrentModel::stateUpdated(const std::vector &statuses) { - typedef std::vector statuses_t; + typedef std::vector statuses_t; - for (statuses_t::const_iterator i = statuses.begin(), end = statuses.end(); i != end; ++i) { - libtorrent::torrent_status const& status = *i; + for (statuses_t::const_iterator i = statuses.begin(), end = statuses.end(); i != end; ++i) { + libtorrent::torrent_status const& status = *i; - const int row = torrentRow(misc::toQString(status.info_hash)); - if (row >= 0) { - m_torrents[row]->refreshStatus(status); - notifyTorrentChanged(row); + const int row = torrentRow(misc::toQString(status.info_hash)); + if (row >= 0) { + m_torrents[row]->refreshStatus(status); + notifyTorrentChanged(row); + } } - } - emit modelRefreshed(); + emit modelRefreshed(); } bool TorrentModel::inhibitSystem() { - QList::const_iterator it = m_torrents.constBegin(); - QList::const_iterator itend = m_torrents.constEnd(); - for ( ; it != itend; ++it) { - switch((*it)->data(TorrentModelItem::TR_STATUS).toInt()) { - case TorrentModelItem::STATE_DOWNLOADING: - case TorrentModelItem::STATE_DOWNLOADING_META: - case TorrentModelItem::STATE_STALLED_DL: - case TorrentModelItem::STATE_SEEDING: - case TorrentModelItem::STATE_STALLED_UP: - return true; - default: - break; + QList::const_iterator it = m_torrents.constBegin(); + QList::const_iterator itend = m_torrents.constEnd(); + for ( ; it != itend; ++it) { + switch((*it)->data(TorrentModelItem::TR_STATUS).toInt()) { + case TorrentModelItem::STATE_DOWNLOADING: + case TorrentModelItem::STATE_DOWNLOADING_META: + case TorrentModelItem::STATE_STALLED_DL: + case TorrentModelItem::STATE_SEEDING: + case TorrentModelItem::STATE_STALLED_UP: + return true; + default: + break; + } } - } - return false; + return false; } diff --git a/src/core/qtlibtorrent/torrentmodel.h b/src/core/qtlibtorrent/torrentmodel.h index 5042537b8..d2d5a64c4 100644 --- a/src/core/qtlibtorrent/torrentmodel.h +++ b/src/core/qtlibtorrent/torrentmodel.h @@ -40,89 +40,89 @@ #include "qtorrenthandle.h" struct TorrentStatusReport { - TorrentStatusReport(): nb_downloading(0), nb_seeding(0), nb_active(0), nb_inactive(0), nb_paused(0) {} - uint nb_downloading; uint nb_seeding; uint nb_active; uint nb_inactive; uint nb_paused; + TorrentStatusReport(): nb_downloading(0), nb_seeding(0), nb_active(0), nb_inactive(0), nb_paused(0) {} + uint nb_downloading; uint nb_seeding; uint nb_active; uint nb_inactive; uint nb_paused; }; class TorrentModelItem : public QObject { -Q_OBJECT + Q_OBJECT public: - enum State {STATE_DOWNLOADING, STATE_DOWNLOADING_META, STATE_ALLOCATING, STATE_STALLED_DL, STATE_SEEDING, STATE_STALLED_UP, STATE_QUEUED_DL, STATE_QUEUED_UP, STATE_CHECKING_UP, STATE_CHECKING_DL, STATE_QUEUED_CHECK, STATE_QUEUED_FASTCHECK, STATE_PAUSED_DL, STATE_PAUSED_UP, STATE_PAUSED_MISSING, STATE_INVALID}; - enum Column {TR_NAME, TR_PRIORITY, TR_SIZE, TR_TOTAL_SIZE, TR_PROGRESS, TR_STATUS, TR_SEEDS, TR_PEERS, TR_DLSPEED, TR_UPSPEED, TR_ETA, TR_RATIO, TR_LABEL, TR_ADD_DATE, TR_SEED_DATE, TR_TRACKER, TR_DLLIMIT, TR_UPLIMIT, TR_AMOUNT_DOWNLOADED, TR_AMOUNT_UPLOADED, TR_AMOUNT_LEFT, TR_TIME_ELAPSED, TR_SAVE_PATH, TR_COMPLETED, TR_RATIO_LIMIT, TR_SEEN_COMPLETE_DATE, TR_LAST_ACTIVITY, NB_COLUMNS}; + enum State {STATE_DOWNLOADING, STATE_DOWNLOADING_META, STATE_ALLOCATING, STATE_STALLED_DL, STATE_SEEDING, STATE_STALLED_UP, STATE_QUEUED_DL, STATE_QUEUED_UP, STATE_CHECKING_UP, STATE_CHECKING_DL, STATE_QUEUED_CHECK, STATE_QUEUED_FASTCHECK, STATE_PAUSED_DL, STATE_PAUSED_UP, STATE_PAUSED_MISSING, STATE_INVALID}; + enum Column {TR_NAME, TR_PRIORITY, TR_SIZE, TR_TOTAL_SIZE, TR_PROGRESS, TR_STATUS, TR_SEEDS, TR_PEERS, TR_DLSPEED, TR_UPSPEED, TR_ETA, TR_RATIO, TR_LABEL, TR_ADD_DATE, TR_SEED_DATE, TR_TRACKER, TR_DLLIMIT, TR_UPLIMIT, TR_AMOUNT_DOWNLOADED, TR_AMOUNT_UPLOADED, TR_AMOUNT_LEFT, TR_TIME_ELAPSED, TR_SAVE_PATH, TR_COMPLETED, TR_RATIO_LIMIT, TR_SEEN_COMPLETE_DATE, TR_LAST_ACTIVITY, NB_COLUMNS}; public: - TorrentModelItem(const QTorrentHandle& h); - void refreshStatus(libtorrent::torrent_status const& status); - inline int columnCount() const { return NB_COLUMNS; } - QVariant data(int column, int role = Qt::DisplayRole) const; - bool setData(int column, const QVariant &value, int role = Qt::DisplayRole); - inline QString const& hash() const { return m_hash; } - State state() const; + TorrentModelItem(const QTorrentHandle& h); + void refreshStatus(libtorrent::torrent_status const& status); + inline int columnCount() const { return NB_COLUMNS; } + QVariant data(int column, int role = Qt::DisplayRole) const; + bool setData(int column, const QVariant &value, int role = Qt::DisplayRole); + inline QString const& hash() const { return m_hash; } + State state() const; signals: - void labelChanged(QString previous, QString current); + void labelChanged(QString previous, QString current); private: - static QIcon getIconByState(State state); - static QColor getColorByState(State state); + static QIcon getIconByState(State state); + static QColor getColorByState(State state); private: - QTorrentHandle m_torrent; - libtorrent::torrent_status m_lastStatus; - QDateTime m_addedTime; - QString m_label; - QString m_name; - QString m_hash; // Cached for safety reasons + QTorrentHandle m_torrent; + libtorrent::torrent_status m_lastStatus; + QDateTime m_addedTime; + QString m_label; + QString m_name; + QString m_hash; // Cached for safety reasons }; class TorrentModel : public QAbstractListModel { - Q_OBJECT - Q_DISABLE_COPY(TorrentModel) + Q_OBJECT + Q_DISABLE_COPY(TorrentModel) public: - explicit TorrentModel(QObject *parent = 0); - ~TorrentModel(); - inline int rowCount(const QModelIndex& index = QModelIndex()) const { Q_UNUSED(index); return m_torrents.size(); } - int columnCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return TorrentModelItem::NB_COLUMNS; } - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::DisplayRole); - QVariant headerData(int section, Qt::Orientation orientation, int role) const; - int torrentRow(const QString &hash) const; - QString torrentHash(int row) const; - void setRefreshInterval(int refreshInterval); - TorrentStatusReport getTorrentStatusReport() const; - Qt::ItemFlags flags(const QModelIndex &index) const; - void populate(); - bool inhibitSystem(); + explicit TorrentModel(QObject *parent = 0); + ~TorrentModel(); + inline int rowCount(const QModelIndex& index = QModelIndex()) const { Q_UNUSED(index); return m_torrents.size(); } + int columnCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return TorrentModelItem::NB_COLUMNS; } + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::DisplayRole); + QVariant headerData(int section, Qt::Orientation orientation, int role) const; + int torrentRow(const QString &hash) const; + QString torrentHash(int row) const; + void setRefreshInterval(int refreshInterval); + TorrentStatusReport getTorrentStatusReport() const; + Qt::ItemFlags flags(const QModelIndex &index) const; + void populate(); + bool inhibitSystem(); signals: - void torrentAdded(TorrentModelItem *torrentItem); - void torrentAboutToBeRemoved(TorrentModelItem *torrentItem); - void torrentChangedLabel(TorrentModelItem *torrentItem, QString previous, QString current); - void modelRefreshed(); + void torrentAdded(TorrentModelItem *torrentItem); + void torrentAboutToBeRemoved(TorrentModelItem *torrentItem); + void torrentChangedLabel(TorrentModelItem *torrentItem, QString previous, QString current); + void modelRefreshed(); private slots: - void addTorrent(const QTorrentHandle& h); - void handleTorrentUpdate(const QTorrentHandle &h); - void handleFinishedTorrent(const QTorrentHandle& h); - void notifyTorrentChanged(int row); - void forceModelRefresh(); - void handleTorrentLabelChange(QString previous, QString current); - void handleTorrentAboutToBeRemoved(const QTorrentHandle & h); - void stateUpdated(const std::vector &statuses); + void addTorrent(const QTorrentHandle& h); + void handleTorrentUpdate(const QTorrentHandle &h); + void handleFinishedTorrent(const QTorrentHandle& h); + void notifyTorrentChanged(int row); + void forceModelRefresh(); + void handleTorrentLabelChange(QString previous, QString current); + void handleTorrentAboutToBeRemoved(const QTorrentHandle & h); + void stateUpdated(const std::vector &statuses); private: - void beginInsertTorrent(int row); - void endInsertTorrent(); - void beginRemoveTorrent(int row); - void endRemoveTorrent(); + void beginInsertTorrent(int row); + void endInsertTorrent(); + void beginRemoveTorrent(int row); + void endRemoveTorrent(); private: - QList m_torrents; - int m_refreshInterval; - QTimer m_refreshTimer; + QList m_torrents; + int m_refreshInterval; + QTimer m_refreshTimer; }; #endif // TORRENTMODEL_H diff --git a/src/core/qtlibtorrent/torrentspeedmonitor.cpp b/src/core/qtlibtorrent/torrentspeedmonitor.cpp index 82e21c203..1cb821dde 100644 --- a/src/core/qtlibtorrent/torrentspeedmonitor.cpp +++ b/src/core/qtlibtorrent/torrentspeedmonitor.cpp @@ -38,88 +38,88 @@ using namespace libtorrent; namespace { - template struct Sample { +template struct Sample { Sample() - : download() - , upload() + : download() + , upload() {} Sample(T download, T upload) - : download(download) - , upload(upload) + : download(download) + , upload(upload) {} template explicit Sample(Sample other) - : download(static_cast(other.download)) - , upload(static_cast(other.upload)) + : download(static_cast(other.download)) + , upload(static_cast(other.upload)) {} T download; T upload; - }; +}; - template - Sample& operator+=(Sample& lhs, Sample const& rhs) { +template +Sample& operator+=(Sample& lhs, Sample const& rhs) { lhs.download += rhs.download; lhs.upload += rhs.upload; return lhs; - } +} - template - Sample& operator-=(Sample& lhs, Sample const& rhs) { +template +Sample& operator-=(Sample& lhs, Sample const& rhs) { lhs.download -= rhs.download; lhs.upload -= rhs.upload; return lhs; - } +} - template - Sample operator+(Sample const& lhs, Sample const& rhs) { +template +Sample operator+(Sample const& lhs, Sample const& rhs) { return Sample(lhs.download + rhs.download, lhs.upload + rhs.upload); - } +} - template - Sample operator-(Sample const& lhs, Sample const& rhs) { +template +Sample operator-(Sample const& lhs, Sample const& rhs) { return Sample(lhs.download - rhs.download, lhs.upload - rhs.upload); - } +} - template - Sample operator*(Sample const& lhs, T rhs) { +template +Sample operator*(Sample const& lhs, T rhs) { return Sample(lhs.download * rhs, lhs.upload * rhs); - } +} - template - Sample operator*(T lhs,Sample const& rhs) { +template +Sample operator*(T lhs,Sample const& rhs) { return Sample(lhs * rhs.download, lhs * rhs.upload); - } +} - template - Sample operator/(Sample const& lhs, T rhs) { +template +Sample operator/(Sample const& lhs, T rhs) { return Sample(lhs.download / rhs, lhs.upload / rhs); - } +} } class SpeedSample { public: - SpeedSample() {} - void addSample(Sample const& item); - Sample average() const; + SpeedSample() {} + void addSample(Sample const& item); + Sample average() const; private: - static const int max_samples = 30; + static const int max_samples = 30; private: - QList > m_speedSamples; - Sample m_sum; + QList > m_speedSamples; + Sample m_sum; }; TorrentSpeedMonitor::TorrentSpeedMonitor(QBtSession* session) - : m_session(session) + : m_session(session) { - connect(m_session, SIGNAL(torrentAboutToBeRemoved(QTorrentHandle)), SLOT(removeSamples(QTorrentHandle))); - connect(m_session, SIGNAL(pausedTorrent(QTorrentHandle)), SLOT(removeSamples(QTorrentHandle))); - connect(m_session, SIGNAL(statsReceived(libtorrent::stats_alert)), SLOT(statsReceived(libtorrent::stats_alert))); + connect(m_session, SIGNAL(torrentAboutToBeRemoved(QTorrentHandle)), SLOT(removeSamples(QTorrentHandle))); + connect(m_session, SIGNAL(pausedTorrent(QTorrentHandle)), SLOT(removeSamples(QTorrentHandle))); + connect(m_session, SIGNAL(statsReceived(libtorrent::stats_alert)), SLOT(statsReceived(libtorrent::stats_alert))); } TorrentSpeedMonitor::~TorrentSpeedMonitor() @@ -127,69 +127,69 @@ TorrentSpeedMonitor::~TorrentSpeedMonitor() void SpeedSample::addSample(Sample const& item) { - m_speedSamples.push_back(item); - m_sum += Sample(item); - if (m_speedSamples.size() > max_samples) { - m_sum -= Sample(m_speedSamples.front()); - m_speedSamples.pop_front(); - } + m_speedSamples.push_back(item); + m_sum += Sample(item); + if (m_speedSamples.size() > max_samples) { + m_sum -= Sample(m_speedSamples.front()); + m_speedSamples.pop_front(); + } } Sample SpeedSample::average() const { - if (m_speedSamples.empty()) - return Sample(); + if (m_speedSamples.empty()) + return Sample(); - return Sample(m_sum) * (qreal(1.) / m_speedSamples.size()); + return Sample(m_sum) * (qreal(1.) / m_speedSamples.size()); } void TorrentSpeedMonitor::removeSamples(const QTorrentHandle& h) { - try { - m_samples.remove(h.hash()); - } catch(invalid_handle&) {} + try { + m_samples.remove(h.hash()); + } catch(invalid_handle&) {} } qlonglong TorrentSpeedMonitor::getETA(const QString &hash, const libtorrent::torrent_status &status) const { - if (QTorrentHandle::is_paused(status)) - return MAX_ETA; + if (QTorrentHandle::is_paused(status)) + return MAX_ETA; - QHash::const_iterator i = m_samples.find(hash); - if (i == m_samples.end()) - return MAX_ETA; + QHash::const_iterator i = m_samples.find(hash); + if (i == m_samples.end()) + return MAX_ETA; - const Sample speed_average = i->average(); + const Sample speed_average = i->average(); - if (QTorrentHandle::is_seed(status)) { - if (!speed_average.upload) - return MAX_ETA; + if (QTorrentHandle::is_seed(status)) { + if (!speed_average.upload) + return MAX_ETA; - bool _unused; - qreal max_ratio = m_session->getMaxRatioPerTorrent(hash, &_unused); - if (max_ratio < 0) - return MAX_ETA; + bool _unused; + qreal max_ratio = m_session->getMaxRatioPerTorrent(hash, &_unused); + if (max_ratio < 0) + return MAX_ETA; - libtorrent::size_type realDL = status.all_time_download; - if (realDL <= 0) - realDL = status.total_wanted; + libtorrent::size_type realDL = status.all_time_download; + if (realDL <= 0) + realDL = status.total_wanted; - return (realDL * max_ratio - status.all_time_upload) / speed_average.upload; - } + return (realDL * max_ratio - status.all_time_upload) / speed_average.upload; + } - if (!speed_average.download) - return MAX_ETA; + if (!speed_average.download) + return MAX_ETA; - return (status.total_wanted - status.total_wanted_done) / speed_average.download; + return (status.total_wanted - status.total_wanted_done) / speed_average.download; } void TorrentSpeedMonitor::statsReceived(const stats_alert &stats) { - Q_ASSERT(stats.interval >= 1000); + Q_ASSERT(stats.interval >= 1000); - Sample transferred(stats.transferred[stats_alert::download_payload], - stats.transferred[stats_alert::upload_payload]); + Sample transferred(stats.transferred[stats_alert::download_payload], + stats.transferred[stats_alert::upload_payload]); - Sample normalized = Sample(Sample(transferred) * 1000LL / static_cast(stats.interval)); + Sample normalized = Sample(Sample(transferred) * 1000LL / static_cast(stats.interval)); - m_samples[misc::toQString(stats.handle.info_hash())].addSample(normalized); + m_samples[misc::toQString(stats.handle.info_hash())].addSample(normalized); } diff --git a/src/core/qtlibtorrent/torrentspeedmonitor.h b/src/core/qtlibtorrent/torrentspeedmonitor.h index 473a4bdd5..cd0c69a92 100644 --- a/src/core/qtlibtorrent/torrentspeedmonitor.h +++ b/src/core/qtlibtorrent/torrentspeedmonitor.h @@ -42,21 +42,21 @@ class SpeedSample; class TorrentSpeedMonitor : public QObject { - Q_OBJECT - Q_DISABLE_COPY(TorrentSpeedMonitor) + Q_OBJECT + Q_DISABLE_COPY(TorrentSpeedMonitor) public: - explicit TorrentSpeedMonitor(QBtSession* session); - ~TorrentSpeedMonitor(); - qlonglong getETA(const QString &hash, const libtorrent::torrent_status &status) const; + explicit TorrentSpeedMonitor(QBtSession* session); + ~TorrentSpeedMonitor(); + qlonglong getETA(const QString &hash, const libtorrent::torrent_status &status) const; private slots: - void statsReceived(const libtorrent::stats_alert& stats); - void removeSamples(const QTorrentHandle& h); + void statsReceived(const libtorrent::stats_alert& stats); + void removeSamples(const QTorrentHandle& h); private: - QHash m_samples; - QBtSession *m_session; + QHash m_samples; + QBtSession *m_session; }; #endif // TORRENTSPEEDMONITOR_H diff --git a/src/core/qtlibtorrent/torrentstatistics.cpp b/src/core/qtlibtorrent/torrentstatistics.cpp index cf8577bb9..b143d6ccf 100644 --- a/src/core/qtlibtorrent/torrentstatistics.cpp +++ b/src/core/qtlibtorrent/torrentstatistics.cpp @@ -9,92 +9,92 @@ #include "preferences.h" TorrentStatistics::TorrentStatistics(QBtSession* session, QObject* parent) - : QObject(parent) - , m_session(session) - , m_sessionUL(0) - , m_sessionDL(0) - , m_lastWrite(0) - , m_dirty(false) + : QObject(parent) + , m_session(session) + , m_sessionUL(0) + , m_sessionDL(0) + , m_lastWrite(0) + , m_dirty(false) { - loadStats(); - connect(&m_timer, SIGNAL(timeout()), this, SLOT(gatherStats())); - m_timer.start(60 * 1000); + loadStats(); + connect(&m_timer, SIGNAL(timeout()), this, SLOT(gatherStats())); + m_timer.start(60 * 1000); } TorrentStatistics::~TorrentStatistics() { - if (m_dirty) - m_lastWrite = 0; - saveStats(); + if (m_dirty) + m_lastWrite = 0; + saveStats(); } quint64 TorrentStatistics::getAlltimeDL() const { - return m_alltimeDL + m_sessionDL; + return m_alltimeDL + m_sessionDL; } quint64 TorrentStatistics::getAlltimeUL() const { - return m_alltimeUL + m_sessionUL; + return m_alltimeUL + m_sessionUL; } void TorrentStatistics::gatherStats() { - libtorrent::session_status ss = m_session->getSessionStatus(); - if (ss.total_download > m_sessionDL) { - m_sessionDL = ss.total_download; - m_dirty = true; - } - if (ss.total_upload > m_sessionUL) { - m_sessionUL = ss.total_upload; - m_dirty = true; - } + libtorrent::session_status ss = m_session->getSessionStatus(); + if (ss.total_download > m_sessionDL) { + m_sessionDL = ss.total_download; + m_dirty = true; + } + if (ss.total_upload > m_sessionUL) { + m_sessionUL = ss.total_upload; + m_dirty = true; + } - saveStats(); + saveStats(); } void TorrentStatistics::saveStats() const { - if (!(m_dirty && (QDateTime::currentMSecsSinceEpoch() - m_lastWrite >= 15*60*1000) )) - return; - QIniSettings s("qBittorrent", "qBittorrent-data"); - QVariantHash v; - v.insert("AlltimeDL", m_alltimeDL + m_sessionDL); - v.insert("AlltimeUL", m_alltimeUL + m_sessionUL); - s.setValue("Stats/AllStats", v); - m_dirty = false; - m_lastWrite = QDateTime::currentMSecsSinceEpoch(); + if (!(m_dirty && (QDateTime::currentMSecsSinceEpoch() - m_lastWrite >= 15*60*1000) )) + return; + QIniSettings s("qBittorrent", "qBittorrent-data"); + QVariantHash v; + v.insert("AlltimeDL", m_alltimeDL + m_sessionDL); + v.insert("AlltimeUL", m_alltimeUL + m_sessionUL); + s.setValue("Stats/AllStats", v); + m_dirty = false; + m_lastWrite = QDateTime::currentMSecsSinceEpoch(); } void TorrentStatistics::loadStats() { - // Temp code. Versions v3.1.4 and v3.1.5 saved the data in the qbittorrent.ini file. - // This code reads the data from there, writes it to the new file, and removes the keys - // from the old file. This code should be removed after some time has passed. - // e.g. When we reach v3.3.0 - // Don't forget to remove: - // 1. Preferences::getStats() - // 2. Preferences::removeStats() - // 3. #include "preferences.h" - Preferences* const pref = Preferences::instance(); - QIniSettings s("qBittorrent", "qBittorrent-data"); - QVariantHash v = pref->getStats(); + // Temp code. Versions v3.1.4 and v3.1.5 saved the data in the qbittorrent.ini file. + // This code reads the data from there, writes it to the new file, and removes the keys + // from the old file. This code should be removed after some time has passed. + // e.g. When we reach v3.3.0 + // Don't forget to remove: + // 1. Preferences::getStats() + // 2. Preferences::removeStats() + // 3. #include "preferences.h" + Preferences* const pref = Preferences::instance(); + QIniSettings s("qBittorrent", "qBittorrent-data"); + QVariantHash v = pref->getStats(); - // Let's test if the qbittorrent.ini holds the key - if (!v.isEmpty()) { - m_dirty = true; + // Let's test if the qbittorrent.ini holds the key + if (!v.isEmpty()) { + m_dirty = true; - // If the user has used qbt > 3.1.5 and then reinstalled/used - // qbt < 3.1.6, there will be stats in qbittorrent-data.ini too - // so we need to merge those 2. - if (s.contains("Stats/AllStats")) { - QVariantHash tmp = s.value("Stats/AllStats").toHash(); - v["AlltimeDL"] = v["AlltimeDL"].toULongLong() + tmp["AlltimeDL"].toULongLong(); - v["AlltimeUL"] = v["AlltimeUL"].toULongLong() + tmp["AlltimeUL"].toULongLong(); + // If the user has used qbt > 3.1.5 and then reinstalled/used + // qbt < 3.1.6, there will be stats in qbittorrent-data.ini too + // so we need to merge those 2. + if (s.contains("Stats/AllStats")) { + QVariantHash tmp = s.value("Stats/AllStats").toHash(); + v["AlltimeDL"] = v["AlltimeDL"].toULongLong() + tmp["AlltimeDL"].toULongLong(); + v["AlltimeUL"] = v["AlltimeUL"].toULongLong() + tmp["AlltimeUL"].toULongLong(); + } } - } - else - v = s.value("Stats/AllStats").toHash(); + else + v = s.value("Stats/AllStats").toHash(); - m_alltimeDL = v["AlltimeDL"].toULongLong(); - m_alltimeUL = v["AlltimeUL"].toULongLong(); + m_alltimeDL = v["AlltimeDL"].toULongLong(); + m_alltimeUL = v["AlltimeUL"].toULongLong(); - if (m_dirty) { - saveStats(); - pref->removeStats(); - } + if (m_dirty) { + saveStats(); + pref->removeStats(); + } } diff --git a/src/core/qtlibtorrent/torrentstatistics.h b/src/core/qtlibtorrent/torrentstatistics.h index 0c38fa857..76751241f 100644 --- a/src/core/qtlibtorrent/torrentstatistics.h +++ b/src/core/qtlibtorrent/torrentstatistics.h @@ -8,34 +8,34 @@ class QBtSession; class TorrentStatistics : QObject { - Q_OBJECT - Q_DISABLE_COPY(TorrentStatistics) + Q_OBJECT + Q_DISABLE_COPY(TorrentStatistics) public: - TorrentStatistics(QBtSession* session, QObject* parent = 0); - ~TorrentStatistics(); + TorrentStatistics(QBtSession* session, QObject* parent = 0); + ~TorrentStatistics(); - quint64 getAlltimeDL() const; - quint64 getAlltimeUL() const; + quint64 getAlltimeDL() const; + quint64 getAlltimeUL() const; private slots: - void gatherStats(); + void gatherStats(); private: - void saveStats() const; - void loadStats(); + void saveStats() const; + void loadStats(); private: - QBtSession* m_session; - // Will overflow at 15.9 EiB - quint64 m_alltimeUL; - quint64 m_alltimeDL; - qint64 m_sessionUL; - qint64 m_sessionDL; - mutable qint64 m_lastWrite; - mutable bool m_dirty; - - QTimer m_timer; + QBtSession* m_session; + // Will overflow at 15.9 EiB + quint64 m_alltimeUL; + quint64 m_alltimeDL; + qint64 m_sessionUL; + qint64 m_sessionDL; + mutable qint64 m_lastWrite; + mutable bool m_dirty; + + QTimer m_timer; }; #endif // TORRENTSTATISTICS_H diff --git a/src/core/qtlibtorrent/trackerinfos.h b/src/core/qtlibtorrent/trackerinfos.h index 5fe5be2b7..f222e5a2e 100644 --- a/src/core/qtlibtorrent/trackerinfos.h +++ b/src/core/qtlibtorrent/trackerinfos.h @@ -35,25 +35,25 @@ class TrackerInfos { public: - QString name_or_url; - QString last_message; - unsigned long num_peers; + QString name_or_url; + QString last_message; + unsigned long num_peers; - //TrackerInfos() {} - TrackerInfos(const TrackerInfos &b) - : name_or_url(b.name_or_url) - , last_message(b.last_message) - , num_peers(b.num_peers) - { - Q_ASSERT(!name_or_url.isEmpty()); - } + //TrackerInfos() {} + TrackerInfos(const TrackerInfos &b) + : name_or_url(b.name_or_url) + , last_message(b.last_message) + , num_peers(b.num_peers) + { + Q_ASSERT(!name_or_url.isEmpty()); + } - TrackerInfos(QString name_or_url) - : name_or_url(name_or_url) - , last_message("") - , num_peers(0) - { - } + TrackerInfos(QString name_or_url) + : name_or_url(name_or_url) + , last_message("") + , num_peers(0) + { + } }; #endif // TRACKERINFOS_H