Remove unused sources.

This commit is contained in:
Vladimir Golovnev (Glassez)
2015-05-06 14:53:16 +03:00
parent d16d1fdb3a
commit 427688cb34
16 changed files with 0 additions and 1750 deletions

View File

@@ -1,341 +0,0 @@
/*
* Bittorrent Client using Qt4 and libtorrent.
* Copyright (C) 2006 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org
*/
#include <QTemporaryFile>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkProxy>
#include <QNetworkCookieJar>
#include <QDebug>
#include "downloadthread.h"
#include "preferences.h"
#include "qinisettings.h"
#include "fs_utils.h"
#include <zlib.h>
/** Download Thread **/
DownloadThread::DownloadThread(QObject* parent)
: QObject(parent)
{
connect(&m_networkManager, SIGNAL(finished (QNetworkReply*)), this, SLOT(processDlFinished(QNetworkReply*)));
#ifndef QT_NO_OPENSSL
connect(&m_networkManager, SIGNAL(sslErrors(QNetworkReply*, QList<QSslError>)), this, SLOT(ignoreSslErrors(QNetworkReply*, QList<QSslError>)));
#endif
}
QByteArray DownloadThread::gUncompress(Bytef *inData, size_t len)
{
if (len <= 4) {
qWarning("gUncompress: Input data is truncated");
return QByteArray();
}
QByteArray result;
z_stream strm;
static const int CHUNK_SIZE = 1024;
char out[CHUNK_SIZE];
/* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = len;
strm.next_in = inData;
const int windowBits = 15;
const int ENABLE_ZLIB_GZIP = 32;
int ret = inflateInit2(&strm, windowBits | ENABLE_ZLIB_GZIP); // gzip decoding
if (ret != Z_OK)
return QByteArray();
// run inflate()
do {
strm.avail_out = CHUNK_SIZE;
strm.next_out = reinterpret_cast<unsigned char*>(out);
ret = inflate(&strm, Z_NO_FLUSH);
Q_ASSERT(ret != Z_STREAM_ERROR); // state not clobbered
switch (ret) {
case Z_NEED_DICT:
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void) inflateEnd(&strm);
return QByteArray();
}
result.append(out, CHUNK_SIZE - strm.avail_out);
}
while (!strm.avail_out);
// clean up and return
inflateEnd(&strm);
return result;
}
void DownloadThread::processDlFinished(QNetworkReply *reply)
{
QString url = reply->url().toString();
qDebug("Download finished: %s", qPrintable(url));
// Check if the request was successful
if (reply->error() != QNetworkReply::NoError) {
// Failure
qDebug("Download failure (%s), reason: %s", qPrintable(url), qPrintable(errorCodeToString(reply->error())));
emit downloadFailure(url, errorCodeToString(reply->error()));
reply->deleteLater();
return;
}
// Check if the server ask us to redirect somewhere else
const QVariant redirection = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (redirection.isValid()) {
// We should redirect
QUrl newUrl = redirection.toUrl();
// Resolve relative urls
if (newUrl.isRelative())
newUrl = reply->url().resolved(newUrl);
const QString newUrlString = newUrl.toString();
qDebug("Redirecting from %s to %s", qPrintable(url), qPrintable(newUrlString));
// Redirect to magnet workaround
if (newUrlString.startsWith("magnet:", Qt::CaseInsensitive)) {
qDebug("Magnet redirect detected.");
reply->abort();
emit magnetRedirect(newUrlString, url);
reply->deleteLater();
return;
}
m_redirectMapping.insert(newUrlString, url);
// redirecting with first cookies
downloadUrl(newUrlString, m_networkManager.cookieJar()->cookiesForUrl(url));
reply->deleteLater();
return;
}
// Checking if it was redirected, restoring initial URL
if (m_redirectMapping.contains(url))
url = m_redirectMapping.take(url);
// Success
QTemporaryFile *tmpfile = new QTemporaryFile;
if (tmpfile->open()) {
tmpfile->setAutoRemove(false);
QString filePath = tmpfile->fileName();
qDebug("Temporary filename is: %s", qPrintable(filePath));
if (reply->isOpen() || reply->open(QIODevice::ReadOnly)) {
QByteArray replyData = reply->readAll();
if (reply->rawHeader("Content-Encoding") == "gzip") {
// uncompress gzip reply
replyData = gUncompress(reinterpret_cast<unsigned char*>(replyData.data()), replyData.length());
}
tmpfile->write(replyData);
tmpfile->close();
// XXX: tmpfile needs to be deleted on Windows before using the file
// or it will complain that the file is used by another process.
delete tmpfile;
// Send finished signal
emit downloadFinished(url, filePath);
}
else {
delete tmpfile;
fsutils::forceRemove(filePath);
// Error when reading the request
emit downloadFailure(url, tr("I/O Error"));
}
}
else {
delete tmpfile;
emit downloadFailure(url, tr("I/O Error"));
}
// Clean up
reply->deleteLater();
}
void DownloadThread::downloadTorrentUrl(const QString &url, const QList<QNetworkCookie> &cookies)
{
// Process request
QNetworkReply *reply = downloadUrl(url, cookies);
connect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(checkDownloadSize(qint64, qint64)));
}
QNetworkReply *DownloadThread::downloadUrl(const QString &url, const QList<QNetworkCookie> &cookies)
{
// Update proxy settings
applyProxySettings();
// Set cookies
if (!cookies.empty()) {
qDebug("Setting %d cookies for url: %s", cookies.size(), qPrintable(url));
m_networkManager.cookieJar()->setCookiesFromUrl(cookies, url);
}
// Process download request
qDebug("url is %s", qPrintable(url));
const QUrl qurl = QUrl::fromEncoded(url.toUtf8());
QNetworkRequest request(qurl);
// Spoof Firefox 3.5 user agent to avoid
// Web server banning
request.setRawHeader("User-Agent", "Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5");
qDebug("Downloading %s...", request.url().toEncoded().data());
qDebug("%d cookies for this URL", m_networkManager.cookieJar()->cookiesForUrl(url).size());
for (int i = 0; i < m_networkManager.cookieJar()->cookiesForUrl(url).size(); ++i) {
qDebug("%s=%s", m_networkManager.cookieJar()->cookiesForUrl(url).at(i).name().data(), m_networkManager.cookieJar()->cookiesForUrl(url).at(i).value().data());
qDebug("Domain: %s, Path: %s", qPrintable(m_networkManager.cookieJar()->cookiesForUrl(url).at(i).domain()), qPrintable(m_networkManager.cookieJar()->cookiesForUrl(url).at(i).path()));
}
// accept gzip
request.setRawHeader("Accept-Encoding", "gzip");
return m_networkManager.get(request);
}
void DownloadThread::checkDownloadSize(qint64 bytesReceived, qint64 bytesTotal)
{
QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
if (!reply) return;
if (bytesTotal > 0) {
// Total number of bytes is available
if (bytesTotal > 10485760) {
// More than 10MB, this is probably not a torrent file, aborting...
reply->abort();
reply->deleteLater();
}
else {
disconnect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(checkDownloadSize(qint64, qint64)));
}
}
else {
if (bytesReceived > 10485760) {
// More than 10MB, this is probably not a torrent file, aborting...
reply->abort();
reply->deleteLater();
}
}
}
void DownloadThread::applyProxySettings()
{
QNetworkProxy proxy;
const Preferences* const pref = Preferences::instance();
if (pref->isProxyEnabled()) {
// Proxy enabled
proxy.setHostName(pref->getProxyIp());
proxy.setPort(pref->getProxyPort());
// Default proxy type is HTTP, we must change if it is SOCKS5
const int proxyType = pref->getProxyType();
if ((proxyType == Proxy::SOCKS5) || (proxyType == Proxy::SOCKS5_PW)) {
qDebug() << Q_FUNC_INFO << "using SOCKS proxy";
proxy.setType(QNetworkProxy::Socks5Proxy);
}
else {
qDebug() << Q_FUNC_INFO << "using HTTP proxy";
proxy.setType(QNetworkProxy::HttpProxy);
}
// Authentication?
if (pref->isProxyAuthEnabled()) {
qDebug("Proxy requires authentication, authenticating");
proxy.setUser(pref->getProxyUsername());
proxy.setPassword(pref->getProxyPassword());
}
}
else {
proxy.setType(QNetworkProxy::NoProxy);
}
m_networkManager.setProxy(proxy);
}
QString DownloadThread::errorCodeToString(QNetworkReply::NetworkError status)
{
switch(status) {
case QNetworkReply::HostNotFoundError:
return tr("The remote host name was not found (invalid hostname)");
case QNetworkReply::OperationCanceledError:
return tr("The operation was canceled");
case QNetworkReply::RemoteHostClosedError:
return tr("The remote server closed the connection prematurely, before the entire reply was received and processed");
case QNetworkReply::TimeoutError:
return tr("The connection to the remote server timed out");
case QNetworkReply::SslHandshakeFailedError:
return tr("SSL/TLS handshake failed");
case QNetworkReply::ConnectionRefusedError:
return tr("The remote server refused the connection");
case QNetworkReply::ProxyConnectionRefusedError:
return tr("The connection to the proxy server was refused");
case QNetworkReply::ProxyConnectionClosedError:
return tr("The proxy server closed the connection prematurely");
case QNetworkReply::ProxyNotFoundError:
return tr("The proxy host name was not found");
case QNetworkReply::ProxyTimeoutError:
return tr("The connection to the proxy timed out or the proxy did not reply in time to the request sent");
case QNetworkReply::ProxyAuthenticationRequiredError:
return tr("The proxy requires authentication in order to honour the request but did not accept any credentials offered");
case QNetworkReply::ContentAccessDenied:
return tr("The access to the remote content was denied (401)");
case QNetworkReply::ContentOperationNotPermittedError:
return tr("The operation requested on the remote content is not permitted");
case QNetworkReply::ContentNotFoundError:
return tr("The remote content was not found at the server (404)");
case QNetworkReply::AuthenticationRequiredError:
return tr("The remote server requires authentication to serve the content but the credentials provided were not accepted");
case QNetworkReply::ProtocolUnknownError:
return tr("The Network Access API cannot honor the request because the protocol is not known");
case QNetworkReply::ProtocolInvalidOperationError:
return tr("The requested operation is invalid for this protocol");
case QNetworkReply::UnknownNetworkError:
return tr("An unknown network-related error was detected");
case QNetworkReply::UnknownProxyError:
return tr("An unknown proxy-related error was detected");
case QNetworkReply::UnknownContentError:
return tr("An unknown error related to the remote content was detected");
case QNetworkReply::ProtocolFailure:
return tr("A breakdown in protocol was detected");
default:
return tr("Unknown error");
}
}
#ifndef QT_NO_OPENSSL
void DownloadThread::ignoreSslErrors(QNetworkReply *reply, const QList<QSslError> &errors)
{
Q_UNUSED(errors)
// Ignore all SSL errors
reply->ignoreSslErrors();
}
#endif

View File

@@ -1,76 +0,0 @@
/*
* Bittorrent Client using Qt4 and libtorrent.
* Copyright (C) 2006 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org
*/
#ifndef DOWNLOADTHREAD_H
#define DOWNLOADTHREAD_H
#include <QNetworkReply>
#include <QNetworkCookie>
#include <QObject>
#include <QHash>
#include <QSslError>
#include <zlib.h>
QT_BEGIN_NAMESPACE
class QNetworkAccessManager;
QT_END_NAMESPACE
class DownloadThread : public QObject
{
Q_OBJECT
public:
DownloadThread(QObject *parent = 0);
QNetworkReply *downloadUrl(const QString &url, const QList<QNetworkCookie> &cookies = QList<QNetworkCookie>());
void downloadTorrentUrl(const QString &url, const QList<QNetworkCookie> &cookies = QList<QNetworkCookie>());
signals:
void downloadFinished(const QString &url, const QString &file_path);
void downloadFailure(const QString &url, const QString &reason);
void magnetRedirect(const QString &url_new, const QString &url_old);
private slots:
void processDlFinished(QNetworkReply *reply);
void checkDownloadSize(qint64 bytesReceived, qint64 bytesTotal);
#ifndef QT_NO_OPENSSL
void ignoreSslErrors(QNetworkReply *,const QList<QSslError> &);
#endif
private:
static QByteArray gUncompress(Bytef *inData, size_t len);
QString errorCodeToString(QNetworkReply::NetworkError status);
void applyProxySettings();
QNetworkAccessManager m_networkManager;
QHash<QString, QString> m_redirectMapping;
};
#endif

View File

@@ -1,135 +0,0 @@
/*
* Bittorrent Client using Qt4 and libtorrent.
* Copyright (C) 2014 Ivan Sorokin
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : vanyacpp@gmail.com
*/
#include "alertdispatcher.h"
#include <libtorrent/session.hpp>
#include <boost/bind.hpp>
#include <QMutexLocker>
const size_t DEFAULT_ALERTS_CAPACITY = 32;
struct QAlertDispatcher::Tag {
Tag(QAlertDispatcher* dispatcher);
QAlertDispatcher* dispatcher;
QMutex alerts_mutex;
};
QAlertDispatcher::Tag::Tag(QAlertDispatcher* dispatcher)
: dispatcher(dispatcher)
{}
QAlertDispatcher::QAlertDispatcher(libtorrent::session *session, QObject* parent)
: 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));
}
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(&current_tag->alerts_mutex);
current_tag->dispatcher = 0;
current_tag.clear();
}
typedef boost::function<void (std::auto_ptr<libtorrent::alert>)> dispatch_function_t;
m_session->set_alert_dispatch(dispatch_function_t());
}
void QAlertDispatcher::getPendingAlertsNoWait(std::vector<libtorrent::alert*>& out) {
Q_ASSERT(out.empty());
out.reserve(DEFAULT_ALERTS_CAPACITY);
QMutexLocker lock(&current_tag->alerts_mutex);
alerts.swap(out);
event_posted = false;
}
void QAlertDispatcher::getPendingAlerts(std::vector<libtorrent::alert*>& out, unsigned long time) {
Q_ASSERT(out.empty());
out.reserve(DEFAULT_ALERTS_CAPACITY);
QMutexLocker lock(&current_tag->alerts_mutex);
while (alerts.empty())
alerts_condvar.wait(&current_tag->alerts_mutex, time);
alerts.swap(out);
event_posted = false;
}
void QAlertDispatcher::dispatch(QSharedPointer<Tag> tag,
std::auto_ptr<libtorrent::alert> alert_ptr) {
QMutexLocker lock(&(tag->alerts_mutex));
QAlertDispatcher* that = tag->dispatcher;
if (!that)
return;
bool was_empty = that->alerts.empty();
that->alerts.push_back(alert_ptr.get());
alert_ptr.release();
if (was_empty)
that->alerts_condvar.wakeAll();
that->enqueueToMainThread();
Q_ASSERT(that->current_tag == tag);
}
void QAlertDispatcher::enqueueToMainThread() {
if (!event_posted) {
event_posted = true;
QMetaObject::invokeMethod(this, "deliverSignal", Qt::QueuedConnection);
}
}
void QAlertDispatcher::deliverSignal() {
emit alertsReceived();
QMutexLocker lock(&current_tag->alerts_mutex);
event_posted = false;
if (!alerts.empty())
enqueueToMainThread();
}

