From 00c1094c7d230fdf0670a7e8c2218bb6b1a677ca Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 7 May 2014 16:44:14 -0700
Subject: [PATCH] DD-22 : WIP : Completed the associate_listing route, take
 edit_url into account and rewrite getListingURL()

---
 indra/newview/llinventorybridge.cpp      |   5 +-
 indra/newview/llmarketplacefunctions.cpp | 157 ++++++++++++++++-------
 indra/newview/llmarketplacefunctions.h   |   2 +
 3 files changed, 115 insertions(+), 49 deletions(-)

diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index f68d69b1c35..11ae3b6189c 100755
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -3226,7 +3226,10 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
 	else if ("marketplace_edit_listing" == action)
 	{
         std::string url = LLMarketplaceData::instance().getListingURL(mUUID);
-        LLUrlAction::openURL(url);
+        if (!url.empty())
+        {
+            LLUrlAction::openURL(url);
+        }
 		return;
 	}
 #ifndef LL_RELEASE_FOR_DOWNLOAD
diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index 701d341753a..74ea453c502 100755
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -109,7 +109,7 @@ void log_SLM_error(const std::string& request, U32 status, const std::string& re
 
 // Merov: This is a temporary hack used by dev while secondlife-staging is down...
 // *TODO : Suppress that before shipping!
-static bool sBypassMerchant = true;
+static bool sBypassMerchant = false;
 
 class LLSLMGetMerchantResponder : public LLHTTPClient::Responder
 {
@@ -180,12 +180,14 @@ class LLSLMGetListingsResponder : public LLHTTPClient::Responder
             
             int listing_id = listing["id"].asInt();
             bool is_listed = listing["is_listed"].asBool();
+            std::string edit_url = listing["edit_url"].asString();
             std::string folder_uuid_string = listing["inventory_info"]["listing_folder_id"].asString();
             std::string version_uuid_string = listing["inventory_info"]["version_folder_id"].asString();
             
             LLUUID folder_id(folder_uuid_string);
             LLUUID version_id(version_uuid_string);
             LLMarketplaceData::instance().addListing(folder_id,listing_id,version_id,is_listed);
+            LLMarketplaceData::instance().setEditURL(folder_id, edit_url);
             it++;
         }
     }
@@ -233,12 +235,14 @@ class LLSLMCreateListingsResponder : public LLHTTPClient::Responder
             
             int listing_id = listing["id"].asInt();
             bool is_listed = listing["is_listed"].asBool();
+            std::string edit_url = listing["edit_url"].asString();
             std::string folder_uuid_string = listing["inventory_info"]["listing_folder_id"].asString();
             std::string version_uuid_string = listing["inventory_info"]["version_folder_id"].asString();
             
             LLUUID folder_id(folder_uuid_string);
             LLUUID version_id(version_uuid_string);
             LLMarketplaceData::instance().addListing(folder_id,listing_id,version_id,is_listed);
+            LLMarketplaceData::instance().setEditURL(folder_id, edit_url);
             it++;
         }
     }
@@ -286,6 +290,7 @@ class LLSLMUpdateListingsResponder : public LLHTTPClient::Responder
             
             int listing_id = listing["id"].asInt();
             bool is_listed = listing["is_listed"].asBool();
+            std::string edit_url = listing["edit_url"].asString();
             std::string folder_uuid_string = listing["inventory_info"]["listing_folder_id"].asString();
             std::string version_uuid_string = listing["inventory_info"]["version_folder_id"].asString();
             
@@ -296,6 +301,7 @@ class LLSLMUpdateListingsResponder : public LLHTTPClient::Responder
             LLMarketplaceData::instance().setListingID(folder_id, listing_id);
             LLMarketplaceData::instance().setVersionFolderID(folder_id, version_id);
             LLMarketplaceData::instance().setActivation(folder_id, is_listed);
+            LLMarketplaceData::instance().setEditURL(folder_id, edit_url);
             
             it++;
         }
@@ -311,16 +317,61 @@ class LLSLMAssociateListingsResponder : public LLHTTPClient::Responder
     
 	virtual void completed(U32 status, const std::string& reason, const LLSD& content) { }
     
-    void completedHeader(U32 status, const std::string& reason, const LLSD& content)
+    virtual void completedRaw(U32 status,
+                              const std::string& reason,
+                              const LLChannelDescriptors& channels,
+                              const LLIOPipe::buffer_ptr_t& buffer)
     {
-		if (isGoodStatus(status))
-		{
-            LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_MERCHANT);
-		}
-		else
+		if (!isGoodStatus(status))
 		{
-            log_SLM_error("Get merchant", status, reason, content.get("error_code"), content.get("error_description"));
+            log_SLM_error("Associate listings", status, reason, "", "");
+            return;
 		}
