Vladimir Golovnev (Glassez)
10 years ago
16 changed files with 0 additions and 1750 deletions
@ -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 |
|
@ -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 |
|
@ -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(¤t_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(¤t_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(¤t_tag->alerts_mutex); |
|
||||||
|
|
||||||
while (alerts.empty()) |
|
||||||
alerts_condvar.wait(¤t_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(¤t_tag->alerts_mutex); |
|
||||||
event_posted = false; |
|
||||||
|
|
||||||
if (!alerts.empty()) |
|
||||||
enqueueToMainThread(); |
|
||||||
} |
|
@ -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
|
|
@ -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); |
|
||||||
} |
|
@ -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
|
|
@ -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(); |
|
||||||
} |
|
||||||
} |
|
@ -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
|
|
@ -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
|
|
@ -1,123 +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 "iconprovider.h" |
|
||||||
#include "core/preferences.h" |
|
||||||
|
|
||||||
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC)) |
|
||||||
#include <QDir> |
|
||||||
#include <QFile> |
|
||||||
#endif |
|
||||||
|
|
||||||
IconProvider* IconProvider::m_instance = 0; |
|
||||||
|
|
||||||
IconProvider::IconProvider() |
|
||||||
{ |
|
||||||
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC)) |
|
||||||
m_useSystemTheme = Preferences::instance()->useSystemIconTheme(); |
|
||||||
#endif |
|
||||||
} |
|
||||||
|
|
||||||
IconProvider * IconProvider::instance() |
|
||||||
{ |
|
||||||
if (!m_instance) |
|
||||||
m_instance = new IconProvider; |
|
||||||
return m_instance; |
|
||||||
} |
|
||||||
|
|
||||||
void IconProvider::drop() |
|
||||||
{ |
|
||||||
if (m_instance) { |
|
||||||
delete m_instance; |
|
||||||
m_instance = 0; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
QIcon IconProvider::getIcon(const QString &iconId) |
|
||||||
{ |
|
||||||
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC)) |
|
||||||
if (m_useSystemTheme) { |
|
||||||
QIcon icon = QIcon::fromTheme(iconId, QIcon(":/icons/oxygen/"+iconId+".png")); |
|
||||||
icon = generateDifferentSizes(icon); |
|
||||||
return icon; |
|
||||||
} |
|
||||||
#endif |
|
||||||
return QIcon(":/icons/oxygen/"+iconId+".png"); |
|
||||||
} |
|
||||||
|
|
||||||
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC)) |
|
||||||
void IconProvider::useSystemIconTheme(bool enable) |
|
||||||
{ |
|
||||||
m_useSystemTheme = enable; |
|
||||||
} |
|
||||||
|
|
||||||
// Makes sure the icon is at least available in 16px and 24px size
|
|
||||||
// It scales the icon from the theme if necessary
|
|
||||||
// Otherwise, the UI looks broken if the icon is not available
|
|
||||||
// in the correct size.
|
|
||||||
QIcon IconProvider::generateDifferentSizes(const QIcon& icon) |
|
||||||
{ |
|
||||||
QIcon new_icon; |
|
||||||
QList<QSize> required_sizes; |
|
||||||
required_sizes << QSize(16, 16) << QSize(24, 24) << QSize(32, 32); |
|
||||||
QList<QIcon::Mode> modes; |
|
||||||
modes << QIcon::Normal << QIcon::Active << QIcon::Selected << QIcon::Disabled; |
|
||||||
foreach (const QSize& size, required_sizes) { |
|
||||||
foreach (QIcon::Mode mode, modes) { |
|
||||||
QPixmap pixoff = icon.pixmap(size, mode, QIcon::Off); |
|
||||||
if (pixoff.height() > size.height()) |
|
||||||
pixoff = pixoff.scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation); |
|
||||||
new_icon.addPixmap(pixoff, mode, QIcon::Off); |
|
||||||
QPixmap pixon = icon.pixmap(size, mode, QIcon::On); |
|
||||||
if (pixon.height() > size.height()) |
|
||||||
pixon = pixoff.scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation); |
|
||||||
new_icon.addPixmap(pixon, mode, QIcon::On); |
|
||||||
} |
|
||||||
} |
|
||||||
return new_icon; |
|
||||||
} |
|
||||||
#endif |
|
||||||
|
|
||||||
QString IconProvider::getIconPath(const QString& iconId) |
|
||||||
{ |
|
||||||
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC)) |
|
||||||
if (m_useSystemTheme) { |
|
||||||
QString path = QDir::temp().absoluteFilePath(iconId+".png"); |
|
||||||
if (!QFile::exists(path)) { |
|
||||||
const QIcon icon = QIcon::fromTheme(iconId); |
|
||||||
if (icon.isNull()) return ":/icons/oxygen/"+iconId+".png"; |
|
||||||
QPixmap px = icon.pixmap(32); |
|
||||||
px.save(path); |
|
||||||
} |
|
||||||
return path; |
|
||||||
} |
|
||||||
#endif |
|
||||||
return ":/icons/oxygen/"+iconId+".png"; |
|
||||||
} |
|
@ -1,63 +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 ICONPROVIDER_H |
|
||||||
#define ICONPROVIDER_H |
|
||||||
|
|
||||||
#include <QIcon> |
|
||||||
#include <QString> |
|
||||||
|
|
||||||
class IconProvider |
|
||||||
{ |
|
||||||
Q_DISABLE_COPY(IconProvider) |
|
||||||
|
|
||||||
private: |
|
||||||
explicit IconProvider(); |
|
||||||
static IconProvider* m_instance; |
|
||||||
|
|
||||||
public: |
|
||||||
static IconProvider* instance(); |
|
||||||
static void drop(); |
|
||||||
QIcon getIcon(const QString& iconId); |
|
||||||
QString getIconPath(const QString& iconId); |
|
||||||
|
|
||||||
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC)) |
|
||||||
public: |
|
||||||
void useSystemIconTheme(bool enable); |
|
||||||
|
|
||||||
private: |
|
||||||
QIcon generateDifferentSizes(const QIcon& icon); |
|
||||||
|
|
||||||
private: |
|
||||||
bool m_useSystemTheme; |
|
||||||
#endif |
|
||||||
}; |
|
||||||
|
|
||||||
#endif // ICONPROVIDER_H
|
|
@ -1,142 +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 |
|
||||||
*/ |
|
||||||
|
|
||||||
#include <libtorrent/version.hpp> |
|
||||||
#include <libtorrent/entry.hpp> |
|
||||||
#include <libtorrent/bencode.hpp> |
|
||||||
#include <libtorrent/torrent_info.hpp> |
|
||||||
#include <libtorrent/file.hpp> |
|
||||||
#include <libtorrent/storage.hpp> |
|
||||||
#include <libtorrent/hasher.hpp> |
|
||||||
#include <libtorrent/file_pool.hpp> |
|
||||||
#include <libtorrent/create_torrent.hpp> |
|
||||||
#include <QFile> |
|
||||||
#include <QDir> |
|
||||||
|
|
||||||
#include "torrentcreatorthread.h" |
|
||||||
#include "core/fs_utils.h" |
|
||||||
#include "core/misc.h" |
|
||||||
|
|
||||||
#include <boost/bind.hpp> |
|
||||||
#include <iostream> |
|
||||||
#include <fstream> |
|
||||||
|
|
||||||
using namespace libtorrent; |
|
||||||
|
|
||||||
// do not include files and folders whose
|
|
||||||
// name starts with a .
|
|
||||||
bool file_filter(std::string const& f) |
|
||||||
{ |
|
||||||
if (filename(f)[0] == '.') return false; |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
void TorrentCreatorThread::create(QString _input_path, QString _save_path, QStringList _trackers, QStringList _url_seeds, QString _comment, bool _is_private, int _piece_size) |
|
||||||
{ |
|
||||||
input_path = fsutils::fromNativePath(_input_path); |
|
||||||
save_path = fsutils::fromNativePath(_save_path); |
|
||||||
if (QFile(save_path).exists()) |
|
||||||
fsutils::forceRemove(save_path); |
|
||||||
trackers = _trackers; |
|
||||||
url_seeds = _url_seeds; |
|
||||||
comment = _comment; |
|
||||||
is_private = _is_private; |
|
||||||
piece_size = _piece_size; |
|
||||||
abort = false; |
|
||||||
start(); |
|
||||||
} |
|
||||||
|
|
||||||
void sendProgressUpdateSignal(int i, int num, TorrentCreatorThread *parent) { |
|
||||||
parent->sendProgressSignal((int)(i*100./(float)num)); |
|
||||||
} |
|
||||||
|
|
||||||
void TorrentCreatorThread::sendProgressSignal(int progress) { |
|
||||||
emit updateProgress(progress); |
|
||||||
} |
|
||||||
|
|
||||||
void TorrentCreatorThread::run() { |
|
||||||
emit updateProgress(0); |
|
||||||
QString creator_str("qBittorrent " VERSION); |
|
||||||
try { |
|
||||||
file_storage fs; |
|
||||||
// Adding files to the torrent
|
|
||||||
libtorrent::add_files(fs, fsutils::toNativePath(input_path).toUtf8().constData(), file_filter); |
|
||||||
if (abort) return; |
|
||||||
create_torrent t(fs, piece_size); |
|
||||||
|
|
||||||
// Add url seeds
|
|
||||||
foreach (const QString &seed, url_seeds) { |
|
||||||
t.add_url_seed(seed.trimmed().toStdString()); |
|
||||||
} |
|
||||||
int tier = 0; |
|
||||||
bool newline = false; |
|
||||||
foreach (const QString &tracker, trackers) { |
|
||||||
if (tracker.isEmpty()) { |
|
||||||
if (newline) |
|
||||||
continue; |
|
||||||
++tier; |
|
||||||
newline = true; |
|
||||||
continue; |
|
||||||
} |
|
||||||
t.add_tracker(tracker.trimmed().toStdString(), tier); |
|
||||||
newline = false; |
|
||||||
} |
|
||||||
if (abort) return; |
|
||||||
// calculate the hash for all pieces
|
|
||||||
const QString parent_path = fsutils::branchPath(input_path) + "/"; |
|
||||||
set_piece_hashes(t, fsutils::toNativePath(parent_path).toUtf8().constData(), boost::bind(sendProgressUpdateSignal, _1, t.num_pieces(), this)); |
|
||||||
// Set qBittorrent as creator and add user comment to
|
|
||||||
// torrent_info structure
|
|
||||||
t.set_creator(creator_str.toUtf8().constData()); |
|
||||||
t.set_comment(comment.toUtf8().constData()); |
|
||||||
// Is private ?
|
|
||||||
t.set_priv(is_private); |
|
||||||
if (abort) return; |
|
||||||
// create the torrent and print it to out
|
|
||||||
qDebug("Saving to %s", qPrintable(save_path)); |
|
||||||
#ifdef _MSC_VER |
|
||||||
wchar_t *wsave_path = new wchar_t[save_path.length()+1]; |
|
||||||
int len = fsutils::toNativePath(save_path).toWCharArray(wsave_path); |
|
||||||
wsave_path[len] = '\0'; |
|
||||||
std::ofstream outfile(wsave_path, std::ios_base::out|std::ios_base::binary); |
|
||||||
delete[] wsave_path; |
|
||||||
#else |
|
||||||
std::ofstream outfile(fsutils::toNativePath(save_path).toLocal8Bit().constData(), std::ios_base::out|std::ios_base::binary); |
|
||||||
#endif |
|
||||||
if (outfile.fail()) |
|
||||||
throw std::exception(); |
|
||||||
bencode(std::ostream_iterator<char>(outfile), t.generate()); |
|
||||||
outfile.close(); |
|
||||||
emit updateProgress(100); |
|
||||||
emit creationSuccess(save_path, parent_path); |
|
||||||
} catch (std::exception& e) { |
|
||||||
emit creationFailure(misc::toQStringU(e.what())); |
|
||||||
} |
|
||||||
} |
|
@ -1,73 +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 TORRENTCREATORTHREAD_H |
|
||||||
#define TORRENTCREATORTHREAD_H |
|
||||||
|
|
||||||
#include <QThread> |
|
||||||
#include <QStringList> |
|
||||||
#include <QDialog> |
|
||||||
|
|
||||||
class TorrentCreatorThread : public QThread { |
|
||||||
Q_OBJECT |
|
||||||
|
|
||||||
public: |
|
||||||
TorrentCreatorThread(QDialog *_parent) { |
|
||||||
parent = _parent; |
|
||||||
} |
|
||||||
~TorrentCreatorThread() { |
|
||||||
abort = true; |
|
||||||
wait(); |
|
||||||
} |
|
||||||
void create(QString _input_path, QString _save_path, QStringList _trackers, QStringList _url_seeds, QString _comment, bool _is_private, int _piece_size); |
|
||||||
void sendProgressSignal(int progress); |
|
||||||
void abortCreation() { abort = true; } |
|
||||||
|
|
||||||
protected: |
|
||||||
void run(); |
|
||||||
|
|
||||||
signals: |
|
||||||
void creationFailure(QString msg); |
|
||||||
void creationSuccess(QString path, QString branch_path); |
|
||||||
void updateProgress(int progress); |
|
||||||
|
|
||||||
private: |
|
||||||
QString input_path; |
|
||||||
QString save_path; |
|
||||||
QStringList trackers; |
|
||||||
QStringList url_seeds; |
|
||||||
QString comment; |
|
||||||
bool is_private; |
|
||||||
int piece_size; |
|
||||||
bool abort; |
|
||||||
QDialog *parent; |
|
||||||
}; |
|
||||||
|
|
||||||
#endif // TORRENTCREATORTHREAD_H
|
|
@ -1,48 +0,0 @@ |
|||||||
/*
|
|
||||||
* Bittorrent Client using Qt4 and libtorrent. |
|
||||||
* Copyright (C) 2014 sledgehammer999 |
|
||||||
* |
|
||||||
* 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 : hammered999@gmail.com |
|
||||||
*/ |
|
||||||
|
|
||||||
#ifndef TORRENTFILTERENUM_H |
|
||||||
#define TORRENTFILTERENUM_H |
|
||||||
|
|
||||||
namespace TorrentFilter |
|
||||||
{ |
|
||||||
enum TorrentFilter |
|
||||||
{ |
|
||||||
ALL, |
|
||||||
DOWNLOADING, |
|
||||||
SEEDING, |
|
||||||
COMPLETED, |
|
||||||
RESUMED, |
|
||||||
PAUSED, |
|
||||||
ACTIVE, |
|
||||||
INACTIVE |
|
||||||
}; |
|
||||||
} |
|
||||||
#endif // TORRENTFILTERENUM_H
|
|
@ -1,145 +0,0 @@ |
|||||||
/*
|
|
||||||
* Bittorrent Client using Qt and libtorrent. |
|
||||||
* Copyright (C) 2014 Vladimir Golovnev <glassez@yandex.ru> |
|
||||||
* |
|
||||||
* 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. |
|
||||||
*/ |
|
||||||
|
|
||||||
#include "core/torrentpersistentdata.h" |
|
||||||
#include "qtorrentfilter.h" |
|
||||||
|
|
||||||
QTorrentFilter::QTorrentFilter(QString filter, QString label) |
|
||||||
: type_(All) |
|
||||||
, label_(label) |
|
||||||
{ |
|
||||||
if (filter == "downloading") |
|
||||||
type_ = Downloading; |
|
||||||
else if (filter == "seeding") |
|
||||||
type_ = Seeding; |
|
||||||
else if (filter == "completed") |
|
||||||
type_ = Completed; |
|
||||||
else if (filter == "paused") |
|
||||||
type_ = Paused; |
|
||||||
else if (filter == "resumed") |
|
||||||
type_ = Resumed; |
|
||||||
else if (filter == "active") |
|
||||||
type_ = Active; |
|
||||||
else if (filter == "inactive") |
|
||||||
type_ = Inactive; |
|
||||||
} |
|
||||||
|
|
||||||
bool QTorrentFilter::apply(const QTorrentHandle& h) const |
|
||||||
{ |
|
||||||
if (!torrentHasLabel(h)) |
|
||||||
return false; |
|
||||||
|
|
||||||
switch (type_) { |
|
||||||
case Downloading: |
|
||||||
return isTorrentDownloading(h); |
|
||||||
case Seeding: |
|
||||||
return isTorrentSeeding(h); |
|
||||||
case Completed: |
|
||||||
return isTorrentCompleted(h); |
|
||||||
case Paused: |
|
||||||
return isTorrentPaused(h); |
|
||||||
case Resumed: |
|
||||||
return isTorrentResumed(h); |
|
||||||
case Active: |
|
||||||
return isTorrentActive(h); |
|
||||||
case Inactive: |
|
||||||
return isTorrentInactive(h); |
|
||||||
default: // All
|
|
||||||
return true; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
bool QTorrentFilter::isTorrentDownloading(const QTorrentHandle &h) const |
|
||||||
{ |
|
||||||
const QTorrentState state = h.torrentState(); |
|
||||||
|
|
||||||
return state == QTorrentState::Downloading |
|
||||||
|| state == QTorrentState::StalledDownloading |
|
||||||
|| state == QTorrentState::CheckingDownloading |
|
||||||
|| state == QTorrentState::PausedDownloading |
|
||||||
|| state == QTorrentState::QueuedDownloading |
|
||||||
|| state == QTorrentState::Error; |
|
||||||
} |
|
||||||
|
|
||||||
bool QTorrentFilter::isTorrentSeeding(const QTorrentHandle &h) const |
|
||||||
{ |
|
||||||
const QTorrentState state = h.torrentState(); |
|
||||||
|
|
||||||
return state == QTorrentState::Uploading |
|
||||||
|| state == QTorrentState::StalledUploading |
|
||||||
|| state == QTorrentState::CheckingUploading |
|
||||||
|| state == QTorrentState::QueuedUploading; |
|
||||||
} |
|
||||||
|
|
||||||
bool QTorrentFilter::isTorrentCompleted(const QTorrentHandle &h) const |
|
||||||
{ |
|
||||||
const QTorrentState state = h.torrentState(); |
|
||||||
|
|
||||||
return state == QTorrentState::Uploading |
|
||||||
|| state == QTorrentState::StalledUploading |
|
||||||
|| state == QTorrentState::CheckingUploading |
|
||||||
|| state == QTorrentState::PausedUploading |
|
||||||
|| state == QTorrentState::QueuedUploading; |
|
||||||
} |
|
||||||
|
|
||||||
bool QTorrentFilter::isTorrentPaused(const QTorrentHandle &h) const |
|
||||||
{ |
|
||||||
const QTorrentState state = h.torrentState(); |
|
||||||
|
|
||||||
return state == QTorrentState::PausedUploading |
|
||||||
|| state == QTorrentState::Error; |
|
||||||
} |
|
||||||
|
|
||||||
bool QTorrentFilter::isTorrentResumed(const QTorrentHandle &h) const |
|
||||||
{ |
|
||||||
const QTorrentState state = h.torrentState(); |
|
||||||
|
|
||||||
return state != QTorrentState::PausedUploading |
|
||||||
&& state != QTorrentState::PausedDownloading; |
|
||||||
} |
|
||||||
|
|
||||||
bool QTorrentFilter::isTorrentActive(const QTorrentHandle &h) const |
|
||||||
{ |
|
||||||
const QTorrentState state = h.torrentState(); |
|
||||||
|
|
||||||
return state == QTorrentState::Downloading |
|
||||||
|| state == QTorrentState::Uploading; |
|
||||||
} |
|
||||||
|
|
||||||
bool QTorrentFilter::isTorrentInactive(const QTorrentHandle &h) const |
|
||||||
{ |
|
||||||
return !isTorrentActive(h); |
|
||||||
} |
|
||||||
|
|
||||||
bool QTorrentFilter::torrentHasLabel(const QTorrentHandle &h) const |
|
||||||
{ |
|
||||||
if (label_.isNull()) |
|
||||||
return true; |
|
||||||
else |
|
||||||
return TorrentPersistentData::instance()->getLabel(h.hash()) == label_; |
|
||||||
} |
|
@ -1,67 +0,0 @@ |
|||||||
/*
|
|
||||||
* Bittorrent Client using Qt and libtorrent. |
|
||||||
* Copyright (C) 2014 Vladimir Golovnev <glassez@yandex.ru> |
|
||||||
* |
|
||||||
* 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. |
|
||||||
*/ |
|
||||||
|
|
||||||
#ifndef QTORRENTFILTER_H |
|
||||||
#define QTORRENTFILTER_H |
|
||||||
|
|
||||||
#include "qtorrenthandle.h" |
|
||||||
|
|
||||||
class QTorrentFilter |
|
||||||
{ |
|
||||||
public: |
|
||||||
enum |
|
||||||
{ |
|
||||||
All, |
|
||||||
Downloading, |
|
||||||
Seeding, |
|
||||||
Completed, |
|
||||||
Paused, |
|
||||||
Resumed, |
|
||||||
Active, |
|
||||||
Inactive |
|
||||||
}; |
|
||||||
|
|
||||||
// label: pass empty string for "no label" or null string (QString()) for "any label"
|
|
||||||
QTorrentFilter(QString filter, QString label = QString()); |
|
||||||
bool apply(const QTorrentHandle& h) const; |
|
||||||
|
|
||||||
private: |
|
||||||
int type_; |
|
||||||
QString label_; |
|
||||||
|
|
||||||
bool isTorrentDownloading(const QTorrentHandle &h) const; |
|
||||||
bool isTorrentSeeding(const QTorrentHandle &h) const; |
|
||||||
bool isTorrentCompleted(const QTorrentHandle &h) const; |
|
||||||
bool isTorrentPaused(const QTorrentHandle &h) const; |
|
||||||
bool isTorrentResumed(const QTorrentHandle &h) const; |
|
||||||
bool isTorrentActive(const QTorrentHandle &h) const; |
|
||||||
bool isTorrentInactive(const QTorrentHandle &h) const; |
|
||||||
bool torrentHasLabel(const QTorrentHandle &h) const; |
|
||||||
}; |
|
||||||
|
|
||||||
#endif // QTORRENTFILTER_H
|
|
Loading…
Reference in new issue