Start work on TorrentSynchronization

This commit is contained in:
Emil Axelsson
2017-11-06 19:07:52 +01:00
parent 1f33359697
commit e201dec907
23 changed files with 377 additions and 108 deletions

View File

@@ -25,16 +25,18 @@
include(${OPENSPACE_CMAKE_EXT_DIR}/module_definition.cmake)
set(HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/syncmodule.h
${CMAKE_CURRENT_SOURCE_DIR}/torrentclient.h
${CMAKE_CURRENT_SOURCE_DIR}/syncs/httpsynchronization.h
# ${CMAKE_CURRENT_SOURCE_DIR}/syncs/resourcesynchronization.h
# ${CMAKE_CURRENT_SOURCE_DIR}/syncs/torrentsynchronization.h
${CMAKE_CURRENT_SOURCE_DIR}/syncs/torrentsynchronization.h
)
source_group("Header Files" FILES ${HEADER_FILES})
set(SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/syncmodule.cpp
${CMAKE_CURRENT_SOURCE_DIR}/torrentclient.cpp
${CMAKE_CURRENT_SOURCE_DIR}/syncs/httpsynchronization.cpp
# ${CMAKE_CURRENT_SOURCE_DIR}/syncs/resourcesynchronization.cpp
# ${CMAKE_CURRENT_SOURCE_DIR}/syncs/torrentsynchronization.cpp
${CMAKE_CURRENT_SOURCE_DIR}/syncs/torrentsynchronization.cpp
)
source_group("Source Files" FILES ${SOURCE_FILES})
@@ -54,3 +56,23 @@ create_new_module(
sync_module
${HEADER_FILES} ${SOURCE_FILES}
)
#####
# 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
)

View File

@@ -24,18 +24,20 @@
#include <modules/sync/syncmodule.h>
#include <modules/sync/syncs/httpsynchronization.h>
#include <modules/sync/syncs/torrentsynchronization.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/engine/configurationmanager.h>
#include <openspace/documentation/documentation.h>
#include <openspace/rendering/renderable.h>
#include <openspace/rendering/screenspacerenderable.h>
#include <openspace/util/factorymanager.h>
#include <ghoul/misc/assert.h>
#include <openspace/util/resourcesynchronization.h>
#include <modules/sync/syncs/httpsynchronization.h>
//#include <modules/sync/syncs/resourcesyncrhonization.h>
//#include <modules/sync/syncs/torrentsyncrhonization.h>
#include <ghoul/misc/assert.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/misc/dictionary.h>
namespace openspace {
@@ -48,14 +50,45 @@ void SyncModule::internalInitialize() {
ghoul_assert(fSynchronization, "ResourceSynchronization factory was not created");
fSynchronization->registerClass<HttpSynchronization>("HttpSynchronization");
fSynchronization->registerClass<TorrentSynchronization>("TorrentSynchronization");
_synchronizationRoot = FileSys.absPath("${SYNC}");
_torrentClient.initialize();
if (!OsEng.configurationManager().hasKey(
ConfigurationManager::KeyHttpSynchronizationRepositories))
{
return;
}
ghoul::Dictionary dictionary = OsEng.configurationManager().value<ghoul::Dictionary>(
ConfigurationManager::KeyHttpSynchronizationRepositories
);
for (std::string key : dictionary.keys()) {
_httpSynchronizationRepositories.push_back(
dictionary.value<std::string>(key)
);
}
}
std::vector<documentation::Documentation> SyncModule::documentations() const {
return {
HttpSynchronization::Documentation()
//ResourceSynchronization::Documentation(),
//TorrentSynchronization::Documentation()
HttpSynchronization::Documentation(),
TorrentSynchronization::Documentation()
};
}
std::string SyncModule::synchronizationRoot() const
{
return _synchronizationRoot;
}
std::vector<std::string> SyncModule::httpSynchronizationRepositories() const {
return _httpSynchronizationRepositories;
}
TorrentClient* SyncModule::torrentClient() {
return &_torrentClient;
}
} // namespace openspace

View File

