Commit 2fca9a2a authored by Alexander Bock's avatar Alexander Bock
Browse files

Remove torrent-based synchronization

parent 66cd0413
master content/2012EventProfile elumenati/spout-implementation elumenati/spoutImplementation feature/2012Fieldlines feature/WSA feature/apollo-missions feature/arrow-renderable feature/asset-helper feature/asset-meta-update-part2 feature/asset-require feature/atmosphere-stars-rendering feature/bufferTransferTestings feature/camera-control-during-path feature/camera-path-stability feature/cef-update feature/change-renderbin-runtime feature/cmake feature/codegen-lua feature/codegen-lua-jenkins feature/compile-times feature/direction-hint-renderable feature/downscaledATM feature/du-meshes-selection feature/fieldlines feature/gamma-correction feature/geojson feature/geojson-renderable feature/getting-started-tour feature/grid-labels feature/grids-update feature/gui-mouseinteraction-fix feature/horizons-framework feature/horizons-unit-tests feature/idle-behavior-updates feature/imageTestKeys2Actions feature/jenkins-codegen feature/jenkins-fix feature/jenkins-timeout feature/juice feature/jwst-pointing feature/jwst-trail-update feature/jwst-update feature/labels-rendering feature/location-measure feature/macos feature/mars-moons feature/mas-model feature/missions feature/model-opacity feature/molecule_rendering feature/mollwide-projection feature/multiple-endpoints feature/orientation-check feature/paper-atmosphere feature/properties-visibility feature/renderable-enabled-event feature/satellites feature/saturn-shepherd-moons feature/science-on-the-sphere feature/sgct-framebuffer-fixes feature/sgct-gui feature/sgct-gui-editable feature/sgct-gui-jenkins feature/sgct-json feature/sgct-ui feature/side-by-side-removal feature/skybrowser feature/skybrowser-cleanup feature/skybrowser-drag-and-drop feature/skybrowser-reload feature/solarbrowsing feature/spacecraft-instruments feature/spaceweather-stream feature/spice-update feature/state-with-time feature/tileprovider-minlevel feature/tileproviders feature/touchEventListener feature/ubuntu2204 feature/unit-tests feature/userproperties feature/various-changes feature/video-on-globe feature/visual-testing feature/visual-testing-try2 feature/warnings feature/wormhole feature/xbox-update hotfix/scaling integration/atm-paper-fixes-2 integration/paper-atmosphere issue/1043 issue/1161 issue/1279 issue/1366-2 issue/1479 issue/1559 issue/1607 issue/1666 issue/1707 issue/1751 issue/1814 issue/1827 issue/1842 issue/1845 issue/1851 issue/1905 issue/1908 issue/1910 issue/1911 issue/1964 issue/1989 issue/1995 issue/2029 issue/2055 issue/2093 issue/2111 issue/2118 issue/2121 issue/2127 issue/2133 issue/2137 issue/2194 issue/2207 issue/2209 issue/2212 issue/2236 issue/2259 issue/2261 issue/2266 issue/2269 issue/843 issue/888 issue/hdrModels jenkins/1 jenkins/2 jenkins/2286 jenkins/utah-test-1 project/2021-wisdome-installation project/climate project/exoplanet-explorer project/exoplanets-expert-tool project/lights-2020-installation project/spaceship-installation project/spvl rc/0.18.1 temp/skybrowser-animation-fixes-merge thesis/2019/spaceweather-stream thesis/2020/software-integration thesis/2020/sonification thesis/2021/airtraffic thesis/2021/fieldlines thesis/2021/multiuser-collab thesis/2021/multiuser-collab3 thesis/2021/skybrowser thesis/2022/climate thesis/2022/cosmic-view thesis/2022/fieldline-rendering thesis/2022/remote-streaming thesis/2022/software-integration thesis/2022/software-integration_dod thesis/2022/software-integration_receive-ra-dec thesis/2022/software-integration_refactor-simp thesis/2022/software-integration_velocity-support thesis/2022/streaming vislabs/release/2.1 research/atmospheres releases/v0.18.0 releases/v0.17.2 releases/v0.17.1 releases/v0.17.0 releases/v0.16.1 releases/v0.16.0 releases/v0.15.2 releases/v0.15.1 releases/v0.15.0 releases/beta/beta-9 releases/beta/beta-8 releases/beta/beta-7 releases/beta/beta-5
No related merge requests found
Showing with 1 addition and 761 deletions
+1 -761
......@@ -10,9 +10,6 @@
[submodule "modules/touch/ext/libTUIO11"]
path = modules/touch/ext/libTUIO11
url = https://github.com/mkalten/TUIO11_CPP
[submodule "modules/sync/ext/libtorrent"]
path = modules/sync/ext/libtorrent
url = https://github.com/OpenSpace/libtorrent.git
[submodule "apps/OpenSpace-MinVR/ext/minvr"]
path = apps/OpenSpace-MinVR/ext/minvr
url = https://github.com/OpenSpace/minvr
......
......@@ -24,8 +24,6 @@
include(${OPENSPACE_CMAKE_EXT_DIR}/module_definition.cmake)
option(OPENSPACE_MODULE_SYNC_USE_LIBTORRENT "Use libtorrent" OFF)
set(HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/syncmodule.h
${CMAKE_CURRENT_SOURCE_DIR}/syncs/httpsynchronization.h
......@@ -42,48 +40,4 @@ set(SOURCE_FILES
)
source_group("Source Files" FILES ${SOURCE_FILES})
if (OPENSPACE_MODULE_SYNC_USE_LIBTORRENT)
set(HEADER_FILES
${HEADER_FILES}
${CMAKE_CURRENT_SOURCE_DIR}/torrentclient.h
${CMAKE_CURRENT_SOURCE_DIR}/syncs/torrentsynchronization.h
)
set(SOURCE_FILES
${SOURCE_FILES}
${CMAKE_CURRENT_SOURCE_DIR}/torrentclient.cpp
${CMAKE_CURRENT_SOURCE_DIR}/syncs/torrentsynchronization.cpp
)
endif ()
create_new_module("Sync" sync_module ${HEADER_FILES} ${SOURCE_FILES})
#####
# Libtorrent
#####
if (OPENSPACE_MODULE_SYNC_USE_LIBTORRENT)
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(LIBTORRENT_encryption OFF CACHE BOOL "Use OpenSSL Encryption" FORCE)
set(LIBTORRENT_shared OFF CACHE BOOL "Use Libtorrent as shared library" FORCE)
include_external_library(
${sync_module}
torrent-rasterbar
${CMAKE_CURRENT_SOURCE_DIR}/ext/libtorrent
)
target_include_directories(
${sync_module}
SYSTEM PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/ext/libtorrent/include
)
target_compile_definitions(openspace-module-sync PUBLIC SYNC_USE_LIBTORRENT)
mark_as_advanced(LIBTORRENT_build_examples LIBTORRENT_build_tests
LIBTORRENT_deprecated-functions LIBTORRENT_dht LIBTORRENT_encryption
LIBTORRENT_exceptions LIBTORRENT_exceptions LIBTORRENT_libiconv
LIBTORRENT_logging LIBTORRENT_shared LIBTORRENT_static_runtime
)
endif () # OPENSPACE_MODULE_SYNC_USE_LIBTORRENT
\ No newline at end of file
Subproject commit 22477e7430a643fc64e55a669e2ad0e87a67647e
......@@ -25,7 +25,6 @@
#include <modules/sync/syncmodule.h>
#include <modules/sync/syncs/httpsynchronization.h>
#include <modules/sync/syncs/torrentsynchronization.h>
#include <modules/sync/syncs/urlsynchronization.h>
#include <modules/sync/tasks/syncassettask.h>
#include <openspace/documentation/documentation.h>
......@@ -87,19 +86,6 @@ void SyncModule::internalInitialize(const ghoul::Dictionary& configuration) {
}
);
#ifdef SYNC_USE_LIBTORRENT
fSynchronization->registerClass(
"TorrentSynchronization",
[this](bool, const ghoul::Dictionary& dictionary) {
return new TorrentSynchronization(
dictionary,
_synchronizationRoot,
_torrentClient
);
}
);
#endif // SYNC_USE_LIBTORRENT
fSynchronization->registerClass(
"UrlSynchronization",
[this](bool, const ghoul::Dictionary& dictionary) {
......@@ -113,17 +99,6 @@ void SyncModule::internalInitialize(const ghoul::Dictionary& configuration) {
auto fTask = FactoryManager::ref().factory<Task>();
ghoul_assert(fTask, "No task factory existed");
fTask->registerClass<SyncAssetTask>("SyncAssetTask");
#ifdef SYNC_USE_LIBTORRENT
_torrentClient.initialize();
global::callback::deinitialize.emplace_back([&]() { _torrentClient.deinitialize(); });
#endif // SYNC_USE_LIBTORRENT
}
void SyncModule::internalDeinitialize() {
#ifdef SYNC_USE_LIBTORRENT
_torrentClient.deinitialize();
#endif // SYNC_USE_LIBTORRENT
}
std::string SyncModule::synchronizationRoot() const {
......@@ -140,10 +115,7 @@ std::vector<std::string> SyncModule::httpSynchronizationRepositories() const {
std::vector<documentation::Documentation> SyncModule::documentations() const {
return {
HttpSynchronization::Documentation(),
#ifdef SYNC_USE_LIBTORRENT
TorrentSynchronization::Documentation()
#endif // SYNC_USE_LIBTORRENT
HttpSynchronization::Documentation()
};
}
......
......@@ -27,10 +27,6 @@
#include <openspace/util/openspacemodule.h>
#ifdef SYNC_USE_LIBTORRENT
#include <modules/sync/torrentclient.h>
#endif // SYNC_USE_LIBTORRENT
namespace openspace {
class SyncModule : public OpenSpaceModule {
......@@ -44,20 +40,12 @@ public:
void addHttpSynchronizationRepository(std::string repository);
std::vector<std::string> httpSynchronizationRepositories() const;
#ifdef SYNC_USE_LIBTORRENT
TorrentClient& torrentClient();
#endif // SYNC_USE_LIBTORRENT
std::vector<documentation::Documentation> documentations() const override;
protected:
void internalInitialize(const ghoul::Dictionary& configuration) override;
void internalDeinitialize() override;
private:
#ifdef SYNC_USE_LIBTORRENT
TorrentClient _torrentClient;
#endif // SYNC_USE_LIBTORRENT
std::vector<std::string> _synchronizationRepositories;
std::string _synchronizationRoot;
};
......
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2019 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#include <modules/sync/syncs/torrentsynchronization.h>
#include <openspace/documentation/verifier.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/filesystem/file.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/misc/dictionary.h>
#include <fstream>
namespace {
constexpr const char* KeyIdentifier = "Identifier";
constexpr const char* KeyMagnet = "Magnet";
} // namespace
namespace openspace {
documentation::Documentation TorrentSynchronization::Documentation() {
using namespace openspace::documentation;
return {
"TorrentSynchronization",
"torrent_synchronization",
{
{
KeyIdentifier,
new StringVerifier,
Optional::No,
"A unique identifier for this torrent"
},
{
KeyMagnet,
new StringVerifier,
Optional::No,
"A magnet link identifying the torrent"
}
}
};
}
TorrentSynchronization::TorrentSynchronization(const ghoul::Dictionary& dict,
std::string synchronizationRoot,
TorrentClient& torrentClient)
: ResourceSynchronization(dict)
, _synchronizationRoot(std::move(synchronizationRoot))
, _torrentClient(torrentClient)
{
documentation::testSpecificationAndThrow(
Documentation(),
dict,
"TorrentSynchronization"
);
_identifier = dict.value<std::string>(KeyIdentifier);
_magnetLink = dict.value<std::string>(KeyMagnet);
}
TorrentSynchronization::~TorrentSynchronization() {
cancel();
}
std::string TorrentSynchronization::uniformResourceName() const {
const size_t begin = _magnetLink.find("=urn") + 1;
const size_t end = _magnetLink.find('&', begin);
std::string xs = _magnetLink.substr(
begin,
(end == std::string::npos) ? end : (end - begin)
);
std::transform(
xs.begin(),
xs.end(),
xs.begin(),
[](char x) { return (x == ':') ? '.' : x; }
);
return xs;
}
std::string TorrentSynchronization::directory() {
ghoul::filesystem::Directory d(
_synchronizationRoot +
ghoul::filesystem::FileSystem::PathSeparator +
"torrent" +
ghoul::filesystem::FileSystem::PathSeparator +
_identifier +
ghoul::filesystem::FileSystem::PathSeparator +
uniformResourceName()
);
return FileSys.absPath(d);
}
void TorrentSynchronization::start() {
if (_enabled) {
return;
}
begin();
if (hasSyncFile()) {
resolve();
}
_enabled = true;
try {
_torrentId = _torrentClient.addMagnetLink(
_magnetLink,
directory(),
[this](TorrentClient::TorrentProgress p) {
updateTorrentProgress(p);
}
);
} catch (const TorrentError& e) {
LERRORC(name(), e.message);
if (!isResolved()) {
reject();
}
}
}
void TorrentSynchronization::cancel() {
if (_enabled) {
_torrentClient.removeTorrent(_torrentId);
_enabled = false;
reset();
}
}
void TorrentSynchronization::clear() {
cancel();
// TODO: Remove all files from directory.
}
bool TorrentSynchronization::hasSyncFile() {
const std::string& path = directory() + ".ossync";
return FileSys.fileExists(path);
}
void TorrentSynchronization::createSyncFile() {
const std::string& directoryName = directory();
const std::string& filepath = directoryName + ".ossync";
FileSys.createDirectory(directoryName, ghoul::filesystem::FileSystem::Recursive::Yes);
std::ofstream syncFile(filepath, std::ofstream::out);
syncFile << "Synchronized";
syncFile.close();
}
size_t TorrentSynchronization::nSynchronizedBytes() {
std::lock_guard<std::mutex> g(_progressMutex);
return _progress.nDownloadedBytes;
}
size_t TorrentSynchronization::nTotalBytes() {
std::lock_guard<std::mutex> g(_progressMutex);
return _progress.nTotalBytes;
}
bool TorrentSynchronization::nTotalBytesIsKnown() {
std::lock_guard<std::mutex> g(_progressMutex);
return _progress.nTotalBytesKnown;
}
void TorrentSynchronization::updateTorrentProgress(
TorrentClient::TorrentProgress progress)
{
std::lock_guard<std::mutex> g(_progressMutex);
_progress = progress;
if (progress.finished && (state() == State::Syncing)) {
createSyncFile();
resolve();
}
}
} // namespace openspace
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2019 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_MODULE_SYNC___TORRENTSYNCHRONIZATION___H__
#define __OPENSPACE_MODULE_SYNC___TORRENTSYNCHRONIZATION___H__
#ifdef SYNC_USE_LIBTORRENT
#include <openspace/util/resourcesynchronization.h>
#include <modules/sync/torrentclient.h>
namespace openspace {
class TorrentSynchronizationJob;
class TorrentSynchronization : public ResourceSynchronization {
public:
TorrentSynchronization(const ghoul::Dictionary& dict, std::string synchronizationRoot,
TorrentClient& client);
virtual ~TorrentSynchronization();
std::string directory() override;
void start() override;
void cancel() override;
void clear() override;
size_t nSynchronizedBytes() override;
size_t nTotalBytes() override;
bool nTotalBytesIsKnown() override;
static documentation::Documentation Documentation();
private:
void updateTorrentProgress(TorrentClient::TorrentProgress p);
std::string uniformResourceName() const;
bool hasSyncFile();
void createSyncFile();
std::atomic_bool _enabled = false;
TorrentClient::TorrentId _torrentId = 0;
TorrentClient::TorrentProgress _progress;
std::mutex _progressMutex;
std::string _identifier;
std::string _magnetLink;
std::string _synchronizationRoot;
TorrentClient& _torrentClient;
};
} // namespace openspace
#endif // SYNC_USE_LIBTORRENT
#endif // __OPENSPACE_MODULE_SYNC___TORRENTSYNCHRONIZATION___H__
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2019 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#include <modules/sync/torrentclient.h>
#include <openspace/openspace.h>
#include <ghoul/fmt.h>
#include <ghoul/logging/logmanager.h>
#ifdef SYNC_USE_LIBTORRENT
#ifdef _MSC_VER
#pragma warning (push)
#pragma warning (disable : 4265)
#pragma warning (disable : 4996)
#endif // _MSC_VER
#include <libtorrent/entry.hpp>
#include <libtorrent/bencode.hpp>
#include <libtorrent/session.hpp>
#include <libtorrent/alert_types.hpp>
#include <libtorrent/torrent_info.hpp>
#include <libtorrent/magnet_uri.hpp>
#ifdef _MSC_VER
#pragma warning (pop)
#endif // _MSC_VER
namespace {
constexpr const char* _loggerCat = "TorrentClient";
constexpr const std::chrono::milliseconds PollInterval(1000);
} // namespace
#endif // SYNC_USE_LIBTORRENT
namespace openspace {
TorrentError::TorrentError(std::string msg)
: RuntimeError(std::move(msg), "TorrentClient")
{}
void TorrentClient::initialize() {
#ifdef SYNC_USE_LIBTORRENT
libtorrent::settings_pack settings;
settings.set_str(
libtorrent::settings_pack::user_agent,
"OpenSpace/" + std::string(OPENSPACE_VERSION_NUMBER)
);
settings.set_str(
libtorrent::settings_pack::listen_interfaces,
"0.0.0.0:6881,0.0.0.0:20280,0.0.0.0:20285,0.0.0.0:20290"
);
settings.set_bool(libtorrent::settings_pack::allow_multiple_connections_per_ip, true);
settings.set_bool(libtorrent::settings_pack::enable_upnp, true);
//settings.set_bool(libtorrent::settings_pack::ignore_limits_on_local_network, true);
settings.set_int(libtorrent::settings_pack::connection_speed, 20);
settings.set_int(libtorrent::settings_pack::active_downloads, -1);
settings.set_int(libtorrent::settings_pack::active_seeds, -1);
settings.set_int(libtorrent::settings_pack::active_limit, 30);
settings.set_str(
libtorrent::settings_pack::dht_bootstrap_nodes,
"router.utorrent.com,dht.transmissionbt.com,router.bittorrent.com,\
router.bitcomet.com"
);
settings.set_int(libtorrent::settings_pack::dht_announce_interval, 15);
_session.apply_settings(settings);
libtorrent::error_code ec;
_isInitialized = true;
_isActive = true;
_torrentThread = std::thread([this]() {
while (_isActive) {
pollAlerts();
std::unique_lock<std::mutex> lock(_abortMutex);
_abortNotifier.wait_for(lock, PollInterval);
}
});
#endif // SYNC_USE_LIBTORRENT
}
void TorrentClient::deinitialize() {
#ifdef SYNC_USE_LIBTORRENT
if (!_isActive) {
return;
}
_isActive = false;
_abortNotifier.notify_all();
if (_torrentThread.joinable()) {
_torrentThread.join();
}
const std::vector<lt::torrent_handle>& handles = _session.get_torrents();
for (const lt::torrent_handle& h : handles) {
_session.remove_torrent(h);
}
_torrents.clear();
_session.abort();
_isInitialized = false;
#endif // SYNC_USE_LIBTORRENT
}
void TorrentClient::pollAlerts() {
#ifdef SYNC_USE_LIBTORRENT
// Libtorrent does not seem to reliably generate alerts for all added torrents.
// To make sure that the program does not keep waiting for already finished
// downsloads, we go through the whole list of torrents when polling.
// However, in theory, the commented code below should be more efficient:
/*
std::vector<libtorrent::alert*> alerts;
{
std::lock_guard<std::mutex> guard(_mutex);
_session->pop_alerts(&alerts);
}
for (lt::alert* a : alerts) {
if (const lt::torrent_alert* alert =
dynamic_cast<lt::torrent_alert*>(a))
{
notify(alert->handle.id());
}
}
*/
std::vector<lt::torrent_handle> handles;
{
std::lock_guard<std::mutex> guard(_mutex);
handles = _session.get_torrents();
}
for (const lt::torrent_handle& h : handles) {
notify(h.id());
}
#endif // SYNC_USE_LIBTORRENT
}
TorrentClient::TorrentId TorrentClient::addTorrentFile(
[[ maybe_unused ]] const std::string& torrentFile,
[[maybe_unused]] const std::string& destination,
[[maybe_unused]] TorrentProgressCallback cb)
{
#ifdef SYNC_USE_LIBTORRENT
std::lock_guard<std::mutex> guard(_mutex);
if (!_isInitialized) {
LERROR("Torrent session not initialized when adding torrent");
return -1;
}
libtorrent::error_code ec;
libtorrent::add_torrent_params p;
p.save_path = destination;
p.ti = std::make_shared<libtorrent::torrent_info>(torrentFile, ec);
if (ec) {
LERROR(fmt::format("{}: {}", torrentFile, ec.message()));
}
const libtorrent::torrent_handle h = _session.add_torrent(p, ec);
if (ec) {
LERROR(fmt::format("{}: {}", torrentFile, ec.message()));
}
TorrentId id = h.id();
_torrents.emplace(id, Torrent{ id, h, std::move(cb) });
return id;
#else // SYNC_USE_LIBTORRENT
throw TorrentError("SyncModule is compiled without libtorrent support");
#endif // SYNC_USE_LIBTORRENT
}
TorrentClient::TorrentId TorrentClient::addMagnetLink(
[[maybe_unused]] const std::string& magnetLink,
[[maybe_unused]] const std::string& destination,
[[maybe_unused]] TorrentProgressCallback cb)
{
#ifdef SYNC_USE_LIBTORRENT
std::lock_guard<std::mutex> guard(_mutex);
// TODO: register callback!
if (!_isInitialized) {
LERROR("Torrent session not initialized when adding torrent");
return -1;
}
libtorrent::error_code ec;
libtorrent::add_torrent_params p = libtorrent::parse_magnet_uri(magnetLink, ec);
if (ec) {
LERROR(fmt::format("{}: {}", magnetLink, ec.message()));
}
p.save_path = destination;
p.storage_mode = libtorrent::storage_mode_allocate;
const libtorrent::torrent_handle h = _session.add_torrent(p, ec);
if (ec) {
LERROR(fmt::format("{}: {}", magnetLink, ec.message()));
}
TorrentId id = h.id();
_torrents.emplace(id, Torrent{ id, h, std::move(cb) });
return id;
#else // SYNC_USE_LIBTORRENT
throw TorrentError("SyncModule is compiled without libtorrent support");
#endif // SYNC_USE_LIBTORRENT
}
void TorrentClient::removeTorrent([[maybe_unused]] TorrentId id) {
#ifdef SYNC_USE_LIBTORRENT
std::lock_guard<std::mutex> guard(_mutex);
const auto it = _torrents.find(id);
if (it == _torrents.end()) {
return;
}
const libtorrent::torrent_handle h = it->second.handle;
_session.remove_torrent(h);
_torrents.erase(it);
#endif // SYNC_USE_LIBTORRENT
}
void TorrentClient::notify([[maybe_unused]] TorrentId id) {
#ifdef SYNC_USE_LIBTORRENT
TorrentProgressCallback callback;
TorrentProgress progress;
{
std::lock_guard<std::mutex> guard(_mutex);
const auto it = _torrents.find(id);
if (it == _torrents.end()) {
return;
}
const libtorrent::torrent_handle h = it->second.handle;
const libtorrent::torrent_status status = h.status();
progress.finished = status.is_finished;
progress.nTotalBytesKnown = status.total_wanted > 0;
progress.nTotalBytes = status.total_wanted;
progress.nDownloadedBytes = status.total_wanted_done;
callback = it->second.callback;
}
callback(progress);
#endif // SYNC_USE_LIBTORRENT
}
} // namespace openspace
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2019 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_MODULE_SYNC___TORRENTCLIENT___H__
#define __OPENSPACE_MODULE_SYNC___TORRENTCLIENT___H__
#ifdef SYNC_USE_LIBTORRENT
#include <ghoul/misc/exception.h>
#include <atomic>
#include <condition_variable>
#include <functional>
#include <mutex>
#include <string>
#include <thread>
#include <unordered_map>
#ifdef SYNC_USE_LIBTORRENT
#ifdef _MSC_VER
#pragma warning (push)
#pragma warning (disable : 4265)
#pragma warning (disable : 4996)
#endif // _MSC_VER
// libtorrent defines a class with the name 'defer', which messes with out #define of the
// defer macro in ghoul/misc/defer.h
#undef defer
#include <libtorrent/torrent_handle.hpp>
#include <libtorrent/session.hpp>
#ifdef _MSC_VER
#pragma warning (pop)
#endif // _MSC_VER
#else // SYNC_USE_LIBTORRENT
// Dummy definition to make TorrentClient compile, these is not actually used if
// SYNC_USE_LIBTORRENT is FALSE
namespace libtorrent {
using torrent_handle = void*;
using session = void*;
} // namespace libtorrent
#endif // SYNC_USE_LIBTORRENT
namespace openspace {
struct TorrentError : public ghoul::RuntimeError {
explicit TorrentError(std::string msg);
};
class TorrentClient {
public:
struct TorrentProgress {
bool finished = false;
bool nTotalBytesKnown = false;
size_t nTotalBytes = 0;
size_t nDownloadedBytes = 0;
};
using TorrentProgressCallback = std::function<void(TorrentProgress)>;
using TorrentId = int32_t;
void initialize();
void deinitialize();
TorrentId addTorrentFile(const std::string& torrentFile,
const std::string& destination, TorrentProgressCallback cb);
TorrentId addMagnetLink(const std::string& magnetLink, const std::string& destination,
TorrentProgressCallback cb);
void removeTorrent(TorrentId id);
private:
struct Torrent {
TorrentId id;
libtorrent::torrent_handle handle;
TorrentProgressCallback callback;
};
void notify(TorrentId id);
void pollAlerts();
#ifdef SYNC_USE_LIBTORRENT
libtorrent::session _session;
bool _isInitialized = false;
std::atomic_bool _isActive = false;
#endif // SYNC_USE_LIBTORRENT
std::thread _torrentThread;
std::condition_variable _abortNotifier;
std::mutex _abortMutex;
std::mutex _mutex;
std::unordered_map<TorrentId, Torrent> _torrents;
};
} // namespace openspace
#endif // SYNC_USE_LIBTORRENT
#endif // __OPENSPACE_MODULE_SYNC___TORRENTCLIENT___H__
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment