DEV-168 - make interface-installed content sets display info on web

installed content section
This commit is contained in:
Roxanne Skelly 2019-07-25 14:37:41 -07:00
parent 22e71115dd
commit 130e68c9b5
12 changed files with 46 additions and 23 deletions

View file

@ -33,12 +33,6 @@ ContentSettingsBackupHandler::ContentSettingsBackupHandler(DomainServerSettingsM
}
static const QString CONTENT_SETTINGS_BACKUP_FILENAME = "content-settings.json";
static const QString INSTALLED_CONTENT = "installed_content";
static const QString INSTALLED_CONTENT_FILENAME = "filename";
static const QString INSTALLED_CONTENT_NAME = "name";
static const QString INSTALLED_CONTENT_CREATION_TIME = "creation_time";
static const QString INSTALLED_CONTENT_INSTALL_TIME = "install_time";
static const QString INSTALLED_CONTENT_INSTALLED_BY = "installed_by";
void ContentSettingsBackupHandler::createBackup(const QString& backupName, QuaZip& zip) {

View file

@ -37,6 +37,12 @@
const QString DATETIME_FORMAT_RE { "\\d{4}-\\d{2}-\\d{2}_\\d{2}-\\d{2}-\\d{2}" };
const QString AUTOMATIC_BACKUP_PREFIX { "autobackup-" };
const QString MANUAL_BACKUP_PREFIX { "backup-" };
const QString INSTALLED_CONTENT = "installed_content";
const QString INSTALLED_CONTENT_FILENAME = "filename";
const QString INSTALLED_CONTENT_NAME = "name";
const QString INSTALLED_CONTENT_CREATION_TIME = "creation_time";
const QString INSTALLED_CONTENT_INSTALL_TIME = "install_time";
const QString INSTALLED_CONTENT_INSTALLED_BY = "installed_by";
struct BackupItemInfo {
BackupItemInfo(QString pId, QString pName, QString pAbsolutePath, QDateTime pCreatedAt, bool pIsManualBackup) :

View file

@ -2606,7 +2606,7 @@ bool DomainServer::processPendingContent(HTTPConnection* connection, QString ite
if (itemName == "restore-file" || itemName == "restore-file-chunk-final" || itemName == "restore-file-chunk-only") {
// invoke our method to hand the new octree file off to the octree server
QMetaObject::invokeMethod(this, "handleOctreeFileReplacement",
Qt::QueuedConnection, Q_ARG(QByteArray, _pendingUploadedContent));
Qt::QueuedConnection, Q_ARG(QByteArray, _pendingUploadedContent), Q_ARG(QString, filename), Q_ARG(QString, QString()));
_pendingUploadedContents.erase(sessionId);
}
} else {
@ -3491,7 +3491,7 @@ void DomainServer::maybeHandleReplacementEntityFile() {
}
}
void DomainServer::handleOctreeFileReplacement(QByteArray octreeFile) {
void DomainServer::handleOctreeFileReplacement(QByteArray octreeFile, QString sourceFilename, QString name) {
OctreeUtils::RawEntityData data;
if (data.readOctreeDataInfoFromData(octreeFile)) {
data.resetIdAndVersion();
@ -3507,6 +3507,18 @@ void DomainServer::handleOctreeFileReplacement(QByteArray octreeFile) {
// process it when it comes back up
qInfo() << "Wrote octree replacement file to" << replacementFilePath << "- stopping server";
QJsonObject installed_content {
{ INSTALLED_CONTENT_FILENAME, sourceFilename },
{ INSTALLED_CONTENT_NAME, name },
{ INSTALLED_CONTENT_CREATION_TIME, 0 },
{ INSTALLED_CONTENT_INSTALL_TIME, QDateTime::currentDateTime().currentMSecsSinceEpoch() },
{ INSTALLED_CONTENT_INSTALLED_BY, "" }
};
QJsonObject jsonObject { { INSTALLED_CONTENT, installed_content } };
_settingsManager.recurseJSONObjectAndOverwriteSettings(jsonObject, ContentSettings);
QMetaObject::invokeMethod(this, "restart", Qt::QueuedConnection);
} else {
qWarning() << "Could not write replacement octree data to file - refusing to process";
@ -3516,6 +3528,8 @@ void DomainServer::handleOctreeFileReplacement(QByteArray octreeFile) {
}
}
static const QString CONTENT_SET_NAME_QUERY_PARAM = "name";
void DomainServer::handleDomainContentReplacementFromURLRequest(QSharedPointer<ReceivedMessage> message) {
qInfo() << "Received request to replace content from a url";
auto node = DependencyManager::get<LimitedNodeList>()->findNodeWithAddr(message->getSenderSockAddr());
@ -3527,13 +3541,16 @@ void DomainServer::handleDomainContentReplacementFromURLRequest(QSharedPointer<R
QNetworkRequest request(modelsURL);
QNetworkReply* reply = networkAccessManager.get(request);
qDebug() << "Downloading JSON from: " << modelsURL;
qDebug() << "Downloading JSON from: " << modelsURL.toString(QUrl::FullyEncoded);
connect(reply, &QNetworkReply::finished, [this, reply, modelsURL]() {
QNetworkReply::NetworkError networkError = reply->error();
if (networkError == QNetworkReply::NoError) {
if (modelsURL.fileName().endsWith(".json.gz")) {
handleOctreeFileReplacement(reply->readAll());
QUrlQuery urlQuery(modelsURL.query(QUrl::FullyEncoded));
QString itemName = urlQuery.queryItemValue(CONTENT_SET_NAME_QUERY_PARAM);
handleOctreeFileReplacement(reply->readAll(), modelsURL.fileName(), itemName);
} else if (modelsURL.fileName().endsWith(".zip")) {
auto deferred = makePromise("recoverFromUploadedBackup");
_contentManager->recoverFromUploadedBackup(deferred, reply->readAll());
@ -3548,6 +3565,6 @@ void DomainServer::handleDomainContentReplacementFromURLRequest(QSharedPointer<R
void DomainServer::handleOctreeFileReplacementRequest(QSharedPointer<ReceivedMessage> message) {
auto node = DependencyManager::get<NodeList>()->nodeWithLocalID(message->getSourceID());
if (node->getCanReplaceContent()) {
handleOctreeFileReplacement(message->readAll());
handleOctreeFileReplacement(message->readAll(), QString(), QString());
}
}

View file

@ -99,7 +99,7 @@ private slots:
void handleDomainContentReplacementFromURLRequest(QSharedPointer<ReceivedMessage> message);
void handleOctreeFileReplacementRequest(QSharedPointer<ReceivedMessage> message);
void handleOctreeFileReplacement(QByteArray octreeFile);
void handleOctreeFileReplacement(QByteArray octreeFile, QString sourceFilename, QString name);
void processOctreeDataRequestMessage(QSharedPointer<ReceivedMessage> message);
void processOctreeDataPersistMessage(QSharedPointer<ReceivedMessage> message);

View file

@ -786,7 +786,7 @@ Rectangle {
}
lightboxPopup.button2text = "CONFIRM";
lightboxPopup.button2method = function() {
Commerce.replaceContentSet(root.itemHref, root.certificateId);
Commerce.replaceContentSet(root.itemHref, root.certificateId, root.itemName);
lightboxPopup.visible = false;
rezzedNotifContainer.visible = true;
rezzedNotifContainerTimer.start();

View file

@ -36,7 +36,7 @@ Rectangle {
break;
case "content set":
urlHandler.handleUrl("hifi://localhost/0,0,0");
Commerce.replaceContentSet(toUrl(resource), "");
Commerce.replaceContentSet(toUrl(resource), "", "");
break;
case "entity":
case "wearable":

View file

@ -729,7 +729,7 @@ Item {
onClicked: {
Tablet.playSound(TabletEnums.ButtonClick);
if (root.itemType === "contentSet") {
sendToPurchases({method: 'showReplaceContentLightbox', itemHref: root.itemHref, certID: root.certificateId});
sendToPurchases({method: 'showReplaceContentLightbox', itemHref: root.itemHref, certID: root.certificateId, itemName: root.itemName});
} else if (root.itemType === "avatar") {
sendToPurchases({method: 'showChangeAvatarLightbox', itemName: root.itemName, itemHref: root.itemHref});
} else if (root.itemType === "app") {

View file

@ -609,7 +609,7 @@ Rectangle {
}
lightboxPopup.button2text = "CONFIRM";
lightboxPopup.button2method = function() {
Commerce.replaceContentSet(msg.itemHref, msg.certID);
Commerce.replaceContentSet(msg.itemHref, msg.certID, msg.itemName);
lightboxPopup.visible = false;
};
lightboxPopup.visible = true;

View file

@ -7788,9 +7788,15 @@ bool Application::askToWearAvatarAttachmentUrl(const QString& url) {
return true;
}
void Application::replaceDomainContent(const QString& url) {
static const QString CONTENT_SET_NAME_QUERY_PARAM = "name";
void Application::replaceDomainContent(const QString& url, const QString& itemName) {
qCDebug(interfaceapp) << "Attempting to replace domain content";
QByteArray urlData(url.toUtf8());
QUrl msgUrl(url);
QUrlQuery urlQuery(msgUrl.query());
urlQuery.addQueryItem(CONTENT_SET_NAME_QUERY_PARAM, itemName);
msgUrl.setQuery(urlQuery.query(QUrl::QUrl::FullyEncoded));
QByteArray urlData(msgUrl.toString(QUrl::QUrl::FullyEncoded).toUtf8());
auto limitedNodeList = DependencyManager::get<NodeList>();
const auto& domainHandler = limitedNodeList->getDomainHandler();
@ -7824,7 +7830,7 @@ bool Application::askToReplaceDomainContent(const QString& url) {
QString details;
if (static_cast<QMessageBox::StandardButton>(answer.toInt()) == QMessageBox::Yes) {
// Given confirmation, send request to domain server to replace content
replaceDomainContent(url);
replaceDomainContent(url, QString());
details = "SuccessfulRequestToReplaceContent";
} else {
details = "UserDeclinedToReplaceContent";

View file

@ -326,7 +326,7 @@ public:
bool isInterstitialMode() const { return _interstitialMode; }
bool failedToConnectToEntityServer() const { return _failedToConnectToEntityServer; }
void replaceDomainContent(const QString& url);
void replaceDomainContent(const QString& url, const QString& itemName);
void loadAvatarScripts(const QVector<QString>& urls);
void unloadAvatarScripts();

View file

@ -259,7 +259,7 @@ void QmlCommerce::authorizeAssetTransfer(const QString& couponID,
ledger->authorizeAssetTransfer(key, couponID, certificateID, amount, optionalMessage);
}
void QmlCommerce::replaceContentSet(const QString& itemHref, const QString& certificateID) {
void QmlCommerce::replaceContentSet(const QString& itemHref, const QString& certificateID, const QString& itemName) {
if (!certificateID.isEmpty()) {
auto ledger = DependencyManager::get<Ledger>();
ledger->updateLocation(
@ -267,7 +267,7 @@ void QmlCommerce::replaceContentSet(const QString& itemHref, const QString& cert
DependencyManager::get<AddressManager>()->getPlaceName(),
true);
}
qApp->replaceDomainContent(itemHref);
qApp->replaceDomainContent(itemHref, itemName);
QJsonObject messageProperties = {
{ "status", "SuccessfulRequestToReplaceContent" },
{ "content_set_url", itemHref } };

View file

@ -90,7 +90,7 @@ protected:
Q_INVOKABLE void transferAssetToUsername(const QString& username, const QString& certificateID, const int& amount, const QString& optionalMessage);
Q_INVOKABLE void authorizeAssetTransfer(const QString& couponID, const QString& certificateID, const int& amount, const QString& optionalMessage);
Q_INVOKABLE void replaceContentSet(const QString& itemHref, const QString& certificateID);
Q_INVOKABLE void replaceContentSet(const QString& itemHref, const QString& certificateID, const QString& itemName);
Q_INVOKABLE QString getInstalledApps(const QString& justInstalledAppID = "");
Q_INVOKABLE bool installApp(const QString& appHref, const bool& alsoOpenImmediately = false);