@@ -22,25 +22,32 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_MODULE_SPACE___SYNCMODULE___H__
#define __OPENSPACE_MODULE_SPACE___SYNCMODULE___H__
#ifndef __OPENSPACE_MODULE_SYNC___SYNCMODULE___H__
#define __OPENSPACE_MODULE_SYNC___SYNCMODULE___H__
#include <openspace/util/openspacemodule.h>
#include <modules/sync/torrentclient.h>
namespace openspace {
class SyncModule : public OpenSpaceModule {
public:
constexpr static const char* Name = "Sync";
SyncModule();
virtual ~SyncModule() = default;
std::vector<documentation::Documentation> documentations() const override;
std::string synchronizationRoot() const;
std::vector<std::string> httpSynchronizationRepositories() const;
TorrentClient* torrentClient();
protected:
void internalInitialize() override;
private:
TorrentClient _torrentClient;
std::vector<std::string> _httpSynchronizationRepositories;
std::string _synchronizationRoot;
};
} // namespace openspace
#endif // __OPENSPACE_MODULE_SPACE___SYNCMODULE___H__
#endif // __OPENSPACE_MODULE_SYNC___SYNCMODULE___H__

View File

@@ -24,7 +24,12 @@
#include "httpsynchronization.h"
#include <modules/sync/syncmodule.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/engine/moduleengine.h>
#include <openspace/util/httprequest.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/filesystem/filesystem.h>
#include <openspace/documentation/verifier.h>
@@ -56,6 +61,13 @@ HttpSynchronization::HttpSynchronization(const ghoul::Dictionary& dict)
_identifier = dict.value<std::string>(KeyIdentifier);
_version = static_cast<int>(dict.value<double>(KeyVersion));
// Configure synchronization based on global settings in SyncModule
// TODO: For testability and decreaing deps, make it possible to inject this instead.
// For example, allow this configuration to be done by the TemplateFactory.
const SyncModule* syncModule = OsEng.moduleEngine().module<SyncModule>();
_synchronizationRoot = syncModule->synchronizationRoot();
_synchronizationRepositories = syncModule->httpSynchronizationRepositories();
}
documentation::Documentation HttpSynchronization::Documentation() {
@@ -82,7 +94,7 @@ documentation::Documentation HttpSynchronization::Documentation() {
std::string HttpSynchronization::directory() {
ghoul::filesystem::Directory d(
_synchronizationOptions.synchronizationRoot +
_synchronizationRoot +
ghoul::filesystem::FileSystem::PathSeparator +
"http" +
ghoul::filesystem::FileSystem::PathSeparator +
@@ -115,7 +127,7 @@ std::vector<std::string> HttpSynchronization::fileListUrls() {
"&" + QueryKeyApplicationVersion + "=" + std::to_string(ApplicationVersion);
std::vector<std::string> urls;
for (const auto& repoUrl : _synchronizationOptions.httpSynchronizationRepositories) {
for (const auto& repoUrl : _synchronizationRepositories) {
urls.push_back(repoUrl + query);
}
@@ -141,7 +153,8 @@ bool HttpSynchronization::trySyncFromUrl(std::string listUrl) {
std::vector<std::thread> downloadThreads;
std::string line = "";
while (fileList >> line) {
std::string filename = ghoul::filesystem::File(line, ghoul::filesystem::File::RawPath::Yes).filename();
size_t lastSlash = line.find_last_of('/');
std::string filename = line.substr(lastSlash + 1);
std::string fileDestination = directory() +
ghoul::filesystem::FileSystem::PathSeparator +

View File

@@ -50,6 +50,8 @@ private:
std::string _identifier;
int _version;
std::string _synchronizationRoot;
std::vector<std::string> _synchronizationRepositories;
};
} // namespace openspace

View File

@@ -24,8 +24,79 @@
#include "torrentsynchronization.h"
#include <modules/sync/syncmodule.h>
#include <openspace/documentation/verifier.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/engine/moduleengine.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/filesystem/filesystem.h>
namespace {
const char* _loggerCat = "TorrentSynchronization";
const char* KeyTorrentFile = "TorrentFile";
}
namespace openspace {
TorrentSynchronization::TorrentSynchronization(const ghoul::Dictionary& dict)
: openspace::ResourceSynchronization()
{
documentation::testSpecificationAndThrow(
Documentation(),
dict,
"TorrentSynchroniztion"
);
_torrentFilePath = dict.value<std::string>(KeyTorrentFile);
// Configure synchronization based on global settings in SyncModule
// TODO: For testability and decreaing deps, make it possible to inject this instead.
// For example, allow this configuration to be done by the TemplateFactory.
SyncModule* syncModule = OsEng.moduleEngine().module<SyncModule>();
_synchronizationRoot = syncModule->synchronizationRoot();
_torrentClient = syncModule->torrentClient();
}
documentation::Documentation TorrentSynchronization::Documentation() {
using namespace openspace::documentation;
return {
"TorrentSynchronization",
"torrent_synchronization",
{
{
KeyTorrentFile,
new StringVerifier,
Optional::No,
"An absolute path to a torrent file"
},
}
};
}
std::string TorrentSynchronization::directory() {
ghoul::filesystem::Directory d(
_synchronizationRoot +
ghoul::filesystem::FileSystem::PathSeparator +
"torrent" +
ghoul::filesystem::FileSystem::PathSeparator +
"test"
);
return FileSys.absPath(d);
}
void TorrentSynchronization::synchronize() {
_torrentClient->addTorrent(_torrentFilePath, directory());
resolve();
return;
}
} // namespace openspace

View File

@@ -25,9 +25,33 @@
#ifndef __OPENSPACE_MODULE_SYNC___TORRENTSYNCHRONIZATION___H__
#define __OPENSPACE_MODULE_SYNC___TORRENTSYNCHRONIZATION___H__
#include <openspace/util/resourcesynchronization.h>
#include <openspace/documentation/documentation.h>
#include <ghoul/misc/dictionary.h>
namespace libtorrent {
class session;
struct torrent_handle;
}
namespace openspace {
class TorrentSynchronizationJob;
class TorrentSynchronization : public ResourceSynchronization {
public:
TorrentSynchronization(const ghoul::Dictionary& dict);
static documentation::Documentation Documentation();
std::string directory() override;
void synchronize() override;
private:
std::string _torrentFilePath;
std::string _synchronizationRoot;
TorrentClient* _torrentClient;
};
} // namespace openspace

View File

@@ -0,0 +1,101 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2017 *
* *
* 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 "torrentclient.h"
#include <libtorrent/entry.hpp>
#include <libtorrent/bencode.hpp>
#include <libtorrent/session.hpp>
#include <libtorrent/alert_types.hpp>
#include <libtorrent/torrent_info.hpp>
#include <openspace/openspace.h>
#include <ghoul/logging/logmanager.h>
namespace {
const char* _loggerCat = "TorrentClient";
}
namespace openspace {
TorrentClient::TorrentClient() {}
TorrentClient::~TorrentClient() {}
void TorrentClient::initialize() {
libtorrent::settings_pack settings;
_session = std::make_unique<libtorrent::session>();
settings.set_str(libtorrent::settings_pack::user_agent, "OpenSpace/" +
std::to_string(openspace::OPENSPACE_VERSION_MAJOR) + "." +
std::to_string(openspace::OPENSPACE_VERSION_MINOR) + "." +
std::to_string(openspace::OPENSPACE_VERSION_PATCH));
settings.set_bool(libtorrent::settings_pack::allow_multiple_connections_per_ip, 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_int(libtorrent::settings_pack::dht_announce_interval, 60);
_session->apply_settings(settings);
_session->add_dht_router({ "router.utorrent.com", 6881 });
_session->add_dht_router({ "dht.transmissionbt.com", 6881 });
_session->add_dht_router({ "router.bittorrent.com", 6881 });
_session->add_dht_router({ "router.bitcomet.com", 6881 });
libtorrent::error_code ec;
_session->listen_on(std::make_pair(20280, 20290), ec);
_session->start_upnp();
}
int TorrentClient::addTorrent(std::string torrentFile, std::string destination) {
if (!_session) {
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, 0);
_session->add_torrent(p, ec);
std::vector<libtorrent::torrent_handle> handles = _session->get_torrents();
libtorrent::torrent_status s = handles[0].status();
LINFO("Torrent: " << s.total_wanted_done << " out of " << s.total_wanted);
}
void TorrentClient::removeTorrent(int id) {
}
}

View File

@@ -0,0 +1,55 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2017 *
* *
* 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__
#include <string>
#include <memory>
namespace libtorrent {
class session;
}
namespace openspace {
struct Torrent {
std::string _torrentFile;
std::string _destination;
};
class TorrentClient {
public:
TorrentClient();
~TorrentClient();
void initialize();
int addTorrent(std::string torrentFile, std::string destination);
void removeTorrent(int id);
private:
std::unique_ptr<libtorrent::session> _session;
};
} // namespace openspace
#endif // __OPENSPACE_MODULE_SYNC___TORRENTCLIENT___H__