Redesign main core classes.

This commit is contained in:
Vladimir Golovnev (Glassez)
2015-04-19 18:17:47 +03:00
parent 60c0939e05
commit d16d1fdb3a
152 changed files with 11366 additions and 8967 deletions

View File

@@ -29,10 +29,14 @@
*/
#include "btjson.h"
#include "core/misc.h"
#include "core/fs_utils.h"
#include "qbtsession.h"
#include "core/torrentpersistentdata.h"
#include "qtorrentfilter.h"
#include "core/preferences.h"
#include "core/bittorrent/session.h"
#include "core/bittorrent/sessionstatus.h"
#include "core/bittorrent/torrenthandle.h"
#include "core/bittorrent/trackerentry.h"
#include "core/torrentfilter.h"
#include "jsonutils.h"
#include <QDebug>
@@ -44,11 +48,6 @@
#include <QElapsedTimer>
#endif
#include <libtorrent/session_status.hpp>
#include <libtorrent/session.hpp>
using namespace libtorrent;
#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
#define CACHED_VARIABLE(VARTYPE, VAR, DUR) \
@@ -156,7 +155,7 @@ static const char KEY_RESPONSE_ID[] = "rid";
static const char KEY_SUFFIX_REMOVED[] = "_removed";
QVariantMap getTranserInfoMap();
QVariantMap toMap(const QTorrentHandle& h);
QVariantMap toMap(BitTorrent::TorrentHandle *const torrent);
void processMap(QVariantMap prevData, QVariantMap data, QVariantMap &syncData);
void processHash(QVariantHash prevData, QVariantHash data, QVariantMap &syncData, QVariantList &removedItems);
void processList(QVariantList prevData, QVariantList data, QVariantList &syncData, QVariantList &removedItems);
@@ -241,16 +240,9 @@ QByteArray btjson::getTorrents(QString filter, QString label,
QString sortedColumn, bool reverse, int limit, int offset)
{
QVariantList torrent_list;
std::vector<torrent_handle> torrents = QBtSession::instance()->getTorrents();
std::vector<torrent_handle>::const_iterator it = torrents.begin();
std::vector<torrent_handle>::const_iterator end = torrents.end();
QTorrentFilter torrentFilter(filter, label);
for (; it != end; ++it) {
QTorrentHandle torrent = QTorrentHandle(*it);
if (torrentFilter.apply(torrent))
TorrentFilter torrentFilter(filter, TorrentFilter::AnyHash, label);
foreach (BitTorrent::TorrentHandle *const torrent, BitTorrent::Session::instance()->torrents()) {
if (torrentFilter.match(torrent))
torrent_list.append(toMap(torrent));
}
@@ -315,18 +307,12 @@ QByteArray btjson::getTorrents(QString filter, QString label,
QByteArray btjson::getSyncMainData(int acceptedResponseId, QVariantMap &lastData, QVariantMap &lastAcceptedData)
{
QVariantMap data;
QVariantHash torrents;
std::vector<torrent_handle> torrentsList = QBtSession::instance()->getTorrents();
std::vector<torrent_handle>::const_iterator it = torrentsList.begin();
std::vector<torrent_handle>::const_iterator end = torrentsList.end();
for (; it != end; ++it) {
QTorrentHandle torrent = QTorrentHandle(*it);
foreach (BitTorrent::TorrentHandle *const torrent, BitTorrent::Session::instance()->torrents()) {
QVariantMap map = toMap(torrent);
map.remove(KEY_TORRENT_HASH);
torrents[torrent.hash()] = map;
torrents[torrent->hash()] = map;
}
data["torrents"] = torrents;
@@ -338,7 +324,7 @@ QByteArray btjson::getSyncMainData(int acceptedResponseId, QVariantMap &lastData
data["labels"] = labels;
QVariantMap serverState = getTranserInfoMap();
serverState[KEY_SYNC_MAINDATA_QUEUEING] = QBtSession::instance()->isQueueingEnabled();
serverState[KEY_SYNC_MAINDATA_QUEUEING] = BitTorrent::Session::instance()->isQueueingEnabled();
serverState[KEY_SYNC_MAINDATA_USE_ALT_SPEED_LIMITS] = Preferences::instance()->isAltBandwidthEnabled();
serverState[KEY_SYNC_MAINDATA_REFRESH_INTERVAL] = Preferences::instance()->getRefreshInterval();
data["server_state"] = serverState;
@@ -359,39 +345,35 @@ QByteArray btjson::getSyncMainData(int acceptedResponseId, QVariantMap &lastData
QByteArray btjson::getTrackersForTorrent(const QString& hash)
{
CACHED_VARIABLE_FOR_HASH(QVariantList, tracker_list, CACHE_DURATION_MS, hash);
try {
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
QHash<QString, TrackerInfos> trackers_data = QBtSession::instance()->getTrackersInfo(hash);
std::vector<announce_entry> vect_trackers = h.trackers();
std::vector<announce_entry>::const_iterator it = vect_trackers.begin();
std::vector<announce_entry>::const_iterator end = vect_trackers.end();
for (; it != end; ++it) {
QVariantMap tracker_dict;
const QString tracker_url = misc::toQString(it->url);
tracker_dict[KEY_TRACKER_URL] = tracker_url;
const TrackerInfos data = trackers_data.value(tracker_url, TrackerInfos(tracker_url));
QString status;
if (it->verified) {
status = tr("Working");
}
else {
if (it->updating && it->fails == 0)
status = tr("Updating...");
else
status = it->fails > 0 ? tr("Not working") : tr("Not contacted yet");
}
tracker_dict[KEY_TRACKER_STATUS] = status;
tracker_dict[KEY_TRACKER_PEERS] = static_cast<qulonglong>(trackers_data.value(tracker_url, TrackerInfos(tracker_url)).num_peers);
tracker_dict[KEY_TRACKER_MSG] = data.last_message.trimmed();
tracker_list.append(tracker_dict);
}
}
catch (const std::exception& e) {
qWarning() << Q_FUNC_INFO << "Invalid torrent: " << misc::toQStringU(e.what());
BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash);
if (!torrent) {
qWarning() << Q_FUNC_INFO << "Invalid torrent " << qPrintable(hash);
return QByteArray();
}
QHash<QString, BitTorrent::TrackerInfo> trackers_data = torrent->trackerInfos();
foreach (const BitTorrent::TrackerEntry &tracker, torrent->trackers()) {
QVariantMap tracker_dict;
tracker_dict[KEY_TRACKER_URL] = tracker.url();
const BitTorrent::TrackerInfo data = trackers_data.value(tracker.url());
QString status;
switch (tracker.status()) {
case BitTorrent::TrackerEntry::NotContacted:
status = tr("Not contacted yet"); break;
case BitTorrent::TrackerEntry::Updating:
status = tr("Updating..."); break;
case BitTorrent::TrackerEntry::Working:
status = tr("Working"); break;
case BitTorrent::TrackerEntry::NotWorking:
status = tr("Not working"); break;
}
tracker_dict[KEY_TRACKER_STATUS] = status;
tracker_dict[KEY_TRACKER_PEERS] = data.numPeers;
tracker_dict[KEY_TRACKER_MSG] = data.lastMessage.trimmed();
tracker_list.append(tracker_dict);
}
return json::toJson(tracker_list);
}
@@ -420,40 +402,33 @@ QByteArray btjson::getTrackersForTorrent(const QString& hash)
QByteArray btjson::getPropertiesForTorrent(const QString& hash)
{
CACHED_VARIABLE_FOR_HASH(QVariantMap, data, CACHE_DURATION_MS, hash);
try {
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
libtorrent::torrent_status status = h.status(torrent_handle::query_accurate_download_counters);
if (!status.has_metadata)
return QByteArray();
// Save path
QString save_path = fsutils::toNativePath(TorrentPersistentData::instance()->getSavePath(hash));
if (save_path.isEmpty())
save_path = fsutils::toNativePath(h.save_path());
data[KEY_PROP_SAVE_PATH] = save_path;
data[KEY_PROP_CREATION_DATE] = h.creation_date_unix();
data[KEY_PROP_PIECE_SIZE] = static_cast<qlonglong>(h.piece_length());
data[KEY_PROP_COMMENT] = h.comment();
data[KEY_PROP_WASTED] = static_cast<qlonglong>(status.total_failed_bytes + status.total_redundant_bytes);
data[KEY_PROP_UPLOADED] = static_cast<qlonglong>(status.all_time_upload);
data[KEY_PROP_UPLOADED_SESSION] = static_cast<qlonglong>(status.total_payload_upload);
data[KEY_PROP_DOWNLOADED] = static_cast<qlonglong>(status.all_time_download);
data[KEY_PROP_DOWNLOADED_SESSION] = static_cast<qlonglong>(status.total_payload_download);
data[KEY_PROP_UP_LIMIT] = h.upload_limit() <= 0 ? -1 : h.upload_limit();
data[KEY_PROP_DL_LIMIT] = h.download_limit() <= 0 ? -1 : h.download_limit();
data[KEY_PROP_TIME_ELAPSED] = status.active_time;
data[KEY_PROP_SEEDING_TIME] = status.seeding_time;
data[KEY_PROP_CONNECT_COUNT] = status.num_connections;
data[KEY_PROP_CONNECT_COUNT_LIMIT] = status.connections_limit;
const qreal ratio = QBtSession::instance()->getRealRatio(status);
data[KEY_PROP_RATIO] = ratio > QBtSession::MAX_RATIO ? -1 : ratio;
}
catch (const std::exception& e) {
qWarning() << Q_FUNC_INFO << "Invalid torrent: " << misc::toQStringU(e.what());
BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash);
if (!torrent) {
qWarning() << Q_FUNC_INFO << "Invalid torrent " << qPrintable(hash);
return QByteArray();
}
if (!torrent->hasMetadata())
return QByteArray();
data[KEY_PROP_SAVE_PATH] = fsutils::toNativePath(torrent->savePath());
data[KEY_PROP_CREATION_DATE] = torrent->creationDate().toTime_t();
data[KEY_PROP_PIECE_SIZE] = torrent->pieceLength();
data[KEY_PROP_COMMENT] = torrent->comment();
data[KEY_PROP_WASTED] = torrent->wastedSize();
data[KEY_PROP_UPLOADED] = torrent->totalUpload();
data[KEY_PROP_UPLOADED_SESSION] = torrent->totalPayloadUpload();
data[KEY_PROP_DOWNLOADED] = torrent->totalDownload();
data[KEY_PROP_DOWNLOADED_SESSION] = torrent->totalPayloadDownload();
data[KEY_PROP_UP_LIMIT] = torrent->uploadLimit() <= 0 ? -1 : torrent->uploadLimit();
data[KEY_PROP_DL_LIMIT] = torrent->downloadLimit() <= 0 ? -1 : torrent->downloadLimit();
data[KEY_PROP_TIME_ELAPSED] = torrent->activeTime();
data[KEY_PROP_SEEDING_TIME] = torrent->seedingTime();
data[KEY_PROP_CONNECT_COUNT] = torrent->connectionsCount();
data[KEY_PROP_CONNECT_COUNT_LIMIT] = torrent->connectionsLimit();
const qreal ratio = torrent->realRatio();
data[KEY_PROP_RATIO] = ratio > BitTorrent::TorrentHandle::MAX_RATIO ? -1 : ratio;
return json::toJson(data);
}
@@ -471,35 +446,33 @@ QByteArray btjson::getPropertiesForTorrent(const QString& hash)
QByteArray btjson::getFilesForTorrent(const QString& hash)
{
CACHED_VARIABLE_FOR_HASH(QVariantList, file_list, CACHE_DURATION_MS, hash);
try {
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
if (!h.has_metadata())
return QByteArray();
const std::vector<int> priorities = h.file_priorities();
std::vector<size_type> fp;
h.file_progress(fp);
for (int i = 0; i < h.num_files(); ++i) {
QVariantMap file_dict;
QString fileName = h.filepath_at(i);
if (fileName.endsWith(".!qB", Qt::CaseInsensitive))
fileName.chop(4);
file_dict[KEY_FILE_NAME] = fsutils::toNativePath(fileName);
const size_type size = h.filesize_at(i);
file_dict[KEY_FILE_SIZE] = static_cast<qlonglong>(size);
file_dict[KEY_FILE_PROGRESS] = (size > 0) ? (fp[i] / (double) size) : 1.;
file_dict[KEY_FILE_PRIORITY] = priorities[i];
if (i == 0)
file_dict[KEY_FILE_IS_SEED] = h.is_seed();
file_list.append(file_dict);
}
}
catch (const std::exception& e) {
qWarning() << Q_FUNC_INFO << "Invalid torrent: " << misc::toQStringU(e.what());
BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash);
if (!torrent) {
qWarning() << Q_FUNC_INFO << "Invalid torrent " << qPrintable(hash);
return QByteArray();
}
if (!torrent->hasMetadata())
return QByteArray();
const QVector<int> priorities = torrent->filePriorities();
QVector<qreal> fp = torrent->filesProgress();
for (int i = 0; i < torrent->filesCount(); ++i) {
QVariantMap file_dict;
QString fileName = torrent->filePath(i);
if (fileName.endsWith(".!qB", Qt::CaseInsensitive))
fileName.chop(4);
file_dict[KEY_FILE_NAME] = fsutils::toNativePath(fileName);
const qlonglong size = torrent->fileSize(i);
file_dict[KEY_FILE_SIZE] = size;
file_dict[KEY_FILE_PROGRESS] = fp[i];
file_dict[KEY_FILE_PRIORITY] = priorities[i];
if (i == 0)
file_dict[KEY_FILE_IS_SEED] = torrent->isSeed();
file_list.append(file_dict);
}
return json::toJson(file_list);
}
@@ -525,19 +498,18 @@ QByteArray btjson::getTransferInfo()
QVariantMap getTranserInfoMap()
{
QVariantMap map;
session_status sessionStatus = QBtSession::instance()->getSessionStatus();
session_settings sessionSettings = QBtSession::instance()->getSession()->settings();
map[KEY_TRANSFER_DLSPEED] = sessionStatus.payload_download_rate;
map[KEY_TRANSFER_DLDATA] = static_cast<qlonglong>(sessionStatus.total_payload_download);
map[KEY_TRANSFER_UPSPEED] = sessionStatus.payload_upload_rate;
map[KEY_TRANSFER_UPDATA] = static_cast<qlonglong>(sessionStatus.total_payload_upload);
map[KEY_TRANSFER_DLRATELIMIT] = sessionSettings.download_rate_limit;
map[KEY_TRANSFER_UPRATELIMIT] = sessionSettings.upload_rate_limit;
map[KEY_TRANSFER_DHT_NODES] = sessionStatus.dht_nodes;
if (!QBtSession::instance()->getSession()->is_listening())
BitTorrent::SessionStatus sessionStatus = BitTorrent::Session::instance()->status();
map[KEY_TRANSFER_DLSPEED] = sessionStatus.payloadDownloadRate();
map[KEY_TRANSFER_DLDATA] = sessionStatus.totalPayloadDownload();
map[KEY_TRANSFER_UPSPEED] = sessionStatus.payloadUploadRate();
map[KEY_TRANSFER_UPDATA] = sessionStatus.totalPayloadUpload();
map[KEY_TRANSFER_DLRATELIMIT] = BitTorrent::Session::instance()->downloadRateLimit();
map[KEY_TRANSFER_UPRATELIMIT] = BitTorrent::Session::instance()->uploadRateLimit();
map[KEY_TRANSFER_DHT_NODES] = sessionStatus.dhtNodes();
if (!BitTorrent::Session::instance()->isListening())
map[KEY_TRANSFER_CONNECTION_STATUS] = "disconnected";
else
map[KEY_TRANSFER_CONNECTION_STATUS] = sessionStatus.has_incoming_connections ? "connected" : "firewalled";
map[KEY_TRANSFER_CONNECTION_STATUS] = sessionStatus.hasIncomingConnections() ? "connected" : "firewalled";
return map;
}
@@ -547,44 +519,39 @@ QByteArray btjson::getTorrentsRatesLimits(QStringList &hashes, bool downloadLimi
foreach (const QString &hash, hashes) {
int limit = -1;
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
if (h.is_valid())
limit = downloadLimits ? h.download_limit() : h.upload_limit();
BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash);
if (torrent)
limit = downloadLimits ? torrent->downloadLimit() : torrent->uploadLimit();
map[hash] = limit;
}
return json::toJson(map);
}
QVariantMap toMap(const QTorrentHandle& h)
QVariantMap toMap(BitTorrent::TorrentHandle *const torrent)
{
libtorrent::torrent_status status = h.status(torrent_handle::query_accurate_download_counters);
QVariantMap ret;
ret[KEY_TORRENT_HASH] = h.hash();
ret[KEY_TORRENT_NAME] = h.name();
ret[KEY_TORRENT_SIZE] = static_cast<qlonglong>(status.total_wanted);
ret[KEY_TORRENT_PROGRESS] = h.progress(status);
ret[KEY_TORRENT_DLSPEED] = status.download_payload_rate;
ret[KEY_TORRENT_UPSPEED] = status.upload_payload_rate;
if (QBtSession::instance()->isQueueingEnabled() && h.queue_position(status) >= 0)
ret[KEY_TORRENT_PRIORITY] = h.queue_position(status);
else
ret[KEY_TORRENT_PRIORITY] = -1;
ret[KEY_TORRENT_SEEDS] = status.num_seeds;
ret[KEY_TORRENT_NUM_COMPLETE] = status.num_complete;
ret[KEY_TORRENT_LEECHS] = status.num_peers - status.num_seeds;
ret[KEY_TORRENT_NUM_INCOMPLETE] = status.num_incomplete;
const qreal ratio = QBtSession::instance()->getRealRatio(status);
ret[KEY_TORRENT_RATIO] = (ratio > QBtSession::MAX_RATIO) ? -1 : ratio;
ret[KEY_TORRENT_STATE] = h.torrentState().toString();
ret[KEY_TORRENT_ETA] = h.eta();
ret[KEY_TORRENT_SEQUENTIAL_DOWNLOAD] = status.sequential_download;
if (h.has_metadata())
ret[KEY_TORRENT_FIRST_LAST_PIECE_PRIO] = h.first_last_piece_first();
ret[KEY_TORRENT_LABEL] = TorrentPersistentData::instance()->getLabel(h.hash());
ret[KEY_TORRENT_SUPER_SEEDING] = status.super_seeding;
ret[KEY_TORRENT_FORCE_START] = h.is_forced(status);
ret[KEY_TORRENT_HASH] = QString(torrent->hash());
ret[KEY_TORRENT_NAME] = torrent->name();
ret[KEY_TORRENT_SIZE] = torrent->wantedSize();
ret[KEY_TORRENT_PROGRESS] = torrent->progress();
ret[KEY_TORRENT_DLSPEED] = torrent->downloadPayloadRate();
ret[KEY_TORRENT_UPSPEED] = torrent->uploadPayloadRate();
ret[KEY_TORRENT_PRIORITY] = torrent->queuePosition();
ret[KEY_TORRENT_SEEDS] = torrent->seedsCount();
ret[KEY_TORRENT_NUM_COMPLETE] = torrent->completeCount();
ret[KEY_TORRENT_LEECHS] = torrent->leechsCount();
ret[KEY_TORRENT_NUM_INCOMPLETE] = torrent->incompleteCount();
const qreal ratio = torrent->realRatio();
ret[KEY_TORRENT_RATIO] = (ratio > BitTorrent::TorrentHandle::MAX_RATIO) ? -1 : ratio;
ret[KEY_TORRENT_STATE] = torrent->state().toString();
ret[KEY_TORRENT_ETA] = torrent->eta();
ret[KEY_TORRENT_SEQUENTIAL_DOWNLOAD] = torrent->isSequentialDownload();
if (torrent->hasMetadata())
ret[KEY_TORRENT_FIRST_LAST_PIECE_PRIO] = torrent->hasFirstLastPiecePriority();
ret[KEY_TORRENT_LABEL] = torrent->label();
ret[KEY_TORRENT_SUPER_SEEDING] = torrent->superSeeding();
ret[KEY_TORRENT_FORCE_START] = torrent->isForced();
return ret;
}

View File

@@ -35,8 +35,6 @@
#include <QString>
#include <QVariant>
class QTorrentHandle;
class btjson
{
Q_DECLARE_TR_FUNCTIONS(misc)

View File

@@ -30,15 +30,14 @@
#include "prefjson.h"
#include "core/preferences.h"
#include "qbtsession.h"
#include "core/scannedfoldersmodel.h"
#include "core/scanfoldersmodel.h"
#include "core/fs_utils.h"
#include <libtorrent/version.hpp>
#ifndef QT_NO_OPENSSL
#include <QSslCertificate>
#include <QSslKey>
#endif
#include <QStringList>
#include <QTranslator>
#include <QCoreApplication>
#include "jsonutils.h"
@@ -183,7 +182,7 @@ void prefjson::setPreferences(const QString& json)
foreach (const QString &old_folder, old_folders) {
// Update deleted folders
if (!new_folders.contains(old_folder)) {
QBtSession::instance()->getScanFoldersModel()->removePath(old_folder);
ScanFoldersModel::instance()->removePath(old_folder);
}
}
int i = 0;
@@ -191,7 +190,7 @@ void prefjson::setPreferences(const QString& json)
qDebug("New watched folder: %s", qPrintable(new_folder));
// Update new folders
if (!old_folders.contains(fsutils::fromNativePath(new_folder))) {
QBtSession::instance()->getScanFoldersModel()->addPath(new_folder, download_at_path.at(i));
ScanFoldersModel::instance()->addPath(new_folder, download_at_path.at(i));
}
++i;
}
@@ -337,5 +336,5 @@ void prefjson::setPreferences(const QString& json)
if (m.contains("dyndns_domain"))
pref->setDynDomainName(m["dyndns_domain"].toString());
// Save preferences
pref->save();
pref->apply();
}

View File

@@ -32,22 +32,19 @@
#include <QCryptographicHash>
#include <queue>
#include <vector>
#include <libtorrent/session.hpp>
#ifndef DISABLE_GUI
// TODO: Drop GUI dependency!
#include "iconprovider.h"
#endif
#include "core/iconprovider.h"
#include "core/misc.h"
#include "core/fs_utils.h"
#include "core/preferences.h"
#include "btjson.h"
#include "prefjson.h"
#include "qbtsession.h"
#include "core/bittorrent/session.h"
#include "core/bittorrent/trackerentry.h"
#include "core/bittorrent/torrentinfo.h"
#include "core/bittorrent/torrenthandle.h"
#include "websessiondata.h"
#include "webapplication.h"
using namespace libtorrent;
static const int API_VERSION = 2;
static const int API_VERSION_MIN = 2;
@@ -195,11 +192,7 @@ void WebApplication::action_public_theme()
return;
}
#ifdef DISABLE_GUI
QString url = ":/icons/oxygen/" + args_.front() + ".png";
#else
QString url = IconProvider::instance()->getIconPath(args_.front());
#endif
qDebug() << Q_FUNC_INFO << "There icon:" << url;
printFile(url);
@@ -312,13 +305,8 @@ void WebApplication::action_command_download()
qDebug("Converting bc link to magnet link");
url = misc::bcLinkToMagnet(url);
}
else if (url.startsWith("magnet:", Qt::CaseInsensitive)) {
QBtSession::instance()->addMagnetSkipAddDlg(url);
}
else {
qDebug("Downloading url: %s", qPrintable(url));
QBtSession::instance()->downloadUrlAndSkipDialog(url);
}
BitTorrent::Session::instance()->addTorrent(url);
}
}
}
@@ -332,11 +320,17 @@ void WebApplication::action_command_upload()
QString filePath = saveTmpFile(torrent.data);
if (!filePath.isEmpty()) {
QTorrentHandle h = QBtSession::instance()->addTorrent(filePath);
if (!h.is_valid()) {
status(415, "Internal Server Error");
BitTorrent::TorrentInfo torrentInfo = BitTorrent::TorrentInfo::loadFromFile(filePath);
if (!torrentInfo.isValid()) {
status(415, "Unsupported Media Type");
print(QObject::tr("Error: '%1' is not a valid torrent file.\n").arg(torrent.filename), Http::CONTENT_TYPE_TXT);
}
else {
if (!BitTorrent::Session::instance()->addTorrent(torrentInfo)) {
status(500, "Internal Server Error");
print(QObject::tr("Error: Could not add torrent to session."), Http::CONTENT_TYPE_TXT);
}
}
// Clean up
fsutils::forceRemove(filePath);
}
@@ -354,37 +348,49 @@ void WebApplication::action_command_addTrackers()
CHECK_PARAMETERS("hash" << "urls");
QString hash = request().posts["hash"];
if (!hash.isEmpty()) {
QString urls = request().posts["urls"];
QStringList list = urls.split('\n');
QBtSession::instance()->addTrackersAndUrlSeeds(hash, list, QStringList());
BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash);
if (torrent) {
QList<BitTorrent::TrackerEntry> trackers;
foreach (const QString &url, request().posts["urls"].split('\n'))
trackers << url;
torrent->addTrackers(trackers);
}
}
void WebApplication::action_command_resumeAll()
{
CHECK_URI(0);
QBtSession::instance()->resumeAllTorrents();
foreach (BitTorrent::TorrentHandle *const torrent, BitTorrent::Session::instance()->torrents())
torrent->resume();
}
void WebApplication::action_command_pauseAll()
{
CHECK_URI(0);
QBtSession::instance()->pauseAllTorrents();
foreach (BitTorrent::TorrentHandle *const torrent, BitTorrent::Session::instance()->torrents())
torrent->pause();
}
void WebApplication::action_command_resume()
{
CHECK_URI(0);
CHECK_PARAMETERS("hash");
QBtSession::instance()->resumeTorrent(request().posts["hash"]);
BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(request().posts["hash"]);
if (torrent)
torrent->resume();
}
void WebApplication::action_command_pause()
{
CHECK_URI(0);
CHECK_PARAMETERS("hash");
QBtSession::instance()->pauseTorrent(request().posts["hash"]);
BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(request().posts["hash"]);
if (torrent)
torrent->pause();
}
void WebApplication::action_command_setPreferences()
@@ -401,22 +407,22 @@ void WebApplication::action_command_setFilePrio()
QString hash = request().posts["hash"];
int file_id = request().posts["id"].toInt();
int priority = request().posts["priority"].toInt();
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash);
if (h.is_valid() && h.has_metadata())
h.file_priority(file_id, priority);
if (torrent && torrent->hasMetadata())
torrent->setFilePriority(file_id, priority);
}
void WebApplication::action_command_getGlobalUpLimit()
{
CHECK_URI(0);
print(QByteArray::number(QBtSession::instance()->getSession()->settings().upload_rate_limit));
print(QByteArray::number(BitTorrent::Session::instance()->uploadRateLimit()));
}
void WebApplication::action_command_getGlobalDlLimit()
{
CHECK_URI(0);
print(QByteArray::number(QBtSession::instance()->getSession()->settings().download_rate_limit));
print(QByteArray::number(BitTorrent::Session::instance()->downloadRateLimit()));
}
void WebApplication::action_command_setGlobalUpLimit()
@@ -426,7 +432,7 @@ void WebApplication::action_command_setGlobalUpLimit()
qlonglong limit = request().posts["limit"].toLongLong();
if (limit == 0) limit = -1;
QBtSession::instance()->setUploadRateLimit(limit);
BitTorrent::Session::instance()->setUploadRateLimit(limit);
if (Preferences::instance()->isAltBandwidthEnabled())
Preferences::instance()->setAltGlobalUploadLimit(limit / 1024.);
else
@@ -440,7 +446,7 @@ void WebApplication::action_command_setGlobalDlLimit()
qlonglong limit = request().posts["limit"].toLongLong();
if (limit == 0) limit = -1;
QBtSession::instance()->setDownloadRateLimit(limit);
BitTorrent::Session::instance()->setDownloadRateLimit(limit);
if (Preferences::instance()->isAltBandwidthEnabled())
Preferences::instance()->setAltGlobalDownloadLimit(limit / 1024.);
else
@@ -474,9 +480,9 @@ void WebApplication::action_command_setTorrentsUpLimit()
QStringList hashes = request().posts["hashes"].split("|");
foreach (const QString &hash, hashes) {
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
if (h.is_valid())
h.set_upload_limit(limit);
BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash);
if (torrent)
torrent->setUploadLimit(limit);
}
}
@@ -491,16 +497,16 @@ void WebApplication::action_command_setTorrentsDlLimit()
QStringList hashes = request().posts["hashes"].split("|");
foreach (const QString &hash, hashes) {
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
if (h.is_valid())
h.set_download_limit(limit);
BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash);
if (torrent)
torrent->setDownloadLimit(limit);
}
}
void WebApplication::action_command_toggleAlternativeSpeedLimits()
{
CHECK_URI(0);
QBtSession::instance()->useAlternativeSpeedsLimit(!Preferences::instance()->isAltBandwidthEnabled());
BitTorrent::Session::instance()->changeSpeedLimitMode(!Preferences::instance()->isAltBandwidthEnabled());
}
void WebApplication::action_command_alternativeSpeedLimitsEnabled()
@@ -515,11 +521,9 @@ void WebApplication::action_command_toggleSequentialDownload()
CHECK_PARAMETERS("hashes");
QStringList hashes = request().posts["hashes"].split("|");
foreach (const QString &hash, hashes) {
try {
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
h.toggleSequentialDownload();
}
catch(invalid_handle&) {}
BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash);
if (torrent)
torrent->toggleSequentialDownload();
}
}
@@ -529,11 +533,9 @@ void WebApplication::action_command_toggleFirstLastPiecePrio()
CHECK_PARAMETERS("hashes");
QStringList hashes = request().posts["hashes"].split("|");
foreach (const QString &hash, hashes) {
try {
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
h.toggleFirstLastPiecePrio();
}
catch(invalid_handle&) {}
BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash);
if (torrent)
torrent->toggleFirstLastPiecePriority();
}
}
@@ -544,11 +546,9 @@ void WebApplication::action_command_setSuperSeeding()
bool value = request().posts["value"] == "true";
QStringList hashes = request().posts["hashes"].split("|");
foreach (const QString &hash, hashes) {
try {
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
h.super_seeding(value);
}
catch(invalid_handle&) {}
BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash);
if (torrent)
torrent->setSuperSeeding(value);
}
}
@@ -559,9 +559,9 @@ void WebApplication::action_command_setForceStart()
bool value = request().posts["value"] == "true";
QStringList hashes = request().posts["hashes"].split("|");
foreach (const QString &hash, hashes) {
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
if (h.is_valid())
QBtSession::instance()->resumeTorrent(hash, value);
BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash);
if (torrent)
torrent->resume(value);
}
}
@@ -571,7 +571,7 @@ void WebApplication::action_command_delete()
CHECK_PARAMETERS("hashes");
QStringList hashes = request().posts["hashes"].split("|");
foreach (const QString &hash, hashes)
QBtSession::instance()->deleteTorrent(hash, false);
BitTorrent::Session::instance()->deleteTorrent(hash, false);
}
void WebApplication::action_command_deletePerm()
@@ -580,7 +580,7 @@ void WebApplication::action_command_deletePerm()
CHECK_PARAMETERS("hashes");
QStringList hashes = request().posts["hashes"].split("|");
foreach (const QString &hash, hashes)
QBtSession::instance()->deleteTorrent(hash, true);
BitTorrent::Session::instance()->deleteTorrent(hash, true);
}
void WebApplication::action_command_increasePrio()
@@ -594,32 +594,7 @@ void WebApplication::action_command_increasePrio()
}
QStringList hashes = request().posts["hashes"].split("|");
std::priority_queue<QPair<int, QTorrentHandle>,
std::vector<QPair<int, QTorrentHandle> >,
std::greater<QPair<int, QTorrentHandle> > > torrent_queue;
// Sort torrents by priority
foreach (const QString &hash, hashes) {
try {
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
if (!h.is_seed())
torrent_queue.push(qMakePair(h.queue_position(), h));
}
catch(invalid_handle&) {}
}
// Increase torrents priority (starting with the ones with highest priority)
while(!torrent_queue.empty()) {
QTorrentHandle h = torrent_queue.top().second;
try {
h.queue_position_up();
}
catch(invalid_handle&) {}
torrent_queue.pop();
}
BitTorrent::Session::instance()->increaseTorrentsPriority(hashes);
}
void WebApplication::action_command_decreasePrio()
@@ -633,33 +608,7 @@ void WebApplication::action_command_decreasePrio()
}
QStringList hashes = request().posts["hashes"].split("|");
std::priority_queue<QPair<int, QTorrentHandle>,
std::vector<QPair<int, QTorrentHandle> >,
std::less<QPair<int, QTorrentHandle> > > torrent_queue;
// Sort torrents by priority
foreach (const QString &hash, hashes) {
try {
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
if (!h.is_seed())
torrent_queue.push(qMakePair(h.queue_position(), h));
}
catch(invalid_handle&) {}
}
// Decrease torrents priority (starting with the ones with lowest priority)
while(!torrent_queue.empty()) {
QTorrentHandle h = torrent_queue.top().second;
try {
h.queue_position_down();
}
catch(invalid_handle&) {}
torrent_queue.pop();
}
BitTorrent::Session::instance()->decreaseTorrentsPriority(hashes);
}
void WebApplication::action_command_topPrio()
@@ -672,10 +621,8 @@ void WebApplication::action_command_topPrio()
return;
}
foreach (const QString &hash, request().posts["hashes"].split("|")) {
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
if (h.is_valid()) h.queue_position_top();
}
QStringList hashes = request().posts["hashes"].split("|");
BitTorrent::Session::instance()->topTorrentsPriority(hashes);
}
void WebApplication::action_command_bottomPrio()
@@ -688,17 +635,18 @@ void WebApplication::action_command_bottomPrio()
return;
}
foreach (const QString &hash, request().posts["hashes"].split("|")) {
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
if (h.is_valid()) h.queue_position_bottom();
}
QStringList hashes = request().posts["hashes"].split("|");
BitTorrent::Session::instance()->bottomTorrentsPriority(hashes);
}
void WebApplication::action_command_recheck()
{
CHECK_URI(0);
CHECK_PARAMETERS("hash");
QBtSession::instance()->recheckTorrent(request().posts["hash"]);
BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(request().posts["hash"]);
if (torrent)
torrent->forceRecheck();
}
bool WebApplication::isPublicScope()