+        
+        LLBufferStream istr(channels, buffer.get());
+        std::stringstream strstrm;
+        strstrm << istr.rdbuf();
+        const std::string body = strstrm.str();
+        
+        Json::Value root;
+        Json::Reader reader;
+        if (!reader.parse(body,root))
+        {
+            log_SLM_error("Associate listings", status, "Json parsing failed", reader.getFormatedErrorMessages(), body);
+            return;
+        }
+        
+        llinfos << "Merov : Update listing completedRaw : data = " << body << llendl;
+        
+        // Extract the info from the Json string
+        Json::ValueIterator it = root["listings"].begin();
+        
+        while (it != root["listings"].end())
+        {
+            Json::Value listing = *it;
+            
+            int listing_id = listing["id"].asInt();
+            bool is_listed = listing["is_listed"].asBool();
+            std::string edit_url = listing["edit_url"].asString();
+            std::string folder_uuid_string = listing["inventory_info"]["listing_folder_id"].asString();
+            std::string version_uuid_string = listing["inventory_info"]["version_folder_id"].asString();
+            
+            LLUUID folder_id(folder_uuid_string);
+            LLUUID version_id(version_uuid_string);
+            
+            // Check that the listing ID is not already associated to some other record
+            LLUUID old_listing = LLMarketplaceData::instance().getListingFolder(listing_id);
+            if (old_listing.notNull())
+            {
+                // If it is already used, unlist the old record (we can't have 2 listings with the same listing ID)
+                LLMarketplaceData::instance().deleteListing(old_listing);
+            }
+            
+            // Add the new association
+            LLMarketplaceData::instance().addListing(folder_id,listing_id,version_id,is_listed);
+            LLMarketplaceData::instance().setEditURL(folder_id, edit_url);
+            it++;
+        }
     }
 };
 
@@ -819,7 +870,8 @@ LLMarketplaceTuple::LLMarketplaceTuple() :
     mListingFolderId(),
     mListingId(0),
     mVersionFolderId(),
-    mIsActive(false)
+    mIsActive(false),
+    mEditURL("")
 {
 }
 
@@ -827,7 +879,8 @@ LLMarketplaceTuple::LLMarketplaceTuple(const LLUUID& folder_id) :
     mListingFolderId(folder_id),
     mListingId(0),
     mVersionFolderId(),
-    mIsActive(false)
+    mIsActive(false),
+    mEditURL("")
 {
 }
 