View File

@@ -1,80 +0,0 @@
/*
* Bittorrent Client using Qt4 and libtorrent.
* Copyright (C) 2014 Ivan Sorokin
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : vanyacpp@gmail.com
*/
#ifndef ALERTDISPATCHER_H
#define ALERTDISPATCHER_H
#include <QObject>
#include <QMutex>
#include <QWaitCondition>
#include <QAtomicPointer>
#include <QSharedPointer>
#include <vector>
#include <memory>
namespace libtorrent {
class session;
class alert;
}
class QAlertDispatcher : public QObject {
Q_OBJECT
Q_DISABLE_COPY(QAlertDispatcher)
struct Tag;
public:
QAlertDispatcher(libtorrent::session *session, QObject* parent);
~QAlertDispatcher();
void getPendingAlertsNoWait(std::vector<libtorrent::alert*>&);
void getPendingAlerts(std::vector<libtorrent::alert*>&, unsigned long time = ULONG_MAX);
signals:
void alertsReceived();
private:
static void dispatch(QSharedPointer<Tag>,
std::auto_ptr<libtorrent::alert>);
void enqueueToMainThread();
private slots:
void deliverSignal();
private:
libtorrent::session *m_session;
QWaitCondition alerts_condvar;
std::vector<libtorrent::alert*> alerts;
QSharedPointer<Tag> current_tag;
bool event_posted;
};
#endif // ALERTDISPATCHER_H

