Add specialized TaskRunner application "Sync" that only synchronizes all scenes in the asset folder

Replace TaskRoot in openspace.cfg with ${TASK} in Taskrunner
Remove Launcher
This commit is contained in:
Alexander Bock
2017-12-26 20:13:23 +01:00
parent 0d6a94789a
commit 339c45a7f6
23 changed files with 202 additions and 1819 deletions
-5
View File
@@ -1,5 +0,0 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>images/header.png</file>
</qresource>
</RCC>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

-132
View File
@@ -1,132 +0,0 @@
/*****************************************************************************************
* *
* 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 "infowidget.h"
#include "syncwidget.h"
#include <QGridLayout>
#include <QLabel>
#include <QProgressBar>
#include <libtorrent/torrent_status.hpp>
InfoWidget::InfoWidget(QString name, int totalBytes)
: QGroupBox(nullptr)
, _name(nullptr)
, _bytes(nullptr)
, _progress(nullptr)
, _messagesLeft(nullptr)
, _messagesCenter(nullptr)
, _messagesRight(nullptr)
, _totalBytes(totalBytes)
{
setFixedHeight(100);
QGridLayout* layout = new QGridLayout;
layout->setHorizontalSpacing(10);
_name = new QLabel(name);
_name->setObjectName("Name");
//_name->setMaximumWidth(300);
_name->setFixedWidth(450);
layout->addWidget(_name, 0, 0, 1, 2);
layout->setRowStretch(1, 10);
_bytes = new QLabel("");
_bytes->setObjectName("Bytes");
layout->addWidget(_bytes, 2, 0);
_progress = new QProgressBar;
_progress->setTextVisible(false);
_progress->setFixedWidth(285);
layout->addWidget(_progress, 2, 1);
_messagesLeft = new QLabel("");
_messagesLeft->setObjectName("MessageLeft");
_messagesCenter = new QLabel("");
_messagesCenter->setObjectName("MessageCenter");
_messagesRight = new QLabel("");
_messagesRight->setObjectName("MessageRight");
layout->addWidget(_messagesLeft, 3, 0, 1, 2);
layout->addWidget(_messagesCenter, 3, 0, 1, 2, Qt::AlignCenter);
layout->addWidget(_messagesRight, 3, 0, 1, 2, Qt::AlignRight);
setLayout(layout);
}
void InfoWidget::update(std::shared_ptr<openspace::DownloadManager::FileFuture> f) {
_bytes->setText(
QString("%1 / %2")
.arg(f->currentSize)
.arg(f->totalSize)
);
_progress->setValue(static_cast<int>(f->progress * 100));
if (f->errorMessage.empty()) {
QString t = "Time remaining %1 s";
_messagesLeft->setText(t.arg(static_cast<int>(f->secondsRemaining)));
}
else {
_messagesLeft->setText(QString::fromStdString(f->errorMessage));
}
}
void InfoWidget::update(libtorrent::torrent_status s) {
_bytes->setText(
QString("%1 / %2")
.arg(s.total_wanted_done)
.arg(s.total_wanted)
);
float progress = static_cast<float>(s.total_wanted_done) / s.total_wanted;
_progress->setValue(static_cast<int>(progress * 100));
if (s.error.empty()) {
int bytesPerSecond = s.download_rate;
long long remainingBytes = s.total_wanted - s.total_wanted_done;
if (bytesPerSecond > 0 && remainingBytes > 0) {
float seconds = static_cast<float>(remainingBytes) / bytesPerSecond;
QString left = "Remaining: %1 s";
_messagesLeft->setText(left.arg(static_cast<int>(seconds)));
QString center = "Peers: %1 (%2) | Seeds: %3 (%4)";
_messagesCenter->setText(center.arg(s.num_peers).arg(s.list_peers).arg(s.num_seeds).arg(s.list_seeds));
QString right = "%1 KiB/s";
_messagesRight->setText(right.arg(bytesPerSecond / 1024));
}
else
_messagesLeft->setText("");
}
else {
_messagesLeft->setText(QString::fromStdString(s.error));
}
}
void InfoWidget::error(QString message) {
_messagesLeft->setText(message);
}
-61
View File
@@ -1,61 +0,0 @@
/*****************************************************************************************
* *
* 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_APP_LAUNCHER___INFOWIDGET___H__
#define __OPENSPACE_APP_LAUNCHER___INFOWIDGET___H__
//#include <QWidget>
#include <QGroupBox>
#include <openspace/engine/downloadmanager.h>
#include <libtorrent/torrent_handle.hpp>
class QLabel;
class QProgressBar;
class InfoWidget : public QGroupBox {
Q_OBJECT
public:
InfoWidget(QString name, int totalBytes = -1);
void update(std::shared_ptr<openspace::DownloadManager::FileFuture> f);
void update(libtorrent::torrent_status s);
void error(QString message);
private:
InfoWidget(const InfoWidget& rhs) = delete;
QLabel* _name;
QLabel* _bytes;
QProgressBar* _progress;
QLabel* _messagesLeft;
QLabel* _messagesCenter;
QLabel* _messagesRight;
int _totalBytes;
};
#endif // __OPENSPACE_APP_LAUNCHER___INFOWIDGET___H__
-174
View File
@@ -1,174 +0,0 @@
/*****************************************************************************************
* *
* 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 <QApplication>
#include <QFile>
#include "mainwindow.h"
#include <ghoul/filesystem/filesystem>
static const QString style = R"style(
QWidget {
/*font-family: "Helvetica";*/
}
QWidget#MainWindow, QTextEdit, QWidget#SyncWidget, QWidget#DownloadArea {
background-color: rgb(40, 40, 40);
}
QTextEdit, QLabel, QComboBox, QCheckBox {
color: #EDEDED;
font-size: 12px;
}
QLabel {
font-size: 13px;
}
QLabel#Image {
margin: -10px 0px -5px 0px;
}
QTextEdit {
border-width: 2px 2px 0px 0px;
border-style: solid;
background-color: rgb(60, 60, 60);
}
QPushButton {
color:#202020;
background-color:
qlineargradient(
x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 white,
stop: 1 #555555
);
border: 1px solid black;
font-size: 11px;
min-height: 20px;
}
QComboBox {
background-color: rgb(60, 60, 60);
min-height: 20px;
}
QComboBox:focus, QComboBox:focus QAbstractItemView {
color: white;
background-color: rgb(60, 60, 60);
selection-background-color: rgb(75, 75, 75);
}
QCheckBox {
border: none;
}
QCheckBox::indicator {
width: 12px;
height: 12px;
}
QCheckBox::indicator::unchecked {
border: 1px solid #5A5A5A;
background: #A0A0A0;
}
QCheckBox::indicator:unchecked:hover {
border: 1px solid #DDDDDD;
}
QCheckBox::indicator::checked {
border: 1px solid #5A5A5A;
background: #5AB65A;
}
QCheckBox::indicator:checked:hover {
border: 1px solid #DDDDDD;
}
QGroupBox, QScrollArea {
border: 0px;
}
InfoWidget {
border-width: 1px;
border-style: solid;
border-color: #BBBBBB;
margin: 2px 1px 2px 1px;
padding: 7.5px;
}
InfoWidget QLabel#Name {
font-size: 17px;
}
InfoWidget QLabel#Bytes {
font-size: 13px;
font-family: "Lucida Console";
}
InfoWidget QLabel#MessageLeft, QLabel#MessageCenter, QLabel#MessageRight {
font-size: 11.5px;
margin-top: -2px;
}
InfoWidget QProgressBar {
border: 2px solid #BBBBBB;
border-radius: 5px;
background: white;
height: 15px;
}
InfoWidget QProgressBar::chunk {
background: qlineargradient(
x1: 0, y1: 0.5, x2: 1, y2: 0.5,
stop: 0 #444444,
stop: 1 #600000
);
}
QScrollBar {
border: 1px solid #000000;
background: #282828;
width: 15px;
margin: 16px 0px 16px 0px;
}
QScrollBar::handle {
background: #B0B0B0;
border: 1px solid #000000;
border-width: 1px 0px 1px 0px;
min-height: 20px;
}
QScrollBar::add-line, QScrollBar::sub-line {
background:#B0B0B0;
border: 1px solid #5A5A5A;
subcontrol-origin: margin;
}
QScrollBar::add-line {
top: 15px;
height: 15px;
}
QScrollBar::sub-line {
height: 15px;
subcontrol-position: top;
}
QScrollBar::up-arrow, QScrollBar::down-arrow {
border: 1px solid #5A5A5A;
width: 3px;
height: 3px;
background-color: #353535;
}
QScrollBar::add-page, QScrollBar::sub-page {
background: none;
}
)style";
int main(int argc, char** argv) {
QApplication app(argc, argv);
app.setStyleSheet(style);
MainWindow window;
window.show();
return app.exec();
}
-349
View File
@@ -1,349 +0,0 @@
/*****************************************************************************************
* *
* 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 "mainwindow.h"
#include "shortcutwidget.h"
#include "syncwidget.h"
#include <openspace/engine/configurationmanager.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/engine/logfactory.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/logging/log.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/logging/consolelog.h>
#include <ghoul/logging/htmllog.h>
#include <ghoul/logging/visualstudiooutputlog.h>
#include <QApplication>
#include <QComboBox>
#include <QDir>
#include <QGridLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QProcess>
#include <QPushButton>
#include <QThread>
namespace {
const QSize WindowSize = QSize(640, 480);
const QString NewsURL = "http://openspaceproject.com/news.txt";
const std::string _configurationFile = "openspace.cfg";
#ifdef WIN32
const QString OpenSpaceExecutable = "OpenSpace.exe";
#else
const QString OpenSpaceExecutable = "./OpenSpace";
#endif
class QLog : public ghoul::logging::Log {
public:
void log(
[[maybe_unused]] ghoul::logging::LogLevel level,
[[maybe_unused]] const std::string& category,
[[maybe_unused]] const std::string& message
) {
//qDebug() << QString::fromStdString(category) << ": " << QString::fromStdString(message);
}
};
}
MainWindow::MainWindow()
: QWidget(nullptr)
, _newsReply(nullptr)
, _informationWidget(nullptr)
, _scenes(nullptr)
, _shortcutWidget(nullptr)
, _syncWidget(nullptr)
{
setObjectName("MainWindow");
setFixedSize(WindowSize);
//setContentsMargins(0, 0, 0, 0);
QGridLayout* layout = new QGridLayout;
layout->setContentsMargins(0, 0, 0, 0);
QLabel* image = new QLabel;
//image->setContentsMargins(0, 0, 0, 0);
image->setObjectName("Image");
QPixmap p = QPixmap(":/images/header.png");
image->setPixmap(p);
layout->addWidget(image, 0, 0, 1, 2);
_informationWidget = new QTextEdit(this);
_informationWidget->setReadOnly(true);
//_informationWidget->setEnabled(false);
layout->addWidget(_informationWidget, 1, 0, 2, 1);
layout->setRowStretch(1, 10);
layout->setColumnStretch(0, 4);
layout->setColumnStretch(1, 5);
QWidget* container = new QWidget;
{
QGridLayout* innerLayout = new QGridLayout;
//QLabel* shortcutLabel = new QLabel("Keyboard Shortcuts:");
//innerLayout->addWidget(shortcutLabel, 0, 0);
//QPushButton* shortcutButton = new QPushButton("Open...");
//QObject::connect(shortcutButton, SIGNAL(clicked(bool)),
// this, SLOT(shortcutButtonPressed())
// );
//innerLayout->addWidget(shortcutButton, 0, 1);
innerLayout->setRowStretch(1, 10);
QLabel* configurationSelectionLabel = new QLabel("Configuration:");
innerLayout->addWidget(configurationSelectionLabel, 2, 0);
_configurations = new QComboBox;
innerLayout->addWidget(_configurations, 2, 1);
QLabel* sceneSelectionLabel = new QLabel("Scenes:");
innerLayout->addWidget(sceneSelectionLabel, 3, 0);
_scenes = new QComboBox;
innerLayout->addWidget(_scenes, 3, 1);
container->setLayout(innerLayout);
}
layout->addWidget(container, 1, 1);
container = new QWidget;
{
QBoxLayout* innerLayout = new QHBoxLayout;
QPushButton* cancelButton = new QPushButton("Exit");
QObject::connect(
cancelButton, SIGNAL(clicked(bool)),
QApplication::instance(), SLOT(quit())
);
innerLayout->addWidget(cancelButton);
QPushButton* syncButton = new QPushButton("Sync");
QObject::connect(
syncButton, SIGNAL(clicked(bool)),
this, SLOT(syncButtonPressed())
);
innerLayout->addWidget(syncButton);
QPushButton* startButton = new QPushButton("Start");
QObject::connect(
startButton, SIGNAL(clicked(bool)),
this, SLOT(startButtonPressed())
);
innerLayout->addWidget(startButton);
container->setLayout(innerLayout);
}
layout->addWidget(container, 2, 1);
setLayout(layout);
initialize();
}
MainWindow::~MainWindow() {
delete _informationWidget;
}
void MainWindow::configureLogging() {
const std::string KeyLogLevel =
openspace::ConfigurationManager::KeyLauncher + '.' + openspace::ConfigurationManager::PartLogLevel;
const std::string KeyLogImmediateFlush =
openspace::ConfigurationManager::KeyLauncher + '.' + openspace::ConfigurationManager::PartImmediateFlush;
const std::string KeyLogs =
openspace::ConfigurationManager::KeyLauncher + '.' + openspace::ConfigurationManager::PartLogs;
ghoul::logging::LogLevel ghoulLogLevel;
std::string logLevel = "None";
bool immediateFlush = false;
if (_optionParser->isSet("d")) {
ghoulLogLevel = static_cast<ghoul::logging::LogLevel>(_optionParser->value("d").toInt());
} else {
if (_configuration->hasKeyAndValue<std::string>(KeyLogLevel)) {
_configuration->getValue(KeyLogLevel, logLevel);
_configuration->getValue(KeyLogImmediateFlush, immediateFlush);
}
ghoulLogLevel = ghoul::logging::levelFromString(logLevel);
}
printf("%d", ghoulLogLevel);
using ImmediateFlush = ghoul::logging::LogManager::ImmediateFlush;
ghoul::logging::LogManager::initialize(
ghoulLogLevel,
immediateFlush ? ImmediateFlush::Yes : ImmediateFlush::No
);
LogMgr.addLog(std::make_unique<ghoul::logging::ConsoleLog>());
// TODO: This can crash the system in cases where the logfile can't be created ---abock
LogMgr.addLog(std::make_unique< ghoul::logging::HTMLLog >("LauncherLog.html", ghoul::logging::HTMLLog::Append::No));
LogMgr.addLog(std::make_unique< QLog >());
if (_configuration->hasKeyAndValue<ghoul::Dictionary>(KeyLogs)) {
ghoul::Dictionary logs;
_configuration->getValue(KeyLogs, logs);
for (size_t i = 1; i <= logs.size(); ++i) {
ghoul::Dictionary logInfo;
logs.getValue(std::to_string(i), logInfo);
try {
LogMgr.addLog(openspace::createLog(logInfo));
}
catch (const ghoul::RuntimeError& e) {
LERRORC(e.component, e.message);
}
}
}
#ifdef WIN32
if (IsDebuggerPresent()) {
LogMgr.addLog(std::make_unique<ghoul::logging::VisualStudioOutputLog>());
}
#endif // WIN32
#ifndef GHOUL_LOGGING_ENABLE_TRACE
if (ghoulLogLevel == ghoul::logging::LogLevel::Trace) {
LWARNING("Desired logging level is set to 'Trace' but application was " <<
"compiled without Trace support");
}
#endif // GHOUL_LOGGING_ENABLE_TRACE
}
void MainWindow::initialize() {
// ParseOptions
generateOptions();
// Get the news information
QNetworkRequest request;
request.setUrl(QUrl(NewsURL));
_newsReply = _networkManager.get(request);
QObject::connect(_newsReply, SIGNAL(finished()),
this, SLOT(newsReadyRead())
);
QObject::connect(_newsReply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(newsNetworkError())
);
_shortcutWidget = new ShortcutWidget(this, Qt::Popup | Qt::Dialog);
_shortcutWidget->setWindowModality(Qt::WindowModal);
_shortcutWidget->hide();
_syncWidget = new SyncWidget(this, Qt::Popup | Qt::Dialog);
_syncWidget->setWindowModality(Qt::WindowModal);
_syncWidget->hide();
std::string configurationFile = _configurationFile;
_configuration = new openspace::ConfigurationManager;
configurationFile = _configuration->findConfiguration( configurationFile );
_configuration->loadFromFile(configurationFile);
configureLogging();
// Load all available scenes
QString modulesDirectory = QString::fromStdString(absPath("${ASSETS}"));
QDir d(modulesDirectory);
d.setFilter(QDir::Files);
QFileInfoList list = d.entryInfoList();
_scenes->addItem("Use Default");
for (const QFileInfo& i : list) {
QString file = i.fileName();
file = file.replace(".scene", "");
_sceneFiles.insert(file, i.absoluteFilePath());
_scenes->addItem(file);
}
_scenes->setCurrentText("Use Default");
_syncWidget->setSceneFiles(_sceneFiles);
// Load all available configuration files
QString configurationDirectory = QString::fromStdString(absPath("${CONFIG}"));
d = QDir(configurationDirectory);
d.setFilter(QDir::Files);
list = d.entryInfoList();
_configurations->addItem("Use Default");
for (const QFileInfo& i : list) {
QString file = i.fileName();
file = file.replace(".xml", "");
_configurationFiles.insert(file, i.absoluteFilePath());
_configurations->addItem(file);
}
_configurations->setCurrentText("Use Default");
}
void MainWindow::shortcutButtonPressed() {
_shortcutWidget->show();
}
void MainWindow::syncButtonPressed() {
_syncWidget->show();
}
void MainWindow::startButtonPressed() {
QString exec = OpenSpaceExecutable;
if (_sceneFiles.contains(_scenes->currentText()))
exec += " -scene \"" + _sceneFiles[_scenes->currentText()] + "\"";
if (_configurationFiles.contains(_configurations->currentText()))
exec += " -sgct \"" + _configurationFiles[_configurations->currentText()] + "\"";
LINFOC("MainWindow", "Executing: " << exec.toStdString());
QProcess::startDetached(exec);
}
void MainWindow::newsNetworkError() {
QString error = _newsReply->errorString();
_informationWidget->setText(error);
_newsReply->deleteLater();
}
void MainWindow::newsReadyRead() {
QByteArray arrayData = _newsReply->readAll();
QString news = QString::fromLatin1(arrayData);
_informationWidget->setText(news);
_newsReply->deleteLater();
}
void MainWindow::generateOptions() {
_optionParser = new QCommandLineParser;
_optionParser->setApplicationDescription("OpenSpace Launcher");
_optionParser->addHelpOption();
_optionParser->addVersionOption();
_optionParser->addOptions({
{ { "d", "debug" },
QCoreApplication::translate("main", "Debug output level"),
QCoreApplication::translate("main", "0, 1, 2, 3, 4, 5, 6, 7"),
QCoreApplication::translate("main", "1"),
}
});
_optionParser->process(*QApplication::instance());
}
-86
View File
@@ -1,86 +0,0 @@
/*****************************************************************************************
* *
* 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_APP_LAUNCHER___MAINWINDOW___H__
#define __OPENSPACE_APP_LAUNCHER___MAINWINDOW___H__
#include <QWidget>
#include <QMap>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QTextEdit>
#include <QCommandLineParser>
class QComboBox;
class QNetworkAccessManager;
class ShortcutWidget;
class SyncWidget;
namespace openspace {
class ConfigurationManager;
}
class MainWindow : public QWidget {
Q_OBJECT
public:
MainWindow();
~MainWindow();
private slots:
void shortcutButtonPressed();
void syncButtonPressed();
void startButtonPressed();
void newsNetworkError();
void newsReadyRead();
void generateOptions();
private:
void initialize();
void configureLogging();
QNetworkReply* _newsReply;
QTextEdit* _informationWidget;
QComboBox* _configurations;
QMap<QString, QString> _configurationFiles;
QComboBox* _scenes;
QMap<QString, QString> _sceneFiles;
ShortcutWidget* _shortcutWidget;
SyncWidget* _syncWidget;
QNetworkAccessManager _networkManager;
openspace::ConfigurationManager* _configuration;
QCommandLineParser* _optionParser;
};
#endif // __OPENSPACE_APP_LAUNCHER___MAINWINDOW___H__
Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

-1
View File
@@ -1 +0,0 @@
IDI_ICON1 ICON DISCARDABLE "openspace.ico"
-29
View File
@@ -1,29 +0,0 @@
/*****************************************************************************************
* *
* 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 "shortcutwidget.h"
ShortcutWidget::ShortcutWidget(QWidget* parent, Qt::WindowFlags f)
: QWidget(parent, f)
{}
-36
View File
@@ -1,36 +0,0 @@
/*****************************************************************************************
* *
* 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_APP_LAUNCHER___SHORTCUTWIDGET___H__
#define __OPENSPACE_APP_LAUNCHER___SHORTCUTWIDGET___H__
#include <QWidget>
class ShortcutWidget : public QWidget {
Q_OBJECT
public:
ShortcutWidget(QWidget* parent, Qt::WindowFlags f = 0);
};
#endif // __OPENSPACE_APP_LAUNCHER___SHORTCUTWIDGET___H__
-735
View File
@@ -1,735 +0,0 @@
/*****************************************************************************************
* *
* 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 "syncwidget.h"
#include "infowidget.h"
#include <openspace/openspace.h>
#include <ghoul/ghoul.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/filesystem/file.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/lua/ghoul_lua.h>
#include <ghoul/lua/luastate.h>
#include <ghoul/misc/dictionary.h>
#include <ghoul/misc/onscopeexit.h>
#include <QApplication>
#include <QCheckBox>
#include <QDir>
#include <QDirIterator>
#include <QFileInfo>
#include <QGridLayout>
#include <QGroupBox>
#include <QPushButton>
#include <QScrollArea>
#include <QString>
#include <QThread>
#include <QTimer>
#include <QVBoxLayout>
#include <libtorrent/entry.hpp>
#include <libtorrent/session.hpp>
#include <libtorrent/alert_types.hpp>
#include <libtorrent/torrent_info.hpp>
#include <fstream>
#include <mutex>
namespace {
const std::string _loggerCat = "SyncWidget";
const std::string _configurationFile = "Launcher.config";
const int nColumns = 3;
const int DownloadApplicationVersion = 1;
const std::string FileDownloadKey = "FileDownload";
const std::string FileRequestKey = "FileRequest";
const std::string TorrentFilesKey = "TorrentFiles";
const std::string UrlKey = "URL";
const std::string FileKey = "File";
const std::string DestinationKey = "Destination";
const std::string IdentifierKey = "Identifier";
const std::string VersionKey = "Version";
const bool OverwriteFiles = false;
const bool CleanInfoWidgets = true;
}
SyncWidget::SyncWidget(QWidget* parent, Qt::WindowFlags f)
: QWidget(parent, f)
, _sceneLayout(nullptr)
, _session(new libtorrent::session)
{
setObjectName("SyncWidget");
setFixedSize(500, 500);
QBoxLayout* layout = new QVBoxLayout;
layout->setContentsMargins(0, 0, 0, 0);
{
QGroupBox* sceneBox = new QGroupBox;
_sceneLayout = new QGridLayout;
sceneBox->setLayout(_sceneLayout);
layout->addWidget(sceneBox);
}
{
QPushButton* syncButton = new QPushButton("Synchronize Data");
syncButton->setObjectName("SyncButton");
QObject::connect(
syncButton, SIGNAL(clicked(bool)),
this, SLOT(syncButtonPressed())
);
layout->addWidget(syncButton);
}
{
QScrollArea* area = new QScrollArea;
area->setWidgetResizable(true);
QWidget* w = new QWidget;
w->setObjectName("DownloadArea");
area->setWidget(w);
_downloadLayout = new QVBoxLayout(w);
_downloadLayout->setMargin(0);
_downloadLayout->setSpacing(0);
_downloadLayout->addStretch(100);
layout->addWidget(area);
}
QPushButton* close = new QPushButton("Close");
layout->addWidget(close, Qt::AlignRight);
QObject::connect(
close, SIGNAL(clicked(bool)),
this, SLOT(close())
);
setLayout(layout);
ghoul::initialize();
// _downloadManager = std::make_unique<openspace::DownloadManager>(
// "http://data.openspaceproject.com/request", DownloadApplicationVersion);
libtorrent::error_code ec;
_session->listen_on(std::make_pair(20280, 20290), ec);
libtorrent::settings_pack settings;
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);
if (ec) {
LFATAL("Failed to open socket: " << ec.message());
return;
}
_session->start_upnp();
// I commented this out as it caused the Linux build nodes to fail during linking
// and I couldn't figure out how to fix it
// it would throw an cxx11 ABI incompatibility error
//std::ifstream file(_configurationFile);
//if (!file.fail()) {
// union {
// uint32_t value;
// std::array<char, 4> data;
// } size;
// file.read(size.data.data(), sizeof(uint32_t));
// std::vector<char> buffer(size.value);
// file.read(buffer.data(), size.value);
// file.close();
// libtorrent::entry e = libtorrent::bdecode(buffer.begin(), buffer.end());
// _session->start_dht(e);
//}
//else
_session->start_dht();
_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 });
QTimer* timer = new QTimer(this);
QObject::connect(timer, SIGNAL(timeout()), this, SLOT(handleTimer()));
timer->start(100);
_mutex.clear();
_scriptEngine.initialize();
}
SyncWidget::~SyncWidget() {
libtorrent::entry dht = _session->dht_state();
// I commented this out as it caused the Linux build nodes to fail during linking
// and I couldn't figure out how to fix it
// it would throw an cxx11 ABI incompatibility error
//std::vector<char> buffer;
//libtorrent::bencode(std::back_inserter(buffer), dht);
//std::ofstream f(_configurationFile);
//union {
// uint32_t value;
// std::array<char, 4> data;
//} size;
//size.value = buffer.size();
//f.write(size.data.data(), sizeof(uint32_t));
//f.write(buffer.data(), buffer.size());
_downloadManager.reset();
ghoul::deinitialize();
delete _session;
}
void SyncWidget::closeEvent(QCloseEvent* event) {
std::vector<libtorrent::torrent_handle> handles = _session->get_torrents();
for (libtorrent::torrent_handle h : handles) {
h.flush_cache();
_session->remove_torrent(h);
}
}
void SyncWidget::setSceneFiles(QMap<QString, QString> sceneFiles) {
_sceneFiles = std::move(sceneFiles);
QStringList keys = _sceneFiles.keys();
for (int i = 0; i < keys.size(); ++i) {
const QString& sceneName = keys[i];
QCheckBox* checkbox = new QCheckBox(sceneName);
QString defaultName = "default";
if (sceneName == defaultName){
checkbox->setChecked(true);
}
_sceneLayout->addWidget(checkbox, i / nColumns, i % nColumns);
}
}
void SyncWidget::clear() {
for (std::shared_ptr<openspace::DownloadManager::FileFuture> f : _futures)
f->abortDownload = true;
using libtorrent::torrent_handle;
for (QMap<torrent_handle, InfoWidget*>::iterator i = _torrentInfoWidgetMap.begin();
i != _torrentInfoWidgetMap.end();
++i)
{
delete i.value();
}
_torrentInfoWidgetMap.clear();
_session->abort();
_directFiles.clear();
_fileRequests.clear();
_torrentFiles.clear();
}
void SyncWidget::handleDirectFiles() {
LDEBUG("Direct Files");
for (const DirectFile& f : _directFiles) {
LDEBUG(f.url.toStdString() << " -> " << f.destination.toStdString());
std::shared_ptr<openspace::DownloadManager::FileFuture> future = _downloadManager->downloadFile(
f.url.toStdString(),
absPath(f.destination.toStdString()),
OverwriteFiles
);
if (future) {
InfoWidget* w = new InfoWidget(f.destination);
_downloadLayout->insertWidget(_downloadLayout->count() - 1, w);
_futures.push_back(future);
_futureInfoWidgetMap[future] = w;
}
}
}
void SyncWidget::handleFileRequest() {
LDEBUG("File Requests");
for (const FileRequest& f : _fileRequests) {
LDEBUG(f.identifier.toStdString() << " (" << f.version << ") -> " << f.destination.toStdString());
ghoul::filesystem::Directory d = FileSys.currentDirectory();
OnExit([&]() { FileSys.setCurrentDirectory(d); });
FileSys.setCurrentDirectory(f.baseDir.toStdString());
std::string identifier = f.identifier.toStdString();
std::string path = absPath(f.destination.toStdString());
int version = f.version;
std::string requestId = path + "$" + identifier;
std::lock_guard<std::mutex> g(_filesDownloadingMutex);
if (_filesDownloading.find(requestId) != _filesDownloading.end()) {
continue; // The file is already being downloaded.
}
_filesDownloading.insert(requestId);
/*
TODO: Adapt to new http request api!
_downloadManager->downloadRequestFilesAsync(
identifier,
path,
version,
OverwriteFiles,
[this, requestId](const std::vector<std::shared_ptr<openspace::DownloadManager::FileFuture>>& futures) {
handleFileFutureAddition(futures);
std::lock_guard<std::mutex> g(_filesDownloadingMutex);
_filesDownloading.erase(requestId);
}
);*/
}
}
void SyncWidget::handleTorrentFiles() {
LDEBUG("Torrent Files");
for (const TorrentFile& f : _torrentFiles) {
LDEBUG(f.file.toStdString() << " -> " << f.destination.toStdString());
ghoul::filesystem::Directory d = FileSys.currentDirectory();
// std::string thisDirectory = absPath("${SCENE}/" + f.module.toStdString() + "/");
FileSys.setCurrentDirectory(f.baseDir.toStdString());
// FileSys.setCurrentDirectory(thisDirectory);
QString file = QString::fromStdString(absPath(f.file.toStdString()));
if (!QFileInfo(file).exists()) {
LERROR(file.toStdString() << " does not exist");
continue;
}
libtorrent::error_code ec;
libtorrent::add_torrent_params p;
//if (f.destination.isEmpty())
//p.save_path = absPath(fullPath(f.module, ".").toStdString());
//else
//p.save_path =
p.save_path = absPath(f.destination.toStdString());
p.ti = std::make_shared<libtorrent::torrent_info>(file.toStdString(), ec);
p.name = f.file.toStdString();
p.storage_mode = libtorrent::storage_mode_allocate;
if (ec) {
LERROR(f.file.toStdString() << ": " << ec.message());
continue;
}
libtorrent::torrent_handle h = _session->add_torrent(p, ec);
if (ec) {
LERROR(f.file.toStdString() << ": " << ec.message());
continue;
}
if (_torrentInfoWidgetMap.find(h) == _torrentInfoWidgetMap.end()) {
QString fileString = f.file;
QString t = QString(".torrent");
fileString.replace(fileString.indexOf(t), t.size(), "");
fileString = f.module + "/" + fileString;
InfoWidget* w = new InfoWidget(fileString, h.status().total_wanted);
_downloadLayout->insertWidget(_downloadLayout->count() - 1, w);
_torrentInfoWidgetMap[h] = w;
}
FileSys.setCurrentDirectory(d);
}
}
void SyncWidget::syncButtonPressed() {
clear();
ghoul::lua::LuaState state;
_scriptEngine.initializeLuaState(state);
for (const QString& scene : selectedScenes()) {
LDEBUG(scene.toStdString());
ghoul::Dictionary sceneDictionary;
try {
ghoul::lua::loadDictionaryFromFile(
scene.toStdString(),
sceneDictionary,
state
);
} catch (const ghoul::lua::LuaRuntimeException& e) {
LERROR(e.message);
return;
}
ghoul::Dictionary modules;
bool success = sceneDictionary.getValue<ghoul::Dictionary>("Assets", modules);
if (!success) {
LERROR("Could not find 'Modules'");
return;
}
QDir sceneDir(scene);
sceneDir.cdUp();
QList<ModuleInformation> modulesList;
for (int i = 1; i <= modules.size(); ++i) {
std::string module = modules.value<std::string>(std::to_string(i));
std::string shortModule = module;
std::string::size_type pos = module.find_last_of(FileSys.PathSeparator);
if (pos != std::string::npos) {
shortModule = module.substr(pos+1);
}
QString m = QString::fromStdString(module);
QString dataFile = sceneDir.absoluteFilePath(
QString::fromStdString(module) + "/" + QString::fromStdString(shortModule) + ".data"
);
if (QFileInfo(dataFile).exists()) {
modulesList.append({
QString::fromStdString(module),
dataFile,
sceneDir.absolutePath() + "/" + QString::fromStdString(module)
});
}
else {
QDir metaModuleDir = sceneDir;
metaModuleDir.cd(QString::fromStdString(module));
QDirIterator it(metaModuleDir.absolutePath(), QStringList() << "*.data", QDir::Files, QDirIterator::Subdirectories);
while (it.hasNext()) {
QString v = it.next();
QDir d(v);
d.cdUp();
modulesList.append({
d.dirName(),
v,
d.absolutePath()
});
}
}
}
modulesList.append({
"common",
sceneDir.absolutePath() + "/common/common.data",
sceneDir.absolutePath() + "/common"
});
for (const ModuleInformation& module : modulesList) {
QString dataFile = module.moduleDatafile;
// QString dataFile = sceneDir.absoluteFilePath(module + "/" + module + ".data");
if (QFileInfo(dataFile).exists()) {
ghoul::Dictionary dataDictionary;
try {
ghoul::lua::loadDictionaryFromFile(dataFile.toStdString(), dataDictionary);
}
catch (const ghoul::lua::LuaLoadingException& exception) {
LWARNINGC(exception.component, exception.message);
}
ghoul::Dictionary directDownloadFiles;
ghoul::Dictionary fileRequests;
ghoul::Dictionary torrentFiles;
bool found = dataDictionary.getValue<ghoul::Dictionary>(FileDownloadKey, directDownloadFiles);
if (found) {
for (int i = 1; i <= directDownloadFiles.size(); ++i) {
if (!directDownloadFiles.hasKeyAndValue<ghoul::Dictionary>(std::to_string(i))) {
LERROR(dataFile.toStdString() << ": " << FileDownloadKey << " is not a dictionary");
continue;
}
ghoul::Dictionary d = directDownloadFiles.value<ghoul::Dictionary>(std::to_string(i));
if (!d.hasKeyAndValue<std::string>(UrlKey)) {
LERROR(dataFile.toStdString() << ": No " << UrlKey);
continue;
}
std::string url = d.value<std::string>(UrlKey);
std::string dest = "";
if (d.hasKeyAndValue<std::string>(DestinationKey))
dest = d.value<std::string>(DestinationKey);
_directFiles.append({
module.moduleName,
QString::fromStdString(url),
"${SYNC}/" + module.moduleName + "/" + QString::fromStdString(dest),
module.modulePath
});
}
}
found = dataDictionary.getValue<ghoul::Dictionary>(FileRequestKey, fileRequests);
if (found) {
for (int i = 1; i <= fileRequests.size(); ++i) {
ghoul::Dictionary d = fileRequests.value<ghoul::Dictionary>(std::to_string(i));
if (!d.hasKeyAndValue<std::string>(IdentifierKey)) {
LERROR(dataFile.toStdString() << ": No " << IdentifierKey);
continue;
}
std::string url = d.value<std::string>(IdentifierKey);
std::string dest = "";
if (d.hasKeyAndValue<std::string>(DestinationKey))
dest = d.value<std::string>(DestinationKey);
if (!d.hasKeyAndValue<double>(VersionKey)) {
LERROR(dataFile.toStdString() << ": No " << VersionKey);
continue;
}
int version = static_cast<int>(d.value<double>(VersionKey));
_fileRequests.append({
module.moduleName,
QString::fromStdString(url),
"${SYNC}/" + module.moduleName + "/" + QString::fromStdString(dest),
module.modulePath,
version
});
}
}
found = dataDictionary.getValue<ghoul::Dictionary>(TorrentFilesKey, torrentFiles);
if (found) {
for (int i = 1; i <= torrentFiles.size(); ++i) {
ghoul::Dictionary d = torrentFiles.value<ghoul::Dictionary>(std::to_string(i));
if (!d.hasKeyAndValue<std::string>(FileKey)) {
LERROR(dataFile.toStdString() << ": No " << FileKey);
continue;
}
std::string file = d.value<std::string>(FileKey);
std::string dest;
if (d.hasKeyAndValue<std::string>(DestinationKey))
dest = d.value<std::string>(DestinationKey);
else
dest = "";
_torrentFiles.append({
module.moduleName,
QString::fromStdString(file),
"${SYNC}/" + module.moduleName + "/" + QString::fromStdString(dest),
module.modulePath
});
}
}
}
}
}
// Remove duplicates for file requests
std::map<QString, FileRequest> uniqueFileRequests;
for (const FileRequest& f : _fileRequests) {
uniqueFileRequests.emplace(std::make_pair(f.baseDir + "/" + f.destination, f));
}
_fileRequests.clear();
for (const auto& f : uniqueFileRequests) {
_fileRequests.append(f.second);
}
// Remove duplicates for direct files
std::map<QString, DirectFile> uniqueDirectFiles;
for (const DirectFile& f : _directFiles) {
uniqueDirectFiles.emplace(std::make_pair(f.destination, f));
}
_directFiles.clear();
for (const auto& f : uniqueDirectFiles) {
_directFiles.append(f.second);
}
// Remove duplicates for torrents
std::map<QString, TorrentFile> uniqueTorrentFiles;
for (const TorrentFile& f : _torrentFiles) {
uniqueTorrentFiles.emplace(std::make_pair(f.destination, f));
}
_directFiles.clear();
for (const auto& f : uniqueTorrentFiles) {
_torrentFiles.append(f.second);
}
handleDirectFiles();
handleFileRequest();
handleTorrentFiles();
}
QStringList SyncWidget::selectedScenes() const {
QStringList result;
int nChildren = _sceneLayout->count();
for (int i = 0; i < nChildren; ++i) {
QWidget* w = _sceneLayout->itemAt(i)->widget();
QCheckBox* c = static_cast<QCheckBox*>(w);
if (c->isChecked()) {
QString t = c->text();
result.append(_sceneFiles[t]);
}
}
std::string scenes;
for (QString s : result)
scenes += s.toStdString() + "; ";
LDEBUG("Downloading scenes: " << scenes);
return result;
}
void SyncWidget::handleTimer() {
using namespace libtorrent;
using FileFuture = openspace::DownloadManager::FileFuture;
std::vector<std::shared_ptr<FileFuture>> toRemove;
for (std::shared_ptr<FileFuture> f : _futures) {
InfoWidget* w = _futureInfoWidgetMap[f];
if (CleanInfoWidgets && (f->isFinished || f->isAborted)) {
toRemove.push_back(f);
_downloadLayout->removeWidget(w);
_futureInfoWidgetMap.erase(f);
delete w;
}
else
w->update(f);
}
for (std::shared_ptr<FileFuture> f : toRemove) {
_futures.erase(std::remove(_futures.begin(), _futures.end(), f), _futures.end());
}
while (_mutex.test_and_set()) {}
for (std::shared_ptr<FileFuture> f : _futuresToAdd) {
InfoWidget* w = new InfoWidget(QString::fromStdString(f->filePath), -1);
_downloadLayout->insertWidget(_downloadLayout->count() - 1, w);
_futureInfoWidgetMap[f] = w;
_futures.push_back(f);
}
_futuresToAdd.clear();
_mutex.clear();
std::vector<torrent_handle> handles = _session->get_torrents();
for (torrent_handle h : handles) {
torrent_status s = h.status();
InfoWidget* w = _torrentInfoWidgetMap[h];
if (w)
w->update(s);
if (CleanInfoWidgets && (s.state == torrent_status::finished || s.state == torrent_status::seeding)) {
_torrentInfoWidgetMap.remove(h);
delete w;
}
}
// Only close every torrent if all torrents are finished
bool allSeeding = true;
for (torrent_handle h : handles) {
torrent_status s = h.status();
allSeeding &= (s.state == torrent_status::seeding);
}
if (allSeeding) {
for (torrent_handle h : handles)
_session->remove_torrent(h);
}
//_session->post_torrent_updates();
//libtorrent::session_settings settings = _session->settings();
//qDebug() << "Session";
//qDebug() << "nPeers: " << _session->status().num_peers;
//qDebug() << "DHT: " << _session->is_dht_running();
//qDebug() << "Incoming TCP" << settings.enable_incoming_tcp;
//qDebug() << "Outgoing TCP" << settings.enable_outgoing_tcp;
//qDebug() << "Incoming UTP" << settings.enable_incoming_utp;
//qDebug() << "Outgoing UTP" << settings.enable_outgoing_utp;
//qDebug() << "===";
//qDebug() << "Alerts";
//std::deque<alert*> alerts;
//_session->pop_alerts(&alerts);
//for (alert* a : alerts) {
// qDebug() << QString::fromStdString(a->message());
// //if (a->category() == alert::status_notification) {
// // state_update_alert* sua = static_cast<state_update_alert*>(a);
// // for (torrent_status s )
// //}
//}
//qDebug() << "===";
// qDebug() << "Name: " << QString::fromStdString(h.name());
// //torrent_status s = h.status();
// qDebug() << "Error: " << QString::fromStdString(s.error);
// qDebug() << "Total Wanted: " << s.total_wanted;
// qDebug() << "Total Wanted Done: " << s.total_wanted_done;
// qDebug() << "Has Incoming: " << s.has_incoming;
// qDebug() << "Connect Candidates: " << s.connect_candidates;
// qDebug() << "Last Seen Complete: " << s.last_seen_complete;
// qDebug() << "List Peers: " << s.list_peers;
// qDebug() << "List Seeds: " << s.list_seeds;
// qDebug() << "Num Pieces: " << s.num_pieces;
// qDebug() << "Download Rate: " << s.download_rate;
// qDebug() << "List Seeds: " << s.list_seeds;
// qDebug() << "Paused: " << s.paused;
// qDebug() << "Progress: " << s.progress;
// qDebug() << "";
}
void SyncWidget::handleFileFutureAddition(
const std::vector<std::shared_ptr<openspace::DownloadManager::FileFuture>>& futures)
{
while (_mutex.test_and_set()) {}
_futuresToAdd.insert(_futuresToAdd.end(), futures.begin(), futures.end());
_mutex.clear();
}
-135
View File
@@ -1,135 +0,0 @@
/*****************************************************************************************
* *
* 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_APP_LAUNCHER___SYNCWIDGET___H__
#define __OPENSPACE_APP_LAUNCHER___SYNCWIDGET___H__
#include <QWidget>
#include <QMap>
#include <openspace/engine/downloadmanager.h>
#include <openspace/scripting/scriptengine.h>
#include <libtorrent/torrent_handle.hpp>
#include <atomic>
//#include <thread>
class QBoxLayout;
class QGridLayout;
class InfoWidget;
namespace libtorrent {
class session;
struct torrent_handle;
}
class SyncWidget : public QWidget {
Q_OBJECT
public:
SyncWidget(QWidget* parent, Qt::WindowFlags f = 0);
~SyncWidget();
void setSceneFiles(QMap<QString, QString> sceneFiles);
private slots:
void syncButtonPressed();
void handleTimer();
void closeEvent(QCloseEvent* event);
private:
struct DirectFile {
QString module;
QString url;
QString destination;
QString baseDir;
};
struct FileRequest {
QString module;
QString identifier;
QString destination;
QString baseDir;
int version;
};
struct TorrentFile {
QString module;
QString file;
QString destination;
QString baseDir;
};
struct ModuleInformation {
QString moduleName;
QString moduleDatafile;
QString modulePath;
};
void clear();
QStringList selectedScenes() const;
void handleFileFutureAddition(
const std::vector<std::shared_ptr<openspace::DownloadManager::FileFuture>>&
futures
);
void handleDirectFiles();
void handleFileRequest();
void handleTorrentFiles();
QMap<QString, QString> _sceneFiles;
QString _modulesDirectory;
QGridLayout* _sceneLayout;
QBoxLayout* _downloadLayout;
libtorrent::session* _session;
QMap<libtorrent::torrent_handle, InfoWidget*> _torrentInfoWidgetMap;
QList<DirectFile> _directFiles;
QList<FileRequest> _fileRequests;
QList<TorrentFile> _torrentFiles;
std::mutex _filesDownloadingMutex;
std::set<std::string> _filesDownloading;
std::vector<std::shared_ptr<openspace::DownloadManager::FileFuture>> _futures;
std::map<
std::shared_ptr<openspace::DownloadManager::FileFuture>,
InfoWidget*
> _futureInfoWidgetMap;
std::vector<std::shared_ptr<openspace::DownloadManager::FileFuture>> _futuresToAdd;
std::atomic_flag _mutex;
std::unique_ptr<openspace::DownloadManager> _downloadManager;
openspace::scripting::ScriptEngine _scriptEngine;
};
#endif // __OPENSPACE_APP_LAUNCHER___SYNCWIDGET___H__
@@ -1,63 +1,36 @@
#########################################################################################
# #
# 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. #
#########################################################################################
##########################################################################################
# #
# 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(${OPENSPACE_CMAKE_EXT_DIR}/application_definition.cmake)
include(${GHOUL_BASE_DIR}/support/cmake/handle_external_library.cmake)
set(SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
${CMAKE_CURRENT_SOURCE_DIR}/infowidget.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mainwindow.cpp
${CMAKE_CURRENT_SOURCE_DIR}/shortcutwidget.cpp
${CMAKE_CURRENT_SOURCE_DIR}/syncwidget.cpp
)
set(HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/infowidget.h
${CMAKE_CURRENT_SOURCE_DIR}/mainwindow.h
${CMAKE_CURRENT_SOURCE_DIR}/shortcutwidget.h
${CMAKE_CURRENT_SOURCE_DIR}/syncwidget.h
)
find_package(Qt5 COMPONENTS Core Widgets Network REQUIRED)
qt5_wrap_cpp(MOC_FILES ${HEADER_FILES})
qt5_add_resources(RESOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/files.qrc)
create_new_application(
Launcher
Sync
MACOSX_BUNDLE
${SOURCE_FILES}
${HEADER_FILES}
${OPENSPACE_APPS_DIR}/Launcher/openspace.rc
${MOC_FILES}
${RESOURCE_FILES}
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
)
target_link_libraries(
Launcher
Sync
libOpenSpace
Qt5::Widgets
Qt5::Network
)
)
+160
View File
@@ -0,0 +1,160 @@
/*****************************************************************************************
* *
* 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 <openspace/rendering/dashboarditem.h>
#include <openspace/rendering/renderable.h>
#include <openspace/scene/translation.h>
#include <openspace/scene/rotation.h>
#include <openspace/scene/scale.h>
#include <openspace/engine/configurationmanager.h>
#include <openspace/engine/moduleengine.h>
#include <openspace/util/factorymanager.h>
#include <openspace/util/progressbar.h>
#include <openspace/util/resourcesynchronization.h>
#include <openspace/util/taskloader.h>
#include <ghoul/ghoul.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/logging/consolelog.h>
// #include <iostream>
// #include <string>
// #include <ghoul/glm.h>
// #include <ghoul/opengl/ghoul_gl.h>
// #include <ghoul/io/texture/texturereader.h>
// #include <ghoul/io/texture/texturereaderdevil.h>
// #include <ghoul/io/texture/texturereaderfreeimage.h>
// #include <ghoul/filesystem/directory.h>
// #include <ghoul/cmdparser/commandlineparser.h>
// #include <ghoul/cmdparser/singlecommand.h>
// #include <openspace/scripting/scriptengine.h>
// #include <openspace/engine/openspaceengine.h>
// #include <openspace/engine/configurationmanager.h>
// #include <openspace/util/task.h>
namespace {
constexpr const char* ConfigurationFile = "openspace.cfg";
constexpr const char* _loggerCat = "Sync";
}
int main(int, char** argv) {
using namespace openspace;
ghoul::initialize();
ghoul::logging::LogManager::initialize(
ghoul::logging::LogLevel::Debug,
ghoul::logging::LogManager::ImmediateFlush::Yes
);
LogMgr.addLog(std::make_unique<ghoul::logging::ConsoleLog>());
LDEBUG("Initialize FileSystem");
ghoul::filesystem::Directory launchDirectory = FileSys.currentDirectory();
#ifdef __APPLE__
ghoul::filesystem::File app(argv[0]);
std::string dirName = app.directoryName();
LINFO("Setting starting directory to '" << dirName << "'");
FileSys.setCurrentDirectory(dirName);
#endif
// initTextureReaders();
FactoryManager::initialize();
FactoryManager::ref().addFactory(
std::make_unique<ghoul::TemplateFactory<Renderable>>(),
"Renderable"
);
FactoryManager::ref().addFactory(
std::make_unique<ghoul::TemplateFactory<Task>>(),
"Task"
);
FactoryManager::ref().addFactory(
std::make_unique<ghoul::TemplateFactory<Translation>>(),
"Translation"
);
FactoryManager::ref().addFactory(
std::make_unique<ghoul::TemplateFactory<Rotation>>(),
"Rotation"
);
FactoryManager::ref().addFactory(
std::make_unique<ghoul::TemplateFactory<Scale>>(),
"Scale"
);
FactoryManager::ref().addFactory(
std::make_unique<ghoul::TemplateFactory<ResourceSynchronization>>(),
"ResourceSynchronization"
);
FactoryManager::ref().addFactory(
std::make_unique<ghoul::TemplateFactory<DashboardItem>>(),
"DashboardItem"
);
openspace::ConfigurationManager configuration;
std::string configurationFile = configuration.findConfiguration(ConfigurationFile);
configuration.loadFromFile(configurationFile);
ghoul::Dictionary moduleConfigurations;
if (configuration.hasKeyAndValue<ghoul::Dictionary>(
ConfigurationManager::KeyModuleConfigurations))
{
configuration.getValue<ghoul::Dictionary>(
ConfigurationManager::KeyModuleConfigurations,
moduleConfigurations
);
}
ModuleEngine moduleEngine;
moduleEngine.initialize(moduleConfigurations);
LINFO("Initialization done.");
TaskLoader taskLoader;
std::vector<std::unique_ptr<Task>> tasks = taskLoader.tasksFromFile(
absPath("${TASKS}/full_sync.task")
);
for (size_t i = 0; i < tasks.size(); i++) {
Task& task = *tasks[i].get();
LINFO(
"Synchronizing scene " << (i + 1) << " out of " <<
tasks.size() << ": " << task.description()
);
ProgressBar progressBar(100);
auto onProgress = [&progressBar](float progress) {
progressBar.print(static_cast<int>(progress * 100.f));
};
task.perform(onProgress);
}
std::cout << "Done synchronizing." << std::endl;
return 0;
};
+4 -7
View File
@@ -205,16 +205,13 @@ int main(int argc, char** argv) {
// If no task file was specified in as argument, run in CLI mode.
std::string tasksRoot;
if (configuration.getValue(ConfigurationManager::KeyConfigTasksRoot, tasksRoot)) {
LINFO("Task root: " << tasksRoot);
FileSys.setCurrentDirectory(ghoul::filesystem::Directory(absPath(tasksRoot)));
}
LINFO("Task root: " << absPath("${TASKS}"));
FileSys.setCurrentDirectory(ghoul::filesystem::Directory(absPath("${TASKS}")));
std::cout << "TASK >";
std::cout << "TASK > ";
while (std::cin >> tasksPath) {
performTasks(tasksPath);
std::cout << "TASK >";
std::cout << "TASK > ";
}
return 0;
@@ -7,6 +7,10 @@ return {
Type = "SyncAssetTask",
Asset = "default"
},
{
Type = "SyncAssetTask",
Asset = "juno"
},
{
Type = "SyncAssetTask",
Asset = "newhorizons"
@@ -18,5 +22,9 @@ return {
{
Type = "SyncAssetTask",
Asset = "rosetta"
},
{
Type = "SyncAssetTask",
Asset = "voyager"
}
}
}
@@ -74,8 +74,6 @@ public:
static const std::string KeyConfigAsset;
/// The key that stores the scene license documentation values
static const std::string KeySceneLicenseDocumentation;
/// The key that stores the location of the scene file that is initially loaded
static const std::string KeyConfigTasksRoot;
/// The key that stores the subdirectory containing a list of all startup scripts to
/// be executed on application start before the scene file is loaded
static const std::string KeyStartupScript;
+2 -3
View File
@@ -36,8 +36,6 @@ return {
-- Asset = "osirisrex",
-- Asset = "voyager",
TasksRoot = "${OPENSPACE_DATA}/tasks",
-- These scripts are executed after the postInitialization of each scene, thus making
-- it possible to have global overrides to default values or execute other scripts
-- regardless of the scene that is loaded
@@ -58,7 +56,8 @@ return {
CACHE = "${BASE_PATH}/cache",
FONTS = "${OPENSPACE_DATA}/fonts",
DOCUMENTATION = "${BASE_PATH}/documentation",
LOGS = "${BASE_PATH}/logs"
LOGS = "${BASE_PATH}/logs",
TASKS = "${OPENSPACE_DATA}/tasks"
},
Fonts = {
Mono = "${FONTS}/Bitstream-Vera-Sans-Mono/VeraMono.ttf",
-1
View File
@@ -63,7 +63,6 @@ const string ConfigurationManager::KeyFactoryDocumentation = "FactoryDocumentati
const string ConfigurationManager::KeyConfigAsset = "Asset";
const string ConfigurationManager::KeySceneLicenseDocumentation = "LicenseDocumentation";
const string ConfigurationManager::KeyConfigTasksRoot = "TasksRoot";
const string ConfigurationManager::KeyLogging = "Logging";
const string ConfigurationManager::PartLogDir = "LogDir";
-8
View File
@@ -60,14 +60,6 @@ documentation::Documentation ConfigurationManager::Documentation() {
"of any scene. These scripts can be used for user-specific customization, "
"such as a global rebinding of keys from the default."
},
{
ConfigurationManager::KeyConfigTasksRoot,
new StringAnnotationVerifier(
"A valid task file as described in the Task documentation"
),
Optional::Yes,
"The root task to be performed when launching the task runner application."
},
{
ConfigurationManager::KeyPaths,
new StringListVerifier,