From f80a765a296caa309f9484f07c12ed3de5f8985e Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Thu, 19 Nov 2015 17:26:59 -0800 Subject: [PATCH] add Assets.uploadData() and Assets.downloadData() --- examples/example/assetsExample.js | 11 ++++ libraries/networking/src/AssetClient.cpp | 62 ++++++++++++++++++++ libraries/networking/src/AssetClient.h | 13 ++++ libraries/script-engine/src/ScriptEngine.cpp | 3 + libraries/script-engine/src/ScriptEngine.h | 3 + 5 files changed, 92 insertions(+) create mode 100644 examples/example/assetsExample.js diff --git a/examples/example/assetsExample.js b/examples/example/assetsExample.js new file mode 100644 index 0000000000..decebbcfa3 --- /dev/null +++ b/examples/example/assetsExample.js @@ -0,0 +1,11 @@ +var data = "this is some data"; +var extension = "txt"; +var uploadedFile; + +Assets.uploadData(data, extension, function (url) { + print("data uploaded to:" + url); + uploadedFile = url; + Assets.downloadData(url, function (data) { + print("data downloaded from:" + url + " the data is:" + data); + }); +}); diff --git a/libraries/networking/src/AssetClient.cpp b/libraries/networking/src/AssetClient.cpp index 6a1b46340c..75b4ca04e8 100644 --- a/libraries/networking/src/AssetClient.cpp +++ b/libraries/networking/src/AssetClient.cpp @@ -365,3 +365,65 @@ void AssetClient::handleNodeKilled(SharedNodePointer node) { } } } + +void AssetScriptingInterface::uploadData(QString data, QString extension, QScriptValue callback) { + QByteArray dataByteArray = data.toUtf8(); + auto upload = DependencyManager::get()->createUpload(dataByteArray, extension); + QObject::connect(upload, &AssetUpload::finished, this, [callback, extension](AssetUpload* upload, const QString& hash) mutable { + if (callback.isFunction()) { + QString url = "atp://" + hash + "." + extension; + QScriptValueList args { url }; + callback.call(QScriptValue(), args); + } + }); + + // start the upload now + upload->start(); +} + +void AssetScriptingInterface::downloadData(QString urlString, QScriptValue callback) { + const QString ATP_SCHEME { "atp://" }; + + if (!urlString.startsWith(ATP_SCHEME)) { + return; + } + + // Make request to atp + auto path = urlString.right(urlString.length() - ATP_SCHEME.length()); + auto parts = path.split(".", QString::SkipEmptyParts); + auto hash = parts.length() > 0 ? parts[0] : ""; + auto extension = parts.length() > 1 ? parts[1] : ""; + + if (hash.length() != SHA256_HASH_HEX_LENGTH) { + return; + } + + auto assetClient = DependencyManager::get(); + auto assetRequest = assetClient->createRequest(hash, extension); + + if (!assetRequest) { + return; + } + + _pendingRequests << assetRequest; + + connect(assetRequest, &AssetRequest::finished, [this, callback](AssetRequest* request) mutable { + Q_ASSERT(request->getState() == AssetRequest::Finished); + + if (request->getError() == AssetRequest::Error::NoError) { + if (callback.isFunction()) { + QString data = QString::fromUtf8(request->getData()); + QScriptValueList args { data }; + callback.call(QScriptValue(), args); + } + } + + request->deleteLater(); + _pendingRequests.remove(request); + }); + + assetRequest->start(); +} + + + diff --git a/libraries/networking/src/AssetClient.h b/libraries/networking/src/AssetClient.h index 22933ea30b..f1bb210614 100644 --- a/libraries/networking/src/AssetClient.h +++ b/libraries/networking/src/AssetClient.h @@ -14,6 +14,7 @@ #define hifi_AssetClient_h #include +#include #include @@ -21,6 +22,7 @@ #include "LimitedNodeList.h" #include "NLPacket.h" #include "Node.h" +#include "ResourceCache.h" class AssetRequest; class AssetUpload; @@ -68,4 +70,15 @@ private: friend class AssetUpload; }; + +class AssetScriptingInterface : public QObject { + Q_OBJECT +public: + Q_INVOKABLE void uploadData(QString data, QString extension, QScriptValue callback); + Q_INVOKABLE void downloadData(QString url, QScriptValue downloadComplete); +protected: + QSet _pendingRequests; +}; + + #endif diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 1b0fb80a05..5326090723 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -381,6 +381,9 @@ void ScriptEngine::init() { auto recordingInterface = DependencyManager::get(); registerGlobalObject("Recording", recordingInterface.data()); + + registerGlobalObject("Assets", &_assetScriptingInterface); + } void ScriptEngine::registerValue(const QString& valueName, QScriptValue value) { diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index c957b0c3b4..1412ba7aaf 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -195,6 +196,8 @@ private: ArrayBufferClass* _arrayBufferClass; + AssetScriptingInterface _assetScriptingInterface; + QHash _registeredHandlers; void forwardHandlerCall(const EntityItemID& entityID, const QString& eventName, QScriptValueList eventHanderArgs); Q_INVOKABLE void entityScriptContentAvailable(const EntityItemID& entityID, const QString& scriptOrURL, const QString& contents, bool isURL, bool success);