From 5af39ea28be1a76ec0c3042a0bf34e7d64835c18 Mon Sep 17 00:00:00 2001 From: Leslie Linden Date: Fri, 16 Sep 2011 11:46:37 -0700 Subject: EXP-1169 FIX -- No synch error icon given on Outbox on Agni where API does not exist * Moved marketplace URL related functions into a new file llmarketplacefunctions.cpp/h. This will the future home of more marketplace-related functions. * Disabled sync button when the marketplace API is unavailable. --- indra/newview/llmarketplacefunctions.cpp | 80 ++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 indra/newview/llmarketplacefunctions.cpp (limited to 'indra/newview/llmarketplacefunctions.cpp') diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp new file mode 100644 index 0000000000..599731a641 --- /dev/null +++ b/indra/newview/llmarketplacefunctions.cpp @@ -0,0 +1,80 @@ +/** + * @file llmarketplacefunctions.cpp + * @brief Implementation of assorted functions related to the marketplace + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llmarketplacefunctions.h" + +#include "llagent.h" +#include "llviewernetwork.h" + + +std::string getMarketplaceBaseURL() +{ + std::string url = "https://marketplace.secondlife.com/"; + + if (!LLGridManager::getInstance()->isInProductionGrid()) + { + std::string gridLabel = LLGridManager::getInstance()->getGridLabel(); + url = llformat("https://marketplace.%s.lindenlab.com/", utf8str_tolower(gridLabel).c_str()); + } + + url += "api/1/users/"; + url += gAgent.getID().getString(); + + return url; +} + +std::string getMarketplaceURL_InventoryImport() +{ + std::string url = getMarketplaceBaseURL(); + + url += "/inventory_import"; + + return url; +} + +std::string getMarketplaceURL_UserStatus() +{ + std::string url = getMarketplaceBaseURL(); + + url += "/user_status"; + + return url; +} + + +static bool gMarketplaceSyncEnabled = false; + +bool getMarketplaceSyncEnabled() +{ + return gMarketplaceSyncEnabled; +} + +void setMarketplaceSyncEnabled(bool syncEnabled) +{ + gMarketplaceSyncEnabled = syncEnabled; +} -- cgit v1.2.3 From c24645f7b51ea27e1686bbe72470a9f3c09fc676 Mon Sep 17 00:00:00 2001 From: Leslie Linden Date: Mon, 14 Nov 2011 14:41:26 -0800 Subject: Updated url for damballah to use secondlife-staging --- indra/newview/llmarketplacefunctions.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'indra/newview/llmarketplacefunctions.cpp') diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index 599731a641..99b0389413 100644 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -38,8 +38,16 @@ std::string getMarketplaceBaseURL() if (!LLGridManager::getInstance()->isInProductionGrid()) { - std::string gridLabel = LLGridManager::getInstance()->getGridLabel(); - url = llformat("https://marketplace.%s.lindenlab.com/", utf8str_tolower(gridLabel).c_str()); + std::string gridLabel = utf8str_tolower(LLGridManager::getInstance()->getGridLabel()); + + if (gridLabel == "damballah") + { + url = "https://marketplace.secondlife-staging.com/"; + } + else + { + url = llformat("https://marketplace.%s.lindenlab.com/", gridLabel.c_str()); + } } url += "api/1/users/"; @@ -67,7 +75,7 @@ std::string getMarketplaceURL_UserStatus() } -static bool gMarketplaceSyncEnabled = false; +static bool gMarketplaceSyncEnabled = true; bool getMarketplaceSyncEnabled() { -- cgit v1.2.3 From 591891306366e683416b187207fa2b94bdc263a8 Mon Sep 17 00:00:00 2001 From: Leslie Linden Date: Mon, 5 Dec 2011 13:37:37 -0800 Subject: First pass at connecting to the new marketplace API --- indra/newview/llmarketplacefunctions.cpp | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) (limited to 'indra/newview/llmarketplacefunctions.cpp') diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index 99b0389413..1c189f6ee2 100644 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -50,8 +50,9 @@ std::string getMarketplaceBaseURL() } } - url += "api/1/users/"; + url += "api/1/"; url += gAgent.getID().getString(); + url += "/inventory"; return url; } @@ -60,29 +61,20 @@ std::string getMarketplaceURL_InventoryImport() { std::string url = getMarketplaceBaseURL(); - url += "/inventory_import"; - - return url; -} - -std::string getMarketplaceURL_UserStatus() -{ - std::string url = getMarketplaceBaseURL(); - - url += "/user_status"; + url += "/import"; return url; } -static bool gMarketplaceSyncEnabled = true; +static bool gMarketplaceImportEnabled = true; -bool getMarketplaceSyncEnabled() +bool getMarketplaceImportEnabled() { - return gMarketplaceSyncEnabled; + return gMarketplaceImportEnabled; } -void setMarketplaceSyncEnabled(bool syncEnabled) +void setMarketplaceImportEnabled(bool importEnabled) { - gMarketplaceSyncEnabled = syncEnabled; + gMarketplaceImportEnabled = importEnabled; } -- cgit v1.2.3 From a255fadfab359931d591c6a874abbea5fcf13526 Mon Sep 17 00:00:00 2001 From: Leslie Linden Date: Tue, 6 Dec 2011 11:19:58 -0800 Subject: Updated to trigger a 'get' to establish marketplace session cookie when outbox panel created. --- indra/newview/llmarketplacefunctions.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llmarketplacefunctions.cpp') diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index 1c189f6ee2..2f8c5bc9ee 100644 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -52,7 +52,7 @@ std::string getMarketplaceBaseURL() url += "api/1/"; url += gAgent.getID().getString(); - url += "/inventory"; + url += "/inventory/"; return url; } @@ -61,7 +61,7 @@ std::string getMarketplaceURL_InventoryImport() { std::string url = getMarketplaceBaseURL(); - url += "/import"; + url += "import/"; return url; } -- cgit v1.2.3 From 35020db3a9310742c9759673e3aa1bbb1d7aa02f Mon Sep 17 00:00:00 2001 From: Leslie Linden Date: Wed, 7 Dec 2011 15:04:39 -0800 Subject: Refactored marketplace inventory import HTTP requests and surrounding support to remove it from the UI panel code. --- indra/newview/llmarketplacefunctions.cpp | 302 ++++++++++++++++++++++++++++--- 1 file changed, 281 insertions(+), 21 deletions(-) (limited to 'indra/newview/llmarketplacefunctions.cpp') diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index 2f8c5bc9ee..b9e02a36b4 100644 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -29,52 +29,312 @@ #include "llmarketplacefunctions.h" #include "llagent.h" +#include "llhttpclient.h" +#include "llviewermedia.h" #include "llviewernetwork.h" -std::string getMarketplaceBaseURL() +// +// Helpers +// + +namespace LLMarketplaceImport { - std::string url = "https://marketplace.secondlife.com/"; + // Basic interface for this namespace + + bool inProgress(); + bool resultPending(); + U32 getResultStatus(); + const LLSD& getResults(); + + void establishMarketplaceSessionCookie(); + void pollStatus(); + void triggerImport(); + + // Internal state variables + + static std::string sMarketplaceCookie = ""; + static bool sImportInProgress = false; + static bool sImportGetPending = false; + static U32 sImportResultStatus = 0; + static LLSD sImportResults = LLSD::emptyMap(); + + + // Internal helper functions + + std::string getBaseURL() + { + std::string url = "https://marketplace.secondlife.com/"; + + if (!LLGridManager::getInstance()->isInProductionGrid()) + { + std::string gridLabel = utf8str_tolower(LLGridManager::getInstance()->getGridLabel()); + + if (gridLabel == "damballah") + { + url = "https://marketplace.secondlife-staging.com/"; + } + else + { + url = llformat("https://marketplace.%s.lindenlab.com/", gridLabel.c_str()); + } + } + + url += "api/1/"; + url += gAgent.getID().getString(); + url += "/inventory/"; + + return url; + } + + std::string getInventoryImportURL() + { + std::string url = getBaseURL(); - if (!LLGridManager::getInstance()->isInProductionGrid()) + url += "import/"; + + return url; + } + + // Responders + + class LLImportPostResponder : public LLHTTPClient::Responder + { + public: + LLImportPostResponder() : LLCurl::Responder() {} + + void completed(U32 status, const std::string& reason, const LLSD& content) + { + sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_DONE); + sImportResultStatus = status; + } + }; + + class LLImportGetResponder : public LLHTTPClient::Responder + { + public: + LLImportGetResponder() : LLCurl::Responder() {} + + void completedHeader(U32 status, const std::string& reason, const LLSD& content) + { + sMarketplaceCookie = content["set-cookie"].asString(); + } + + void completed(U32 status, const std::string& reason, const LLSD& content) + { + sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_PROCESSING); + sImportGetPending = false; + sImportResultStatus = status; + sImportResults = content; + } + }; + + // Coroutine testing +/* + std::string gTimeDelayDebugFunc = ""; + + void timeDelay(LLCoros::self& self, LLPanelMarketplaceOutbox* outboxPanel) { - std::string gridLabel = utf8str_tolower(LLGridManager::getInstance()->getGridLabel()); + waitForEventOn(self, "mainloop"); + + LLTimer delayTimer; + delayTimer.reset(); + delayTimer.setTimerExpirySec(5.0f); - if (gridLabel == "damballah") + while (!delayTimer.hasExpired()) { - url = "https://marketplace.secondlife-staging.com/"; + waitForEventOn(self, "mainloop"); } - else + + outboxPanel->onImportPostComplete(MarketplaceErrorCodes::IMPORT_DONE, LLSD::emptyMap()); + + gTimeDelayDebugFunc = ""; + } + + std::string gImportPollingFunc = ""; + + void importPoll(LLCoros::self& self, LLPanelMarketplaceOutbox* outboxPanel) + { + waitForEventOn(self, "mainloop"); + + while (outboxPanel->isImportInProgress()) { - url = llformat("https://marketplace.%s.lindenlab.com/", gridLabel.c_str()); + LLTimer delayTimer; + delayTimer.reset(); + delayTimer.setTimerExpirySec(5.0f); + + while (!delayTimer.hasExpired()) + { + waitForEventOn(self, "mainloop"); + } + + //outboxPanel-> } + + gImportPollingFunc = ""; } + +*/ + + // Basic API - url += "api/1/"; - url += gAgent.getID().getString(); - url += "/inventory/"; + bool inProgress() + { + return sImportInProgress; + } + + bool resultPending() + { + return sImportGetPending; + } + + U32 getResultStatus() + { + return sImportResultStatus; + } + + const LLSD& getResults() + { + return sImportResults; + } + + void establishMarketplaceSessionCookie() + { + sImportInProgress = true; + sImportGetPending = true; + + std::string url = getInventoryImportURL(); + + LLHTTPClient::get(url, new LLImportGetResponder(), LLViewerMedia::getHeaders()); + } + + void pollStatus() + { + sImportGetPending = true; - return url; + std::string url = getInventoryImportURL(); + + // Make the headers for the post + LLSD headers = LLSD::emptyMap(); + headers["Accept"] = "*/*"; + headers["Cookie"] = sMarketplaceCookie; + headers["Content-Type"] = "application/xml"; + headers["User-Agent"] = LLViewerMedia::getCurrentUserAgent(); + + LLHTTPClient::get(url, new LLImportGetResponder(), headers); + } + + void triggerImport() + { + sImportInProgress = true; + sImportResultStatus = MarketplaceErrorCodes::IMPORT_PROCESSING; + sImportResults = LLSD::emptyMap(); + + std::string url = getInventoryImportURL(); + + // Make the headers for the post + LLSD headers = LLSD::emptyMap(); + headers["Accept"] = "*/*"; + headers["Connection"] = "Keep-Alive"; + headers["Cookie"] = sMarketplaceCookie; + headers["Content-Type"] = "application/xml"; + headers["User-Agent"] = LLViewerMedia::getCurrentUserAgent(); + + LLHTTPClient::post(url, LLSD(), new LLImportPostResponder(), headers); + + // Set a timer (for testing only) + //gTimeDelayDebugFunc = LLCoros::instance().launch("LLPanelMarketplaceOutbox timeDelay", boost::bind(&timeDelay, _1, this)); + } } -std::string getMarketplaceURL_InventoryImport() + +// +// Interface class +// + + +//static +void LLMarketplaceInventoryImporter::update() { - std::string url = getMarketplaceBaseURL(); + if (instanceExists()) + { + LLMarketplaceInventoryImporter::instance().updateImport(); + } +} - url += "import/"; +LLMarketplaceInventoryImporter::LLMarketplaceInventoryImporter() + : mImportInProgress(false) + , mInitialized(false) + , mStatusChangedSignal(NULL) + , mStatusReportSignal(NULL) +{ +} - return url; +void LLMarketplaceInventoryImporter::initialize() +{ + if (!mInitialized) + { + LLMarketplaceImport::establishMarketplaceSessionCookie(); + } } +boost::signals2::connection LLMarketplaceInventoryImporter::setStatusChangedCallback(const status_changed_signal_t::slot_type& cb) +{ + if (mStatusChangedSignal == NULL) + { + mStatusChangedSignal = new status_changed_signal_t(); + } -static bool gMarketplaceImportEnabled = true; + return mStatusChangedSignal->connect(cb); +} -bool getMarketplaceImportEnabled() +boost::signals2::connection LLMarketplaceInventoryImporter::setStatusReportCallback(const status_report_signal_t::slot_type& cb) { - return gMarketplaceImportEnabled; + if (mStatusReportSignal == NULL) + { + mStatusReportSignal = new status_report_signal_t(); + } + + return mStatusReportSignal->connect(cb); } -void setMarketplaceImportEnabled(bool importEnabled) +bool LLMarketplaceInventoryImporter::triggerImport() { - gMarketplaceImportEnabled = importEnabled; + LLMarketplaceImport::triggerImport(); + + return LLMarketplaceImport::inProgress(); } + +void LLMarketplaceInventoryImporter::updateImport() +{ + const bool in_progress = LLMarketplaceImport::inProgress(); + + if (in_progress && !LLMarketplaceImport::resultPending()) + { + LLMarketplaceImport::pollStatus(); + } + + if (mImportInProgress != in_progress) + { + mImportInProgress = in_progress; + + if (mStatusChangedSignal) + { + (*mStatusChangedSignal)(mImportInProgress); + } + + // If we are no longer in progress, report results + if (!mImportInProgress && mStatusReportSignal) + { + if (mInitialized) + { + (*mStatusReportSignal)(LLMarketplaceImport::getResultStatus(), LLMarketplaceImport::getResults()); + } + else + { + mInitialized = true; + } + } + } +} + -- cgit v1.2.3 From 67f1321f31d5988e7b383cfbf4fbd6537f3d2710 Mon Sep 17 00:00:00 2001 From: Leslie Linden Date: Thu, 8 Dec 2011 16:46:30 -0800 Subject: Initial functional merchant outbox floater --- indra/newview/llmarketplacefunctions.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'indra/newview/llmarketplacefunctions.cpp') diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index b9e02a36b4..9c67c589b8 100644 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -55,6 +55,7 @@ namespace LLMarketplaceImport static std::string sMarketplaceCookie = ""; static bool sImportInProgress = false; + static bool sImportPostPending = false; static bool sImportGetPending = false; static U32 sImportResultStatus = 0; static LLSD sImportResults = LLSD::emptyMap(); @@ -106,6 +107,7 @@ namespace LLMarketplaceImport void completed(U32 status, const std::string& reason, const LLSD& content) { sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_DONE); + sImportPostPending = false; sImportResultStatus = status; } }; @@ -185,7 +187,7 @@ namespace LLMarketplaceImport bool resultPending() { - return sImportGetPending; + return (sImportPostPending || sImportGetPending); } U32 getResultStatus() @@ -226,7 +228,8 @@ namespace LLMarketplaceImport void triggerImport() { - sImportInProgress = true; + sImportInProgress = true; + sImportPostPending = true; sImportResultStatus = MarketplaceErrorCodes::IMPORT_PROCESSING; sImportResults = LLSD::emptyMap(); -- cgit v1.2.3 From e826cbd90750fd38565e4e44390948f36254cf1f Mon Sep 17 00:00:00 2001 From: Leslie Linden Date: Mon, 12 Dec 2011 15:02:52 -0800 Subject: EXP-1682 FIX EXP-1683 FIX EXP-1705 FIX EXP-1707 FIX * Outbox folder count now uses inventory API directly rather than inventory folder view for folder count and item status * Asynchronous fetches are triggered for the outbox content when the window is opened and when it receives focus * Marketplace URL's for empty and non-merchant outbox view have been updated * "Copy to Merchant Outbox" and "Delete" context menu items should be fully functional now with item counts, etc. --- indra/newview/llmarketplacefunctions.cpp | 101 ++++++++++++++++++++----------- 1 file changed, 65 insertions(+), 36 deletions(-) (limited to 'indra/newview/llmarketplacefunctions.cpp') diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index 9c67c589b8..225bb059c9 100644 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -30,6 +30,7 @@ #include "llagent.h" #include "llhttpclient.h" +#include "lltrans.h" #include "llviewermedia.h" #include "llviewernetwork.h" @@ -38,6 +39,59 @@ // Helpers // +static std::string getMarketplaceDomain() +{ + std::string domain = "secondlife.com"; + + if (!LLGridManager::getInstance()->isInProductionGrid()) + { + const std::string& grid_label = LLGridManager::getInstance()->getGridLabel(); + const std::string& grid_label_lower = utf8str_tolower(grid_label); + + if (grid_label_lower == "damballah") + { + domain = "secondlife-staging.com"; + } + else + { + domain = llformat("%s.lindenlab.com", grid_label_lower.c_str()); + } + } + + return domain; +} + +static std::string getMarketplaceURL(const std::string& urlStringName) +{ + LLStringUtil::format_map_t domain_arg; + domain_arg["[MARKETPLACE_DOMAIN_NAME]"] = getMarketplaceDomain(); + + std::string marketplace_url = LLTrans::getString(urlStringName, domain_arg); + + return marketplace_url; +} + +LLStringUtil::format_map_t getMarketplaceStringSubstitutions() +{ + std::string marketplace_url = getMarketplaceURL("MarketplaceURL"); + std::string marketplace_url_create = getMarketplaceURL("MarketplaceURL_CreateStore"); + std::string marketplace_url_dashboard = getMarketplaceURL("MarketplaceURL_Dashboard"); + std::string marketplace_url_info = getMarketplaceURL("MarketplaceURL_LearnMore"); + + LLStringUtil::format_map_t agent_map; + agent_map["[AGENT_ID]"] = gAgent.getID().getString(); + + LLStringUtil::format(marketplace_url_dashboard, agent_map); + + LLStringUtil::format_map_t marketplace_sub_map; + marketplace_sub_map["[MARKETPLACE_URL]"] = marketplace_url; + marketplace_sub_map["[MARKETPLACE_CREATE_STORE_URL]"] = marketplace_url_create; + marketplace_sub_map["[MARKETPLACE_LEARN_MORE_URL]"] = marketplace_url_info; + marketplace_sub_map["[MARKETPLACE_DASHBOARD_URL]"] = marketplace_url_dashboard; + + return marketplace_sub_map; +} + namespace LLMarketplaceImport { // Basic interface for this namespace @@ -61,42 +115,6 @@ namespace LLMarketplaceImport static LLSD sImportResults = LLSD::emptyMap(); - // Internal helper functions - - std::string getBaseURL() - { - std::string url = "https://marketplace.secondlife.com/"; - - if (!LLGridManager::getInstance()->isInProductionGrid()) - { - std::string gridLabel = utf8str_tolower(LLGridManager::getInstance()->getGridLabel()); - - if (gridLabel == "damballah") - { - url = "https://marketplace.secondlife-staging.com/"; - } - else - { - url = llformat("https://marketplace.%s.lindenlab.com/", gridLabel.c_str()); - } - } - - url += "api/1/"; - url += gAgent.getID().getString(); - url += "/inventory/"; - - return url; - } - - std::string getInventoryImportURL() - { - std::string url = getBaseURL(); - - url += "import/"; - - return url; - } - // Responders class LLImportPostResponder : public LLHTTPClient::Responder @@ -200,6 +218,17 @@ namespace LLMarketplaceImport return sImportResults; } + static std::string getInventoryImportURL() + { + std::string url = getMarketplaceURL("MarketplaceURL"); + + url += "api/1/"; + url += gAgent.getID().getString(); + url += "/inventory/import/"; + + return url; + } + void establishMarketplaceSessionCookie() { sImportInProgress = true; -- cgit v1.2.3 From 52fab641041ed1ba409a03fee77a0cdaec86dea2 Mon Sep 17 00:00:00 2001 From: Leslie Linden Date: Tue, 20 Dec 2011 16:16:49 -0800 Subject: * Added "InventoryOutboxLogging" debug setting to log merchant outbox related web API calls. Each message begins with the tag "SLM". --- indra/newview/llmarketplacefunctions.cpp | 39 ++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) (limited to 'indra/newview/llmarketplacefunctions.cpp') diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index 225bb059c9..9a83c5fcb7 100644 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -31,6 +31,7 @@ #include "llagent.h" #include "llhttpclient.h" #include "lltrans.h" +#include "llviewercontrol.h" #include "llviewermedia.h" #include "llviewernetwork.h" @@ -108,12 +109,13 @@ namespace LLMarketplaceImport // Internal state variables static std::string sMarketplaceCookie = ""; + static LLSD sImportId = LLSD::emptyMap(); static bool sImportInProgress = false; static bool sImportPostPending = false; static bool sImportGetPending = false; static U32 sImportResultStatus = 0; static LLSD sImportResults = LLSD::emptyMap(); - + // Responders @@ -124,9 +126,17 @@ namespace LLMarketplaceImport void completed(U32 status, const std::string& reason, const LLSD& content) { + if (gSavedSettings.getBOOL("InventoryOutboxLogging")) + { + llinfos << " SLM POST status: " << status << llendl; + llinfos << " SLM POST reason: " << reason << llendl; + llinfos << " SLM POST content: " << content.asString() << llendl; + } + sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_DONE); sImportPostPending = false; sImportResultStatus = status; + sImportId = content; } }; @@ -142,6 +152,13 @@ namespace LLMarketplaceImport void completed(U32 status, const std::string& reason, const LLSD& content) { + if (gSavedSettings.getBOOL("InventoryOutboxLogging")) + { + llinfos << " SLM GET status: " << status << llendl; + llinfos << " SLM GET reason: " << reason << llendl; + llinfos << " SLM GET content: " << content.asString() << llendl; + } + sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_PROCESSING); sImportGetPending = false; sImportResultStatus = status; @@ -236,6 +253,11 @@ namespace LLMarketplaceImport std::string url = getInventoryImportURL(); + if (gSavedSettings.getBOOL("InventoryOutboxLogging")) + { + llinfos << " SLM GET: " << url << llendl; + } + LLHTTPClient::get(url, new LLImportGetResponder(), LLViewerMedia::getHeaders()); } @@ -245,18 +267,26 @@ namespace LLMarketplaceImport std::string url = getInventoryImportURL(); + url += sImportId.asString(); + // Make the headers for the post LLSD headers = LLSD::emptyMap(); headers["Accept"] = "*/*"; headers["Cookie"] = sMarketplaceCookie; - headers["Content-Type"] = "application/xml"; + headers["Content-Type"] = "application/llsd+xml"; headers["User-Agent"] = LLViewerMedia::getCurrentUserAgent(); + if (gSavedSettings.getBOOL("InventoryOutboxLogging")) + { + llinfos << " SLM GET: " << url << llendl; + } + LLHTTPClient::get(url, new LLImportGetResponder(), headers); } void triggerImport() { + sImportId = LLSD::emptyMap(); sImportInProgress = true; sImportPostPending = true; sImportResultStatus = MarketplaceErrorCodes::IMPORT_PROCESSING; @@ -272,6 +302,11 @@ namespace LLMarketplaceImport headers["Content-Type"] = "application/xml"; headers["User-Agent"] = LLViewerMedia::getCurrentUserAgent(); + if (gSavedSettings.getBOOL("InventoryOutboxLogging")) + { + llinfos << " SLM POST: " << url << llendl; + } + LLHTTPClient::post(url, LLSD(), new LLImportPostResponder(), headers); // Set a timer (for testing only) -- cgit v1.2.3 From 00b767e5a91d9e3379119c867164f9be40f888cc Mon Sep 17 00:00:00 2001 From: Leslie Linden Date: Wed, 11 Jan 2012 10:05:15 -0800 Subject: EXP-1791 - Handle case where initialization with SLM fails in the Merchant Outbox floater in the viewer * Added code to clear and re-initialize the SLM cookie when authentication errors are encountered. * Re-organized logic for outbox import a bit to hopefully be more robust when errors are encountered. --- indra/newview/llmarketplacefunctions.cpp | 175 +++++++++++++++++++------------ 1 file changed, 109 insertions(+), 66 deletions(-) (limited to 'indra/newview/llmarketplacefunctions.cpp') diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index 9a83c5fcb7..ea6634a39e 100644 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -97,14 +97,15 @@ namespace LLMarketplaceImport { // Basic interface for this namespace + bool hasSessionCookie(); bool inProgress(); bool resultPending(); U32 getResultStatus(); const LLSD& getResults(); - void establishMarketplaceSessionCookie(); - void pollStatus(); - void triggerImport(); + bool establishMarketplaceSessionCookie(); + bool pollStatus(); + bool triggerImport(); // Internal state variables @@ -116,7 +117,6 @@ namespace LLMarketplaceImport static U32 sImportResultStatus = 0; static LLSD sImportResults = LLSD::emptyMap(); - // Responders class LLImportPostResponder : public LLHTTPClient::Responder @@ -147,7 +147,12 @@ namespace LLMarketplaceImport void completedHeader(U32 status, const std::string& reason, const LLSD& content) { - sMarketplaceCookie = content["set-cookie"].asString(); + const std::string& set_cookie_string = content["set-cookie"].asString(); + + if (!set_cookie_string.empty()) + { + sMarketplaceCookie = set_cookie_string; + } } void completed(U32 status, const std::string& reason, const LLSD& content) @@ -158,6 +163,16 @@ namespace LLMarketplaceImport llinfos << " SLM GET reason: " << reason << llendl; llinfos << " SLM GET content: " << content.asString() << llendl; } + + if (status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) + { + if (gSavedSettings.getBOOL("InventoryOutboxLogging")) + { + llinfos << " SLM GET clearing marketplace cookie due to authentication failure" << llendl; + } + + sMarketplaceCookie.clear(); + } sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_PROCESSING); sImportGetPending = false; @@ -165,56 +180,14 @@ namespace LLMarketplaceImport sImportResults = content; } }; - - // Coroutine testing -/* - std::string gTimeDelayDebugFunc = ""; - - void timeDelay(LLCoros::self& self, LLPanelMarketplaceOutbox* outboxPanel) - { - waitForEventOn(self, "mainloop"); - - LLTimer delayTimer; - delayTimer.reset(); - delayTimer.setTimerExpirySec(5.0f); - - while (!delayTimer.hasExpired()) - { - waitForEventOn(self, "mainloop"); - } - - outboxPanel->onImportPostComplete(MarketplaceErrorCodes::IMPORT_DONE, LLSD::emptyMap()); - - gTimeDelayDebugFunc = ""; - } - - std::string gImportPollingFunc = ""; - - void importPoll(LLCoros::self& self, LLPanelMarketplaceOutbox* outboxPanel) + + // Basic API + + bool hasSessionCookie() { - waitForEventOn(self, "mainloop"); - - while (outboxPanel->isImportInProgress()) - { - LLTimer delayTimer; - delayTimer.reset(); - delayTimer.setTimerExpirySec(5.0f); - - while (!delayTimer.hasExpired()) - { - waitForEventOn(self, "mainloop"); - } - - //outboxPanel-> - } - - gImportPollingFunc = ""; + return !sMarketplaceCookie.empty(); } -*/ - - // Basic API - bool inProgress() { return sImportInProgress; @@ -246,8 +219,13 @@ namespace LLMarketplaceImport return url; } - void establishMarketplaceSessionCookie() + bool establishMarketplaceSessionCookie() { + if (hasSessionCookie()) + { + return false; + } + sImportInProgress = true; sImportGetPending = true; @@ -259,10 +237,17 @@ namespace LLMarketplaceImport } LLHTTPClient::get(url, new LLImportGetResponder(), LLViewerMedia::getHeaders()); + + return true; } - void pollStatus() + bool pollStatus() { + if (!hasSessionCookie()) + { + return false; + } + sImportGetPending = true; std::string url = getInventoryImportURL(); @@ -282,10 +267,17 @@ namespace LLMarketplaceImport } LLHTTPClient::get(url, new LLImportGetResponder(), headers); + + return true; } - void triggerImport() + bool triggerImport() { + if (!hasSessionCookie()) + { + return false; + } + sImportId = LLSD::emptyMap(); sImportInProgress = true; sImportPostPending = true; @@ -309,8 +301,7 @@ namespace LLMarketplaceImport LLHTTPClient::post(url, LLSD(), new LLImportPostResponder(), headers); - // Set a timer (for testing only) - //gTimeDelayDebugFunc = LLCoros::instance().launch("LLPanelMarketplaceOutbox timeDelay", boost::bind(&timeDelay, _1, this)); + return true; } } @@ -330,8 +321,10 @@ void LLMarketplaceInventoryImporter::update() } LLMarketplaceInventoryImporter::LLMarketplaceInventoryImporter() - : mImportInProgress(false) + : mAutoTriggerImport(false) + , mImportInProgress(false) , mInitialized(false) + , mErrorInitSignal(NULL) , mStatusChangedSignal(NULL) , mStatusReportSignal(NULL) { @@ -339,12 +332,24 @@ LLMarketplaceInventoryImporter::LLMarketplaceInventoryImporter() void LLMarketplaceInventoryImporter::initialize() { - if (!mInitialized) + llassert(!mInitialized); + + if (!LLMarketplaceImport::hasSessionCookie()) { LLMarketplaceImport::establishMarketplaceSessionCookie(); } } +boost::signals2::connection LLMarketplaceInventoryImporter::setInitializationErrorCallback(const status_report_signal_t::slot_type& cb) +{ + if (mErrorInitSignal == NULL) + { + mErrorInitSignal = new status_report_signal_t(); + } + + return mErrorInitSignal->connect(cb); +} + boost::signals2::connection LLMarketplaceInventoryImporter::setStatusChangedCallback(const status_changed_signal_t::slot_type& cb) { if (mStatusChangedSignal == NULL) @@ -367,9 +372,18 @@ boost::signals2::connection LLMarketplaceInventoryImporter::setStatusReportCallb bool LLMarketplaceInventoryImporter::triggerImport() { - LLMarketplaceImport::triggerImport(); + const bool import_triggered = LLMarketplaceImport::triggerImport(); - return LLMarketplaceImport::inProgress(); + if (!import_triggered) + { + mInitialized = false; + + initialize(); + + mAutoTriggerImport = true; + } + + return import_triggered; } void LLMarketplaceInventoryImporter::updateImport() @@ -378,7 +392,16 @@ void LLMarketplaceInventoryImporter::updateImport() if (in_progress && !LLMarketplaceImport::resultPending()) { - LLMarketplaceImport::pollStatus(); + const bool polling_status = LLMarketplaceImport::pollStatus(); + + if (!polling_status) + { + mInitialized = false; + + initialize(); + + mAutoTriggerImport = true; + } } if (mImportInProgress != in_progress) @@ -390,16 +413,36 @@ void LLMarketplaceInventoryImporter::updateImport() (*mStatusChangedSignal)(mImportInProgress); } - // If we are no longer in progress, report results - if (!mImportInProgress && mStatusReportSignal) + // If we are no longer in progress + if (!mImportInProgress) { if (mInitialized) { - (*mStatusReportSignal)(LLMarketplaceImport::getResultStatus(), LLMarketplaceImport::getResults()); + // Report results + if (mStatusReportSignal) + { + (*mStatusReportSignal)(LLMarketplaceImport::getResultStatus(), LLMarketplaceImport::getResults()); + } } else { - mInitialized = true; + // Look for results success + mInitialized = LLMarketplaceImport::hasSessionCookie(); + + if (mInitialized) + { + // Follow up with auto trigger of import + if (mAutoTriggerImport) + { + mAutoTriggerImport = false; + + triggerImport(); + } + } + else if (mErrorInitSignal) + { + (*mErrorInitSignal)(LLMarketplaceImport::getResultStatus(), LLMarketplaceImport::getResults()); + } } } } -- cgit v1.2.3 From 0a1cb4f03ee1aeb0cfc9d9bdb837043d0f46f292 Mon Sep 17 00:00:00 2001 From: Leslie Linden Date: Wed, 11 Jan 2012 11:26:56 -0800 Subject: EXP-1791 FIX -- Handle case where initialization with SLM fails in the Merchant Outbox floater in the viewer * Updated marketplace import to properly handle failed cases of authentications and invalid cookies. The import will reset to an uninitialized state and then trigger and initialization followed immediately by an import when appropriate. --- indra/newview/llmarketplacefunctions.cpp | 67 +++++++++++++++++++------------- 1 file changed, 40 insertions(+), 27 deletions(-) (limited to 'indra/newview/llmarketplacefunctions.cpp') diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index ea6634a39e..84cbe3cac2 100644 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -133,6 +133,17 @@ namespace LLMarketplaceImport llinfos << " SLM POST content: " << content.asString() << llendl; } + if ((status == MarketplaceErrorCodes::IMPORT_REDIRECT) || + (status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR)) + { + if (gSavedSettings.getBOOL("InventoryOutboxLogging")) + { + llinfos << " SLM POST clearing marketplace cookie due to authentication failure" << llendl; + } + + sMarketplaceCookie.clear(); + } + sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_DONE); sImportPostPending = false; sImportResultStatus = status; @@ -330,16 +341,6 @@ LLMarketplaceInventoryImporter::LLMarketplaceInventoryImporter() { } -void LLMarketplaceInventoryImporter::initialize() -{ - llassert(!mInitialized); - - if (!LLMarketplaceImport::hasSessionCookie()) - { - LLMarketplaceImport::establishMarketplaceSessionCookie(); - } -} - boost::signals2::connection LLMarketplaceInventoryImporter::setInitializationErrorCallback(const status_report_signal_t::slot_type& cb) { if (mErrorInitSignal == NULL) @@ -370,17 +371,32 @@ boost::signals2::connection LLMarketplaceInventoryImporter::setStatusReportCallb return mStatusReportSignal->connect(cb); } +void LLMarketplaceInventoryImporter::initialize() +{ + llassert(!mInitialized); + + if (!LLMarketplaceImport::hasSessionCookie()) + { + LLMarketplaceImport::establishMarketplaceSessionCookie(); + } +} + +void LLMarketplaceInventoryImporter::reinitializeAndTriggerImport() +{ + mInitialized = false; + + initialize(); + + mAutoTriggerImport = true; +} + bool LLMarketplaceInventoryImporter::triggerImport() { const bool import_triggered = LLMarketplaceImport::triggerImport(); if (!import_triggered) { - mInitialized = false; - - initialize(); - - mAutoTriggerImport = true; + reinitializeAndTriggerImport(); } return import_triggered; @@ -396,23 +412,14 @@ void LLMarketplaceInventoryImporter::updateImport() if (!polling_status) { - mInitialized = false; - - initialize(); - - mAutoTriggerImport = true; + reinitializeAndTriggerImport(); } } if (mImportInProgress != in_progress) { mImportInProgress = in_progress; - - if (mStatusChangedSignal) - { - (*mStatusChangedSignal)(mImportInProgress); - } - + // If we are no longer in progress if (!mImportInProgress) { @@ -436,7 +443,7 @@ void LLMarketplaceInventoryImporter::updateImport() { mAutoTriggerImport = false; - triggerImport(); + mImportInProgress = triggerImport(); } } else if (mErrorInitSignal) @@ -445,6 +452,12 @@ void LLMarketplaceInventoryImporter::updateImport() } } } + + // Make sure we trigger the status change with the final state (in case of auto trigger after initialize) + if (mStatusChangedSignal) + { + (*mStatusChangedSignal)(mImportInProgress); + } } } -- cgit v1.2.3 From 59950f6178699b96e86bfd2c0bc701271b3f1a6b Mon Sep 17 00:00:00 2001 From: Leslie Linden Date: Wed, 11 Jan 2012 16:49:32 -0800 Subject: EXP-1778 FIX -- Link to Marketplace Error log in transfer failed viewer notification * Added a link to the "imports" log from the "done with errors" notification when sending folders to the marketplace. --- indra/newview/llmarketplacefunctions.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'indra/newview/llmarketplacefunctions.cpp') diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index 84cbe3cac2..ee7505c4f4 100644 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -72,23 +72,21 @@ static std::string getMarketplaceURL(const std::string& urlStringName) return marketplace_url; } -LLStringUtil::format_map_t getMarketplaceStringSubstitutions() +LLSD getMarketplaceStringSubstitutions() { std::string marketplace_url = getMarketplaceURL("MarketplaceURL"); std::string marketplace_url_create = getMarketplaceURL("MarketplaceURL_CreateStore"); std::string marketplace_url_dashboard = getMarketplaceURL("MarketplaceURL_Dashboard"); + std::string marketplace_url_imports = getMarketplaceURL("MarketplaceURL_Imports"); std::string marketplace_url_info = getMarketplaceURL("MarketplaceURL_LearnMore"); - LLStringUtil::format_map_t agent_map; - agent_map["[AGENT_ID]"] = gAgent.getID().getString(); - - LLStringUtil::format(marketplace_url_dashboard, agent_map); - - LLStringUtil::format_map_t marketplace_sub_map; + LLSD marketplace_sub_map; + marketplace_sub_map["[MARKETPLACE_URL]"] = marketplace_url; marketplace_sub_map["[MARKETPLACE_CREATE_STORE_URL]"] = marketplace_url_create; marketplace_sub_map["[MARKETPLACE_LEARN_MORE_URL]"] = marketplace_url_info; marketplace_sub_map["[MARKETPLACE_DASHBOARD_URL]"] = marketplace_url_dashboard; + marketplace_sub_map["[MARKETPLACE_IMPORTS_URL]"] = marketplace_url_imports; return marketplace_sub_map; } -- cgit v1.2.3 From 652ef621543497aa947970d374285d8f851ed682 Mon Sep 17 00:00:00 2001 From: Leslie Linden Date: Tue, 17 Jan 2012 15:51:30 -0800 Subject: EXP-1791 FIX -- Handle case where initialization with SLM fails in the Merchant Outbox floater in the viewer * Timeout now triggers the re-initialization logic in the merchant outbox. --- indra/newview/llmarketplacefunctions.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'indra/newview/llmarketplacefunctions.cpp') diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index ee7505c4f4..a3f0a6062c 100644 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -132,11 +132,12 @@ namespace LLMarketplaceImport } if ((status == MarketplaceErrorCodes::IMPORT_REDIRECT) || - (status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR)) + (status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) || + (status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT)) { if (gSavedSettings.getBOOL("InventoryOutboxLogging")) { - llinfos << " SLM POST clearing marketplace cookie due to authentication failure" << llendl; + llinfos << " SLM POST clearing marketplace cookie due to authentication failure or timeout" << llendl; } sMarketplaceCookie.clear(); @@ -173,11 +174,12 @@ namespace LLMarketplaceImport llinfos << " SLM GET content: " << content.asString() << llendl; } - if (status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) + if ((status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) || + (status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT)) { if (gSavedSettings.getBOOL("InventoryOutboxLogging")) { - llinfos << " SLM GET clearing marketplace cookie due to authentication failure" << llendl; + llinfos << " SLM GET clearing marketplace cookie due to authentication failure or timeout" << llendl; } sMarketplaceCookie.clear(); -- cgit v1.2.3