View File

@@ -1,195 +0,0 @@
/*
* Bittorrent Client using Qt4 and libtorrent.
* Copyright (C) 2011 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org
*/
#include <QList>
#include "qbtsession.h"
#include "core/misc.h"
#include "torrentspeedmonitor.h"
using namespace libtorrent;
namespace {
template<class T> struct Sample {
Sample()
: download()
, upload()
{}
Sample(T download, T upload)
: download(download)
, upload(upload)
{}
template <typename U>
explicit Sample(Sample<U> other)
: download(static_cast<U>(other.download))
, upload(static_cast<U>(other.upload))
{}
T download;
T upload;
};
template <typename T>
Sample<T>& operator+=(Sample<T>& lhs, Sample<T> const& rhs) {
lhs.download += rhs.download;
lhs.upload += rhs.upload;
return lhs;
}
template <typename T>
Sample<T>& operator-=(Sample<T>& lhs, Sample<T> const& rhs) {
lhs.download -= rhs.download;
lhs.upload -= rhs.upload;
return lhs;
}
template <typename T>
Sample<T> operator+(Sample<T> const& lhs, Sample<T> const& rhs) {
return Sample<T>(lhs.download + rhs.download, lhs.upload + rhs.upload);
}
template <typename T>
Sample<T> operator-(Sample<T> const& lhs, Sample<T> const& rhs) {
return Sample<T>(lhs.download - rhs.download, lhs.upload - rhs.upload);
}
template <typename T>
Sample<T> operator*(Sample<T> const& lhs, T rhs) {
return Sample<T>(lhs.download * rhs, lhs.upload * rhs);
}
template <typename T>
Sample<T> operator*(T lhs,Sample<T> const& rhs) {
return Sample<T>(lhs * rhs.download, lhs * rhs.upload);
}
template <typename T>
Sample<T> operator/(Sample<T> const& lhs, T rhs) {
return Sample<T>(lhs.download / rhs, lhs.upload / rhs);
}
}
class SpeedSample {
public:
SpeedSample() {}
void addSample(Sample<int> const& item);
Sample<qreal> average() const;
private:
static const int max_samples = 30;
private:
QList<Sample<int> > m_speedSamples;
Sample<long long> m_sum;
};
TorrentSpeedMonitor::TorrentSpeedMonitor(QBtSession* 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)));
}
TorrentSpeedMonitor::~TorrentSpeedMonitor()
{}
void SpeedSample::addSample(Sample<int> const& item)
{
m_speedSamples.push_back(item);
m_sum += Sample<long long>(item);
if (m_speedSamples.size() > max_samples) {
m_sum -= Sample<long long>(m_speedSamples.front());
m_speedSamples.pop_front();
}
}
Sample<qreal> SpeedSample::average() const
{
if (m_speedSamples.empty())
return Sample<qreal>();
return Sample<qreal>(m_sum) * (qreal(1.) / m_speedSamples.size());
}
void TorrentSpeedMonitor::removeSamples(const QTorrentHandle& h) {
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;
QHash<QString, SpeedSample>::const_iterator i = m_samples.find(hash);
if (i == m_samples.end())
return MAX_ETA;
const Sample<qreal> speed_average = i->average();
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;
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;
}
if (!speed_average.download)
return MAX_ETA;
return (status.total_wanted - status.total_wanted_done) / speed_average.download;
}
void TorrentSpeedMonitor::statsReceived(const stats_alert &stats)
{
Q_ASSERT(stats.interval >= 1000);
Sample<int> transferred(stats.transferred[stats_alert::download_payload],
stats.transferred[stats_alert::upload_payload]);
Sample<int> normalized = Sample<int>(Sample<long long>(transferred) * 1000LL / static_cast<long long>(stats.interval));
m_samples[misc::toQString(stats.handle.info_hash())].addSample(normalized);
}

