Work to using the request mechanism for downloading

This commit is contained in:
Alexander Bock
2015-06-11 02:03:50 +02:00
parent f369d0e1f3
commit 549992b5e3
6 changed files with 215 additions and 62 deletions

View File

@@ -153,6 +153,7 @@ void MainWindow::initialize() {
_scenes->addItem(i.fileName());
}
_syncWidget.setSceneFiles(_sceneFiles);
_syncWidget.setModulesDirectory(ModulesDirectory);
}
void MainWindow::shortcutButtonPressed() {

View File

@@ -27,6 +27,7 @@
#include <openspace/engine/downloadmanager.h>
#include <ghoul/ghoul.h>
#include <ghoul/filesystem/file.h>
#include <ghoul/misc/dictionary.h>
#include <ghoul/lua/ghoul_lua.h>
@@ -41,6 +42,17 @@
namespace {
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 DestinationKey = "Destination";
const std::string IdentifierKey = "Identifier";
const std::string VersionKey = "Version";
}
SyncWidget::SyncWidget(QWidget* parent)
@@ -58,13 +70,18 @@ SyncWidget::SyncWidget(QWidget* parent)
}
{
QPushButton* syncButton = new QPushButton("Synchronize Scenes");
QObject::connect(
syncButton, SIGNAL(clicked(bool)),
this, SLOT(syncButtonPressed())
);
layout->addWidget(syncButton);
}
setLayout(layout);
ghoul::initialize();
openspace::DownloadManager::initialize("http://openspace.itn.liu.se/request.cgi");
openspace::DownloadManager::initialize("http://openspace.itn.liu.se/data/request", DownloadApplicationVersion);
}
SyncWidget::~SyncWidget() {
@@ -86,82 +103,147 @@ void SyncWidget::setSceneFiles(QMap<QString, QString> sceneFiles) {
}
}
void SyncWidget::setModulesDirectory(QString modulesDirectory) {
_modulesDirectory = std::move(modulesDirectory);
}
void SyncWidget::clear() {
}
void SyncWidget::handleDirectFiles(QString module, QStringList files) {
qDebug() << files;
void SyncWidget::handleDirectFiles(QString module, DirectFiles files) {
qDebug() << "Direct Files";
for (const DirectFile& f : files) {
qDebug() << f.url << " -> " << f.destination;
DlManager.downloadFile(
f.url.toStdString(),
fullPath(module, f.destination).toStdString(),
[](const ghoul::filesystem::File& f) { qDebug() << QString::fromStdString(f.filename()) << "finished";}
);
}
}
void SyncWidget::handleTorrentFiles(QString module, QStringList torrents) {
qDebug() << torrents;
void SyncWidget::handleFileRequest(QString module, FileRequests files) {
qDebug() << "File Requests";
for (const FileRequest& f : files) {
qDebug() << f.identifier << " (" << f.version << ")" << " -> " << f.destination;
}
}
void SyncWidget::handleTorrentFiles(QString module, TorrentFiles files) {
qDebug() << "Torrent Files";
for (const TorrentFile& f : files) {
qDebug() << f.file;
}
}
void SyncWidget::syncButtonPressed() {
clear();
for (const QString& scene : selectedScenes()) {
qDebug() << scene;
ghoul::Dictionary sceneDictionary;
ghoul::lua::loadDictionaryFromFile(
scene.toStdString(),
sceneDictionary
);
qDebug() << _sceneFiles;
ghoul::Dictionary modules;
bool success = sceneDictionary.getValue<ghoul::Dictionary>("Modules", modules);
qDebug() << success;
ghoul::Dictionary sceneDictionary;
ghoul::lua::loadDictionaryFromFile(
scene.toStdString(),
sceneDictionary
);
QStringList modulesList;
for (int i = 1; i <= modules.size(); ++i) {
std::string module = modules.value<std::string>(std::to_string(i));
modulesList.append(QString::fromStdString(module));
}
qDebug() << modulesList;
ghoul::Dictionary modules;
bool success = sceneDictionary.getValue<ghoul::Dictionary>("Modules", modules);
qDebug() << success;
QDir sceneDir(scene);
sceneDir.cdUp();
for (QString module : modulesList) {
QString dataFile = sceneDir.absoluteFilePath(module + "/" + module + ".data");
QStringList modulesList;
for (int i = 1; i < modules.size(); ++i) {
std::string module = modules.value<std::string>(std::to_string(i));
modulesList.append(QString::fromStdString(module));
}
qDebug() << modulesList;
qDebug() << module;
qDebug() << dataFile << QFileInfo(dataFile).exists();
QDir sceneDir(scene);
sceneDir.cdUp();
for (QString module : modulesList) {
QString moduleFile = sceneDir.absoluteFilePath(module + "/" + module + ".mod");
QString dataFile = sceneDir.absoluteFilePath(module + "/" + module + ".data");
if (QFileInfo(dataFile).exists()) {
ghoul::Dictionary dataDictionary;
ghoul::lua::loadDictionaryFromFile(dataFile.toStdString(), dataDictionary);
qDebug() << module;
qDebug() << moduleFile << QFileInfo(moduleFile).exists();
qDebug() << dataFile << QFileInfo(dataFile).exists();
ghoul::Dictionary directDownloadFiles;
ghoul::Dictionary fileRequests;
ghoul::Dictionary torrentFiles;
if (QFileInfo(dataFile).exists()) {
ghoul::Dictionary dataDictionary;
ghoul::lua::loadDictionaryFromFile(dataFile.toStdString(), dataDictionary);
bool found = dataDictionary.getValue<ghoul::Dictionary>(FileDownloadKey, directDownloadFiles);
if (found) {
DirectFiles files;
//QStringList files;
for (int i = 1; i <= directDownloadFiles.size(); ++i) {
ghoul::Dictionary d = directDownloadFiles.value<ghoul::Dictionary>(std::to_string(i));
std::string url = d.value<std::string>(UrlKey);
std::string dest = d.value<std::string>(DestinationKey);
ghoul::Dictionary directFiles;
ghoul::Dictionary torrentFiles;
bool found = dataDictionary.getValue<ghoul::Dictionary>("Files", directFiles);
if (found) {
QStringList files;
for (int i = 1; i < directFiles.size(); ++i) {
std::string f = directFiles.value<std::string>(std::to_string(i));
files.append(QString::fromStdString(f));
files.append({
QString::fromStdString(url),
QString::fromStdString(dest)
});
}
handleDirectFiles(module, files);
}
handleDirectFiles(module, files);
}
found = dataDictionary.getValue<ghoul::Dictionary>("Torrents", torrentFiles);
if (found) {
QStringList torrents;
for (int i = 1; i < torrentFiles.size(); ++i) {
std::string f = torrentFiles.value<std::string>(std::to_string(i));
torrents.append(QString::fromStdString(f));
found = dataDictionary.getValue<ghoul::Dictionary>(FileRequestKey, fileRequests);
if (found) {
FileRequests files;
for (int i = 1; i <= fileRequests.size(); ++i) {
ghoul::Dictionary d = fileRequests.value<ghoul::Dictionary>(std::to_string(i));
std::string url = d.value<std::string>(IdentifierKey);
std::string dest = d.value<std::string>(DestinationKey);
int version = static_cast<int>(d.value<double>(VersionKey));
files.append({
QString::fromStdString(url),
QString::fromStdString(dest),
version
});
}
handleFileRequest(module, files);
}
found = dataDictionary.getValue<ghoul::Dictionary>(TorrentFilesKey, torrentFiles);
if (found) {
TorrentFiles torrents;
for (int i = 1; i <= torrentFiles.size(); ++i) {
std::string f = torrentFiles.value<std::string>(std::to_string(i));
torrents.append({QString::fromStdString(f)});
}
handleTorrentFiles(module, torrents);
}
handleTorrentFiles(module, torrents);
}
}
}
}
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]);
}
}
qDebug() << result;
return result;
}
QString SyncWidget::fullPath(QString module, QString destination) const {
return _modulesDirectory + "/" + module + "/" + destination;
}

View File

@@ -37,19 +37,42 @@ public:
SyncWidget(QWidget* parent);
~SyncWidget();
void setSceneFiles(QMap<QString, QString> sceneFiles);
void setSceneFiles(QMap<QString, QString> sceneFiles);
void setModulesDirectory(QString modulesDirectory);
private slots:
void syncButtonPressed();
private:
struct DirectFile {
QString url;
QString destination;
};
typedef QList<DirectFile> DirectFiles;
struct FileRequest {
QString identifier;
QString destination;
int version;
};
typedef QList<FileRequest> FileRequests;
struct TorrentFile {
QString file;
};
typedef QList<TorrentFile> TorrentFiles;
void clear();
QStringList selectedScenes() const;
void handleDirectFiles(QString module, QStringList files);
void handleTorrentFiles(QString module, QStringList torrents);
QString fullPath(QString module, QString destination) const;
void handleDirectFiles(QString module, DirectFiles files);
void handleFileRequest(QString module, FileRequests files);
void handleTorrentFiles(QString module, TorrentFiles files);
QMap<QString, QString> _sceneFiles;
QString _modulesDirectory;
QGridLayout* _sceneLayout;
};

View File

@@ -27,6 +27,7 @@
#include <ghoul/designpattern/singleton.h>
#include <ghoul/filesystem/file.h>
#include <ghoul/filesystem/directory.h>
#include <functional>
#include <string>
@@ -34,18 +35,33 @@ namespace openspace {
class DownloadManager : public ghoul::Singleton<DownloadManager> {
public:
typedef std::function<void (const ghoul::filesystem::File&)> DownloadFinishedCallback;
typedef std::function <
void(const ghoul::filesystem::File&, float progress)
> DownloadProgressCallback;
typedef std::function<
void (const ghoul::filesystem::File&)
> DownloadFinishedCallback;
DownloadManager(std::string requestURL);
DownloadManager(std::string requestURL, int applicationVersion);
bool downloadFile(
const std::string& url,
const ghoul::filesystem::File& file,
DownloadFinishedCallback callback = DownloadFinishedCallback()
DownloadFinishedCallback finishedCallback = DownloadFinishedCallback(),
DownloadProgressCallback progressCallback = DownloadProgressCallback()
);
bool downloadRequestFiles(
const std::string& identifier,
const ghoul::filesystem::Directory& destination,
int version,
DownloadFinishedCallback finishedCallback = DownloadFinishedCallback(),
DownloadProgressCallback progressCallback = DownloadProgressCallback()
);
private:
std::string _requestURL;
int _applicationVersion;
};
#define DlManager (openspace::DownloadManager::ref())

View File

@@ -33,6 +33,10 @@
namespace {
const std::string _loggerCat = "DownloadManager";
const std::string RequestIdentifier = "identifier";
const std::string RequestFileVersion = "file_version";
const std::string RequestApplicationVersion = "application_version";
size_t writeData(void* ptr, size_t size, size_t nmemb, FILE* stream) {
size_t written;
@@ -43,8 +47,9 @@ namespace {
namespace openspace {
DownloadManager::DownloadManager(std::string requestURL)
DownloadManager::DownloadManager(std::string requestURL, int applicationVersion)
: _requestURL(std::move(requestURL))
, _applicationVersion(std::move(applicationVersion))
{
curl_global_init(CURL_GLOBAL_ALL);
// Check if URL is accessible
@@ -53,7 +58,8 @@ DownloadManager::DownloadManager(std::string requestURL)
bool DownloadManager::downloadFile(
const std::string& url,
const ghoul::filesystem::File& file,
DownloadFinishedCallback callback)
DownloadFinishedCallback finishedCallback,
DownloadProgressCallback progressCallback)
{
CURL* curl = curl_easy_init();
if (curl) {
@@ -62,20 +68,44 @@ bool DownloadManager::downloadFile(
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeData);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
LDEBUG("Starting download for file: '" << url <<
"' into file '" << file.filename() << "'");
CURLcode res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
fclose(fp);
// TODO: incorporate progressCallback ---abock
// http://curl.haxx.se/libcurl/c/progressfunc.html
if (res != CURLE_OK) {
LERROR("Error downloading file 'url': " << curl_easy_strerror(res));
return false;
}
if (callback)
callback(file);
if (finishedCallback)
finishedCallback(file);
return true;
}
}
bool DownloadManager::downloadRequestFiles(
const std::string& identifier,
const ghoul::filesystem::Directory& destination,
int version,
DownloadFinishedCallback finishedCallback,
DownloadProgressCallback progressCallback)
{
// Escaping is necessary ---abock
const std::string fullRequest =_requestURL + "?" +
RequestIdentifier + "=" + identifier + "&" +
RequestFileVersion + "=" + std::to_string(version) + "&" +
RequestApplicationVersion = "=" + std::to_string(_applicationVersion);
return true;
}
} // namespace openspace

View File

@@ -87,6 +87,7 @@ namespace {
const std::string _sgctConfigArgumentCommand = "-config";
const int CacheVersion = 1;
const int DownloadVersion = 1;
struct {
std::string configurationName;
@@ -292,7 +293,7 @@ bool OpenSpaceEngine::initialize() {
std::string requestURL = "";
bool success = configurationManager()->getValue(ConfigurationManager::KeyDownloadRequestURL, requestURL);
if (success)
DownloadManager::initialize(requestURL);
DownloadManager::initialize(requestURL, DownloadVersion);
// Load SPICE time kernel
success = loadSpiceKernels();