View File

@@ -26,14 +26,17 @@
* exception statement from your version.
*/
#include "webui.h"
#include "core/http/server.h"
#include "webapplication.h"
#include "core/net/dnsupdater.h"
#include "core/preferences.h"
#include "core/logger.h"
#include "core/http/server.h"
#include "core/net/dnsupdater.h"
#include "core/net/portforwarder.h"
#include "webapplication.h"
#include "webui.h"
WebUI::WebUI(QObject *parent) : QObject(parent)
WebUI::WebUI(QObject *parent)
: QObject(parent)
, m_port(0)
{
init();
connect(Preferences::instance(), SIGNAL(changed()), SLOT(init()));
@@ -46,9 +49,13 @@ void WebUI::init()
if (pref->isWebUiEnabled()) {
const quint16 port = pref->getWebUiPort();
if (m_port != port) {
Net::PortForwarder::instance()->deletePort(port);
m_port = port;
}
if (httpServer_) {
if (httpServer_->serverPort() != port)
if (httpServer_->serverPort() != m_port)
httpServer_->close();
}
else {
@@ -72,11 +79,11 @@ void WebUI::init()
#endif
if (!httpServer_->isListening()) {
bool success = httpServer_->listen(QHostAddress::Any, port);
bool success = httpServer_->listen(QHostAddress::Any, m_port);
if (success)
logger->addMessage(tr("The Web UI is listening on port %1").arg(port));
logger->addMessage(tr("The Web UI is listening on port %1").arg(m_port));
else
logger->addMessage(tr("Web User Interface Error - Unable to bind Web UI to port %1").arg(port), Log::CRITICAL);
logger->addMessage(tr("Web User Interface Error - Unable to bind Web UI to port %1").arg(m_port), Log::CRITICAL);
}
// DynDNS
@@ -90,6 +97,12 @@ void WebUI::init()
if (dynDNSUpdater_)
delete dynDNSUpdater_;
}
// Use UPnP/NAT-PMP for Web UI
if (pref->useUPnPForWebUIPort())
Net::PortForwarder::instance()->addPort(m_port);
else
Net::PortForwarder::instance()->deletePort(m_port);
}
else {
if (httpServer_)
@@ -98,5 +111,6 @@ void WebUI::init()
delete webapp_;
if (dynDNSUpdater_)
delete dynDNSUpdater_;
Net::PortForwarder::instance()->deletePort(m_port);
}
}

View File

@@ -58,6 +58,7 @@ private:
QPointer<Http::Server> httpServer_;
QPointer<Net::DNSUpdater> dynDNSUpdater_;
QPointer<AbstractWebApplication> webapp_;
qint16 m_port;
};
#endif // WEBUI_H

View File

@@ -5,7 +5,6 @@ HEADERS += \
$$PWD/jsonutils.h \
$$PWD/extra_translations.h \
$$PWD/webapplication.h \
$$PWD/qtorrentfilter.h \
$$PWD/websessiondata.h \
$$PWD/abstractwebapplication.h
@@ -14,7 +13,6 @@ SOURCES += \
$$PWD/btjson.cpp \
$$PWD/prefjson.cpp \
$$PWD/webapplication.cpp \
$$PWD/qtorrentfilter.cpp \
$$PWD/abstractwebapplication.cpp
# QJson JSON parser/serializer for using with Qt4