View File

@@ -1,62 +0,0 @@
/*
* Bittorrent Client using Qt4 and libtorrent.
* Copyright (C) 2011 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org
*/
#ifndef TORRENTSPEEDMONITOR_H
#define TORRENTSPEEDMONITOR_H
#include <QObject>
#include <QString>
#include <QHash>
#include "qtorrenthandle.h"
#include <libtorrent/alert_types.hpp>
class QBtSession;
class SpeedSample;
class TorrentSpeedMonitor : public QObject
{
Q_OBJECT
Q_DISABLE_COPY(TorrentSpeedMonitor)
public:
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);
private:
QHash<QString, SpeedSample> m_samples;
QBtSession *m_session;
};
#endif // TORRENTSPEEDMONITOR_H

View File

@@ -1,100 +0,0 @@
#include "torrentstatistics.h"
#include <QDateTime>
#include <libtorrent/session.hpp>
#include "qbtsession.h"
#include "core/qinisettings.h"
#include "core/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)
{
loadStats();
connect(&m_timer, SIGNAL(timeout()), this, SLOT(gatherStats()));
m_timer.start(60 * 1000);
}
TorrentStatistics::~TorrentStatistics() {
if (m_dirty)
m_lastWrite = 0;
saveStats();
}
quint64 TorrentStatistics::getAlltimeDL() const {
return m_alltimeDL + m_sessionDL;
}
quint64 TorrentStatistics::getAlltimeUL() const {
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;
}
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();
}
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 "core/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;
// 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();
m_alltimeDL = v["AlltimeDL"].toULongLong();
m_alltimeUL = v["AlltimeUL"].toULongLong();
if (m_dirty) {
saveStats();
pref->removeStats();
}
}

View File

@@ -1,41 +0,0 @@
#ifndef TORRENTSTATISTICS_H
#define TORRENTSTATISTICS_H
#include <QObject>
#include <QTimer>
class QBtSession;
class TorrentStatistics : QObject
{
Q_OBJECT
Q_DISABLE_COPY(TorrentStatistics)
public:
TorrentStatistics(QBtSession* session, QObject* parent = 0);
~TorrentStatistics();
quint64 getAlltimeDL() const;
quint64 getAlltimeUL() const;
private slots:
void gatherStats();
private:
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;
};
#endif // TORRENTSTATISTICS_H

View File

@@ -1,59 +0,0 @@
/*
* Bittorrent Client using Qt4 and libtorrent.
* Copyright (C) 2010 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org
*/
#ifndef TRACKERINFOS_H
#define TRACKERINFOS_H
#include <QString>
class TrackerInfos {
public:
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(QString name_or_url)
: name_or_url(name_or_url)
, last_message("")
, num_peers(0)
{
}
};
#endif // TRACKERINFOS_H