From 630c253b03a640e3bdde8322a26fb36c11989424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sat, 30 Aug 2014 23:31:27 +0200 Subject: [PATCH] HaikuDepot/WebAppInterface: Support bulk transfers. Refactor code to send different JSON requests. --- src/apps/haikudepot/WebAppInterface.cpp | 155 +++++++++++++++++------- src/apps/haikudepot/WebAppInterface.h | 12 ++ 2 files changed, 122 insertions(+), 45 deletions(-) diff --git a/src/apps/haikudepot/WebAppInterface.cpp b/src/apps/haikudepot/WebAppInterface.cpp index fe1f01775a..c2a1138049 100644 --- a/src/apps/haikudepot/WebAppInterface.cpp +++ b/src/apps/haikudepot/WebAppInterface.cpp @@ -67,6 +67,26 @@ public: return *this; } + JsonBuilder& AddStrings(const StringList& strings) + { + for (int i = 0; i < strings.CountItems(); i++) + AddItem(strings.ItemAtFast(i)); + return *this; + } + + JsonBuilder& AddItem(const char* item) + { + if (fInList) + fString << ",\""; + else + fString << '"'; + // TODO: Escape item + fString << item; + fString << "\""; + fInList = true; + return *this; + } + JsonBuilder& AddValue(const char* name, const char* value) { _StartName(name); @@ -234,25 +254,6 @@ status_t WebAppInterface::RetrievePackageInfo(const BString& packageName, BMessage& message) { - BUrl url("https://depot.haiku-os.org/api/v1/pkg"); - - ProtocolListener listener; - BUrlContext context; - BHttpHeaders headers; - // Content-Type - headers.AddHeader("Content-Type", "application/json"); - - BHttpRequest request(url, true, "HTTP", &listener, &context); - - // Authentication - if (!fUsername.IsEmpty() && !fPassword.IsEmpty()) { - request.SetUserName(fUsername); - request.SetPassword(fPassword); - } - - request.SetMethod(B_HTTP_POST); - request.SetHeaders(headers); - BString jsonString = JsonBuilder() .AddValue("jsonrpc", "2.0") .AddValue("id", ++fRequestIndex) @@ -267,36 +268,41 @@ WebAppInterface::RetrievePackageInfo(const BString& packageName, .EndArray() .End(); - printf("Sending JSON:\n%s\n", jsonString.String()); +// printf("Sending JSON:\n%s\n", jsonString.String()); - BMemoryIO* data = new BMemoryIO( - jsonString.String(), jsonString.Length() - 1); + return _SendJsonRequest(jsonString, message); +} - request.AdoptInputData(data, jsonString.Length() - 1); - BMallocIO replyData; - listener.SetDownloadIO(&replyData); -// listener.SetDebug(true); +status_t +WebAppInterface::RetrieveBulkPackageInfo(const StringList& packageNames, + BMessage& message) +{ + BString jsonString = JsonBuilder() + .AddValue("jsonrpc", "2.0") + .AddValue("id", ++fRequestIndex) + .AddValue("method", "getBulkPkg") + .AddArray("params") + .AddObject() + .AddArray("pkgNames") + .AddStrings(packageNames) + .EndArray() + .AddValue("architectureCode", "x86_gcc2") + .AddValue("naturalLanguageCode", "en") + .AddValue("versionType", "LATEST") + .AddArray("filter") + .AddItem("PKGCATEGORIES") + .AddItem("PKGSCREENSHOTS") + .AddItem("PKGICONS") + .AddItem("PKGVERSIONLOCALIZATIONDESCRIPTIONS") + .EndArray() + .EndObject() + .EndArray() + .End(); - thread_id thread = request.Run(); - wait_for_thread(thread, NULL); - - const BHttpResult& result = dynamic_cast( - request.Result()); - - int32 statusCode = result.StatusCode(); - if (statusCode != 200) { - printf("Response code: %" B_PRId32 "\n", statusCode); - return B_ERROR; - } - - jsonString.SetTo(static_cast(replyData.Buffer()), - replyData.BufferLength()); - if (jsonString.Length() == 0) - return B_ERROR; - - BJson parser; - return parser.Parse(message, jsonString); +// printf("Sending JSON:\n%s\n", jsonString.String()); + + return _SendJsonRequest(jsonString, message); } @@ -328,3 +334,62 @@ WebAppInterface::RetrievePackageIcon(const BString& packageName, return B_ERROR; } + + +status_t +WebAppInterface::_SendJsonRequest(BString jsonString, BMessage& reply) const +{ + BUrl url("https://depot.haiku-os.org/api/v1/pkg"); + + ProtocolListener listener; + BUrlContext context; + BHttpHeaders headers; + // Content-Type + headers.AddHeader("Content-Type", "application/json"); + + BHttpRequest request(url, true, "HTTP", &listener, &context); + + // Authentication + if (!fUsername.IsEmpty() && !fPassword.IsEmpty()) { + request.SetUserName(fUsername); + request.SetPassword(fPassword); + } + + request.SetMethod(B_HTTP_POST); + request.SetHeaders(headers); + + BMemoryIO* data = new BMemoryIO( + jsonString.String(), jsonString.Length() - 1); + + request.AdoptInputData(data, jsonString.Length() - 1); + + BMallocIO replyData; + listener.SetDownloadIO(&replyData); +// listener.SetDebug(true); + + thread_id thread = request.Run(); + wait_for_thread(thread, NULL); + + const BHttpResult& result = dynamic_cast( + request.Result()); + + int32 statusCode = result.StatusCode(); + if (statusCode != 200) { + printf("Response code: %" B_PRId32 "\n", statusCode); + return B_ERROR; + } + + jsonString.SetTo(static_cast(replyData.Buffer()), + replyData.BufferLength()); + if (jsonString.Length() == 0) + return B_ERROR; + + BJson parser; + status_t status = parser.Parse(reply, jsonString); + if (status == B_BAD_DATA) { +// printf("Parser choked on JSON:\n%s\n", jsonString.String()); + } + return status; +} + + diff --git a/src/apps/haikudepot/WebAppInterface.h b/src/apps/haikudepot/WebAppInterface.h index f5e2a28dd7..5436b99a72 100644 --- a/src/apps/haikudepot/WebAppInterface.h +++ b/src/apps/haikudepot/WebAppInterface.h @@ -9,10 +9,14 @@ #include #include +#include "List.h" + class BDataIO; class BMessage; +typedef List StringList; + class WebAppInterface { public: @@ -26,10 +30,18 @@ public: const BString& packageName, BMessage& message); + status_t RetrieveBulkPackageInfo( + const StringList& packageNames, + BMessage& message); + status_t RetrievePackageIcon( const BString& packageName, BDataIO* stream); +private: + status_t _SendJsonRequest(BString jsonString, + BMessage& reply) const; + private: BString fUsername; BString fPassword;