mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2026-01-09 09:02:31 -06:00
Rename Core to Base (Closes #3733).
This commit is contained in:
64
src/base/bittorrent/cachestatus.cpp
Normal file
64
src/base/bittorrent/cachestatus.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015 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 "cachestatus.h"
|
||||
|
||||
using namespace BitTorrent;
|
||||
|
||||
CacheStatus::CacheStatus(const libtorrent::cache_status &nativeStatus)
|
||||
: m_nativeStatus(nativeStatus)
|
||||
{
|
||||
}
|
||||
|
||||
int CacheStatus::totalUsedBuffers() const
|
||||
{
|
||||
return m_nativeStatus.total_used_buffers;
|
||||
}
|
||||
|
||||
qreal CacheStatus::readRatio() const
|
||||
{
|
||||
if (m_nativeStatus.blocks_read > 0)
|
||||
return (static_cast<qreal>(m_nativeStatus.blocks_read_hit) / m_nativeStatus.blocks_read);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
int CacheStatus::jobQueueLength() const
|
||||
{
|
||||
return m_nativeStatus.job_queue_length;
|
||||
}
|
||||
|
||||
int CacheStatus::averageJobTime() const
|
||||
{
|
||||
return m_nativeStatus.average_job_time;
|
||||
}
|
||||
|
||||
qlonglong CacheStatus::queuedBytes() const
|
||||
{
|
||||
return m_nativeStatus.queued_bytes;
|
||||
}
|
||||
53
src/base/bittorrent/cachestatus.h
Normal file
53
src/base/bittorrent/cachestatus.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015 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 BITTORRENT_CACHESTATUS_H
|
||||
#define BITTORRENT_CACHESTATUS_H
|
||||
|
||||
#include <libtorrent/disk_io_thread.hpp>
|
||||
#include <QtGlobal>
|
||||
|
||||
namespace BitTorrent
|
||||
{
|
||||
class CacheStatus
|
||||
{
|
||||
public:
|
||||
CacheStatus(const libtorrent::cache_status &nativeStatus);
|
||||
|
||||
int totalUsedBuffers() const;
|
||||
qreal readRatio() const;
|
||||
int jobQueueLength() const;
|
||||
int averageJobTime() const;
|
||||
qlonglong queuedBytes() const;
|
||||
|
||||
private:
|
||||
libtorrent::cache_status m_nativeStatus;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // BITTORRENT_CACHESTATUS_H
|
||||
98
src/base/bittorrent/infohash.cpp
Normal file
98
src/base/bittorrent/infohash.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015 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 <QHash>
|
||||
#include "infohash.h"
|
||||
|
||||
using namespace BitTorrent;
|
||||
|
||||
InfoHash::InfoHash()
|
||||
: m_valid(false)
|
||||
{
|
||||
}
|
||||
|
||||
InfoHash::InfoHash(const libtorrent::sha1_hash &nativeHash)
|
||||
: m_valid(true)
|
||||
, m_nativeHash(nativeHash)
|
||||
{
|
||||
char out[(libtorrent::sha1_hash::size * 2) + 1];
|
||||
libtorrent::to_hex((char const*)&m_nativeHash[0], libtorrent::sha1_hash::size, out);
|
||||
m_hashString = QString(out);
|
||||
}
|
||||
|
||||
InfoHash::InfoHash(const QString &hashString)
|
||||
: m_valid(false)
|
||||
, m_hashString(hashString)
|
||||
{
|
||||
QByteArray raw = m_hashString.toLatin1();
|
||||
if (raw.size() == 40)
|
||||
m_valid = libtorrent::from_hex(raw.constData(), 40, (char*)&m_nativeHash[0]);
|
||||
}
|
||||
|
||||
|
||||
InfoHash::InfoHash(const InfoHash &other)
|
||||
: m_valid(other.m_valid)
|
||||
, m_nativeHash(other.m_nativeHash)
|
||||
, m_hashString(other.m_hashString)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool InfoHash::isValid() const
|
||||
{
|
||||
return m_valid;
|
||||
}
|
||||
|
||||
|
||||
InfoHash::operator libtorrent::sha1_hash() const
|
||||
{
|
||||
return m_nativeHash;
|
||||
}
|
||||
|
||||
|
||||
InfoHash::operator QString() const
|
||||
{
|
||||
return m_hashString;
|
||||
}
|
||||
|
||||
|
||||
bool InfoHash::operator==(const InfoHash &other) const
|
||||
{
|
||||
return (m_nativeHash == other.m_nativeHash);
|
||||
}
|
||||
|
||||
|
||||
bool InfoHash::operator!=(const InfoHash &other) const
|
||||
{
|
||||
return (m_nativeHash != other.m_nativeHash);
|
||||
}
|
||||
|
||||
uint qHash(const InfoHash &key, uint seed)
|
||||
{
|
||||
return qHash(static_cast<QString>(key), seed);
|
||||
}
|
||||
61
src/base/bittorrent/infohash.h
Normal file
61
src/base/bittorrent/infohash.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015 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 BITTORRENT_INFOHASH_H
|
||||
#define BITTORRENT_INFOHASH_H
|
||||
|
||||
#include <libtorrent/sha1_hash.hpp>
|
||||
#include <QString>
|
||||
|
||||
namespace BitTorrent
|
||||
{
|
||||
class InfoHash
|
||||
{
|
||||
public:
|
||||
InfoHash();
|
||||
InfoHash(const libtorrent::sha1_hash &nativeHash);
|
||||
InfoHash(const QString &hashString);
|
||||
InfoHash(const InfoHash &other);
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
operator libtorrent::sha1_hash() const;
|
||||
operator QString() const;
|
||||
bool operator==(const InfoHash &other) const;
|
||||
bool operator!=(const InfoHash &other) const;
|
||||
|
||||
private:
|
||||
bool m_valid;
|
||||
libtorrent::sha1_hash m_nativeHash;
|
||||
QString m_hashString;
|
||||
};
|
||||
}
|
||||
|
||||
uint qHash(const BitTorrent::InfoHash &key, uint seed);
|
||||
|
||||
#endif // BITTORRENT_INFOHASH_H
|
||||
93
src/base/bittorrent/magneturi.cpp
Normal file
93
src/base/bittorrent/magneturi.cpp
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015 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 <libtorrent/bencode.hpp>
|
||||
#include <libtorrent/error_code.hpp>
|
||||
#include <libtorrent/magnet_uri.hpp>
|
||||
|
||||
#include "base/utils/string.h"
|
||||
#include "magneturi.h"
|
||||
|
||||
namespace libt = libtorrent;
|
||||
using namespace BitTorrent;
|
||||
|
||||
MagnetUri::MagnetUri(const QString &url)
|
||||
: m_valid(false)
|
||||
, m_url(url)
|
||||
{
|
||||
if (url.isEmpty()) return;
|
||||
|
||||
libt::error_code ec;
|
||||
libt::parse_magnet_uri(url.toUtf8().constData(), m_addTorrentParams, ec);
|
||||
if (ec) return;
|
||||
|
||||
m_valid = true;
|
||||
m_hash = m_addTorrentParams.info_hash;
|
||||
m_name = Utils::String::fromStdString(m_addTorrentParams.name);
|
||||
|
||||
foreach (const std::string &tracker, m_addTorrentParams.trackers)
|
||||
m_trackers.append(Utils::String::fromStdString(tracker));
|
||||
|
||||
foreach (const std::string &urlSeed, m_addTorrentParams.url_seeds)
|
||||
m_urlSeeds.append(QUrl(urlSeed.c_str()));
|
||||
}
|
||||
|
||||
bool MagnetUri::isValid() const
|
||||
{
|
||||
return m_valid;
|
||||
}
|
||||
|
||||
InfoHash MagnetUri::hash() const
|
||||
{
|
||||
return m_hash;
|
||||
}
|
||||
|
||||
QString MagnetUri::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
QList<TrackerEntry> MagnetUri::trackers() const
|
||||
{
|
||||
return m_trackers;
|
||||
}
|
||||
|
||||
QList<QUrl> MagnetUri::urlSeeds() const
|
||||
{
|
||||
return m_urlSeeds;
|
||||
}
|
||||
|
||||
QString MagnetUri::url() const
|
||||
{
|
||||
return m_url;
|
||||
}
|
||||
|
||||
libtorrent::add_torrent_params MagnetUri::addTorrentParams() const
|
||||
{
|
||||
return m_addTorrentParams;
|
||||
}
|
||||
68
src/base/bittorrent/magneturi.h
Normal file
68
src/base/bittorrent/magneturi.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015 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 BITTORRENT_MAGNETURI_H
|
||||
#define BITTORRENT_MAGNETURI_H
|
||||
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
#include <QUrl>
|
||||
|
||||
#include <libtorrent/add_torrent_params.hpp>
|
||||
|
||||
#include "infohash.h"
|
||||
#include "trackerentry.h"
|
||||
|
||||
namespace BitTorrent
|
||||
{
|
||||
class MagnetUri
|
||||
{
|
||||
public:
|
||||
explicit MagnetUri(const QString &url = QString());
|
||||
|
||||
bool isValid() const;
|
||||
InfoHash hash() const;
|
||||
QString name() const;
|
||||
QList<TrackerEntry> trackers() const;
|
||||
QList<QUrl> urlSeeds() const;
|
||||
QString url() const;
|
||||
|
||||
libtorrent::add_torrent_params addTorrentParams() const;
|
||||
|
||||
private:
|
||||
bool m_valid;
|
||||
QString m_url;
|
||||
InfoHash m_hash;
|
||||
QString m_name;
|
||||
QList<TrackerEntry> m_trackers;
|
||||
QList<QUrl> m_urlSeeds;
|
||||
libtorrent::add_torrent_params m_addTorrentParams;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // BITTORRENT_MAGNETURI_H
|
||||
255
src/base/bittorrent/peerinfo.cpp
Normal file
255
src/base/bittorrent/peerinfo.cpp
Normal file
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015 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 "base/net/geoipmanager.h"
|
||||
#include "base/utils/string.h"
|
||||
#include "base/unicodestrings.h"
|
||||
#include "peerinfo.h"
|
||||
|
||||
namespace libt = libtorrent;
|
||||
using namespace BitTorrent;
|
||||
|
||||
// PeerAddress
|
||||
|
||||
PeerAddress::PeerAddress()
|
||||
: port(0)
|
||||
{
|
||||
}
|
||||
|
||||
PeerAddress::PeerAddress(QHostAddress ip, ushort port)
|
||||
: ip(ip)
|
||||
, port(port)
|
||||
{
|
||||
}
|
||||
|
||||
// PeerInfo
|
||||
|
||||
PeerInfo::PeerInfo(const libt::peer_info &nativeInfo)
|
||||
: m_nativeInfo(nativeInfo)
|
||||
{
|
||||
}
|
||||
|
||||
bool PeerInfo::fromDHT() const
|
||||
{
|
||||
return (m_nativeInfo.source & libt::peer_info::dht);
|
||||
}
|
||||
|
||||
bool PeerInfo::fromPeX() const
|
||||
{
|
||||
return (m_nativeInfo.source & libt::peer_info::pex);
|
||||
}
|
||||
|
||||
bool PeerInfo::fromLSD() const
|
||||
{
|
||||
return (m_nativeInfo.source & libt::peer_info::lsd);
|
||||
}
|
||||
|
||||
#ifndef DISABLE_COUNTRIES_RESOLUTION
|
||||
QString PeerInfo::country() const
|
||||
{
|
||||
return Net::GeoIPManager::instance()->lookup(address().ip);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool PeerInfo::isInteresting() const
|
||||
{
|
||||
return (m_nativeInfo.flags & libt::peer_info::interesting);
|
||||
}
|
||||
|
||||
bool PeerInfo::isChocked() const
|
||||
{
|
||||
return (m_nativeInfo.flags & libt::peer_info::choked);
|
||||
}
|
||||
|
||||
bool PeerInfo::isRemoteInterested() const
|
||||
{
|
||||
return (m_nativeInfo.flags & libt::peer_info::remote_interested);
|
||||
}
|
||||
|
||||
bool PeerInfo::isRemoteChocked() const
|
||||
{
|
||||
return (m_nativeInfo.flags & libt::peer_info::remote_choked);
|
||||
}
|
||||
|
||||
|
||||
bool PeerInfo::isSupportsExtensions() const
|
||||
{
|
||||
return (m_nativeInfo.flags & libt::peer_info::supports_extensions);
|
||||
}
|
||||
|
||||
bool PeerInfo::isLocalConnection() const
|
||||
{
|
||||
return (m_nativeInfo.flags & libt::peer_info::local_connection);
|
||||
}
|
||||
|
||||
bool PeerInfo::isHandshake() const
|
||||
{
|
||||
return (m_nativeInfo.flags & libt::peer_info::handshake);
|
||||
}
|
||||
|
||||
|
||||
bool PeerInfo::isConnecting() const
|
||||
{
|
||||
return (m_nativeInfo.flags & libt::peer_info::connecting);
|
||||
}
|
||||
|
||||
bool PeerInfo::isQueued() const
|
||||
{
|
||||
return (m_nativeInfo.flags & libt::peer_info::queued);
|
||||
}
|
||||
|
||||
|
||||
bool PeerInfo::isOnParole() const
|
||||
{
|
||||
return (m_nativeInfo.flags & libt::peer_info::on_parole);
|
||||
}
|
||||
|
||||
bool PeerInfo::isSeed() const
|
||||
{
|
||||
return (m_nativeInfo.flags & libt::peer_info::seed);
|
||||
}
|
||||
|
||||
bool PeerInfo::optimisticUnchoke() const
|
||||
{
|
||||
return (m_nativeInfo.flags & libt::peer_info::optimistic_unchoke);
|
||||
}
|
||||
|
||||
|
||||
bool PeerInfo::isSnubbed() const
|
||||
{
|
||||
return (m_nativeInfo.flags & libt::peer_info::snubbed);
|
||||
}
|
||||
|
||||
bool PeerInfo::isUploadOnly() const
|
||||
{
|
||||
return (m_nativeInfo.flags & libt::peer_info::upload_only);
|
||||
}
|
||||
|
||||
bool PeerInfo::isEndgameMode() const
|
||||
{
|
||||
return (m_nativeInfo.flags & libt::peer_info::endgame_mode);
|
||||
}
|
||||
|
||||
|
||||
bool PeerInfo::isHolepunched() const
|
||||
{
|
||||
return (m_nativeInfo.flags & libt::peer_info::holepunched);
|
||||
}
|
||||
|
||||
bool PeerInfo::useI2PSocket() const
|
||||
{
|
||||
return (m_nativeInfo.flags & libt::peer_info::i2p_socket);
|
||||
}
|
||||
|
||||
bool PeerInfo::useUTPSocket() const
|
||||
{
|
||||
return (m_nativeInfo.flags & libt::peer_info::utp_socket);
|
||||
}
|
||||
|
||||
bool PeerInfo::useSSLSocket() const
|
||||
{
|
||||
return (m_nativeInfo.flags & libt::peer_info::ssl_socket);
|
||||
}
|
||||
|
||||
bool PeerInfo::isRC4Encrypted() const
|
||||
{
|
||||
return (m_nativeInfo.flags & libt::peer_info::rc4_encrypted);
|
||||
}
|
||||
|
||||
bool PeerInfo::isPlaintextEncrypted() const
|
||||
{
|
||||
return (m_nativeInfo.flags & libt::peer_info::plaintext_encrypted);
|
||||
}
|
||||
|
||||
|
||||
PeerAddress PeerInfo::address() const
|
||||
{
|
||||
return PeerAddress(QHostAddress(QString::fromStdString(m_nativeInfo.ip.address().to_string())),
|
||||
m_nativeInfo.ip.port());
|
||||
}
|
||||
|
||||
QString PeerInfo::client() const
|
||||
{
|
||||
return Utils::String::fromStdString(m_nativeInfo.client);
|
||||
}
|
||||
|
||||
|
||||
qreal PeerInfo::progress() const
|
||||
{
|
||||
return m_nativeInfo.progress;
|
||||
}
|
||||
|
||||
int PeerInfo::payloadUpSpeed() const
|
||||
{
|
||||
return m_nativeInfo.payload_up_speed;
|
||||
}
|
||||
|
||||
|
||||
int PeerInfo::payloadDownSpeed() const
|
||||
{
|
||||
return m_nativeInfo.payload_down_speed;
|
||||
}
|
||||
|
||||
qlonglong PeerInfo::totalUpload() const
|
||||
{
|
||||
return m_nativeInfo.total_upload;
|
||||
}
|
||||
|
||||
|
||||
qlonglong PeerInfo::totalDownload() const
|
||||
{
|
||||
return m_nativeInfo.total_download;
|
||||
}
|
||||
|
||||
QBitArray PeerInfo::pieces() const
|
||||
{
|
||||
QBitArray result(m_nativeInfo.pieces.size());
|
||||
|
||||
for (int i = 0; i < m_nativeInfo.pieces.size(); ++i)
|
||||
result.setBit(i, m_nativeInfo.pieces.get_bit(i));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QString PeerInfo::connectionType() const
|
||||
{
|
||||
if (m_nativeInfo.flags & libt::peer_info::utp_socket)
|
||||
return QString::fromUtf8(C_UTP);
|
||||
|
||||
QString connection;
|
||||
switch(m_nativeInfo.connection_type) {
|
||||
case libt::peer_info::http_seed:
|
||||
case libt::peer_info::web_seed:
|
||||
connection = "Web";
|
||||
break;
|
||||
default:
|
||||
connection = "BT";
|
||||
}
|
||||
|
||||
return connection;
|
||||
}
|
||||
101
src/base/bittorrent/peerinfo.h
Normal file
101
src/base/bittorrent/peerinfo.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015 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 BITTORRENT_PEERINFO_H
|
||||
#define BITTORRENT_PEERINFO_H
|
||||
|
||||
#include <libtorrent/peer_info.hpp>
|
||||
|
||||
#include <QHostAddress>
|
||||
#include <QBitArray>
|
||||
|
||||
namespace BitTorrent
|
||||
{
|
||||
struct PeerAddress
|
||||
{
|
||||
QHostAddress ip;
|
||||
ushort port;
|
||||
|
||||
PeerAddress();
|
||||
PeerAddress(QHostAddress ip, ushort port);
|
||||
};
|
||||
|
||||
class PeerInfo
|
||||
{
|
||||
public:
|
||||
PeerInfo(const libtorrent::peer_info &nativeInfo);
|
||||
|
||||
bool fromDHT() const;
|
||||
bool fromPeX() const;
|
||||
bool fromLSD() const;
|
||||
|
||||
bool isInteresting() const;
|
||||
bool isChocked() const;
|
||||
bool isRemoteInterested() const;
|
||||
bool isRemoteChocked() const;
|
||||
bool isSupportsExtensions() const;
|
||||
bool isLocalConnection() const;
|
||||
|
||||
bool isHandshake() const;
|
||||
bool isConnecting() const;
|
||||
bool isQueued() const;
|
||||
bool isOnParole() const;
|
||||
bool isSeed() const;
|
||||
|
||||
bool optimisticUnchoke() const;
|
||||
bool isSnubbed() const;
|
||||
bool isUploadOnly() const;
|
||||
bool isEndgameMode() const;
|
||||
bool isHolepunched() const;
|
||||
|
||||
bool useI2PSocket() const;
|
||||
bool useUTPSocket() const;
|
||||
bool useSSLSocket() const;
|
||||
|
||||
bool isRC4Encrypted() const;
|
||||
bool isPlaintextEncrypted() const;
|
||||
|
||||
PeerAddress address() const;
|
||||
QString client() const;
|
||||
qreal progress() const;
|
||||
int payloadUpSpeed() const;
|
||||
int payloadDownSpeed() const;
|
||||
qlonglong totalUpload() const;
|
||||
qlonglong totalDownload() const;
|
||||
QBitArray pieces() const;
|
||||
QString connectionType() const;
|
||||
#ifndef DISABLE_COUNTRIES_RESOLUTION
|
||||
QString country() const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
libtorrent::peer_info m_nativeInfo;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // BITTORRENT_PEERINFO_H
|
||||
96
src/base/bittorrent/private/bandwidthscheduler.cpp
Normal file
96
src/base/bittorrent/private/bandwidthscheduler.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt 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 <QTime>
|
||||
#include <QDateTime>
|
||||
|
||||
#include "base/preferences.h"
|
||||
#include "bandwidthscheduler.h"
|
||||
|
||||
BandwidthScheduler::BandwidthScheduler(QObject *parent)
|
||||
: QTimer(parent)
|
||||
{
|
||||
Q_ASSERT(Preferences::instance()->isSchedulerEnabled());
|
||||
// Single shot, we call start() again manually
|
||||
setSingleShot(true);
|
||||
// Connect Signals/Slots
|
||||
connect(this, SIGNAL(timeout()), this, SLOT(start()));
|
||||
}
|
||||
|
||||
void BandwidthScheduler::start()
|
||||
{
|
||||
const Preferences* const pref = Preferences::instance();
|
||||
Q_ASSERT(pref->isSchedulerEnabled());
|
||||
bool alt_bw_enabled = pref->isAltBandwidthEnabled();
|
||||
|
||||
QTime start = pref->getSchedulerStartTime();
|
||||
QTime end = pref->getSchedulerEndTime();
|
||||
QTime now = QTime::currentTime();
|
||||
int sched_days = pref->getSchedulerDays();
|
||||
int day = QDateTime::currentDateTime().toLocalTime().date().dayOfWeek();
|
||||
bool new_mode = false;
|
||||
bool reverse = false;
|
||||
|
||||
if (start > end) {
|
||||
QTime temp = start;
|
||||
start = end;
|
||||
end = temp;
|
||||
reverse = true;
|
||||
}
|
||||
|
||||
if ((start <= now) && (end >= now)) {
|
||||
switch(sched_days) {
|
||||
case EVERY_DAY:
|
||||
new_mode = true;
|
||||
break;
|
||||
case WEEK_ENDS:
|
||||
if ((day == 6) || (day == 7))
|
||||
new_mode = true;
|
||||
break;
|
||||
case WEEK_DAYS:
|
||||
if ((day != 6) && (day != 7))
|
||||
new_mode = true;
|
||||
break;
|
||||
default:
|
||||
if (day == (sched_days - 2))
|
||||
new_mode = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (reverse)
|
||||
new_mode = !new_mode;
|
||||
|
||||
if (new_mode != alt_bw_enabled)
|
||||
emit switchToAlternativeMode(new_mode);
|
||||
|
||||
// Timeout regularly to accommodate for external system clock changes
|
||||
// eg from the user or from a timesync utility
|
||||
QTimer::start(1500);
|
||||
}
|
||||
50
src/base/bittorrent/private/bandwidthscheduler.h
Normal file
50
src/base/bittorrent/private/bandwidthscheduler.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt 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 BANDWIDTHSCHEDULER_H
|
||||
#define BANDWIDTHSCHEDULER_H
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
class BandwidthScheduler : public QTimer
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
BandwidthScheduler(QObject *parent = 0);
|
||||
|
||||
public slots:
|
||||
void start();
|
||||
|
||||
signals:
|
||||
void switchToAlternativeMode(bool alternative);
|
||||
};
|
||||
|
||||
#endif // BANDWIDTHSCHEDULER_H
|
||||
439
src/base/bittorrent/private/filterparserthread.cpp
Normal file
439
src/base/bittorrent/private/filterparserthread.cpp
Normal file
@@ -0,0 +1,439 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libt.
|
||||
* 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 <QFile>
|
||||
#include <QHostAddress>
|
||||
#include <QDataStream>
|
||||
#include <QStringList>
|
||||
|
||||
#include <libtorrent/session.hpp>
|
||||
#include <libtorrent/ip_filter.hpp>
|
||||
|
||||
#include "base/logger.h"
|
||||
#include "filterparserthread.h"
|
||||
|
||||
namespace libt = libtorrent;
|
||||
|
||||
FilterParserThread::FilterParserThread(libt::session *s, QObject *parent)
|
||||
: QThread(parent)
|
||||
, m_session(s)
|
||||
, m_abort(false)
|
||||
{
|
||||
}
|
||||
|
||||
FilterParserThread::~FilterParserThread()
|
||||
{
|
||||
m_abort = true;
|
||||
wait();
|
||||
}
|
||||
|
||||
// Parser for eMule ip filter in DAT format
|
||||
int FilterParserThread::parseDATFilterFile(QString m_filePath, libt::ip_filter &filter)
|
||||
{
|
||||
int ruleCount = 0;
|
||||
QFile file(m_filePath);
|
||||
if (!file.exists()) return ruleCount;
|
||||
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
Logger::instance()->addMessage(tr("I/O Error: Could not open ip filter file in read mode."), Log::CRITICAL);
|
||||
return ruleCount;
|
||||
}
|
||||
|
||||
unsigned int nbLine = 0;
|
||||
while (!file.atEnd() && !m_abort) {
|
||||
++nbLine;
|
||||
QByteArray line = file.readLine();
|
||||
// Ignoring empty lines
|
||||
line = line.trimmed();
|
||||
if (line.isEmpty()) continue;
|
||||
// Ignoring commented lines
|
||||
if (line.startsWith('#') || line.startsWith("//")) continue;
|
||||
|
||||
// Line should be split by commas
|
||||
QList<QByteArray> partsList = line.split(',');
|
||||
const uint nbElem = partsList.size();
|
||||
|
||||
// IP Range should be split by a dash
|
||||
QList<QByteArray> IPs = partsList.first().split('-');
|
||||
if (IPs.size() != 2) {
|
||||
qDebug("Ipfilter.dat: line %d is malformed.", nbLine);
|
||||
qDebug("Line was %s", line.constData());
|
||||
continue;
|
||||
}
|
||||
|
||||
boost::system::error_code ec;
|
||||
const QString strStartIP = cleanupIPAddress(IPs.at(0));
|
||||
if (strStartIP.isEmpty()) {
|
||||
qDebug("Ipfilter.dat: line %d is malformed.", nbLine);
|
||||
qDebug("Start IP of the range is malformated: %s", qPrintable(strStartIP));
|
||||
continue;
|
||||
}
|
||||
libt::address startAddr = libt::address::from_string(qPrintable(strStartIP), ec);
|
||||
if (ec) {
|
||||
qDebug("Ipfilter.dat: line %d is malformed.", nbLine);
|
||||
qDebug("Start IP of the range is malformated: %s", qPrintable(strStartIP));
|
||||
continue;
|
||||
}
|
||||
|
||||
const QString strEndIP = cleanupIPAddress(IPs.at(1));
|
||||
if (strEndIP.isEmpty()) {
|
||||
qDebug("Ipfilter.dat: line %d is malformed.", nbLine);
|
||||
qDebug("End IP of the range is malformated: %s", qPrintable(strEndIP));
|
||||
continue;
|
||||
}
|
||||
|
||||
libt::address endAddr = libt::address::from_string(qPrintable(strEndIP), ec);
|
||||
if (ec) {
|
||||
qDebug("Ipfilter.dat: line %d is malformed.", nbLine);
|
||||
qDebug("End IP of the range is malformated: %s", qPrintable(strEndIP));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (startAddr.is_v4() != endAddr.is_v4()) {
|
||||
qDebug("Ipfilter.dat: line %d is malformed.", nbLine);
|
||||
qDebug("One IP is IPv4 and the other is IPv6!");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if there is an access value (apparently not mandatory)
|
||||
int nbAccess = 0;
|
||||
if (nbElem > 1) {
|
||||
// There is possibly one
|
||||
nbAccess = partsList.at(1).trimmed().toInt();
|
||||
}
|
||||
|
||||
if (nbAccess > 127) {
|
||||
// Ignoring this rule because access value is too high
|
||||
continue;
|
||||
}
|
||||
|
||||
// Now Add to the filter
|
||||
try {
|
||||
filter.add_rule(startAddr, endAddr, libt::ip_filter::blocked);
|
||||
++ruleCount;
|
||||
}
|
||||
catch(std::exception &) {
|
||||
qDebug("Bad line in filter file, avoided crash...");
|
||||
}
|
||||
}
|
||||
|
||||
file.close();
|
||||
return ruleCount;
|
||||
}
|
||||
|
||||
// Parser for PeerGuardian ip filter in p2p format
|
||||
int FilterParserThread::parseP2PFilterFile(QString m_filePath, libt::ip_filter &filter)
|
||||
{
|
||||
int ruleCount = 0;
|
||||
QFile file(m_filePath);
|
||||
if (!file.exists()) return ruleCount;
|
||||
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
Logger::instance()->addMessage(tr("I/O Error: Could not open ip filter file in read mode."), Log::CRITICAL);
|
||||
return ruleCount;
|
||||
}
|
||||
|
||||
unsigned int nbLine = 0;
|
||||
while (!file.atEnd() && !m_abort) {
|
||||
++nbLine;
|
||||
QByteArray line = file.readLine().trimmed();
|
||||
if (line.isEmpty()) continue;
|
||||
// Ignoring commented lines
|
||||
if (line.startsWith('#') || line.startsWith("//")) continue;
|
||||
|
||||
// Line is split by :
|
||||
QList<QByteArray> partsList = line.split(':');
|
||||
if (partsList.size() < 2) {
|
||||
qDebug("p2p file: line %d is malformed.", nbLine);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get IP range
|
||||
QList<QByteArray> IPs = partsList.last().split('-');
|
||||
if (IPs.size() != 2) {
|
||||
qDebug("p2p file: line %d is malformed.", nbLine);
|
||||
qDebug("line was: %s", line.constData());
|
||||
continue;
|
||||
}
|
||||
|
||||
boost::system::error_code ec;
|
||||
QString strStartIP = cleanupIPAddress(IPs.at(0));
|
||||
if (strStartIP.isEmpty()) {
|
||||
qDebug("p2p file: line %d is malformed.", nbLine);
|
||||
qDebug("Start IP is invalid: %s", qPrintable(strStartIP));
|
||||
continue;
|
||||
}
|
||||
|
||||
libt::address startAddr = libt::address::from_string(qPrintable(strStartIP), ec);
|
||||
if (ec) {
|
||||
qDebug("p2p file: line %d is malformed.", nbLine);
|
||||
qDebug("Start IP is invalid: %s", qPrintable(strStartIP));
|
||||
continue;
|
||||
}
|
||||
|
||||
QString strEndIP = cleanupIPAddress(IPs.at(1));
|
||||
if (strEndIP.isEmpty()) {
|
||||
qDebug("p2p file: line %d is malformed.", nbLine);
|
||||
qDebug("End IP is invalid: %s", qPrintable(strStartIP));
|
||||
continue;
|
||||
}
|
||||
|
||||
libt::address endAddr = libt::address::from_string(qPrintable(strEndIP), ec);
|
||||
if (ec) {
|
||||
qDebug("p2p file: line %d is malformed.", nbLine);
|
||||
qDebug("End IP is invalid: %s", qPrintable(strStartIP));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (startAddr.is_v4() != endAddr.is_v4()) {
|
||||
qDebug("p2p file: line %d is malformed.", nbLine);
|
||||
qDebug("Line was: %s", line.constData());
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
filter.add_rule(startAddr, endAddr, libt::ip_filter::blocked);
|
||||
++ruleCount;
|
||||
}
|
||||
catch(std::exception &) {
|
||||
qDebug("p2p file: line %d is malformed.", nbLine);
|
||||
qDebug("Line was: %s", line.constData());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
file.close();
|
||||
return ruleCount;
|
||||
}
|
||||
|
||||
int FilterParserThread::getlineInStream(QDataStream &stream, std::string &name, char delim)
|
||||
{
|
||||
char c;
|
||||
int total_read = 0;
|
||||
int read;
|
||||
do {
|
||||
read = stream.readRawData(&c, 1);
|
||||
total_read += read;
|
||||
if (read > 0) {
|
||||
if (c != delim) {
|
||||
name += c;
|
||||
}
|
||||
else {
|
||||
// Delim found
|
||||
return total_read;
|
||||
}
|
||||
}
|
||||
}
|
||||
while(read > 0);
|
||||
|
||||
return total_read;
|
||||
}
|
||||
|
||||
// Parser for PeerGuardian ip filter in p2p format
|
||||
int FilterParserThread::parseP2BFilterFile(QString m_filePath, libt::ip_filter &filter)
|
||||
{
|
||||
int ruleCount = 0;
|
||||
QFile file(m_filePath);
|
||||
if (!file.exists()) return ruleCount;
|
||||
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
Logger::instance()->addMessage(tr("I/O Error: Could not open ip filter file in read mode."), Log::CRITICAL);
|
||||
return ruleCount;
|
||||
}
|
||||
|
||||
QDataStream stream(&file);
|
||||
// Read header
|
||||
char buf[7];
|
||||
unsigned char version;
|
||||
if (!stream.readRawData(buf, sizeof(buf))
|
||||
|| memcmp(buf, "\xFF\xFF\xFF\xFFP2B", 7)
|
||||
|| !stream.readRawData((char*)&version, sizeof(version))) {
|
||||
Logger::instance()->addMessage(tr("Parsing Error: The filter file is not a valid PeerGuardian P2B file."), Log::CRITICAL);
|
||||
return ruleCount;
|
||||
}
|
||||
|
||||
if ((version == 1) || (version == 2)) {
|
||||
qDebug ("p2b version 1 or 2");
|
||||
unsigned int start, end;
|
||||
|
||||
std::string name;
|
||||
while(getlineInStream(stream, name, '\0') && !m_abort) {
|
||||
if (!stream.readRawData((char*)&start, sizeof(start))
|
||||
|| !stream.readRawData((char*)&end, sizeof(end))) {
|
||||
Logger::instance()->addMessage(tr("Parsing Error: The filter file is not a valid PeerGuardian P2B file."), Log::CRITICAL);
|
||||
return ruleCount;
|
||||
}
|
||||
|
||||
// Network byte order to Host byte order
|
||||
// asio address_v4 constructor expects it
|
||||
// that way
|
||||
libt::address_v4 first(ntohl(start));
|
||||
libt::address_v4 last(ntohl(end));
|
||||
// Apply to bittorrent session
|
||||
try {
|
||||
filter.add_rule(first, last, libt::ip_filter::blocked);
|
||||
++ruleCount;
|
||||
}
|
||||
catch(std::exception &) {}
|
||||
}
|
||||
}
|
||||
else if (version == 3) {
|
||||
qDebug ("p2b version 3");
|
||||
unsigned int namecount;
|
||||
if (!stream.readRawData((char*)&namecount, sizeof(namecount))) {
|
||||
Logger::instance()->addMessage(tr("Parsing Error: The filter file is not a valid PeerGuardian P2B file."), Log::CRITICAL);
|
||||
return ruleCount;
|
||||
}
|
||||
|
||||
namecount = ntohl(namecount);
|
||||
// Reading names although, we don't really care about them
|
||||
for (unsigned int i = 0; i < namecount; ++i) {
|
||||
std::string name;
|
||||
if (!getlineInStream(stream, name, '\0')) {
|
||||
Logger::instance()->addMessage(tr("Parsing Error: The filter file is not a valid PeerGuardian P2B file."), Log::CRITICAL);
|
||||
return ruleCount;
|
||||
}
|
||||
|
||||
if (m_abort) return ruleCount;
|
||||
}
|
||||
|
||||
// Reading the ranges
|
||||
unsigned int rangecount;
|
||||
if (!stream.readRawData((char*)&rangecount, sizeof(rangecount))) {
|
||||
Logger::instance()->addMessage(tr("Parsing Error: The filter file is not a valid PeerGuardian P2B file."), Log::CRITICAL);
|
||||
return ruleCount;
|
||||
}
|
||||
|
||||
rangecount = ntohl(rangecount);
|
||||
unsigned int name, start, end;
|
||||
for (unsigned int i = 0; i < rangecount; ++i) {
|
||||
if (!stream.readRawData((char*)&name, sizeof(name))
|
||||
|| !stream.readRawData((char*)&start, sizeof(start))
|
||||
|| !stream.readRawData((char*)&end, sizeof(end))) {
|
||||
Logger::instance()->addMessage(tr("Parsing Error: The filter file is not a valid PeerGuardian P2B file."), Log::CRITICAL);
|
||||
return ruleCount;
|
||||
}
|
||||
|
||||
// Network byte order to Host byte order
|
||||
// asio address_v4 constructor expects it
|
||||
// that way
|
||||
libt::address_v4 first(ntohl(start));
|
||||
libt::address_v4 last(ntohl(end));
|
||||
// Apply to bittorrent session
|
||||
try {
|
||||
filter.add_rule(first, last, libt::ip_filter::blocked);
|
||||
++ruleCount;
|
||||
}
|
||||
catch(std::exception &) {}
|
||||
|
||||
if (m_abort) return ruleCount;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Logger::instance()->addMessage(tr("Parsing Error: The filter file is not a valid PeerGuardian P2B file."), Log::CRITICAL);
|
||||
}
|
||||
|
||||
file.close();
|
||||
return ruleCount;
|
||||
}
|
||||
|
||||
// Process ip filter file
|
||||
// Supported formats:
|
||||
// * eMule IP list (DAT): http://wiki.phoenixlabs.org/wiki/DAT_Format
|
||||
// * PeerGuardian Text (P2P): http://wiki.phoenixlabs.org/wiki/P2P_Format
|
||||
// * PeerGuardian Binary (P2B): http://wiki.phoenixlabs.org/wiki/P2B_Format
|
||||
void FilterParserThread::processFilterFile(QString _filePath)
|
||||
{
|
||||
if (isRunning()) {
|
||||
// Already parsing a filter, m_abort first
|
||||
m_abort = true;
|
||||
wait();
|
||||
}
|
||||
|
||||
m_abort = false;
|
||||
m_filePath = _filePath;
|
||||
// Run it
|
||||
start();
|
||||
}
|
||||
|
||||
void FilterParserThread::processFilterList(libt::session *s, const QStringList &IPs)
|
||||
{
|
||||
// First, import current filter
|
||||
libt::ip_filter filter = s->get_ip_filter();
|
||||
foreach (const QString &ip, IPs) {
|
||||
qDebug("Manual ban of peer %s", ip.toLocal8Bit().constData());
|
||||
boost::system::error_code ec;
|
||||
libt::address addr = libt::address::from_string(ip.toLocal8Bit().constData(), ec);
|
||||
Q_ASSERT(!ec);
|
||||
if (!ec)
|
||||
filter.add_rule(addr, addr, libt::ip_filter::blocked);
|
||||
}
|
||||
|
||||
s->set_ip_filter(filter);
|
||||
}
|
||||
|
||||
QString FilterParserThread::cleanupIPAddress(QString _ip)
|
||||
{
|
||||
QHostAddress ip(_ip.trimmed());
|
||||
if (ip.isNull()) return QString();
|
||||
|
||||
return ip.toString();
|
||||
}
|
||||
|
||||
void FilterParserThread::run()
|
||||
{
|
||||
qDebug("Processing filter file");
|
||||
libt::ip_filter filter = m_session->get_ip_filter();
|
||||
int ruleCount = 0;
|
||||
if (m_filePath.endsWith(".p2p", Qt::CaseInsensitive)) {
|
||||
// PeerGuardian p2p file
|
||||
ruleCount = parseP2PFilterFile(m_filePath, filter);
|
||||
}
|
||||
else if (m_filePath.endsWith(".p2b", Qt::CaseInsensitive)) {
|
||||
// PeerGuardian p2b file
|
||||
ruleCount = parseP2BFilterFile(m_filePath, filter);
|
||||
}
|
||||
else if (m_filePath.endsWith(".dat", Qt::CaseInsensitive)) {
|
||||
// eMule DAT format
|
||||
ruleCount = parseDATFilterFile(m_filePath, filter);
|
||||
}
|
||||
|
||||
if (m_abort) return;
|
||||
|
||||
try {
|
||||
m_session->set_ip_filter(filter);
|
||||
emit IPFilterParsed(ruleCount);
|
||||
}
|
||||
catch(std::exception &) {
|
||||
emit IPFilterError();
|
||||
}
|
||||
|
||||
qDebug("IP Filter thread: finished parsing, filter applied");
|
||||
}
|
||||
74
src/base/bittorrent/private/filterparserthread.h
Normal file
74
src/base/bittorrent/private/filterparserthread.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt 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 FILTERPARSERTHREAD_H
|
||||
#define FILTERPARSERTHREAD_H
|
||||
|
||||
#include <QThread>
|
||||
|
||||
class QDataStream;
|
||||
class QStringList;
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
class session;
|
||||
struct ip_filter;
|
||||
}
|
||||
|
||||
class FilterParserThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FilterParserThread(libtorrent::session *s, QObject *parent = 0);
|
||||
~FilterParserThread();
|
||||
|
||||
int parseDATFilterFile(QString filePath, libtorrent::ip_filter &filter);
|
||||
int parseP2PFilterFile(QString filePath, libtorrent::ip_filter &filter);
|
||||
int getlineInStream(QDataStream &stream, std::string &name, char delim);
|
||||
int parseP2BFilterFile(QString filePath, libtorrent::ip_filter &filter);
|
||||
void processFilterFile(QString _filePath);
|
||||
static void processFilterList(libtorrent::session *s, const QStringList &IPs);
|
||||
|
||||
signals:
|
||||
void IPFilterParsed(int ruleCount);
|
||||
void IPFilterError();
|
||||
|
||||
protected:
|
||||
QString cleanupIPAddress(QString _ip);
|
||||
void run();
|
||||
|
||||
private:
|
||||
libtorrent::session *m_session;
|
||||
bool m_abort;
|
||||
QString m_filePath;
|
||||
};
|
||||
|
||||
#endif // BITTORRENT_FILTERPARSERTHREAD_H
|
||||
56
src/base/bittorrent/private/speedmonitor.cpp
Normal file
56
src/base/bittorrent/private/speedmonitor.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2011 Christophe Dumez <chris@qbittorrent.org>
|
||||
*
|
||||
* 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 <QList>
|
||||
#include "speedmonitor.h"
|
||||
|
||||
void SpeedMonitor::addSample(const SpeedSample &sample)
|
||||
{
|
||||
m_speedSamples.push_back(sample);
|
||||
m_sum += sample;
|
||||
if (m_speedSamples.size() > MAX_SAMPLES) {
|
||||
m_sum -= m_speedSamples.front();
|
||||
m_speedSamples.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
SpeedSampleAvg SpeedMonitor::average() const
|
||||
{
|
||||
if (m_speedSamples.empty())
|
||||
return SpeedSampleAvg();
|
||||
|
||||
qreal k = qreal(1.) / m_speedSamples.size();
|
||||
return SpeedSampleAvg(m_sum.download * k, m_sum.upload * k);
|
||||
}
|
||||
|
||||
void SpeedMonitor::reset()
|
||||
{
|
||||
m_sum = SpeedSample();
|
||||
m_speedSamples.clear();
|
||||
}
|
||||
84
src/base/bittorrent/private/speedmonitor.h
Normal file
84
src/base/bittorrent/private/speedmonitor.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2011 Christophe Dumez <chris@qbittorrent.org>
|
||||
*
|
||||
* 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 SPEEDMONITOR_H
|
||||
#define SPEEDMONITOR_H
|
||||
|
||||
template<typename T> class QList;
|
||||
|
||||
template<typename T>
|
||||
struct Sample
|
||||
{
|
||||
Sample()
|
||||
: download()
|
||||
, upload()
|
||||
{
|
||||
}
|
||||
|
||||
Sample(T dl, T ul)
|
||||
: download(dl)
|
||||
, upload(ul)
|
||||
{
|
||||
}
|
||||
|
||||
Sample<T> &operator+=(const Sample<T> &other)
|
||||
{
|
||||
download += other.download;
|
||||
upload += other.upload;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Sample<T> &operator-=(const Sample<T> &other)
|
||||
{
|
||||
download -= other.download;
|
||||
upload -= other.upload;
|
||||
return *this;
|
||||
}
|
||||
|
||||
T download;
|
||||
T upload;
|
||||
};
|
||||
|
||||
typedef Sample<qlonglong> SpeedSample;
|
||||
typedef Sample<qreal> SpeedSampleAvg;
|
||||
|
||||
class SpeedMonitor
|
||||
{
|
||||
public:
|
||||
void addSample(const SpeedSample &sample);
|
||||
SpeedSampleAvg average() const;
|
||||
void reset();
|
||||
|
||||
private:
|
||||
static const int MAX_SAMPLES = 30;
|
||||
QList<SpeedSample> m_speedSamples;
|
||||
SpeedSample m_sum;
|
||||
};
|
||||
|
||||
#endif // SPEEDMONITOR_H
|
||||
115
src/base/bittorrent/private/statistics.cpp
Normal file
115
src/base/bittorrent/private/statistics.cpp
Normal file
@@ -0,0 +1,115 @@
|
||||
#include <QDateTime>
|
||||
|
||||
#include <libtorrent/session.hpp>
|
||||
|
||||
#include "base/qinisettings.h"
|
||||
#include "base/preferences.h"
|
||||
#include "base/bittorrent/sessionstatus.h"
|
||||
#include "base/bittorrent/session.h"
|
||||
#include "statistics.h"
|
||||
|
||||
static const qint64 SAVE_INTERVAL = 15 * 60 * 1000;
|
||||
|
||||
namespace libt = libtorrent;
|
||||
using namespace BitTorrent;
|
||||
|
||||
Statistics::Statistics(Session *session)
|
||||
: QObject(session)
|
||||
, m_session(session)
|
||||
, m_sessionUL(0)
|
||||
, m_sessionDL(0)
|
||||
, m_lastWrite(0)
|
||||
, m_dirty(false)
|
||||
{
|
||||
load();
|
||||
connect(&m_timer, SIGNAL(timeout()), this, SLOT(gather()));
|
||||
m_timer.start(60 * 1000);
|
||||
}
|
||||
|
||||
Statistics::~Statistics()
|
||||
{
|
||||
if (m_dirty)
|
||||
m_lastWrite = 0;
|
||||
save();
|
||||
}
|
||||
|
||||
quint64 Statistics::getAlltimeDL() const
|
||||
{
|
||||
return m_alltimeDL + m_sessionDL;
|
||||
}
|
||||
|
||||
quint64 Statistics::getAlltimeUL() const
|
||||
{
|
||||
return m_alltimeUL + m_sessionUL;
|
||||
}
|
||||
|
||||
void Statistics::gather()
|
||||
{
|
||||
SessionStatus ss = m_session->status();
|
||||
if (ss.totalDownload() > m_sessionDL) {
|
||||
m_sessionDL = ss.totalDownload();
|
||||
m_dirty = true;
|
||||
}
|
||||
if (ss.totalUpload() > m_sessionUL) {
|
||||
m_sessionUL = ss.totalUpload();
|
||||
m_dirty = true;
|
||||
}
|
||||
|
||||
save();
|
||||
}
|
||||
|
||||
void Statistics::save() const
|
||||
{
|
||||
qint64 now = QDateTime::currentMSecsSinceEpoch();
|
||||
|
||||
if (!m_dirty || ((now - m_lastWrite) < SAVE_INTERVAL))
|
||||
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 = now;
|
||||
}
|
||||
|
||||
void Statistics::load()
|
||||
{
|
||||
// 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 "base/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) {
|
||||
save();
|
||||
pref->removeStats();
|
||||
}
|
||||
}
|
||||
41
src/base/bittorrent/private/statistics.h
Normal file
41
src/base/bittorrent/private/statistics.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef STATISTICS_H
|
||||
#define STATISTICS_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QTimer>
|
||||
|
||||
namespace BitTorrent { class Session; }
|
||||
|
||||
class Statistics : QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_DISABLE_COPY(Statistics)
|
||||
|
||||
public:
|
||||
Statistics(BitTorrent::Session *session);
|
||||
~Statistics();
|
||||
|
||||
quint64 getAlltimeDL() const;
|
||||
quint64 getAlltimeUL() const;
|
||||
|
||||
private slots:
|
||||
void gather();
|
||||
|
||||
private:
|
||||
void save() const;
|
||||
void load();
|
||||
|
||||
private:
|
||||
BitTorrent::Session *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 // STATISTICS_H
|
||||
2445
src/base/bittorrent/session.cpp
Normal file
2445
src/base/bittorrent/session.cpp
Normal file
File diff suppressed because it is too large
Load Diff
375
src/base/bittorrent/session.h
Normal file
375
src/base/bittorrent/session.h
Normal file
@@ -0,0 +1,375 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
||||
*
|
||||
* 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 BITTORRENT_SESSION_H
|
||||
#define BITTORRENT_SESSION_H
|
||||
|
||||
#include <QFile>
|
||||
#include <QHash>
|
||||
#include <QPointer>
|
||||
#include <QVector>
|
||||
#include <QMutex>
|
||||
#include <QWaitCondition>
|
||||
#include <QNetworkConfigurationManager>
|
||||
|
||||
#include "base/tristatebool.h"
|
||||
#include "base/types.h"
|
||||
#include "torrentinfo.h"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
class session;
|
||||
class entry;
|
||||
struct add_torrent_params;
|
||||
struct pe_settings;
|
||||
struct proxy_settings;
|
||||
struct session_settings;
|
||||
struct session_status;
|
||||
|
||||
class alert;
|
||||
struct torrent_alert;
|
||||
struct state_update_alert;
|
||||
struct stats_alert;
|
||||
struct add_torrent_alert;
|
||||
struct torrent_checked_alert;
|
||||
struct torrent_finished_alert;
|
||||
struct torrent_removed_alert;
|
||||
struct torrent_deleted_alert;
|
||||
struct torrent_delete_failed_alert;
|
||||
struct torrent_paused_alert;
|
||||
struct torrent_resumed_alert;
|
||||
struct save_resume_data_alert;
|
||||
struct save_resume_data_failed_alert;
|
||||
struct file_renamed_alert;
|
||||
struct storage_moved_alert;
|
||||
struct storage_moved_failed_alert;
|
||||
struct metadata_received_alert;
|
||||
struct file_error_alert;
|
||||
struct file_completed_alert;
|
||||
struct tracker_error_alert;
|
||||
struct tracker_reply_alert;
|
||||
struct tracker_warning_alert;
|
||||
struct portmap_error_alert;
|
||||
struct portmap_alert;
|
||||
struct peer_blocked_alert;
|
||||
struct peer_ban_alert;
|
||||
struct fastresume_rejected_alert;
|
||||
struct url_seed_alert;
|
||||
struct listen_succeeded_alert;
|
||||
struct listen_failed_alert;
|
||||
struct external_ip_alert;
|
||||
}
|
||||
|
||||
class QTimer;
|
||||
class QStringList;
|
||||
class QString;
|
||||
class QUrl;
|
||||
template<typename T> class QList;
|
||||
|
||||
class FilterParserThread;
|
||||
class BandwidthScheduler;
|
||||
class Statistics;
|
||||
|
||||
typedef QPair<QString, QString> QStringPair;
|
||||
|
||||
namespace BitTorrent
|
||||
{
|
||||
class InfoHash;
|
||||
class CacheStatus;
|
||||
class SessionStatus;
|
||||
class TorrentHandle;
|
||||
class Tracker;
|
||||
class MagnetUri;
|
||||
class TrackerEntry;
|
||||
struct AddTorrentData;
|
||||
|
||||
struct AddTorrentParams
|
||||
{
|
||||
QString name;
|
||||
QString label;
|
||||
QString savePath;
|
||||
bool disableTempPath; // e.g. for imported torrents
|
||||
bool sequential;
|
||||
TriStateBool addForced;
|
||||
TriStateBool addPaused;
|
||||
QVector<int> filePriorities; // used if TorrentInfo is set
|
||||
bool ignoreShareRatio;
|
||||
bool skipChecking;
|
||||
|
||||
AddTorrentParams();
|
||||
};
|
||||
|
||||
struct TorrentStatusReport
|
||||
{
|
||||
uint nbDownloading = 0;
|
||||
uint nbSeeding = 0;
|
||||
uint nbCompleted = 0;
|
||||
uint nbActive = 0;
|
||||
uint nbInactive = 0;
|
||||
uint nbPaused = 0;
|
||||
uint nbResumed = 0;
|
||||
uint nbErrored = 0;
|
||||
};
|
||||
|
||||
class Session : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_DISABLE_COPY(Session)
|
||||
|
||||
public:
|
||||
static void initInstance();
|
||||
static void freeInstance();
|
||||
static Session *instance();
|
||||
|
||||
bool isDHTEnabled() const;
|
||||
bool isLSDEnabled() const;
|
||||
bool isPexEnabled() const;
|
||||
bool isQueueingEnabled() const;
|
||||
qreal globalMaxRatio() const;
|
||||
bool isTempPathEnabled() const;
|
||||
bool isAppendExtensionEnabled() const;
|
||||
bool useAppendLabelToSavePath() const;
|
||||
QString defaultSavePath() const;
|
||||
QString tempPath() const;
|
||||
|
||||
TorrentHandle *findTorrent(const InfoHash &hash) const;
|
||||
QHash<InfoHash, TorrentHandle *> torrents() const;
|
||||
TorrentStatusReport torrentStatusReport() const;
|
||||
bool hasActiveTorrents() const;
|
||||
bool hasUnfinishedTorrents() const;
|
||||
SessionStatus status() const;
|
||||
CacheStatus cacheStatus() const;
|
||||
quint64 getAlltimeDL() const;
|
||||
quint64 getAlltimeUL() const;
|
||||
int downloadRateLimit() const;
|
||||
int uploadRateLimit() const;
|
||||
bool isListening() const;
|
||||
|
||||
void changeSpeedLimitMode(bool alternative);
|
||||
void setDownloadRateLimit(int rate);
|
||||
void setUploadRateLimit(int rate);
|
||||
void setGlobalMaxRatio(qreal ratio);
|
||||
void enableIPFilter(const QString &filterPath, bool force = false);
|
||||
void disableIPFilter();
|
||||
void banIP(const QString &ip);
|
||||
|
||||
bool isKnownTorrent(const InfoHash &hash) const;
|
||||
bool addTorrent(QString source, const AddTorrentParams ¶ms = AddTorrentParams());
|
||||
bool addTorrent(const TorrentInfo &torrentInfo, const AddTorrentParams ¶ms = AddTorrentParams());
|
||||
bool deleteTorrent(const QString &hash, bool deleteLocalFiles = false);
|
||||
bool loadMetadata(const QString &magnetUri);
|
||||
bool cancelLoadMetadata(const InfoHash &hash);
|
||||
|
||||
void recursiveTorrentDownload(const InfoHash &hash);
|
||||
void increaseTorrentsPriority(const QStringList &hashes);
|
||||
void decreaseTorrentsPriority(const QStringList &hashes);
|
||||
void topTorrentsPriority(const QStringList &hashes);
|
||||
void bottomTorrentsPriority(const QStringList &hashes);
|
||||
|
||||
// TorrentHandle interface
|
||||
void handleTorrentRatioLimitChanged(TorrentHandle *const torrent);
|
||||
void handleTorrentSavePathChanged(TorrentHandle *const torrent);
|
||||
void handleTorrentLabelChanged(TorrentHandle *const torrent, const QString &oldLabel);
|
||||
void handleTorrentMetadataReceived(TorrentHandle *const torrent);
|
||||
void handleTorrentPaused(TorrentHandle *const torrent);
|
||||
void handleTorrentResumed(TorrentHandle *const torrent);
|
||||
void handleTorrentChecked(TorrentHandle *const torrent);
|
||||
void handleTorrentFinished(TorrentHandle *const torrent);
|
||||
void handleTorrentTrackersAdded(TorrentHandle *const torrent, const QList<TrackerEntry> &newTrackers);
|
||||
void handleTorrentTrackersRemoved(TorrentHandle *const torrent, const QList<TrackerEntry> &deletedTrackers);
|
||||
void handleTorrentTrackersChanged(TorrentHandle *const torrent);
|
||||
void handleTorrentUrlSeedsAdded(TorrentHandle *const torrent, const QList<QUrl> &newUrlSeeds);
|
||||
void handleTorrentUrlSeedsRemoved(TorrentHandle *const torrent, const QList<QUrl> &urlSeeds);
|
||||
void handleTorrentResumeDataReady(TorrentHandle *const torrent, const libtorrent::entry &data);
|
||||
void handleTorrentResumeDataFailed(TorrentHandle *const torrent);
|
||||
void handleTorrentTrackerReply(TorrentHandle *const torrent, const QString &trackerUrl);
|
||||
void handleTorrentTrackerWarning(TorrentHandle *const torrent, const QString &trackerUrl);
|
||||
void handleTorrentTrackerError(TorrentHandle *const torrent, const QString &trackerUrl);
|
||||
void handleTorrentTrackerAuthenticationRequired(TorrentHandle *const torrent, const QString &trackerUrl);
|
||||
|
||||
signals:
|
||||
void torrentsUpdated();
|
||||
void addTorrentFailed(const QString &error);
|
||||
void torrentAdded(BitTorrent::TorrentHandle *const torrent);
|
||||
void torrentAboutToBeRemoved(BitTorrent::TorrentHandle *const torrent);
|
||||
void torrentPaused(BitTorrent::TorrentHandle *const torrent);
|
||||
void torrentResumed(BitTorrent::TorrentHandle *const torrent);
|
||||
void torrentFinished(BitTorrent::TorrentHandle *const torrent);
|
||||
void torrentFinishedChecking(BitTorrent::TorrentHandle *const torrent);
|
||||
void torrentSavePathChanged(BitTorrent::TorrentHandle *const torrent);
|
||||
void torrentLabelChanged(BitTorrent::TorrentHandle *const torrent, const QString &oldLabel);
|
||||
void allTorrentsFinished();
|
||||
void metadataLoaded(const BitTorrent::TorrentInfo &info);
|
||||
void torrentMetadataLoaded(BitTorrent::TorrentHandle *const torrent);
|
||||
void fullDiskError(BitTorrent::TorrentHandle *const torrent, const QString &msg);
|
||||
void trackerSuccess(BitTorrent::TorrentHandle *const torrent, const QString &tracker);
|
||||
void trackerWarning(BitTorrent::TorrentHandle *const torrent, const QString &tracker);
|
||||
void trackerError(BitTorrent::TorrentHandle *const torrent, const QString &tracker);
|
||||
void trackerAuthenticationRequired(BitTorrent::TorrentHandle *const torrent);
|
||||
void recursiveTorrentDownloadPossible(BitTorrent::TorrentHandle *const torrent);
|
||||
void speedLimitModeChanged(bool alternative);
|
||||
void ipFilterParsed(bool error, int ruleCount);
|
||||
void trackersAdded(BitTorrent::TorrentHandle *const torrent, const QList<BitTorrent::TrackerEntry> &trackers);
|
||||
void trackersRemoved(BitTorrent::TorrentHandle *const torrent, const QList<BitTorrent::TrackerEntry> &trackers);
|
||||
void trackersChanged(BitTorrent::TorrentHandle *const torrent);
|
||||
void trackerlessStateChanged(BitTorrent::TorrentHandle *const torrent, bool trackerless);
|
||||
void downloadFromUrlFailed(const QString &url, const QString &reason);
|
||||
void downloadFromUrlFinished(const QString &url);
|
||||
|
||||
private slots:
|
||||
void configure();
|
||||
void readAlerts();
|
||||
void refresh();
|
||||
void processBigRatios();
|
||||
void generateResumeData(bool final = false);
|
||||
void handleIPFilterParsed(int ruleCount);
|
||||
void handleIPFilterError();
|
||||
void handleDownloadFinished(const QString &url, const QString &filePath);
|
||||
void handleDownloadFailed(const QString &url, const QString &reason);
|
||||
void handleRedirectedToMagnet(const QString &url, const QString &magnetUri);
|
||||
void switchToAlternativeMode(bool alternative);
|
||||
|
||||
// Session reconfiguration triggers
|
||||
void networkOnlineStateChanged(const bool online);
|
||||
void networkConfigurationChange(const QNetworkConfiguration&);
|
||||
|
||||
private:
|
||||
explicit Session(QObject *parent = 0);
|
||||
~Session();
|
||||
|
||||
bool hasPerTorrentRatioLimit() const;
|
||||
|
||||
void initResumeFolder();
|
||||
|
||||
// Session configuration
|
||||
void setSessionSettings();
|
||||
void setProxySettings(libtorrent::proxy_settings proxySettings);
|
||||
void adjustLimits();
|
||||
void adjustLimits(libtorrent::session_settings &sessionSettings);
|
||||
const QStringList getListeningIPs();
|
||||
void setListeningPort();
|
||||
void setDefaultSavePath(const QString &path);
|
||||
void setDefaultTempPath(const QString &path = QString());
|
||||
void preAllocateAllFiles(bool b);
|
||||
void setMaxConnectionsPerTorrent(int max);
|
||||
void setMaxUploadsPerTorrent(int max);
|
||||
void enableLSD(bool enable);
|
||||
void enableDHT(bool enable);
|
||||
void changeSpeedLimitMode_impl(bool alternative);
|
||||
|
||||
void setAppendLabelToSavePath(bool append);
|
||||
void setAppendExtension(bool append);
|
||||
|
||||
void startUpTorrents();
|
||||
bool addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri,
|
||||
const TorrentInfo &torrentInfo = TorrentInfo(),
|
||||
const QByteArray &fastresumeData = QByteArray());
|
||||
|
||||
void updateRatioTimer();
|
||||
void exportTorrentFile(TorrentHandle *const torrent, TorrentExportFolder folder = TorrentExportFolder::Regular);
|
||||
void saveTorrentResumeData(TorrentHandle *const torrent);
|
||||
|
||||
void handleAlert(libtorrent::alert *a);
|
||||
void dispatchTorrentAlert(libtorrent::alert *a);
|
||||
void handleAddTorrentAlert(libtorrent::add_torrent_alert *p);
|
||||
void handleStateUpdateAlert(libtorrent::state_update_alert *p);
|
||||
void handleMetadataReceivedAlert(libtorrent::metadata_received_alert *p);
|
||||
void handleFileErrorAlert(libtorrent::file_error_alert *p);
|
||||
void handleTorrentRemovedAlert(libtorrent::torrent_removed_alert *p);
|
||||
void handleTorrentDeletedAlert(libtorrent::torrent_deleted_alert *p);
|
||||
void handleTorrentDeleteFailedAlert(libtorrent::torrent_delete_failed_alert *p);
|
||||
void handlePortmapWarningAlert(libtorrent::portmap_error_alert *p);
|
||||
void handlePortmapAlert(libtorrent::portmap_alert *p);
|
||||
void handlePeerBlockedAlert(libtorrent::peer_blocked_alert *p);
|
||||
void handlePeerBanAlert(libtorrent::peer_ban_alert *p);
|
||||
void handleUrlSeedAlert(libtorrent::url_seed_alert *p);
|
||||
void handleListenSucceededAlert(libtorrent::listen_succeeded_alert *p);
|
||||
void handleListenFailedAlert(libtorrent::listen_failed_alert *p);
|
||||
void handleExternalIPAlert(libtorrent::external_ip_alert *p);
|
||||
|
||||
void saveResumeData();
|
||||
bool writeResumeDataFile(TorrentHandle *const torrent, const libtorrent::entry &data);
|
||||
|
||||
void dispatchAlerts(std::auto_ptr<libtorrent::alert> alertPtr);
|
||||
void getPendingAlerts(QVector<libtorrent::alert *> &out, ulong time = 0);
|
||||
|
||||
AddTorrentData addDataFromParams(const AddTorrentParams ¶ms);
|
||||
|
||||
// BitTorrent
|
||||
libtorrent::session *m_nativeSession;
|
||||
|
||||
bool m_LSDEnabled;
|
||||
bool m_DHTEnabled;
|
||||
bool m_PeXEnabled;
|
||||
bool m_queueingEnabled;
|
||||
bool m_torrentExportEnabled;
|
||||
bool m_finishedTorrentExportEnabled;
|
||||
bool m_preAllocateAll;
|
||||
qreal m_globalMaxRatio;
|
||||
int m_numResumeData;
|
||||
int m_extraLimit;
|
||||
bool m_appendLabelToSavePath;
|
||||
bool m_appendExtension;
|
||||
uint m_refreshInterval;
|
||||
MaxRatioAction m_highRatioAction;
|
||||
QList<BitTorrent::TrackerEntry> m_additionalTrackers;
|
||||
QString m_defaultSavePath;
|
||||
QString m_tempPath;
|
||||
QString m_filterPath;
|
||||
QString m_resumeFolderPath;
|
||||
QFile m_resumeFolderLock;
|
||||
QHash<InfoHash, QString> m_savePathsToRemove;
|
||||
|
||||
QTimer *m_refreshTimer;
|
||||
QTimer *m_bigRatioTimer;
|
||||
QTimer *m_resumeDataTimer;
|
||||
Statistics *m_statistics;
|
||||
// IP filtering
|
||||
QPointer<FilterParserThread> m_filterParser;
|
||||
QPointer<BandwidthScheduler> m_bwScheduler;
|
||||
// Tracker
|
||||
QPointer<Tracker> m_tracker;
|
||||
|
||||
QHash<InfoHash, TorrentInfo> m_loadedMetadata;
|
||||
QHash<InfoHash, TorrentHandle *> m_torrents;
|
||||
QHash<InfoHash, AddTorrentData> m_addingTorrents;
|
||||
QHash<QString, AddTorrentParams> m_downloadedTorrents;
|
||||
TorrentStatusReport m_torrentStatusReport;
|
||||
|
||||
QMutex m_alertsMutex;
|
||||
QWaitCondition m_alertsWaitCondition;
|
||||
QVector<libtorrent::alert *> m_alerts;
|
||||
|
||||
QNetworkConfigurationManager m_networkManager;
|
||||
|
||||
static Session *m_instance;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // BITTORRENT_SESSION_H
|
||||
136
src/base/bittorrent/sessionstatus.cpp
Normal file
136
src/base/bittorrent/sessionstatus.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015 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 "sessionstatus.h"
|
||||
|
||||
using namespace BitTorrent;
|
||||
|
||||
SessionStatus::SessionStatus(const libtorrent::session_status &nativeStatus)
|
||||
: m_nativeStatus(nativeStatus)
|
||||
{
|
||||
}
|
||||
|
||||
bool SessionStatus::hasIncomingConnections() const
|
||||
{
|
||||
return m_nativeStatus.has_incoming_connections;
|
||||
}
|
||||
|
||||
int SessionStatus::payloadDownloadRate() const
|
||||
{
|
||||
return m_nativeStatus.payload_download_rate;
|
||||
}
|
||||
|
||||
int SessionStatus::payloadUploadRate() const
|
||||
{
|
||||
return m_nativeStatus.payload_upload_rate;
|
||||
}
|
||||
|
||||
int SessionStatus::downloadRate() const
|
||||
{
|
||||
return m_nativeStatus.download_rate;
|
||||
}
|
||||
|
||||
int SessionStatus::uploadRate() const
|
||||
{
|
||||
return m_nativeStatus.upload_rate;
|
||||
}
|
||||
|
||||
int SessionStatus::ipOverheadDownloadRate() const
|
||||
{
|
||||
return m_nativeStatus.ip_overhead_download_rate;
|
||||
}
|
||||
|
||||
int SessionStatus::ipOverheadUploadRate() const
|
||||
{
|
||||
return m_nativeStatus.ip_overhead_upload_rate;
|
||||
}
|
||||
|
||||
int SessionStatus::dhtDownloadRate() const
|
||||
{
|
||||
return m_nativeStatus.dht_download_rate;
|
||||
}
|
||||
|
||||
int SessionStatus::dhtUploadRate() const
|
||||
{
|
||||
return m_nativeStatus.dht_upload_rate;
|
||||
}
|
||||
|
||||
int SessionStatus::trackerDownloadRate() const
|
||||
{
|
||||
return m_nativeStatus.tracker_download_rate;
|
||||
}
|
||||
|
||||
int SessionStatus::trackerUploadRate() const
|
||||
{
|
||||
return m_nativeStatus.tracker_upload_rate;
|
||||
}
|
||||
|
||||
qlonglong SessionStatus::totalDownload() const
|
||||
{
|
||||
return m_nativeStatus.total_download;
|
||||
}
|
||||
|
||||
qlonglong SessionStatus::totalUpload() const
|
||||
{
|
||||
return m_nativeStatus.total_upload;
|
||||
}
|
||||
|
||||
qlonglong SessionStatus::totalPayloadDownload() const
|
||||
{
|
||||
return m_nativeStatus.total_payload_download;
|
||||
}
|
||||
|
||||
qlonglong SessionStatus::totalPayloadUpload() const
|
||||
{
|
||||
return m_nativeStatus.total_payload_upload;
|
||||
}
|
||||
|
||||
qlonglong SessionStatus::totalWasted() const
|
||||
{
|
||||
return (m_nativeStatus.total_redundant_bytes + m_nativeStatus.total_failed_bytes);
|
||||
}
|
||||
|
||||
int SessionStatus::diskReadQueue() const
|
||||
{
|
||||
return m_nativeStatus.disk_read_queue;
|
||||
}
|
||||
|
||||
int SessionStatus::diskWriteQueue() const
|
||||
{
|
||||
return m_nativeStatus.disk_write_queue;
|
||||
}
|
||||
|
||||
int SessionStatus::dhtNodes() const
|
||||
{
|
||||
return m_nativeStatus.dht_nodes;
|
||||
}
|
||||
|
||||
int SessionStatus::peersCount() const
|
||||
{
|
||||
return m_nativeStatus.num_peers;
|
||||
}
|
||||
79
src/base/bittorrent/sessionstatus.h
Normal file
79
src/base/bittorrent/sessionstatus.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015 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 BITTORRENT_SESSIONSTATUS_H
|
||||
#define BITTORRENT_SESSIONSTATUS_H
|
||||
|
||||
#include <libtorrent/session_status.hpp>
|
||||
#include <QtGlobal>
|
||||
|
||||
namespace BitTorrent
|
||||
{
|
||||
class SessionStatus
|
||||
{
|
||||
public:
|
||||
SessionStatus(const libtorrent::session_status &nativeStatus);
|
||||
|
||||
bool hasIncomingConnections() const;
|
||||
|
||||
// Return current download rate for the BT
|
||||
// session. Payload means that it only take into
|
||||
// account "useful" part of the rate
|
||||
int payloadDownloadRate() const;
|
||||
|
||||
// Return current upload rate for the BT
|
||||
// session. Payload means that it only take into
|
||||
// account "useful" part of the rate
|
||||
int payloadUploadRate() const;
|
||||
|
||||
// Additional download/upload rates
|
||||
int uploadRate() const;
|
||||
int downloadRate() const;
|
||||
int ipOverheadUploadRate() const;
|
||||
int ipOverheadDownloadRate() const;
|
||||
int dhtUploadRate() const;
|
||||
int dhtDownloadRate() const;
|
||||
int trackerUploadRate() const;
|
||||
int trackerDownloadRate() const;
|
||||
|
||||
qlonglong totalDownload() const;
|
||||
qlonglong totalUpload() const;
|
||||
qlonglong totalPayloadDownload() const;
|
||||
qlonglong totalPayloadUpload() const;
|
||||
qlonglong totalWasted() const;
|
||||
int diskReadQueue() const;
|
||||
int diskWriteQueue() const;
|
||||
int dhtNodes() const;
|
||||
int peersCount() const;
|
||||
|
||||
private:
|
||||
libtorrent::session_status m_nativeStatus;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // BITTORRENT_SESSIONSTATUS_H
|
||||
165
src/base/bittorrent/torrentcreatorthread.cpp
Normal file
165
src/base/bittorrent/torrentcreatorthread.cpp
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt 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/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 <boost/bind.hpp>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include "base/utils/fs.h"
|
||||
#include "base/utils/misc.h"
|
||||
#include "base/utils/string.h"
|
||||
#include "torrentcreatorthread.h"
|
||||
|
||||
namespace libt = libtorrent;
|
||||
using namespace BitTorrent;
|
||||
|
||||
// do not include files and folders whose
|
||||
// name starts with a .
|
||||
bool fileFilter(const std::string &f)
|
||||
{
|
||||
return (libt::filename(f)[0] != '.');
|
||||
}
|
||||
|
||||
TorrentCreatorThread::TorrentCreatorThread(QObject *parent)
|
||||
: QThread(parent)
|
||||
{
|
||||
}
|
||||
|
||||
TorrentCreatorThread::~TorrentCreatorThread()
|
||||
{
|
||||
m_abort = true;
|
||||
wait();
|
||||
}
|
||||
|
||||
void TorrentCreatorThread::create(const QString &inputPath, const QString &savePath, const QStringList &trackers,
|
||||
const QStringList &urlSeeds, const QString &comment, bool isPrivate, int pieceSize)
|
||||
{
|
||||
m_inputPath = Utils::Fs::fromNativePath(inputPath);
|
||||
m_savePath = Utils::Fs::fromNativePath(savePath);
|
||||
if (QFile(m_savePath).exists())
|
||||
Utils::Fs::forceRemove(m_savePath);
|
||||
m_trackers = trackers;
|
||||
m_urlSeeds = urlSeeds;
|
||||
m_comment = comment;
|
||||
m_private = isPrivate;
|
||||
m_pieceSize = pieceSize;
|
||||
m_abort = false;
|
||||
|
||||
start();
|
||||
}
|
||||
|
||||
void TorrentCreatorThread::sendProgressSignal(int numHashes, int numPieces)
|
||||
{
|
||||
emit updateProgress(static_cast<int>((numHashes * 100.) / numPieces));
|
||||
}
|
||||
|
||||
void TorrentCreatorThread::abortCreation()
|
||||
{
|
||||
m_abort = true;
|
||||
}
|
||||
|
||||
void TorrentCreatorThread::run()
|
||||
{
|
||||
emit updateProgress(0);
|
||||
|
||||
QString creator_str("qBittorrent " VERSION);
|
||||
try {
|
||||
libt::file_storage fs;
|
||||
// Adding files to the torrent
|
||||
libt::add_files(fs, Utils::String::toStdString(Utils::Fs::toNativePath(m_inputPath)), fileFilter);
|
||||
if (m_abort) return;
|
||||
|
||||
libt::create_torrent t(fs, m_pieceSize);
|
||||
|
||||
// Add url seeds
|
||||
foreach (const QString &seed, m_urlSeeds)
|
||||
t.add_url_seed(Utils::String::toStdString(seed.trimmed()));
|
||||
|
||||
int tier = 0;
|
||||
bool newline = false;
|
||||
foreach (const QString &tracker, m_trackers) {
|
||||
if (tracker.isEmpty()) {
|
||||
if (newline)
|
||||
continue;
|
||||
++tier;
|
||||
newline = true;
|
||||
continue;
|
||||
}
|
||||
t.add_tracker(Utils::String::toStdString(tracker.trimmed()), tier);
|
||||
newline = false;
|
||||
}
|
||||
if (m_abort) return;
|
||||
|
||||
// calculate the hash for all pieces
|
||||
const QString parentPath = Utils::Fs::branchPath(m_inputPath) + "/";
|
||||
libt::set_piece_hashes(t, Utils::String::toStdString(Utils::Fs::toNativePath(parentPath)), boost::bind(&TorrentCreatorThread::sendProgressSignal, this, _1, t.num_pieces()));
|
||||
// Set qBittorrent as creator and add user comment to
|
||||
// torrent_info structure
|
||||
t.set_creator(creator_str.toUtf8().constData());
|
||||
t.set_comment(m_comment.toUtf8().constData());
|
||||
// Is private ?
|
||||
t.set_priv(m_private);
|
||||
if (m_abort) return;
|
||||
|
||||
// create the torrent and print it to out
|
||||
qDebug("Saving to %s", qPrintable(m_savePath));
|
||||
#ifdef _MSC_VER
|
||||
wchar_t *savePathW = new wchar_t[m_savePath.length() + 1];
|
||||
int len = Utils::Fs::toNativePath(m_savePath).toWCharArray(savePathW);
|
||||
savePathW[len] = L'\0';
|
||||
std::ofstream outfile(savePathW, std::ios_base::out | std::ios_base::binary);
|
||||
delete[] savePathW;
|
||||
#else
|
||||
std::ofstream outfile(Utils::Fs::toNativePath(m_savePath).toLocal8Bit().constData(), std::ios_base::out | std::ios_base::binary);
|
||||
#endif
|
||||
if (outfile.fail())
|
||||
throw std::exception();
|
||||
|
||||
libt::bencode(std::ostream_iterator<char>(outfile), t.generate());
|
||||
outfile.close();
|
||||
|
||||
emit updateProgress(100);
|
||||
emit creationSuccess(m_savePath, parentPath);
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
emit creationFailure(Utils::String::fromStdString(e.what()));
|
||||
}
|
||||
}
|
||||
73
src/base/bittorrent/torrentcreatorthread.h
Normal file
73
src/base/bittorrent/torrentcreatorthread.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt 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 BITTORRENT_TORRENTCREATORTHREAD_H
|
||||
#define BITTORRENT_TORRENTCREATORTHREAD_H
|
||||
|
||||
#include <QThread>
|
||||
#include <QStringList>
|
||||
|
||||
namespace BitTorrent
|
||||
{
|
||||
class TorrentCreatorThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TorrentCreatorThread(QObject *parent = 0);
|
||||
~TorrentCreatorThread();
|
||||
|
||||
void create(const QString &inputPath, const QString &savePath, const QStringList &trackers,
|
||||
const QStringList &urlSeeds, const QString &comment, bool isPrivate, int pieceSize);
|
||||
void abortCreation();
|
||||
|
||||
protected:
|
||||
void run();
|
||||
|
||||
signals:
|
||||
void creationFailure(const QString &msg);
|
||||
void creationSuccess(const QString &path, const QString &branchPath);
|
||||
void updateProgress(int progress);
|
||||
|
||||
private:
|
||||
void sendProgressSignal(int numHashes, int numPieces);
|
||||
|
||||
QString m_inputPath;
|
||||
QString m_savePath;
|
||||
QStringList m_trackers;
|
||||
QStringList m_urlSeeds;
|
||||
QString m_comment;
|
||||
bool m_private;
|
||||
int m_pieceSize;
|
||||
bool m_abort;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // BITTORRENT_TORRENTCREATORTHREAD_H
|
||||
1837
src/base/bittorrent/torrenthandle.cpp
Normal file
1837
src/base/bittorrent/torrenthandle.cpp
Normal file
File diff suppressed because it is too large
Load Diff
418
src/base/bittorrent/torrenthandle.h
Normal file
418
src/base/bittorrent/torrenthandle.h
Normal file
@@ -0,0 +1,418 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
||||
*
|
||||
* 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 BITTORRENT_TORRENTHANDLE_H
|
||||
#define BITTORRENT_TORRENTHANDLE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QDateTime>
|
||||
#include <QQueue>
|
||||
#include <QVector>
|
||||
#include <QHash>
|
||||
|
||||
#include <libtorrent/torrent_handle.hpp>
|
||||
#include <boost/function.hpp>
|
||||
|
||||
#include "base/tristatebool.h"
|
||||
#include "private/speedmonitor.h"
|
||||
#include "infohash.h"
|
||||
#include "torrentinfo.h"
|
||||
|
||||
class QBitArray;
|
||||
class QStringList;
|
||||
template<typename T, typename U> struct QPair;
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
class alert;
|
||||
struct stats_alert;
|
||||
struct torrent_checked_alert;
|
||||
struct torrent_finished_alert;
|
||||
struct torrent_paused_alert;
|
||||
struct torrent_resumed_alert;
|
||||
struct save_resume_data_alert;
|
||||
struct save_resume_data_failed_alert;
|
||||
struct file_renamed_alert;
|
||||
struct file_rename_failed_alert;
|
||||
struct storage_moved_alert;
|
||||
struct storage_moved_failed_alert;
|
||||
struct metadata_received_alert;
|
||||
struct file_completed_alert;
|
||||
struct tracker_error_alert;
|
||||
struct tracker_reply_alert;
|
||||
struct tracker_warning_alert;
|
||||
struct fastresume_rejected_alert;
|
||||
struct torrent_status;
|
||||
}
|
||||
|
||||
namespace BitTorrent
|
||||
{
|
||||
struct PeerAddress;
|
||||
class Session;
|
||||
class PeerInfo;
|
||||
class TrackerEntry;
|
||||
struct AddTorrentParams;
|
||||
|
||||
struct AddTorrentData
|
||||
{
|
||||
bool resumed;
|
||||
// for both new and resumed torrents
|
||||
QString name;
|
||||
QString label;
|
||||
QString savePath;
|
||||
bool disableTempPath;
|
||||
bool sequential;
|
||||
bool hasSeedStatus;
|
||||
bool skipChecking;
|
||||
TriStateBool addForced;
|
||||
TriStateBool addPaused;
|
||||
// for new torrents
|
||||
QVector<int> filePriorities;
|
||||
// for resumed torrents
|
||||
qreal ratioLimit;
|
||||
};
|
||||
|
||||
struct TrackerInfo
|
||||
{
|
||||
QString lastMessage;
|
||||
quint32 numPeers;
|
||||
|
||||
TrackerInfo();
|
||||
};
|
||||
|
||||
class TorrentState
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
Unknown = -1,
|
||||
|
||||
ForcedDownloading,
|
||||
Downloading,
|
||||
DownloadingMetadata,
|
||||
Allocating,
|
||||
StalledDownloading,
|
||||
|
||||
ForcedUploading,
|
||||
Uploading,
|
||||
StalledUploading,
|
||||
|
||||
QueuedDownloading,
|
||||
QueuedUploading,
|
||||
|
||||
CheckingUploading,
|
||||
CheckingDownloading,
|
||||
|
||||
QueuedForChecking,
|
||||
CheckingResumeData,
|
||||
|
||||
PausedDownloading,
|
||||
PausedUploading,
|
||||
|
||||
MissingFiles,
|
||||
Error
|
||||
};
|
||||
|
||||
TorrentState(int value);
|
||||
|
||||
operator int() const;
|
||||
QString toString() const;
|
||||
|
||||
private:
|
||||
int m_value;
|
||||
};
|
||||
|
||||
class TorrentHandle : public QObject
|
||||
{
|
||||
Q_DISABLE_COPY(TorrentHandle)
|
||||
|
||||
public:
|
||||
static const qreal USE_GLOBAL_RATIO;
|
||||
static const qreal NO_RATIO_LIMIT;
|
||||
|
||||
static const qreal MAX_RATIO;
|
||||
|
||||
TorrentHandle(Session *session, const libtorrent::torrent_handle &nativeHandle,
|
||||
const AddTorrentData &data);
|
||||
~TorrentHandle();
|
||||
|
||||
bool isValid() const;
|
||||
InfoHash hash() const;
|
||||
QString name() const;
|
||||
QDateTime creationDate() const;
|
||||
QString creator() const;
|
||||
QString comment() const;
|
||||
bool isPrivate() const;
|
||||
qlonglong totalSize() const;
|
||||
qlonglong wantedSize() const;
|
||||
qlonglong completedSize() const;
|
||||
qlonglong incompletedSize() const;
|
||||
qlonglong pieceLength() const;
|
||||
qlonglong wastedSize() const;
|
||||
QString currentTracker() const;
|
||||
|
||||
// 1. savePath() - the path where all the files and subfolders of torrent are stored (as always).
|
||||
// 2. rootPath() - absolute path of torrent file tree (save path + first item from 1st torrent file path).
|
||||
// 3. contentPath() - absolute path of torrent content (root path for multifile torrents, absolute file path for singlefile torrents).
|
||||
//
|
||||
// These methods have 'actual' parameter (defaults to false) which allow to get actual or final path variant.
|
||||
//
|
||||
// Examples.
|
||||
// Suppose we have three torrent with following structures and save path `/home/user/torrents`:
|
||||
//
|
||||
// Torrent A (multifile)
|
||||
//
|
||||
// torrentA/
|
||||
// subdir1/
|
||||
// subdir2/
|
||||
// file1
|
||||
// file2
|
||||
// file3
|
||||
// file4
|
||||
//
|
||||
//
|
||||
// Torrent B (singlefile)
|
||||
//
|
||||
// torrentB/
|
||||
// subdir1/
|
||||
// file1
|
||||
//
|
||||
//
|
||||
// Torrent C (singlefile)
|
||||
//
|
||||
// file1
|
||||
//
|
||||
//
|
||||
// Results:
|
||||
// | | rootPath | contentPath |
|
||||
// |---|------------------------------|--------------------------------------------|
|
||||
// | A | /home/user/torrents/torrentA | /home/user/torrents/torrentA |
|
||||
// | B | /home/user/torrents/torrentB | /home/user/torrents/torrentB/subdir1/file1 |
|
||||
// | C | /home/user/torrents/file1 | /home/user/torrents/file1 |
|
||||
|
||||
QString savePath(bool actual = false) const;
|
||||
QString rootPath(bool actual = false) const;
|
||||
QString contentPath(bool actual = false) const;
|
||||
|
||||
int filesCount() const;
|
||||
int piecesCount() const;
|
||||
int piecesHave() const;
|
||||
qreal progress() const;
|
||||
QString label() const;
|
||||
QDateTime addedTime() const;
|
||||
qreal ratioLimit() const;
|
||||
|
||||
QString filePath(int index) const;
|
||||
QString fileName(int index) const;
|
||||
qlonglong fileSize(int index) const;
|
||||
QStringList absoluteFilePaths() const;
|
||||
QStringList absoluteFilePathsUnwanted() const;
|
||||
QPair<int, int> fileExtremityPieces(int index) const;
|
||||
QVector<int> filePriorities() const;
|
||||
|
||||
TorrentInfo info() const;
|
||||
bool isSeed() const;
|
||||
bool isPaused() const;
|
||||
bool isResumed() const;
|
||||
bool isQueued() const;
|
||||
bool isForced() const;
|
||||
bool isChecking() const;
|
||||
bool isDownloading() const;
|
||||
bool isUploading() const;
|
||||
bool isCompleted() const;
|
||||
bool isActive() const;
|
||||
bool isInactive() const;
|
||||
bool isErrored() const;
|
||||
bool isSequentialDownload() const;
|
||||
bool hasFirstLastPiecePriority() const;
|
||||
TorrentState state() const;
|
||||
bool hasMetadata() const;
|
||||
bool hasMissingFiles() const;
|
||||
bool hasError() const;
|
||||
bool hasFilteredPieces() const;
|
||||
int queuePosition() const;
|
||||
QList<TrackerEntry> trackers() const;
|
||||
QHash<QString, TrackerInfo> trackerInfos() const;
|
||||
QList<QUrl> urlSeeds() const;
|
||||
QString error() const;
|
||||
qlonglong totalDownload() const;
|
||||
qlonglong totalUpload() const;
|
||||
int activeTime() const;
|
||||
int finishedTime() const;
|
||||
int seedingTime() const;
|
||||
qulonglong eta() const;
|
||||
QVector<qreal> filesProgress() const;
|
||||
int seedsCount() const;
|
||||
int peersCount() const;
|
||||
int leechsCount() const;
|
||||
int totalSeedsCount() const;
|
||||
int totalPeersCount() const;
|
||||
int totalLeechersCount() const;
|
||||
int completeCount() const;
|
||||
int incompleteCount() const;
|
||||
QDateTime lastSeenComplete() const;
|
||||
QDateTime completedTime() const;
|
||||
int timeSinceUpload() const;
|
||||
int timeSinceDownload() const;
|
||||
int timeSinceActivity() const;
|
||||
int downloadLimit() const;
|
||||
int uploadLimit() const;
|
||||
bool superSeeding() const;
|
||||
QList<PeerInfo> peers() const;
|
||||
QBitArray pieces() const;
|
||||
QBitArray downloadingPieces() const;
|
||||
QVector<int> pieceAvailability() const;
|
||||
qreal distributedCopies() const;
|
||||
qreal maxRatio(bool *usesGlobalRatio = 0) const;
|
||||
qreal realRatio() const;
|
||||
int uploadPayloadRate() const;
|
||||
int downloadPayloadRate() const;
|
||||
qlonglong totalPayloadUpload() const;
|
||||
qlonglong totalPayloadDownload() const;
|
||||
int connectionsCount() const;
|
||||
int connectionsLimit() const;
|
||||
qlonglong nextAnnounce() const;
|
||||
|
||||
void setName(const QString &name);
|
||||
void setLabel(const QString &label);
|
||||
void setSequentialDownload(bool b);
|
||||
void toggleSequentialDownload();
|
||||
void setFirstLastPiecePriority(bool b);
|
||||
void toggleFirstLastPiecePriority();
|
||||
void pause();
|
||||
void resume(bool forced = false);
|
||||
void move(QString path);
|
||||
void forceReannounce(int index = -1);
|
||||
void forceDHTAnnounce();
|
||||
void forceRecheck();
|
||||
void setTrackerLogin(const QString &username, const QString &password);
|
||||
void renameFile(int index, const QString &name);
|
||||
bool saveTorrentFile(const QString &path);
|
||||
void prioritizeFiles(const QVector<int> &priorities);
|
||||
void setFilePriority(int index, int priority);
|
||||
void setRatioLimit(qreal limit);
|
||||
void setUploadLimit(int limit);
|
||||
void setDownloadLimit(int limit);
|
||||
void setSuperSeeding(bool enable);
|
||||
void flushCache();
|
||||
void addTrackers(const QList<TrackerEntry> &trackers);
|
||||
void replaceTrackers(QList<TrackerEntry> trackers);
|
||||
void addUrlSeeds(const QList<QUrl> &urlSeeds);
|
||||
void removeUrlSeeds(const QList<QUrl> &urlSeeds);
|
||||
bool connectPeer(const PeerAddress &peerAddress);
|
||||
|
||||
QString toMagnetUri() const;
|
||||
|
||||
bool needSaveResumeData() const;
|
||||
|
||||
// Session interface
|
||||
libtorrent::torrent_handle nativeHandle() const;
|
||||
|
||||
void handleAlert(libtorrent::alert *a);
|
||||
void handleStateUpdate(const libtorrent::torrent_status &nativeStatus);
|
||||
void handleTempPathChanged();
|
||||
void handleAppendExtensionToggled();
|
||||
void saveResumeData();
|
||||
|
||||
private:
|
||||
typedef boost::function<void ()> EventTrigger;
|
||||
|
||||
void initialize();
|
||||
void updateStatus();
|
||||
void updateStatus(const libtorrent::torrent_status &nativeStatus);
|
||||
void updateState();
|
||||
void updateTorrentInfo();
|
||||
|
||||
void handleStorageMovedAlert(libtorrent::storage_moved_alert *p);
|
||||
void handleStorageMovedFailedAlert(libtorrent::storage_moved_failed_alert *p);
|
||||
void handleTrackerReplyAlert(libtorrent::tracker_reply_alert *p);
|
||||
void handleTrackerWarningAlert(libtorrent::tracker_warning_alert *p);
|
||||
void handleTrackerErrorAlert(libtorrent::tracker_error_alert *p);
|
||||
void handleTorrentCheckedAlert(libtorrent::torrent_checked_alert *p);
|
||||
void handleTorrentFinishedAlert(libtorrent::torrent_finished_alert *p);
|
||||
void handleTorrentPausedAlert(libtorrent::torrent_paused_alert *p);
|
||||
void handleTorrentResumedAlert(libtorrent::torrent_resumed_alert *p);
|
||||
void handleSaveResumeDataAlert(libtorrent::save_resume_data_alert *p);
|
||||
void handleSaveResumeDataFailedAlert(libtorrent::save_resume_data_failed_alert *p);
|
||||
void handleFastResumeRejectedAlert(libtorrent::fastresume_rejected_alert *p);
|
||||
void handleFileRenamedAlert(libtorrent::file_renamed_alert *p);
|
||||
void handleFileRenameFailedAlert(libtorrent::file_rename_failed_alert *p);
|
||||
void handleFileCompletedAlert(libtorrent::file_completed_alert *p);
|
||||
void handleMetadataReceivedAlert(libtorrent::metadata_received_alert *p);
|
||||
void handleStatsAlert(libtorrent::stats_alert *p);
|
||||
|
||||
bool isMoveInProgress() const;
|
||||
bool useTempPath() const;
|
||||
QString nativeActualSavePath() const;
|
||||
|
||||
void adjustActualSavePath();
|
||||
void adjustActualSavePath_impl();
|
||||
void moveStorage(const QString &newPath);
|
||||
void appendExtensionsToIncompleteFiles();
|
||||
void removeExtensionsFromIncompleteFiles();
|
||||
bool addTracker(const TrackerEntry &tracker);
|
||||
bool addUrlSeed(const QUrl &urlSeed);
|
||||
bool removeUrlSeed(const QUrl &urlSeed);
|
||||
|
||||
Session *const m_session;
|
||||
libtorrent::torrent_handle m_nativeHandle;
|
||||
libtorrent::torrent_status m_nativeStatus;
|
||||
TorrentState m_state;
|
||||
TorrentInfo m_torrentInfo;
|
||||
SpeedMonitor m_speedMonitor;
|
||||
|
||||
InfoHash m_hash;
|
||||
|
||||
QString m_oldPath;
|
||||
QString m_newPath;
|
||||
// m_queuedPath is where files should be moved to,
|
||||
// when current moving is completed
|
||||
QString m_queuedPath;
|
||||
// m_moveFinishedTriggers is activated only when the following conditions are met:
|
||||
// all file rename jobs complete, all file move jobs complete
|
||||
QQueue<EventTrigger> m_moveFinishedTriggers;
|
||||
int m_renameCount;
|
||||
|
||||
// Persistent data
|
||||
QString m_name;
|
||||
QString m_savePath;
|
||||
QString m_label;
|
||||
bool m_hasSeedStatus;
|
||||
qreal m_ratioLimit;
|
||||
bool m_tempPathDisabled;
|
||||
bool m_hasMissingFiles;
|
||||
|
||||
bool m_pauseAfterRecheck;
|
||||
bool m_needSaveResumeData;
|
||||
QHash<QString, TrackerInfo> m_trackerInfos;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // BITTORRENT_TORRENTHANDLE_H
|
||||
223
src/base/bittorrent/torrentinfo.cpp
Normal file
223
src/base/bittorrent/torrentinfo.cpp
Normal file
@@ -0,0 +1,223 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015 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 <QString>
|
||||
#include <QList>
|
||||
#include <QUrl>
|
||||
#include <QDateTime>
|
||||
|
||||
#include <libtorrent/error_code.hpp>
|
||||
|
||||
#include "base/utils/misc.h"
|
||||
#include "base/utils/fs.h"
|
||||
#include "base/utils/string.h"
|
||||
#include "infohash.h"
|
||||
#include "trackerentry.h"
|
||||
#include "torrentinfo.h"
|
||||
|
||||
namespace libt = libtorrent;
|
||||
using namespace BitTorrent;
|
||||
|
||||
TorrentInfo::TorrentInfo(boost::intrusive_ptr<const libt::torrent_info> nativeInfo)
|
||||
: m_nativeInfo(const_cast<libt::torrent_info *>(nativeInfo.get()))
|
||||
{
|
||||
}
|
||||
|
||||
TorrentInfo::TorrentInfo(const TorrentInfo &other)
|
||||
: m_nativeInfo(other.m_nativeInfo)
|
||||
{
|
||||
}
|
||||
|
||||
TorrentInfo &TorrentInfo::operator=(const TorrentInfo &other)
|
||||
{
|
||||
m_nativeInfo = other.m_nativeInfo;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TorrentInfo TorrentInfo::loadFromFile(const QString &path, QString &error)
|
||||
{
|
||||
error.clear();
|
||||
libt::error_code ec;
|
||||
TorrentInfo info(new libt::torrent_info(Utils::String::toStdString(Utils::Fs::toNativePath(path)), ec));
|
||||
if (ec) {
|
||||
error = QString::fromUtf8(ec.message().c_str());
|
||||
qDebug("Cannot load .torrent file: %s", qPrintable(error));
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
TorrentInfo TorrentInfo::loadFromFile(const QString &path)
|
||||
{
|
||||
QString error;
|
||||
return loadFromFile(path, error);
|
||||
}
|
||||
|
||||
bool TorrentInfo::isValid() const
|
||||
{
|
||||
return (m_nativeInfo && m_nativeInfo->is_valid() && (m_nativeInfo->num_files() > 0));
|
||||
}
|
||||
|
||||
InfoHash TorrentInfo::hash() const
|
||||
{
|
||||
if (!isValid()) return InfoHash();
|
||||
return m_nativeInfo->info_hash();
|
||||
}
|
||||
|
||||
QString TorrentInfo::name() const
|
||||
{
|
||||
if (!isValid()) return QString();
|
||||
return Utils::String::fromStdString(m_nativeInfo->name());
|
||||
}
|
||||
|
||||
QDateTime TorrentInfo::creationDate() const
|
||||
{
|
||||
if (!isValid()) return QDateTime();
|
||||
boost::optional<time_t> t = m_nativeInfo->creation_date();
|
||||
return t ? QDateTime::fromTime_t(*t) : QDateTime();
|
||||
}
|
||||
|
||||
QString TorrentInfo::creator() const
|
||||
{
|
||||
if (!isValid()) return QString();
|
||||
return Utils::String::fromStdString(m_nativeInfo->creator());
|
||||
}
|
||||
|
||||
QString TorrentInfo::comment() const
|
||||
{
|
||||
if (!isValid()) return QString();
|
||||
return Utils::String::fromStdString(m_nativeInfo->comment());
|
||||
}
|
||||
|
||||
bool TorrentInfo::isPrivate() const
|
||||
{
|
||||
if (!isValid()) return false;
|
||||
return m_nativeInfo->priv();
|
||||
}
|
||||
|
||||
qlonglong TorrentInfo::totalSize() const
|
||||
{
|
||||
if (!isValid()) return -1;
|
||||
return m_nativeInfo->total_size();
|
||||
}
|
||||
|
||||
int TorrentInfo::filesCount() const
|
||||
{
|
||||
if (!isValid()) return -1;
|
||||
return m_nativeInfo->num_files();
|
||||
}
|
||||
|
||||
int TorrentInfo::pieceLength() const
|
||||
{
|
||||
if (!isValid()) return -1;
|
||||
return m_nativeInfo->piece_length();
|
||||
}
|
||||
|
||||
int TorrentInfo::piecesCount() const
|
||||
{
|
||||
if (!isValid()) return -1;
|
||||
return m_nativeInfo->num_pieces();
|
||||
}
|
||||
|
||||
QString TorrentInfo::filePath(int index) const
|
||||
{
|
||||
if (!isValid()) return QString();
|
||||
return Utils::Fs::fromNativePath(Utils::String::fromStdString(m_nativeInfo->files().file_path(index)));
|
||||
}
|
||||
|
||||
QStringList TorrentInfo::filePaths() const
|
||||
{
|
||||
QStringList list;
|
||||
for (int i = 0; i < filesCount(); ++i)
|
||||
list << filePath(i);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
QString TorrentInfo::fileName(int index) const
|
||||
{
|
||||
return Utils::Fs::fileName(filePath(index));
|
||||
}
|
||||
|
||||
QString TorrentInfo::origFilePath(int index) const
|
||||
{
|
||||
if (!isValid()) return QString();
|
||||
return Utils::Fs::fromNativePath(Utils::String::fromStdString(m_nativeInfo->orig_files().file_path(index)));
|
||||
}
|
||||
|
||||
qlonglong TorrentInfo::fileSize(int index) const
|
||||
{
|
||||
if (!isValid()) return -1;
|
||||
return m_nativeInfo->files().file_size(index);
|
||||
}
|
||||
|
||||
qlonglong TorrentInfo::fileOffset(int index) const
|
||||
{
|
||||
if (!isValid()) return -1;
|
||||
return m_nativeInfo->file_at(index).offset;
|
||||
}
|
||||
|
||||
QList<TrackerEntry> TorrentInfo::trackers() const
|
||||
{
|
||||
if (!isValid()) return QList<TrackerEntry>();
|
||||
|
||||
QList<TrackerEntry> trackers;
|
||||
foreach (const libt::announce_entry &tracker, m_nativeInfo->trackers())
|
||||
trackers.append(tracker);
|
||||
|
||||
return trackers;
|
||||
}
|
||||
|
||||
QList<QUrl> TorrentInfo::urlSeeds() const
|
||||
{
|
||||
if (!isValid()) return QList<QUrl>();
|
||||
|
||||
QList<QUrl> urlSeeds;
|
||||
foreach (const libt::web_seed_entry &webSeed, m_nativeInfo->web_seeds())
|
||||
if (webSeed.type == libt::web_seed_entry::url_seed)
|
||||
urlSeeds.append(QUrl(webSeed.url.c_str()));
|
||||
|
||||
return urlSeeds;
|
||||
}
|
||||
|
||||
QByteArray TorrentInfo::metadata() const
|
||||
{
|
||||
if (!isValid()) return QByteArray();
|
||||
return QByteArray(m_nativeInfo->metadata().get(), m_nativeInfo->metadata_size());
|
||||
}
|
||||
|
||||
void TorrentInfo::renameFile(uint index, const QString &newPath)
|
||||
{
|
||||
if (!isValid()) return;
|
||||
m_nativeInfo->rename_file(index, Utils::String::toStdString(newPath));
|
||||
}
|
||||
|
||||
boost::intrusive_ptr<libtorrent::torrent_info> TorrentInfo::nativeInfo() const
|
||||
{
|
||||
return m_nativeInfo;
|
||||
}
|
||||
87
src/base/bittorrent/torrentinfo.h
Normal file
87
src/base/bittorrent/torrentinfo.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015 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 BITTORRENT_TORRENTINFO_H
|
||||
#define BITTORRENT_TORRENTINFO_H
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <libtorrent/torrent_info.hpp>
|
||||
|
||||
class QString;
|
||||
class QUrl;
|
||||
class QDateTime;
|
||||
class QStringList;
|
||||
class QByteArray;
|
||||
template<typename T> class QList;
|
||||
|
||||
namespace BitTorrent
|
||||
{
|
||||
class InfoHash;
|
||||
class TrackerEntry;
|
||||
|
||||
class TorrentInfo
|
||||
{
|
||||
public:
|
||||
explicit TorrentInfo(boost::intrusive_ptr<const libtorrent::torrent_info> nativeInfo = boost::intrusive_ptr<const libtorrent::torrent_info>());
|
||||
TorrentInfo(const TorrentInfo &other);
|
||||
|
||||
static TorrentInfo loadFromFile(const QString &path, QString &error);
|
||||
static TorrentInfo loadFromFile(const QString &path);
|
||||
|
||||
TorrentInfo &operator=(const TorrentInfo &other);
|
||||
|
||||
bool isValid() const;
|
||||
InfoHash hash() const;
|
||||
QString name() const;
|
||||
QDateTime creationDate() const;
|
||||
QString creator() const;
|
||||
QString comment() const;
|
||||
bool isPrivate() const;
|
||||
qlonglong totalSize() const;
|
||||
int filesCount() const;
|
||||
int pieceLength() const;
|
||||
int piecesCount() const;
|
||||
QString filePath(int index) const;
|
||||
QStringList filePaths() const;
|
||||
QString fileName(int index) const;
|
||||
QString origFilePath(int index) const;
|
||||
qlonglong fileSize(int index) const;
|
||||
qlonglong fileOffset(int index) const;
|
||||
QList<TrackerEntry> trackers() const;
|
||||
QList<QUrl> urlSeeds() const;
|
||||
QByteArray metadata() const;
|
||||
|
||||
void renameFile(uint index, const QString &newPath);
|
||||
boost::intrusive_ptr<libtorrent::torrent_info> nativeInfo() const;
|
||||
|
||||
private:
|
||||
boost::intrusive_ptr<libtorrent::torrent_info> m_nativeInfo;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // BITTORRENT_TORRENTINFO_H
|
||||
257
src/base/bittorrent/tracker.cpp
Normal file
257
src/base/bittorrent/tracker.cpp
Normal file
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt4 and libtorrent.
|
||||
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* 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 <vector>
|
||||
#include <libtorrent/bencode.hpp>
|
||||
#include <libtorrent/entry.hpp>
|
||||
|
||||
#include "base/preferences.h"
|
||||
#include "base/http/server.h"
|
||||
#include "base/utils/string.h"
|
||||
#include "tracker.h"
|
||||
|
||||
// static limits
|
||||
static const int MAX_TORRENTS = 100;
|
||||
static const int MAX_PEERS_PER_TORRENT = 1000;
|
||||
static const int ANNOUNCE_INTERVAL = 1800; // 30min
|
||||
|
||||
using namespace BitTorrent;
|
||||
|
||||
// Peer
|
||||
bool Peer::operator!=(const Peer &other) const
|
||||
{
|
||||
return uid() != other.uid();
|
||||
}
|
||||
|
||||
bool Peer::operator==(const Peer &other) const
|
||||
{
|
||||
return uid() == other.uid();
|
||||
}
|
||||
|
||||
QString Peer::uid() const
|
||||
{
|
||||
return ip + ":" + QString::number(port);
|
||||
}
|
||||
|
||||
libtorrent::entry Peer::toEntry(bool noPeerId) const
|
||||
{
|
||||
libtorrent::entry::dictionary_type peerMap;
|
||||
if (!noPeerId)
|
||||
peerMap["id"] = libtorrent::entry(Utils::String::toStdString(peerId));
|
||||
peerMap["ip"] = libtorrent::entry(Utils::String::toStdString(ip));
|
||||
peerMap["port"] = libtorrent::entry(port);
|
||||
|
||||
return libtorrent::entry(peerMap);
|
||||
}
|
||||
|
||||
// Tracker
|
||||
|
||||
Tracker::Tracker(QObject *parent)
|
||||
: Http::ResponseBuilder(parent)
|
||||
, m_server(new Http::Server(this, this))
|
||||
{
|
||||
}
|
||||
|
||||
Tracker::~Tracker()
|
||||
{
|
||||
if (m_server->isListening())
|
||||
qDebug("Shutting down the embedded tracker...");
|
||||
// TODO: Store the torrent list
|
||||
}
|
||||
|
||||
bool Tracker::start()
|
||||
{
|
||||
const int listenPort = Preferences::instance()->getTrackerPort();
|
||||
|
||||
if (m_server->isListening()) {
|
||||
if (m_server->serverPort() == listenPort) {
|
||||
// Already listening on the right port, just return
|
||||
return true;
|
||||
}
|
||||
// Wrong port, closing the server
|
||||
m_server->close();
|
||||
}
|
||||
|
||||
qDebug("Starting the embedded tracker...");
|
||||
// Listen on the predefined port
|
||||
return m_server->listen(QHostAddress::Any, listenPort);
|
||||
}
|
||||
|
||||
Http::Response Tracker::processRequest(const Http::Request &request, const Http::Environment &env)
|
||||
{
|
||||
clear(); // clear response
|
||||
|
||||
//qDebug("Tracker received the following request:\n%s", qPrintable(parser.toString()));
|
||||
// Is request a GET request?
|
||||
if (request.method != "GET") {
|
||||
qDebug("Tracker: Unsupported HTTP request: %s", qPrintable(request.method));
|
||||
status(100, "Invalid request type");
|
||||
}
|
||||
else if (!request.path.startsWith("/announce", Qt::CaseInsensitive)) {
|
||||
qDebug("Tracker: Unrecognized path: %s", qPrintable(request.path));
|
||||
status(100, "Invalid request type");
|
||||
}
|
||||
else {
|
||||
// OK, this is a GET request
|
||||
m_request = request;
|
||||
m_env = env;
|
||||
respondToAnnounceRequest();
|
||||
}
|
||||
|
||||
return response();
|
||||
}
|
||||
|
||||
void Tracker::respondToAnnounceRequest()
|
||||
{
|
||||
const QStringMap &gets = m_request.gets;
|
||||
TrackerAnnounceRequest annonceReq;
|
||||
|
||||
// IP
|
||||
annonceReq.peer.ip = m_env.clientAddress.toString();
|
||||
|
||||
// 1. Get info_hash
|
||||
if (!gets.contains("info_hash")) {
|
||||
qDebug("Tracker: Missing info_hash");
|
||||
status(101, "Missing info_hash");
|
||||
return;
|
||||
}
|
||||
annonceReq.infoHash = gets.value("info_hash");
|
||||
// info_hash cannot be longer than 20 bytes
|
||||
/*if (annonce_req.info_hash.toLatin1().length() > 20) {
|
||||
qDebug("Tracker: Info_hash is not 20 byte long: %s (%d)", qPrintable(annonce_req.info_hash), annonce_req.info_hash.toLatin1().length());
|
||||
status(150, "Invalid infohash");
|
||||
return;
|
||||
}*/
|
||||
|
||||
// 2. Get peer ID
|
||||
if (!gets.contains("peer_id")) {
|
||||
qDebug("Tracker: Missing peer_id");
|
||||
status(102, "Missing peer_id");
|
||||
return;
|
||||
}
|
||||
annonceReq.peer.peerId = gets.value("peer_id");
|
||||
// peer_id cannot be longer than 20 bytes
|
||||
/*if (annonce_req.peer.peer_id.length() > 20) {
|
||||
qDebug("Tracker: peer_id is not 20 byte long: %s", qPrintable(annonce_req.peer.peer_id));
|
||||
status(151, "Invalid peerid");
|
||||
return;
|
||||
}*/
|
||||
|
||||
// 3. Get port
|
||||
if (!gets.contains("port")) {
|
||||
qDebug("Tracker: Missing port");
|
||||
status(103, "Missing port");
|
||||
return;
|
||||
}
|
||||
bool ok = false;
|
||||
annonceReq.peer.port = gets.value("port").toInt(&ok);
|
||||
if (!ok || annonceReq.peer.port < 1 || annonceReq.peer.port > 65535) {
|
||||
qDebug("Tracker: Invalid port number (%d)", annonceReq.peer.port);
|
||||
status(103, "Missing port");
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. Get event
|
||||
annonceReq.event = "";
|
||||
if (gets.contains("event")) {
|
||||
annonceReq.event = gets.value("event");
|
||||
qDebug("Tracker: event is %s", qPrintable(annonceReq.event));
|
||||
}
|
||||
|
||||
// 5. Get numwant
|
||||
annonceReq.numwant = 50;
|
||||
if (gets.contains("numwant")) {
|
||||
int tmp = gets.value("numwant").toInt();
|
||||
if (tmp > 0) {
|
||||
qDebug("Tracker: numwant = %d", tmp);
|
||||
annonceReq.numwant = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
// 6. no_peer_id (extension)
|
||||
annonceReq.noPeerId = false;
|
||||
if (gets.contains("no_peer_id"))
|
||||
annonceReq.noPeerId = true;
|
||||
|
||||
// 7. TODO: support "compact" extension
|
||||
|
||||
// Done parsing, now let's reply
|
||||
if (m_torrents.contains(annonceReq.infoHash)) {
|
||||
if (annonceReq.event == "stopped") {
|
||||
qDebug("Tracker: Peer stopped downloading, deleting it from the list");
|
||||
m_torrents[annonceReq.infoHash].remove(annonceReq.peer.uid());
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Unknown torrent
|
||||
if (m_torrents.size() == MAX_TORRENTS) {
|
||||
// Reached max size, remove a random torrent
|
||||
m_torrents.erase(m_torrents.begin());
|
||||
}
|
||||
}
|
||||
// Register the user
|
||||
PeerList peers = m_torrents.value(annonceReq.infoHash);
|
||||
if (peers.size() == MAX_PEERS_PER_TORRENT) {
|
||||
// Too many peers, remove a random one
|
||||
peers.erase(peers.begin());
|
||||
}
|
||||
peers[annonceReq.peer.uid()] = annonceReq.peer;
|
||||
m_torrents[annonceReq.infoHash] = peers;
|
||||
|
||||
// Reply
|
||||
replyWithPeerList(annonceReq);
|
||||
}
|
||||
|
||||
void Tracker::replyWithPeerList(const TrackerAnnounceRequest &annonceReq)
|
||||
{
|
||||
// Prepare the entry for bencoding
|
||||
libtorrent::entry::dictionary_type replyDict;
|
||||
replyDict["interval"] = libtorrent::entry(ANNOUNCE_INTERVAL);
|
||||
QList<Peer> peers = m_torrents.value(annonceReq.infoHash).values();
|
||||
libtorrent::entry::list_type peerList;
|
||||
foreach (const Peer &p, peers) {
|
||||
//if (p != annonce_req.peer)
|
||||
peerList.push_back(p.toEntry(annonceReq.noPeerId));
|
||||
}
|
||||
replyDict["peers"] = libtorrent::entry(peerList);
|
||||
libtorrent::entry replyEntry(replyDict);
|
||||
// bencode
|
||||
std::vector<char> buf;
|
||||
libtorrent::bencode(std::back_inserter(buf), replyEntry);
|
||||
QByteArray reply(&buf[0], static_cast<int>(buf.size()));
|
||||
qDebug("Tracker: reply with the following bencoded data:\n %s", reply.constData());
|
||||
|
||||
// HTTP reply
|
||||
print(reply, Http::CONTENT_TYPE_TXT);
|
||||
}
|
||||
|
||||
|
||||
103
src/base/bittorrent/tracker.h
Normal file
103
src/base/bittorrent/tracker.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* 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 BITTORRENT_TRACKER_H
|
||||
#define BITTORRENT_TRACKER_H
|
||||
|
||||
#include <QHash>
|
||||
#include "base/http/types.h"
|
||||
#include "base/http/responsebuilder.h"
|
||||
#include "base/http/irequesthandler.h"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
class entry;
|
||||
}
|
||||
|
||||
namespace Http
|
||||
{
|
||||
class Server;
|
||||
}
|
||||
|
||||
namespace BitTorrent
|
||||
{
|
||||
struct Peer
|
||||
{
|
||||
QString ip;
|
||||
QString peerId;
|
||||
int port;
|
||||
|
||||
bool operator!=(const Peer &other) const;
|
||||
bool operator==(const Peer &other) const;
|
||||
QString uid() const;
|
||||
libtorrent::entry toEntry(bool noPeerId) const;
|
||||
};
|
||||
|
||||
struct TrackerAnnounceRequest
|
||||
{
|
||||
QString infoHash;
|
||||
QString event;
|
||||
int numwant;
|
||||
Peer peer;
|
||||
// Extensions
|
||||
bool noPeerId;
|
||||
};
|
||||
|
||||
typedef QHash<QString, Peer> PeerList;
|
||||
typedef QHash<QString, PeerList> TorrentList;
|
||||
|
||||
/* Basic Bittorrent tracker implementation in Qt */
|
||||
/* Following http://wiki.theory.org/BitTorrent_Tracker_Protocol */
|
||||
class Tracker : public Http::ResponseBuilder, public Http::IRequestHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_DISABLE_COPY(Tracker)
|
||||
|
||||
public:
|
||||
explicit Tracker(QObject *parent = 0);
|
||||
~Tracker();
|
||||
|
||||
bool start();
|
||||
Http::Response processRequest(const Http::Request &request, const Http::Environment &env);
|
||||
|
||||
private:
|
||||
void respondToAnnounceRequest();
|
||||
void replyWithPeerList(const TrackerAnnounceRequest &annonceReq);
|
||||
|
||||
Http::Server *m_server;
|
||||
TorrentList m_torrents;
|
||||
|
||||
Http::Request m_request;
|
||||
Http::Environment m_env;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // BITTORRENT_TRACKER_H
|
||||
95
src/base/bittorrent/trackerentry.cpp
Normal file
95
src/base/bittorrent/trackerentry.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015 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 <QString>
|
||||
|
||||
#include "base/utils/misc.h"
|
||||
#include "base/utils/string.h"
|
||||
#include "trackerentry.h"
|
||||
|
||||
using namespace BitTorrent;
|
||||
|
||||
TrackerEntry::TrackerEntry(const QString &url)
|
||||
: m_nativeEntry(libtorrent::announce_entry(Utils::String::toStdString(url)))
|
||||
{
|
||||
}
|
||||
|
||||
TrackerEntry::TrackerEntry(const libtorrent::announce_entry &nativeEntry)
|
||||
: m_nativeEntry(nativeEntry)
|
||||
{
|
||||
}
|
||||
|
||||
TrackerEntry::TrackerEntry(const TrackerEntry &other)
|
||||
: m_nativeEntry(other.m_nativeEntry)
|
||||
{
|
||||
}
|
||||
|
||||
QString TrackerEntry::url() const
|
||||
{
|
||||
return Utils::String::fromStdString(m_nativeEntry.url);
|
||||
}
|
||||
|
||||
int TrackerEntry::tier() const
|
||||
{
|
||||
return m_nativeEntry.tier;
|
||||
}
|
||||
|
||||
TrackerEntry::Status TrackerEntry::status() const
|
||||
{
|
||||
// libtorrent::announce_entry::is_working() returns
|
||||
// true when the tracker hasn't been tried yet.
|
||||
if (m_nativeEntry.verified && m_nativeEntry.is_working())
|
||||
return Working;
|
||||
else if ((m_nativeEntry.fails == 0) && m_nativeEntry.updating)
|
||||
return Updating;
|
||||
else if (m_nativeEntry.fails == 0)
|
||||
return NotContacted;
|
||||
else
|
||||
return NotWorking;
|
||||
}
|
||||
|
||||
void TrackerEntry::setTier(int value)
|
||||
{
|
||||
m_nativeEntry.tier = value;
|
||||
}
|
||||
|
||||
TrackerEntry &TrackerEntry::operator=(const TrackerEntry &other)
|
||||
{
|
||||
this->m_nativeEntry = other.m_nativeEntry;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool TrackerEntry::operator==(const TrackerEntry &other)
|
||||
{
|
||||
return (QUrl(url()) == QUrl(other.url()));
|
||||
}
|
||||
|
||||
libtorrent::announce_entry TrackerEntry::nativeEntry() const
|
||||
{
|
||||
return m_nativeEntry;
|
||||
}
|
||||
68
src/base/bittorrent/trackerentry.h
Normal file
68
src/base/bittorrent/trackerentry.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015 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 BITTORRENT_TRACKERENTRY_H
|
||||
#define BITTORRENT_TRACKERENTRY_H
|
||||
|
||||
#include <libtorrent/torrent_info.hpp>
|
||||
|
||||
class QString;
|
||||
|
||||
namespace BitTorrent
|
||||
{
|
||||
class TrackerEntry
|
||||
{
|
||||
public:
|
||||
enum Status
|
||||
{
|
||||
NotContacted,
|
||||
Working,
|
||||
Updating,
|
||||
NotWorking
|
||||
};
|
||||
|
||||
TrackerEntry(const QString &url);
|
||||
TrackerEntry(const libtorrent::announce_entry &nativeEntry);
|
||||
TrackerEntry(const TrackerEntry &other);
|
||||
|
||||
QString url() const;
|
||||
int tier() const;
|
||||
Status status() const;
|
||||
|
||||
void setTier(int value);
|
||||
TrackerEntry &operator=(const TrackerEntry &other);
|
||||
bool operator==(const TrackerEntry &other);
|
||||
|
||||
libtorrent::announce_entry nativeEntry() const;
|
||||
|
||||
private:
|
||||
libtorrent::announce_entry m_nativeEntry;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // BITTORRENT_TRACKERENTRY_H
|
||||
Reference in New Issue
Block a user