HaikuDepot: Work on retrieving more pkg info

* Simple, incomplete JSON string-builder.
 * Not yet using the new bulk information method of the web-app.
 * Not yet parsing the reply and doing anything with it, consequently
   commented out.
 * What works is generating a JSON command and receiving the reply.
This commit is contained in:
Stephan Aßmus
2014-04-24 00:21:33 +02:00
parent 5153d5ee57
commit e08beebef9
4 changed files with 233 additions and 62 deletions
+19
View File
@@ -609,6 +609,7 @@ Model::_PopulateAllPackagesThread(bool fromCacheOnly)
if (package.Get() == NULL)
continue;
// _PopulatePackageInfo(package, fromCacheOnly);
_PopulatePackageIcon(package, fromCacheOnly);
// TODO: Average user rating. It needs to be shown in the
// list view, so without the user clicking the package.
@@ -616,6 +617,24 @@ Model::_PopulateAllPackagesThread(bool fromCacheOnly)
}
void
Model::_PopulatePackageInfo(const PackageInfoRef& package, bool fromCacheOnly)
{
if (fromCacheOnly)
return;
// Retrieve info from web-app
WebAppInterface interface;
BMessage info;
status_t status = interface.RetrievePackageInfo(package->Title(), info);
if (status == B_OK) {
// TODO: Parse message...
info.PrintToStream();
}
}
void
Model::_PopulatePackageIcon(const PackageInfoRef& package, bool fromCacheOnly)
{
+3
View File
@@ -93,6 +93,9 @@ private:
static int32 _PopulateAllPackagesEntry(void* cookie);
void _PopulateAllPackagesThread(bool fromCacheOnly);
void _PopulatePackageInfo(
const PackageInfoRef& package,
bool fromCacheOnly);
void _PopulatePackageIcon(
const PackageInfoRef& package,
bool fromCacheOnly);
+205 -62
View File
@@ -10,19 +10,137 @@
#include <File.h>
#include <HttpHeaders.h>
#include <HttpRequest.h>
#include <Message.h>
#include <Url.h>
#include <UrlContext.h>
#include <UrlProtocolListener.h>
#include <UrlProtocolRoster.h>
#include "List.h"
#include "PackageInfo.h"
class JsonBuilder {
public:
JsonBuilder()
:
fString("{"),
fInList(false)
{
}
JsonBuilder& AddObject()
{
fString << '{';
fInList = false;
return *this;
}
JsonBuilder& AddObject(const char* name)
{
_StartName(name);
fString << "\":{";
fInList = false;
return *this;
}
JsonBuilder& EndObject()
{
fString << '}';
fInList = true;
return *this;
}
JsonBuilder& AddArray(const char* name)
{
_StartName(name);
fString << "\":[";
fInList = false;
return *this;
}
JsonBuilder& EndArray()
{
fString << ']';
fInList = true;
return *this;
}
JsonBuilder& AddValue(const char* name, const char* value)
{
_StartName(name);
// TODO: Escape value
fString << "\":\"";
fString << value;
fString << "\"";
fInList = true;
return *this;
}
JsonBuilder& AddValue(const char* name, int value)
{
_StartName(name);
fString << "\":";
fString << value;
fInList = true;
return *this;
}
JsonBuilder& AddValue(const char* name, bool value)
{
_StartName(name);
fString << "\":";
if (value)
fString << "true";
else
fString << "false";
fInList = true;
return *this;
}
const BString& End()
{
fString << "}\n";
return fString;
}
private:
void _StartName(const char* name)
{
if (fInList)
fString << ",\"";
else
fString << '"';
fString << name;
}
private:
BString fString;
bool fInList;
};
class ProtocolListener : public BUrlProtocolListener {
public:
ProtocolListener()
:
fDownloadIO(NULL)
fDownloadIO(NULL),
fDebug(false)
{
}
@@ -38,18 +156,23 @@ public:
virtual void ResponseStarted(BUrlRequest* caller)
{
// printf("ResponseStarted(%p)\n", caller);
if (fDebug)
printf("ResponseStarted(%p)\n", caller);
}
virtual void HeadersReceived(BUrlRequest* caller)
{
// printf("HeadersReceived(%p)\n", caller);
if (fDebug)
printf("HeadersReceived(%p)\n", caller);
}
virtual void DataReceived(BUrlRequest* caller, const char* data,
off_t position, ssize_t size)
{
// printf("DataReceived(%p): %ld bytes\n", caller, size);
if (fDebug) {
printf("DataReceived(%p): %ld bytes\n", caller, size);
printf("%.*s", (int)size, data);
}
if (fDownloadIO != NULL)
fDownloadIO->Write(data, size);
@@ -65,12 +188,14 @@ public:
virtual void UploadProgress(BUrlRequest* caller, ssize_t bytesSent,
ssize_t bytesTotal)
{
// printf("UploadProgress(%p): %ld/%ld\n", caller, bytesSent, bytesTotal);
if (fDebug)
printf("UploadProgress(%p): %ld/%ld\n", caller, bytesSent, bytesTotal);
}
virtual void RequestCompleted(BUrlRequest* caller, bool success)
{
// printf("RequestCompleted(%p): %d\n", caller, success);
if (fDebug)
printf("RequestCompleted(%p): %d\n", caller, success);
}
virtual void DebugMessage(BUrlRequest* caller,
@@ -84,11 +209,22 @@ public:
fDownloadIO = downloadIO;
}
void SetDebug(bool debug)
{
fDebug = debug;
}
private:
BDataIO* fDownloadIO;
bool fDebug;
};
int
WebAppInterface::fRequestIndex = 0;
WebAppInterface::WebAppInterface()
{
}
@@ -108,62 +244,69 @@ WebAppInterface::SetAuthorization(const BString& username,
}
//void
//WebAppInterface::_TestGetPackage()
//{
// BUrl url("https://depot.haiku-os.org/api/v1/pkg");
//
// ProtocolListener listener;
// BUrlContext context;
// BHttpHeaders headers;
//
// // Authentication
// if (!fUsername.IsEmpty() && !fPassword.IsEmpty()) {
// BString plain;
// plain << fUsername << ':' << fPassword;
//
// char base64[1024];
// ssize_t base64Size = encode_base64(base64, plain, plain.Length(),
// false);
//
// if (base64Size > 0 && base64Size <= (ssize_t)sizeof(base64)) {
// base64[base64Size] = '\0';
//
// BString authorization("Basic ");
// authorization << base64;
//
// headers.AddHeader("Authorization", authorization);
// }
// }
// // Content-Type
// headers.AddHeader("Content-Type", "application/json");
//
// BHttpRequest request(url, true, "HTTP", &listener, &context);
// request.SetMethod(B_HTTP_POST);
// request.SetHeaders(headers);
//
// BMallocIO* data = new BMallocIO();
//
// BString jsonString
// = "{"
// "\"jsonrpc\":\"2.0\","
// "\"id\":4143431,"
// "\"method\":\"getPkg\","
// "\"params\":[{"
// "\"name\":\"apr\","
// "\"architectureCode\":\"x86\","
// "\"versionType\":\"NONE\""
// "}]"
// "}"
// ;
//
// data->WriteAt(0, jsonString.String(), jsonString.Length());
// data->Seek(0, SEEK_SET);
// request.AdoptInputData(data);
//
// thread_id thread = request.Run();
// wait_for_thread(thread, NULL);
//}
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)
.AddValue("method", "getPkg")
.AddArray("params")
.AddObject()
.AddValue("name", packageName)
.AddValue("architectureCode", "x86_gcc2")
.AddValue("naturalLanguageCode", "en")
.AddValue("versionType", "NONE")
.EndObject()
.EndArray()
.End();
printf("Sending JSON:\n%s\n", jsonString.String());
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<const BHttpResult&>(
request.Result());
int32 statusCode = result.StatusCode();
if (statusCode == 200)
return B_OK;
printf("Response code: %ld\n", statusCode);
return B_ERROR;
}
status_t
+6
View File
@@ -11,6 +11,7 @@
class BDataIO;
class BMessage;
class WebAppInterface {
@@ -21,6 +22,10 @@ public:
void SetAuthorization(const BString& username,
const BString& password);
status_t RetrievePackageInfo(
const BString& packageName,
BMessage& message);
status_t RetrievePackageIcon(
const BString& packageName,
BDataIO* stream);
@@ -28,6 +33,7 @@ public:
private:
BString fUsername;
BString fPassword;
static int fRequestIndex;
};