First cut of a snapshot uploader

Will need to test end-to-end shortly, etc...
This commit is contained in:
David Kelly 2016-08-05 10:51:51 -07:00
parent e0973f3c29
commit c8f3a898d2
7 changed files with 126 additions and 2 deletions

View file

@ -5082,6 +5082,11 @@ void Application::takeSnapshot(bool notify) {
emit DependencyManager::get<WindowScriptingInterface>()->snapshotTaken(path, notify);
}
void Application::shareSnapshot(const QString& path) {
// not much to do here, everything is done in snapshot code...
Snapshot::uploadSnapshot(path);
}
float Application::getRenderResolutionScale() const {
if (Menu::getInstance()->isOptionChecked(MenuOption::RenderResolutionOne)) {
return 1.0f;

View file

@ -249,6 +249,7 @@ public:
float getAverageSimsPerSecond() const { return _simCounter.rate(); }
void takeSnapshot(bool notify);
void shareSnapshot(const QString& filename);
signals:
void svoImportRequested(const QString& url);

View file

@ -202,7 +202,13 @@ void WindowScriptingInterface::copyToClipboard(const QString& text) {
void WindowScriptingInterface::takeSnapshot(bool notify) {
// only evil-doers call takeSnapshot from a random thread
qApp->postLambdaEvent([&] {
qApp->postLambdaEvent([notify] {
qApp->takeSnapshot(notify);
});
}
void WindowScriptingInterface::shareSnapshot(const QString& path) {
qApp->postLambdaEvent([path] {
qApp->shareSnapshot(path);
});
}

View file

@ -55,12 +55,14 @@ public slots:
QScriptValue save(const QString& title = "", const QString& directory = "", const QString& nameFilter = "");
void copyToClipboard(const QString& text);
void takeSnapshot(bool notify);
void shareSnapshot(const QString& path);
signals:
void domainChanged(const QString& domainHostname);
void svoImportRequested(const QString& url);
void domainConnectionRefused(const QString& reasonMessage, int reasonCode);
void snapshotTaken(const QString& path, bool notify);
void snapshotShared(bool success);
private slots:
WebWindowClass* doCreateWebWindow(const QString& title, const QString& url, int width, int height);

View file

@ -32,6 +32,7 @@
#include "Application.h"
#include "Snapshot.h"
#include "scripting/WindowScriptingInterface.h"
// filename format: hifi-snap-by-%username%-on-%date%_%time%_@-%location%.jpg
// %1 <= username, %2 <= date and time, %3 <= current location
@ -141,3 +142,90 @@ QFile* Snapshot::savedFileForSnapshot(QImage & shot, bool isTemporary) {
return imageTempFile;
}
}
void Snapshot::uploadSnapshot(const QString& filename) {
const QString SNAPSHOT_UPLOAD_URL = "/api/v1/snapshots";
static SnapshotUploader uploader;
qDebug() << "uploading snapshot " << filename;
QFile* file = new QFile(filename);
Q_ASSERT(file->exists());
file->open(QIODevice::ReadOnly);
QHttpPart imagePart;
imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg"));
imagePart.setHeader(QNetworkRequest::ContentDispositionHeader,
QVariant("form-data; name=\"image\"; filename=\"" + file->fileName() + "\""));
imagePart.setBodyDevice(file);
QHttpMultiPart* multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
file->setParent(multiPart); // we cannot delete the file now, so delete it with the multiPart
multiPart->append(imagePart);
auto accountManager = DependencyManager::get<AccountManager>();
JSONCallbackParameters callbackParams;
callbackParams.jsonCallbackReceiver = &uploader;
callbackParams.jsonCallbackMethod = "uploadSuccess";
callbackParams.errorCallbackReceiver = &uploader;
callbackParams.errorCallbackMethod = "uploadFailure";
accountManager->sendRequest(SNAPSHOT_UPLOAD_URL,
AccountManagerAuth::Required,
QNetworkAccessManager::PostOperation,
callbackParams,
nullptr,
multiPart);
}
void SnapshotUploader::uploadSuccess(QNetworkReply& reply) {
const QString STORY_UPLOAD_URL = "/api/v1/user_stories";
static SnapshotUploader uploader;
// parse the reply for the thumbnail_url
QByteArray contents = reply.readAll();
QJsonParseError jsonError;
auto doc = QJsonDocument::fromJson(contents, &jsonError);
if (jsonError.error == QJsonParseError::NoError) {
QString thumbnail_url = doc.object().value("thumbnail_url").toString();
// create json post data
QJsonObject rootObject;
QJsonObject userStoryObject;
userStoryObject.insert("thumbnail_url", thumbnail_url);
userStoryObject.insert("action", "snapshot");
rootObject.insert("user_story", userStoryObject);
auto accountManager = DependencyManager::get<AccountManager>();
JSONCallbackParameters callbackParams;
callbackParams.jsonCallbackReceiver = &uploader;
callbackParams.jsonCallbackMethod = "createStorySuccess";
callbackParams.errorCallbackReceiver = &uploader;
callbackParams.errorCallbackMethod = "createStoryFailure";
accountManager->sendRequest(STORY_UPLOAD_URL,
AccountManagerAuth::Required,
QNetworkAccessManager::PostOperation,
callbackParams,
QJsonDocument(rootObject).toJson());
} else {
qDebug() << "Error parsing upload response: " << jsonError.errorString();
emit DependencyManager::get<WindowScriptingInterface>()->snapshotShared(false);
}
}
void SnapshotUploader::uploadFailure(QNetworkReply& reply) {
// TODO: parse response, potentially helpful for logging (?)
emit DependencyManager::get<WindowScriptingInterface>()->snapshotShared(false);
}
void SnapshotUploader::createStorySuccess(QNetworkReply& reply) {
emit DependencyManager::get<WindowScriptingInterface>()->snapshotShared(true);
}
void SnapshotUploader::createStoryFailure(QNetworkReply& reply) {
// TODO: parse response, potentially helpful for logging (?)
emit DependencyManager::get<WindowScriptingInterface>()->snapshotShared(false);
}

View file

@ -32,6 +32,16 @@ private:
QUrl _URL;
};
class SnapshotUploader: public QObject {
Q_OBJECT
public slots:
void uploadSuccess(QNetworkReply& reply);
void uploadFailure(QNetworkReply& reply);
void createStorySuccess(QNetworkReply& reply);
void createStoryFailure(QNetworkReply& reply);
};
class Snapshot {
public:
static QString saveSnapshot(QImage image);
@ -40,6 +50,7 @@ public:
static Setting::Handle<QString> snapshotsLocation;
static Setting::Handle<bool> hasSetSnapshotsLocation;
static void uploadSnapshot(const QString& filename);
private:
static QFile* savedFileForSnapshot(QImage & image, bool isTemporary);
};

View file

@ -24,7 +24,18 @@ function confirmShare(data) {
if (!Window.confirm("Share snapshot " + data.localPath + "?")) { // This dialog will be more elaborate...
return;
}
Window.alert("Pretending to upload. That code will go here.");
Window.snapshotShared.connect(snapshotShared);
Window.shareSnapshot(data.localPath);
}
function snapshotShared(success) {
if(success) {
// for now just print status
print('snapshot uploaded and shared');
} else {
// for now just print an error.
print('snapshot upload/share failed');
}
}
function onClicked() {