From 5a0beec1f5a3c4dc02f39ffcc6dce41030632187 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 9 Mar 2016 11:43:56 -0800 Subject: [PATCH 01/12] Replace old drag&drop with new UI --- interface/resources/qml/AssetServer.qml | 1 + interface/resources/qml/hifi/MenuOption.qml | 1 - interface/src/Application.cpp | 94 ++------------------- interface/src/Application.h | 4 +- interface/src/Menu.cpp | 12 --- interface/src/Menu.h | 1 - 6 files changed, 11 insertions(+), 102 deletions(-) diff --git a/interface/resources/qml/AssetServer.qml b/interface/resources/qml/AssetServer.qml index 34f6502b40..ea2a082c8a 100644 --- a/interface/resources/qml/AssetServer.qml +++ b/interface/resources/qml/AssetServer.qml @@ -35,6 +35,7 @@ Window { property var scripts: ScriptDiscoveryService; property var scriptsModel: scripts.scriptsModelFilter property var currentDirectory; + property alias currentFileUrl: fileUrlTextField.text; Settings { category: "Overlay.AssetServer" diff --git a/interface/resources/qml/hifi/MenuOption.qml b/interface/resources/qml/hifi/MenuOption.qml index 477197f57e..da28d1daf3 100644 --- a/interface/resources/qml/hifi/MenuOption.qml +++ b/interface/resources/qml/hifi/MenuOption.qml @@ -155,7 +155,6 @@ QtObject { readonly property string toolWindow: "Tool Window"; readonly property string transmitterDrive: "Transmitter Drive"; readonly property string turnWithHead: "Turn using Head"; - readonly property string uploadAsset: "Upload File to Asset Server"; readonly property string useAudioForMouth: "Use Audio for Mouth"; readonly property string useCamera: "Use Camera"; readonly property string velocityFilter: "Velocity Filter"; diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 85ae8604e8..a824c22b0f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -158,7 +158,6 @@ #include "Stars.h" #include "ui/AddressBarDialog.h" #include "ui/AvatarInputs.h" -#include "ui/AssetUploadDialogFactory.h" #include "ui/DialogsManager.h" #include "ui/LoginDialog.h" #include "ui/overlays/Cube3DOverlay.h" @@ -3937,9 +3936,6 @@ void Application::nodeAdded(SharedNodePointer node) { if (node->getType() == NodeType::AvatarMixer) { // new avatar mixer, send off our identity packet right away getMyAvatar()->sendIdentityPacket(); - } else if (node->getType() == NodeType::AssetServer) { - // the addition of an asset-server always re-enables the upload to asset server menu option - Menu::getInstance()->getActionForOption(MenuOption::UploadAsset)->setEnabled(true); } } @@ -3989,10 +3985,6 @@ void Application::nodeKilled(SharedNodePointer node) { } else if (node->getType() == NodeType::AvatarMixer) { // our avatar mixer has gone away - clear the hash of avatars DependencyManager::get()->clearOtherAvatars(); - } else if (node->getType() == NodeType::AssetServer - && !DependencyManager::get()->soloNodeOfType(NodeType::AssetServer)) { - // this was our last asset server - disable the menu option to upload an asset - Menu::getInstance()->getActionForOption(MenuOption::UploadAsset)->setEnabled(false); } } void Application::trackIncomingOctreePacket(ReceivedMessage& message, SharedNodePointer sendingNode, bool wasStatsPacket) { @@ -4218,7 +4210,10 @@ bool Application::acceptURL(const QString& urlString, bool defaultUpload) { } } - return defaultUpload && askToUploadAsset(urlString); + if (defaultUpload) { + toggleAssetServerWidget(urlString); + } + return defaultUpload; } void Application::setSessionUUID(const QUuid& sessionUUID) { @@ -4280,80 +4275,6 @@ bool Application::askToLoadScript(const QString& scriptFilenameOrURL) { return true; } -bool Application::askToUploadAsset(const QString& filename) { - if (!DependencyManager::get()->getThisNodeCanRez()) { - OffscreenUi::warning(_window, "Failed Upload", - QString("You don't have upload rights on that domain.\n\n")); - return false; - } - - QUrl url { filename }; - if (auto upload = DependencyManager::get()->createUpload(url.toLocalFile())) { - - QMessageBox messageBox; - messageBox.setWindowTitle("Asset upload"); - messageBox.setText("You are about to upload the following file to the asset server:\n" + - url.toDisplayString()); - messageBox.setInformativeText("Do you want to continue?"); - messageBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); - messageBox.setDefaultButton(QMessageBox::Ok); - - // Option to drop model in world for models - if (filename.endsWith(FBX_EXTENSION, Qt::CaseInsensitive) || filename.endsWith(OBJ_EXTENSION, Qt::CaseInsensitive)) { - auto checkBox = new QCheckBox(&messageBox); - checkBox->setText("Add to scene"); - messageBox.setCheckBox(checkBox); - } - - if (messageBox.exec() != QMessageBox::Ok) { - upload->deleteLater(); - return false; - } - - // connect to the finished signal so we know when the AssetUpload is done - if (messageBox.checkBox() && (messageBox.checkBox()->checkState() == Qt::Checked)) { - // Custom behavior for models - QObject::connect(upload, &AssetUpload::finished, this, &Application::modelUploadFinished); - } else { - QObject::connect(upload, &AssetUpload::finished, - &AssetUploadDialogFactory::getInstance(), - &AssetUploadDialogFactory::handleUploadFinished); - } - - // start the upload now - upload->start(); - return true; - } - - // display a message box with the error - OffscreenUi::warning(_window, "Failed Upload", QString("Failed to upload %1.\n\n").arg(filename)); - return false; -} - -void Application::modelUploadFinished(AssetUpload* upload, const QString& hash) { - auto fileInfo = QFileInfo(upload->getFilename()); - auto filename = fileInfo.fileName(); - - if ((upload->getError() == AssetUpload::NoError) && - (filename.endsWith(FBX_EXTENSION, Qt::CaseInsensitive) || - filename.endsWith(OBJ_EXTENSION, Qt::CaseInsensitive))) { - - auto entities = DependencyManager::get(); - - EntityItemProperties properties; - properties.setType(EntityTypes::Model); - properties.setModelURL(QString("%1:%2.%3").arg(URL_SCHEME_ATP).arg(hash).arg(fileInfo.completeSuffix())); - properties.setPosition(_myCamera.getPosition() + _myCamera.getOrientation() * Vectors::FRONT * 2.0f); - properties.setName(QUrl(upload->getFilename()).fileName()); - - entities->addEntity(properties); - - upload->deleteLater(); - } else { - AssetUploadDialogFactory::getInstance().handleUploadFinished(upload, hash); - } -} - bool Application::askToWearAvatarAttachmentUrl(const QString& url) { QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); @@ -4453,9 +4374,12 @@ void Application::toggleRunningScriptsWidget() { //} } -void Application::toggleAssetServerWidget() { +void Application::toggleAssetServerWidget(QString filePath) { static const QUrl url("AssetServer.qml"); - DependencyManager::get()->show(url, "AssetServer"); + auto urlSetter = [=](QQmlContext* context, QObject* newObject){ + newObject->setProperty("currentFileUrl", filePath); + }; + DependencyManager::get()->show(url, "AssetServer", urlSetter); } void Application::packageModel() { diff --git a/interface/src/Application.h b/interface/src/Application.h index 956eb5a1ea..e73524ee66 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -242,7 +242,7 @@ public slots: Q_INVOKABLE void loadScriptURLDialog(); void toggleLogDialog(); void toggleRunningScriptsWidget(); - void toggleAssetServerWidget(); + void toggleAssetServerWidget(QString filePath = ""); void handleLocalServerConnection(); void readArgumentsFromLocalSocket(); @@ -303,8 +303,6 @@ private slots: bool acceptSnapshot(const QString& urlString); bool askToSetAvatarUrl(const QString& url); bool askToLoadScript(const QString& scriptFilenameOrURL); - bool askToUploadAsset(const QString& asset); - void modelUploadFinished(AssetUpload* upload, const QString& hash); bool askToWearAvatarAttachmentUrl(const QString& url); void displayAvatarAttachmentWarning(const QString& message) const; diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index e9f45a6b9a..ab3add788d 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -35,7 +35,6 @@ #include "MainWindow.h" #include "render/DrawStatus.h" #include "scripting/MenuScriptingInterface.h" -#include "ui/AssetUploadDialogFactory.h" #include "ui/DialogsManager.h" #include "ui/StandAloneJSConsole.h" #include "InterfaceLogging.h" @@ -365,17 +364,6 @@ Menu::Menu() { // Developer > Assets >>> MenuWrapper* assetDeveloperMenu = developerMenu->addMenu("Assets"); - auto& assetDialogFactory = AssetUploadDialogFactory::getInstance(); - assetDialogFactory.setDialogParent(this); - QAction* assetUpload = addActionToQMenuAndActionHash(assetDeveloperMenu, - MenuOption::UploadAsset, - 0, - &assetDialogFactory, - SLOT(showDialog())); - - // disable the asset upload action by default - it gets enabled only if asset server becomes present - assetUpload->setEnabled(false); - auto& atpMigrator = ATPAssetMigrator::getInstance(); atpMigrator.setDialogParent(this); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index c605813753..b697bd5317 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -168,7 +168,6 @@ namespace MenuOption { const QString ToolWindow = "Tool Window"; const QString TransmitterDrive = "Transmitter Drive"; const QString TurnWithHead = "Turn using Head"; - const QString UploadAsset = "Upload File to Asset Server"; const QString UseAudioForMouth = "Use Audio for Mouth"; const QString UseCamera = "Use Camera"; const QString UseAnimPreAndPostRotations = "Use Anim Pre and Post Rotations"; From 03c38eada3952833bd3381fb91c8689f6de27411 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 9 Mar 2016 12:06:33 -0800 Subject: [PATCH 02/12] add folder rename handling --- assignment-client/src/assets/AssetServer.cpp | 58 +++++++++++++++++--- 1 file changed, 49 insertions(+), 9 deletions(-) diff --git a/assignment-client/src/assets/AssetServer.cpp b/assignment-client/src/assets/AssetServer.cpp index 13257967ac..403941221d 100644 --- a/assignment-client/src/assets/AssetServer.cpp +++ b/assignment-client/src/assets/AssetServer.cpp @@ -511,6 +511,10 @@ bool AssetServer::setMapping(const AssetPath& path, const AssetHash& hash) { } } +bool pathIsFolder(const AssetPath& path) { + return path.endsWith('/'); +} + bool AssetServer::deleteMappings(const AssetPathList& paths) { // take a copy of the current mappings in case persistence of these deletes fails auto oldMappings = _fileMappings; @@ -538,23 +542,59 @@ bool AssetServer::deleteMappings(const AssetPathList& paths) { } bool AssetServer::renameMapping(const AssetPath& oldPath, const AssetPath& newPath) { - // take the old hash to remove the old mapping - auto oldMapping = _fileMappings[oldPath].toString(); + if (pathIsFolder(oldPath)) { + if (!pathIsFolder(newPath)) { + // we were asked to rename a path to a folder to a path that isn't a folder, this is a fail + return false; + } - if (!oldMapping.isEmpty()) { - _fileMappings[newPath] = oldMapping; + // take a copy of the old mappings + auto oldMappings = _fileMappings; + + // iterate the current mappings and adjust any that matches the renamed folder + auto it = oldMappings.begin(); + while (it != oldMappings.end()) { + + if (it->toString().startsWith(oldPath)) { + auto oldKey = it.key(); + auto newKey = oldKey.replace(0, oldPath.size(), newPath); + + // remove the old version from the in memory file mappings + _fileMappings.remove(oldKey); + _fileMappings.insert(newKey, it.value()); + } + + ++it; + } if (writeMappingsToFile()) { - // persisted the renamed mapping, return success + // persisted the changed mappings return success return true; } else { - // we couldn't persist the renamed mapping, rollback and return failure - _fileMappings[oldPath] = oldMapping; + // couldn't persist the renamed paths, rollback and return failure + _fileMappings = oldMappings; return false; } } else { - // failed to find a mapping that was to be renamed, return failure - return false; + // take the old hash to remove the old mapping + auto oldMapping = _fileMappings[oldPath].toString(); + + if (!oldMapping.isEmpty()) { + _fileMappings[newPath] = oldMapping; + + if (writeMappingsToFile()) { + // persisted the renamed mapping, return success + return true; + } else { + // we couldn't persist the renamed mapping, rollback and return failure + _fileMappings[oldPath] = oldMapping; + + return false; + } + } else { + // failed to find a mapping that was to be renamed, return failure + return false; + } } } From a53b038ac2dee5616a36d4c08ba4d1392f51e95b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 9 Mar 2016 12:10:36 -0800 Subject: [PATCH 03/12] add folder delete handling --- assignment-client/src/assets/AssetServer.cpp | 33 +++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/assignment-client/src/assets/AssetServer.cpp b/assignment-client/src/assets/AssetServer.cpp index 403941221d..ccd03aa2a3 100644 --- a/assignment-client/src/assets/AssetServer.cpp +++ b/assignment-client/src/assets/AssetServer.cpp @@ -521,11 +521,35 @@ bool AssetServer::deleteMappings(const AssetPathList& paths) { // enumerate the paths to delete and remove them all for (auto& path : paths) { - auto oldMapping = _fileMappings.take(path); - if (!oldMapping.isNull()) { - qDebug() << "Deleted a mapping:" << path << "=>" << oldMapping.toString(); + + // figure out if this path will delete a file or folder + if (pathIsFolder(path)) { + // enumerate the in memory file mappings and remove anything that matches + auto it = _fileMappings.begin(); + auto sizeBefore = _fileMappings.size(); + + while (it != _fileMappings.end()) { + if (it->toString().startsWith(path)) { + it = _fileMappings.erase(it); + } else { + ++it; + } + } + + auto sizeNow = _fileMappings.size(); + if (sizeBefore != sizeNow) { + qDebug() << "Deleted" << sizeBefore - sizeNow << "mappings in folder: " << path; + } else { + qDebug() << "Did not find any mappings in folder:" << path; + } + } else { - qDebug() << "Unable to delete a mapping that was not found:" << path; + auto oldMapping = _fileMappings.take(path); + if (!oldMapping.isNull()) { + qDebug() << "Deleted a mapping:" << path << "=>" << oldMapping.toString(); + } else { + qDebug() << "Unable to delete a mapping that was not found:" << path; + } } } @@ -542,6 +566,7 @@ bool AssetServer::deleteMappings(const AssetPathList& paths) { } bool AssetServer::renameMapping(const AssetPath& oldPath, const AssetPath& newPath) { + // figure out if this rename is for a file or folder if (pathIsFolder(oldPath)) { if (!pathIsFolder(newPath)) { // we were asked to rename a path to a folder to a path that isn't a folder, this is a fail From 6b8a71f96a02cf25893881dfeef1bc1a87c16706 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 9 Mar 2016 12:16:36 -0800 Subject: [PATCH 04/12] add debug for mapping operations --- assignment-client/src/assets/AssetServer.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/assignment-client/src/assets/AssetServer.cpp b/assignment-client/src/assets/AssetServer.cpp index ccd03aa2a3..9825e75c61 100644 --- a/assignment-client/src/assets/AssetServer.cpp +++ b/assignment-client/src/assets/AssetServer.cpp @@ -498,6 +498,7 @@ bool AssetServer::setMapping(const AssetPath& path, const AssetHash& hash) { // attempt to write to file if (writeMappingsToFile()) { // persistence succeeded, we are good to go + qDebug() << "Set mapping:" << path << "=>" << hash; return true; } else { // failed to persist this mapping to file - put back the old one in our in-memory representation @@ -507,6 +508,8 @@ bool AssetServer::setMapping(const AssetPath& path, const AssetHash& hash) { _fileMappings[path] = oldMapping; } + qWarning() << "Failed to persist mapping:" << path << "=>" << hash; + return false; } } @@ -578,8 +581,8 @@ bool AssetServer::renameMapping(const AssetPath& oldPath, const AssetPath& newPa // iterate the current mappings and adjust any that matches the renamed folder auto it = oldMappings.begin(); - while (it != oldMappings.end()) { + while (it != oldMappings.end()) { if (it->toString().startsWith(oldPath)) { auto oldKey = it.key(); auto newKey = oldKey.replace(0, oldPath.size(), newPath); @@ -593,12 +596,16 @@ bool AssetServer::renameMapping(const AssetPath& oldPath, const AssetPath& newPa } if (writeMappingsToFile()) { - // persisted the changed mappings return success + // persisted the changed mappings, return success + qDebug() << "Renamed mapping:" << oldPath << "=>" << newPath; + return true; } else { // couldn't persist the renamed paths, rollback and return failure _fileMappings = oldMappings; + qWarning() << "Failed to persist renamed mapping:" << oldPath << "=>" << newPath; + return false; } } else { @@ -610,11 +617,15 @@ bool AssetServer::renameMapping(const AssetPath& oldPath, const AssetPath& newPa if (writeMappingsToFile()) { // persisted the renamed mapping, return success + qDebug() << "Renamed mapping:" << oldPath << "=>" << newPath; + return true; } else { // we couldn't persist the renamed mapping, rollback and return failure _fileMappings[oldPath] = oldMapping; + qDebug() << "Failed to persist renamed mapping:" << oldPath << "=>" << newPath; + return false; } } else { From 5a197838f4785020776964499800c5babf8a6637 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 9 Mar 2016 13:14:39 -0800 Subject: [PATCH 05/12] add a deleteMapping call for single path to scripting interface --- libraries/script-engine/src/AssetScriptingInterface.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/script-engine/src/AssetScriptingInterface.h b/libraries/script-engine/src/AssetScriptingInterface.h index 287300cac8..d01eb939e2 100644 --- a/libraries/script-engine/src/AssetScriptingInterface.h +++ b/libraries/script-engine/src/AssetScriptingInterface.h @@ -29,6 +29,7 @@ public: Q_INVOKABLE void setMapping(QString path, QString hash, QScriptValue callback); Q_INVOKABLE void getMapping(QString path, QScriptValue callback); Q_INVOKABLE void deleteMappings(QStringList paths, QScriptValue callback); + Q_INVOKABLE void deleteMapping(QString path, QScriptValue callback) { deleteMappings(QStringList(path), callback); } Q_INVOKABLE void getAllMappings(QScriptValue callback); Q_INVOKABLE void renameMapping(QString oldPath, QString newPath, QScriptValue callback); protected: From a65d06c7ce2eba355bdd3abee72ac03e3ce2d6e1 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 9 Mar 2016 13:14:55 -0800 Subject: [PATCH 06/12] fix rename to take old mapping first --- assignment-client/src/assets/AssetServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignment-client/src/assets/AssetServer.cpp b/assignment-client/src/assets/AssetServer.cpp index 9825e75c61..ce95d7d4cb 100644 --- a/assignment-client/src/assets/AssetServer.cpp +++ b/assignment-client/src/assets/AssetServer.cpp @@ -610,7 +610,7 @@ bool AssetServer::renameMapping(const AssetPath& oldPath, const AssetPath& newPa } } else { // take the old hash to remove the old mapping - auto oldMapping = _fileMappings[oldPath].toString(); + auto oldMapping = _fileMappings.take(oldPath).toString(); if (!oldMapping.isEmpty()) { _fileMappings[newPath] = oldMapping; From 5e9751c6ed2b78c15e378b6da3bf76b3dcd9526a Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 9 Mar 2016 13:28:05 -0800 Subject: [PATCH 07/12] bug fixes for rename/delete operations --- assignment-client/src/assets/AssetServer.cpp | 23 ++++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/assignment-client/src/assets/AssetServer.cpp b/assignment-client/src/assets/AssetServer.cpp index ce95d7d4cb..4f85a0f9e9 100644 --- a/assignment-client/src/assets/AssetServer.cpp +++ b/assignment-client/src/assets/AssetServer.cpp @@ -532,7 +532,7 @@ bool AssetServer::deleteMappings(const AssetPathList& paths) { auto sizeBefore = _fileMappings.size(); while (it != _fileMappings.end()) { - if (it->toString().startsWith(path)) { + if (it.key().startsWith(path)) { it = _fileMappings.erase(it); } else { ++it; @@ -573,6 +573,8 @@ bool AssetServer::renameMapping(const AssetPath& oldPath, const AssetPath& newPa if (pathIsFolder(oldPath)) { if (!pathIsFolder(newPath)) { // we were asked to rename a path to a folder to a path that isn't a folder, this is a fail + qWarning() << "Cannot rename mapping from folder path" << oldPath << "to file path" << newPath; + return false; } @@ -583,12 +585,12 @@ bool AssetServer::renameMapping(const AssetPath& oldPath, const AssetPath& newPa auto it = oldMappings.begin(); while (it != oldMappings.end()) { - if (it->toString().startsWith(oldPath)) { - auto oldKey = it.key(); - auto newKey = oldKey.replace(0, oldPath.size(), newPath); + if (it.key().startsWith(oldPath)) { + auto newKey = it.key(); + newKey.replace(0, oldPath.size(), newPath); // remove the old version from the in memory file mappings - _fileMappings.remove(oldKey); + _fileMappings.remove(it.key()); _fileMappings.insert(newKey, it.value()); } @@ -597,18 +599,25 @@ bool AssetServer::renameMapping(const AssetPath& oldPath, const AssetPath& newPa if (writeMappingsToFile()) { // persisted the changed mappings, return success - qDebug() << "Renamed mapping:" << oldPath << "=>" << newPath; + qDebug() << "Renamed folder mapping:" << oldPath << "=>" << newPath; return true; } else { // couldn't persist the renamed paths, rollback and return failure _fileMappings = oldMappings; - qWarning() << "Failed to persist renamed mapping:" << oldPath << "=>" << newPath; + qWarning() << "Failed to persist renamed folder mapping:" << oldPath << "=>" << newPath; return false; } } else { + if (pathIsFolder(newPath)) { + // we were asked to rename a path to a file to a path that is a folder, this is a fail + qWarning() << "Cannot rename mapping from file path" << oldPath << "to folder path" << newPath; + + return false; + } + // take the old hash to remove the old mapping auto oldMapping = _fileMappings.take(oldPath).toString(); From d3dc81c7a09cb8b37d8506c56e3e853e91ef864b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 9 Mar 2016 13:37:39 -0800 Subject: [PATCH 08/12] add delete debug, handle rename in memory state rollback --- assignment-client/src/assets/AssetServer.cpp | 21 ++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/assignment-client/src/assets/AssetServer.cpp b/assignment-client/src/assets/AssetServer.cpp index 4f85a0f9e9..5543dfeed5 100644 --- a/assignment-client/src/assets/AssetServer.cpp +++ b/assignment-client/src/assets/AssetServer.cpp @@ -561,6 +561,8 @@ bool AssetServer::deleteMappings(const AssetPathList& paths) { // persistence succeeded we are good to go return true; } else { + qWarning() << "Failed to persist deleted mappings, rolling back"; + // we didn't delete the previous mapping, put it back in our in-memory representation _fileMappings = oldMappings; @@ -619,10 +621,13 @@ bool AssetServer::renameMapping(const AssetPath& oldPath, const AssetPath& newPa } // take the old hash to remove the old mapping - auto oldMapping = _fileMappings.take(oldPath).toString(); + auto oldSourceMapping = _fileMappings.take(oldPath).toString(); - if (!oldMapping.isEmpty()) { - _fileMappings[newPath] = oldMapping; + // in case we're overwriting, keep the current destination mapping for potential rollback + auto oldDestinationMapping = _fileMappings.value(newPath); + + if (!oldSourceMapping.isEmpty()) { + _fileMappings[newPath] = oldSourceMapping; if (writeMappingsToFile()) { // persisted the renamed mapping, return success @@ -631,7 +636,15 @@ bool AssetServer::renameMapping(const AssetPath& oldPath, const AssetPath& newPa return true; } else { // we couldn't persist the renamed mapping, rollback and return failure - _fileMappings[oldPath] = oldMapping; + _fileMappings[oldPath] = oldSourceMapping; + + if (!oldDestinationMapping.isNull()) { + // put back the overwritten mapping for the destination path + _fileMappings[newPath] = oldDestinationMapping.toString(); + } else { + // clear the new mapping + _fileMappings.remove(newPath); + } qDebug() << "Failed to persist renamed mapping:" << oldPath << "=>" << newPath; From a98640323722b8b17d9db345998b43aa26a82489 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 9 Mar 2016 13:42:35 -0800 Subject: [PATCH 09/12] add a leading slash for faked migrated mappings --- assignment-client/src/assets/AssetServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignment-client/src/assets/AssetServer.cpp b/assignment-client/src/assets/AssetServer.cpp index 5543dfeed5..6dea815622 100644 --- a/assignment-client/src/assets/AssetServer.cpp +++ b/assignment-client/src/assets/AssetServer.cpp @@ -155,7 +155,7 @@ void AssetServer::performMappingMigration() { // add a new mapping with the old extension and a truncated version of the hash static const int TRUNCATED_HASH_NUM_CHAR = 16; - auto fakeFileName = hash.left(TRUNCATED_HASH_NUM_CHAR) + fullExtension; + auto fakeFileName = "/" + hash.left(TRUNCATED_HASH_NUM_CHAR) + fullExtension; qDebug() << "\tAdding a migration mapping from" << fakeFileName << "to" << hash; From 6bd7afc7b3232f7e9150d5d1ee02133296c30bd9 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 9 Mar 2016 14:19:28 -0800 Subject: [PATCH 10/12] Confirm overrides --- interface/resources/qml/AssetServer.qml | 81 ++++++++++++++++++++----- 1 file changed, 65 insertions(+), 16 deletions(-) diff --git a/interface/resources/qml/AssetServer.qml b/interface/resources/qml/AssetServer.qml index ea2a082c8a..fdb9b81d87 100644 --- a/interface/resources/qml/AssetServer.qml +++ b/interface/resources/qml/AssetServer.qml @@ -44,10 +44,58 @@ Window { property alias directory: root.currentDirectory } + function doDeleteFile(path) { + console.log("Deleting " + path); + + } + function doUploadFile(path, mapping, addToWorld) { + console.log("Uploading " + path + " to " + mapping + " (addToWorld: " + addToWorld + ")"); + + + } + function doRenameFile(oldPath, newPath) { + console.log("Renaming " + oldPath + " to " + newPath); + + } + + function fileExists(destinationPath) { + return true; // TODO get correct value + } + + function askForOverride(path, callback) { + var object = desktop.messageBox({ + icon: OriginalDialogs.StandardIcon.Question, + buttons: OriginalDialogs.StandardButton.Yes | OriginalDialogs.StandardButton.No, + defaultButton: OriginalDialogs.StandardButton.No, + text: "Override?", + informativeText: "The following file already exists:\n" + path + + "\nDo you want to override it?" + }); + object.selected.connect(function(button) { + if (button === OriginalDialogs.StandardButton.Yes) { + callback(); + } + }); + } + + function canAddToWorld() { + var supportedExtensions = [/\.fbx\b/i, /\.obj\b/i]; + var path = scriptsModel.data(treeView.currentIndex, 0x100); + + return supportedExtensions.reduce(function(total, current) { + return total | new RegExp(current).test(path); + }, false); + } + function reload() { print("reload"); } function addToWorld() { + var path = scriptsModel.data(treeView.currentIndex, 0x100); + if (!path) { + return; + } + print("addToWorld"); } function renameFile() { @@ -62,12 +110,13 @@ Window { placeholderText: "Enter path here" }); object.selected.connect(function(destinationPath) { - console.log("Renaming " + path + " to " + destinationPath); - - - - - + if (fileExists(destinationPath)) { + askForOverride(path, function() { + doRenameFile(path, destinationPath); + }); + } else { + doRenameFile(path, destinationPath); + } }); } function deleteFile() { @@ -87,10 +136,7 @@ Window { }); object.selected.connect(function(button) { if (button === OriginalDialogs.StandardButton.Yes) { - console.log("Deleting " + path); - - - + doDeleteFile(path); } }); } @@ -120,12 +166,13 @@ Window { placeholderText: "Enter path here" }); object.selected.connect(function(destinationPath) { - console.log("Uploading " + fileUrl + " to " + destinationPath + " (addToWorld: " + addToWorld + ")"); - - - - - + if (fileExists(destinationPath)) { + askForOverride(fileUrl, function() { + doUploadFile(fileUrl, destinationPath, addToWorld); + }); + } else { + doUploadFile(fileUrl, destinationPath, addToWorld); + } }); } @@ -161,6 +208,8 @@ Window { height: 26 width: 120 + enabled: canAddToWorld() + onClicked: root.addToWorld() } From 96ba57a94609fb558978ae79543cc0b9036ea55e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 9 Mar 2016 14:24:14 -0800 Subject: [PATCH 11/12] remove client side caching of ATP mappings --- libraries/networking/src/AssetClient.cpp | 4 --- libraries/networking/src/AssetClient.h | 2 -- libraries/networking/src/MappingRequest.cpp | 28 --------------------- 3 files changed, 34 deletions(-) diff --git a/libraries/networking/src/AssetClient.cpp b/libraries/networking/src/AssetClient.cpp index 7c967e681a..19b0be3917 100644 --- a/libraries/networking/src/AssetClient.cpp +++ b/libraries/networking/src/AssetClient.cpp @@ -91,8 +91,6 @@ void AssetClient::clearCache() { return; } - _mappingCache.clear(); - if (auto cache = NetworkAccessManager::getInstance().cache()) { qDebug() << "AssetClient::clearCache(): Clearing disk cache."; cache->clear(); @@ -578,6 +576,4 @@ void AssetClient::handleNodeKilled(SharedNodePointer node) { messageMapIt->second.clear(); } } - - _mappingCache.clear(); } diff --git a/libraries/networking/src/AssetClient.h b/libraries/networking/src/AssetClient.h index 87b8646be1..299039ae8e 100644 --- a/libraries/networking/src/AssetClient.h +++ b/libraries/networking/src/AssetClient.h @@ -95,8 +95,6 @@ private: std::unordered_map> _pendingInfoRequests; std::unordered_map> _pendingUploads; - QHash _mappingCache; - friend class AssetRequest; friend class AssetUpload; friend class GetMappingRequest; diff --git a/libraries/networking/src/MappingRequest.cpp b/libraries/networking/src/MappingRequest.cpp index 187694e134..0ab7d8fb36 100644 --- a/libraries/networking/src/MappingRequest.cpp +++ b/libraries/networking/src/MappingRequest.cpp @@ -32,14 +32,6 @@ void GetMappingRequest::doStart() { auto assetClient = DependencyManager::get(); - // Check cache - auto it = assetClient->_mappingCache.constFind(_path); - if (it != assetClient->_mappingCache.constEnd()) { - _hash = it.value(); - emit finished(this); - return; - } - assetClient->getAssetMapping(_path, [this, assetClient](bool responseReceived, AssetServerError error, QSharedPointer message) { if (!responseReceived) { _error = NetworkError; @@ -59,7 +51,6 @@ void GetMappingRequest::doStart() { if (!_error) { _hash = message->read(SHA256_HASH_LENGTH).toHex(); - assetClient->_mappingCache[_path] = _hash; } emit finished(this); }); @@ -88,12 +79,10 @@ void GetAllMappingsRequest::doStart() { if (!error) { int numberOfMappings; message->readPrimitive(&numberOfMappings); - assetClient->_mappingCache.clear(); for (auto i = 0; i < numberOfMappings; ++i) { auto path = message->readString(); auto hash = message->readString(); _mappings[path] = hash; - assetClient->_mappingCache[path] = hash; } } emit finished(this); @@ -122,9 +111,6 @@ void SetMappingRequest::doStart() { } } - if (!error) { - assetClient->_mappingCache[_path] = _hash; - } emit finished(this); }); }; @@ -151,12 +137,6 @@ void DeleteMappingsRequest::doStart() { } } - if (!error) { - // enumerate the paths and remove them from the cache - for (auto& path : _paths) { - assetClient->_mappingCache.remove(path); - } - } emit finished(this); }); }; @@ -189,14 +169,6 @@ void RenameMappingRequest::doStart() { } } - if (!error) { - // take the hash mapped for the old path from the cache - auto hash = assetClient->_mappingCache.take(_oldPath); - if (!hash.isEmpty()) { - // use the hash mapped for the old path for the new path - assetClient->_mappingCache[_newPath] = hash; - } - } emit finished(this); }); } From e2b976d9f15903b41af6b839d540767dfe61402c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 9 Mar 2016 14:24:35 -0800 Subject: [PATCH 12/12] remove debug, fix asset find bug for incorrect folder --- assignment-client/src/assets/AssetServer.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/assignment-client/src/assets/AssetServer.cpp b/assignment-client/src/assets/AssetServer.cpp index 13257967ac..2218c5b5e3 100644 --- a/assignment-client/src/assets/AssetServer.cpp +++ b/assignment-client/src/assets/AssetServer.cpp @@ -220,12 +220,10 @@ void AssetServer::handleGetMappingOperation(ReceivedMessage& message, SharedNode auto it = _fileMappings.find(assetPath); if (it != _fileMappings.end()) { auto assetHash = it->toString(); - qDebug() << "Found mapping for: " << assetPath << "=>" << assetHash; replyPacket.writePrimitive(AssetServerError::NoError); replyPacket.write(QByteArray::fromHex(assetHash.toUtf8())); } else { - qDebug() << "Mapping not found for: " << assetPath; replyPacket.writePrimitive(AssetServerError::AssetNotFound); } } @@ -314,7 +312,7 @@ void AssetServer::handleAssetGetInfo(QSharedPointer message, Sh replyPacket->write(assetHash); QString fileName = QString(hexHash); - QFileInfo fileInfo { _resourcesDirectory.filePath(fileName) }; + QFileInfo fileInfo { _filesDirectory.filePath(fileName) }; if (fileInfo.exists() && fileInfo.isReadable()) { qDebug() << "Opening file: " << fileInfo.filePath();