@@ -835,7 +888,8 @@ LLMarketplaceTuple::LLMarketplaceTuple(const LLUUID& folder_id, S32 listing_id,
     mListingFolderId(folder_id),
     mListingId(listing_id),
     mVersionFolderId(version_id),
-    mIsActive(is_listed)
+    mIsActive(is_listed),
+    mEditURL("")
 {
 }
 
@@ -924,23 +978,31 @@ void LLMarketplaceData::updateSLMListing(const LLUUID& folder_id, S32 listing_id
 	LLHTTPClient::putRaw(url, data, size, new LLSLMUpdateListingsResponder(), headers);
 }
 
-// PUT /associate_inventory/:listing_folder_id/:version_folder_id/:listing_id
 void LLMarketplaceData::associateSLMListing(const LLUUID& folder_id, S32 listing_id, const LLUUID& version_id)
 {
 	LLSD headers = LLSD::emptyMap();
 	headers["Accept"] = "application/json";
 	headers["Content-Type"] = "application/json";
     
-    LLSD data = LLSD::emptyMap();
+    Json::Value root;
+    Json::FastWriter writer;
+    
+    // Note : we're assuming that sending unchanged info won't break anything server side...
+    root["listing"]["id"] = listing_id;
+    root["listing"]["inventory_info"]["listing_folder_id"] = folder_id.asString();
+    root["listing"]["inventory_info"]["version_folder_id"] = version_id.asString();
     
-	// Send request
-    std::string url = getSLMConnectURL("/associate_inventory/")
-                        + folder_id.asString() + "/"
-                        + version_id.asString() + "/"
-                        + llformat("%d",listing_id);
+    std::string json_str = writer.write(root);
     
-    llinfos << "Merov : associate listing : " << url << llendl;
-	LLHTTPClient::put(url, data, new LLSLMAssociateListingsResponder(), headers);
+	// postRaw() takes ownership of the buffer and releases it later.
+	size_t size = json_str.size();
+	U8 *data = new U8[size];
+	memcpy(data, (U8*)(json_str.c_str()), size);
+    
+	// Send request
+    std::string url = getSLMConnectURL("/associate_inventory/") + llformat("%d",listing_id);
+    llinfos << "Merov : associate listing : " << url << ", data = " << json_str << llendl;
+	LLHTTPClient::putRaw(url, data, size, new LLSLMAssociateListingsResponder(), headers);
 }
 
 std::string LLMarketplaceData::getSLMConnectURL(const std::string& route)
@@ -1027,39 +1089,31 @@ bool LLMarketplaceData::setVersionFolder(const LLUUID& folder_id, const LLUUID&
     return true;
 }
 
-// Methods privately called or called by SLM responders to perform changes
-bool LLMarketplaceData::addListing(const LLUUID& folder_id, S32 listing_id, const LLUUID& version_id, bool is_listed)
+bool LLMarketplaceData::associateListing(const LLUUID& folder_id, S32 listing_id)
 {
     if (isListed(folder_id))
     {
         // Listing already exists -> exit with error
         return false;
     }
-	mMarketplaceItems[folder_id] = LLMarketplaceTuple(folder_id, listing_id, version_id, is_listed);
-
-    update_marketplace_category(folder_id);
-    gInventory.notifyObservers();
+    
+    // Post the listing update request to SLM
+    LLUUID version_id;
+    associateSLMListing(folder_id, listing_id, version_id);
+    
     return true;
 }
 
-bool LLMarketplaceData::associateListing(const LLUUID& folder_id, S32 listing_id)
+// Methods privately called or called by SLM responders to perform changes
+bool LLMarketplaceData::addListing(const LLUUID& folder_id, S32 listing_id, const LLUUID& version_id, bool is_listed)
 {
     if (isListed(folder_id))
     {
         // Listing already exists -> exit with error
         return false;
     }
-	mMarketplaceItems[folder_id] = LLMarketplaceTuple(folder_id);
-    
-    // Check that the listing ID is not already associated to some other record
-    LLUUID old_listing = getListingFolder(listing_id);
-    if (old_listing.notNull())
-    {
-        // If it is already used, unlist the old record (we can't have 2 listings with the same listing ID)
-        deleteListing(old_listing);
-    }
-    
-    setListingID(folder_id,listing_id);
+	mMarketplaceItems[folder_id] = LLMarketplaceTuple(folder_id, listing_id, version_id, is_listed);
+
     update_marketplace_category(folder_id);
     gInventory.notifyObservers();
     return true;
@@ -1150,19 +1204,11 @@ bool LLMarketplaceData::isVersionFolder(const LLUUID& folder_id)
 
 std::string LLMarketplaceData::getListingURL(const LLUUID& folder_id)
 {
-    // Get the listing id (i.e. go up the hierarchy to find the listing folder
-    // URL format will be something like : https://marketplace.secondlife.com/p/listing/<listing_id>
-	std::string marketplace_url = getMarketplaceURL("MarketplaceURL");
-    
     S32 depth = depth_nesting_in_marketplace(folder_id);
     LLUUID listing_uuid = nested_parent_id(folder_id, depth);
-    S32 listing_id = getListingID(listing_uuid);
     
-    if (listing_id != 0)
-    {
-        marketplace_url += llformat("p/listing/%d",listing_id);
-    }
-    return marketplace_url;
+    marketplace_items_list_t::iterator it = mMarketplaceItems.find(listing_uuid);
+    return (it == mMarketplaceItems.end() ? "" : (it->second).mEditURL);
 }
 
 // Modifiers
@@ -1230,4 +1276,19 @@ bool LLMarketplaceData::setActivation(const LLUUID& folder_id, bool activate)
     return false;
 }
 
+bool LLMarketplaceData::setEditURL(const LLUUID& folder_id, const std::string& edit_url)
+{
+    marketplace_items_list_t::iterator it = mMarketplaceItems.find(folder_id);
+    if (it == mMarketplaceItems.end())
+    {
+        return false;
+    }
+    else
+    {
+        (it->second).mEditURL = edit_url;
+        return true;
+    }
+}
+
+
 
diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h
index 3be1abf24fc..ed4af544db7 100755
--- a/indra/newview/llmarketplacefunctions.h
+++ b/indra/newview/llmarketplacefunctions.h
@@ -143,6 +143,7 @@ class LLMarketplaceTuple
     S32 mListingId;
     LLUUID mVersionFolderId;
     bool mIsActive;
+    std::string mEditURL;
 };
 // Note: The listing folder UUID is used as a key to this map. It could therefore be taken off the LLMarketplaceTuple objects themselves
 typedef std::map<LLUUID, LLMarketplaceTuple> marketplace_items_list_t;
@@ -193,6 +194,7 @@ class LLMarketplaceData
     bool setListingID(const LLUUID& folder_id, S32 listing_id);
     bool setVersionFolderID(const LLUUID& folder_id, const LLUUID& version_id);
     bool setActivation(const LLUUID& folder_id, bool activate);
+    bool setEditURL(const LLUUID& folder_id, const std::string& edit_url);
     
     // Used to flag if count values for Marketplace are likely to have to be updated
     bool checkDirtyCount() { if (mDirtyCount) { mDirtyCount = false; return true; } else { return false; } }
-- 
GitLab