hrev47067 adds 3 changesets to branch 'master' old head: a04a520b0d0c0d075c2a002bb42a1fe7be20ca69 new head: 5bd5f161e896a560c55776fbbada27b47e0794c8 overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=5bd5f16+%5Ea04a520 ---------------------------------------------------------------------------- 22949ba: HaikuDepot: SharedBitmap: Added loading from buffers. Refactored loading from a buffer when loading from resources and re-used that for instantiating a SharedBitmap from a BMallocIO. b34f1a8: HaikuDepot: Refactored setting title and icon in listview... ... so that it is also done when a package state change notification is received that has the icon bit set. 5bd5f16: HaikuDepot: Populate package icons from web app. * Transformed ConnectionTest into WebAppInterface * Added methods to Model to trigger the population of all packages with additional information that is needed in the list view. * This launches a thread which tries to retrieve icons for all known packages from depot.haiku-os.org. This is uncached and very slow. I guess it could even be fast enough with a change to the protocol where icons are not retrieved one at a time. [ Stephan Aßmus <superstippi@xxxxxx> ] ---------------------------------------------------------------------------- 11 files changed, 464 insertions(+), 294 deletions(-) src/apps/haikudepot/ConnectionTest.cpp | 214 ---------------------------- src/apps/haikudepot/ConnectionTest.h | 30 ---- src/apps/haikudepot/Jamfile | 9 +- src/apps/haikudepot/MainWindow.cpp | 3 + src/apps/haikudepot/Model.cpp | 104 +++++++++++++- src/apps/haikudepot/Model.h | 15 +- src/apps/haikudepot/PackageInfo.cpp | 119 +++++++++++----- src/apps/haikudepot/PackageInfo.h | 10 ++ src/apps/haikudepot/PackageListView.cpp | 24 +++- src/apps/haikudepot/WebAppInterface.cpp | 196 +++++++++++++++++++++++++ src/apps/haikudepot/WebAppInterface.h | 34 +++++ ############################################################################ Commit: 22949ba2effc01699eb47262e2061326547b1591 URL: http://cgit.haiku-os.org/haiku/commit/?id=22949ba Author: Stephan Aßmus <superstippi@xxxxxx> Date: Fri Mar 28 22:43:04 2014 UTC HaikuDepot: SharedBitmap: Added loading from buffers. Refactored loading from a buffer when loading from resources and re-used that for instantiating a SharedBitmap from a BMallocIO. ---------------------------------------------------------------------------- diff --git a/src/apps/haikudepot/PackageInfo.cpp b/src/apps/haikudepot/PackageInfo.cpp index 4a7ae89..71457dc 100644 --- a/src/apps/haikudepot/PackageInfo.cpp +++ b/src/apps/haikudepot/PackageInfo.cpp @@ -26,6 +26,8 @@ SharedBitmap::SharedBitmap(BBitmap* bitmap) : BReferenceable(), fResourceID(-1), + fBuffer(NULL), + fSize(0), fMimeType() { fBitmap[0] = bitmap; @@ -38,6 +40,8 @@ SharedBitmap::SharedBitmap(int32 resourceID) : BReferenceable(), fResourceID(resourceID), + fBuffer(NULL), + fSize(0), fMimeType() { fBitmap[0] = NULL; @@ -50,6 +54,8 @@ SharedBitmap::SharedBitmap(const char* mimeType) : BReferenceable(), fResourceID(-1), + fBuffer(NULL), + fSize(0), fMimeType(mimeType) { fBitmap[0] = NULL; @@ -58,18 +64,36 @@ SharedBitmap::SharedBitmap(const char* mimeType) } +SharedBitmap::SharedBitmap(const BMallocIO& data) + : + BReferenceable(), + fResourceID(-1), + fBuffer(new(std::nothrow) uint8[data.BufferLength()]), + fSize(data.BufferLength()), + fMimeType() +{ + if (fBuffer != NULL) + memcpy(fBuffer, data.Buffer(), fSize); + + fBitmap[0] = NULL; + fBitmap[1] = NULL; + fBitmap[2] = NULL; +} + + SharedBitmap::~SharedBitmap() { delete fBitmap[0]; delete fBitmap[1]; delete fBitmap[2]; + delete[] fBuffer; } const BBitmap* SharedBitmap::Bitmap(Size which) { - if (fResourceID == -1 && fMimeType.Length() == 0) + if (fResourceID == -1 && fMimeType.Length() == 0 && fBuffer == NULL) return fBitmap[0]; int32 index = 0; @@ -93,6 +117,8 @@ SharedBitmap::Bitmap(Size which) if (fBitmap[index] == NULL) { if (fResourceID >= 0) fBitmap[index] = _CreateBitmapFromResource(size); + else if (fBuffer != NULL) + fBitmap[index] = _CreateBitmapFromBuffer(size); else if (fMimeType.Length() > 0) fBitmap[index] = _CreateBitmapFromMimeType(size); } @@ -112,45 +138,26 @@ SharedBitmap::_CreateBitmapFromResource(int32 size) const size_t dataSize; const void* data = resources.LoadResource(B_VECTOR_ICON_TYPE, fResourceID, &dataSize); - if (data != NULL) { - BBitmap* bitmap = new BBitmap(BRect(0, 0, size - 1, size - 1), 0, - B_RGBA32); - status = bitmap->InitCheck(); - if (status == B_OK) { - status = BIconUtils::GetVectorIcon( - reinterpret_cast<const uint8*>(data), dataSize, bitmap); - }; - - if (status != B_OK) { - delete bitmap; - bitmap = NULL; - } - - return bitmap; - } + if (data != NULL) + return _LoadIconFromBuffer(data, dataSize, size); data = resources.LoadResource(B_MESSAGE_TYPE, fResourceID, &dataSize); - if (data != NULL) { - BMemoryIO stream(data, dataSize); + if (data != NULL) + return _LoadBitmapFromBuffer(data, dataSize); - // Try to read as an archived bitmap. - BMessage archive; - status = archive.Unflatten(&stream); - if (status != B_OK) - return NULL; - - BBitmap* bitmap = new BBitmap(&archive); + return NULL; +} - status = bitmap->InitCheck(); - if (status != B_OK) { - delete bitmap; - bitmap = NULL; - } - return bitmap; - } +BBitmap* +SharedBitmap::_CreateBitmapFromBuffer(int32 size) const +{ + BBitmap* bitmap = _LoadIconFromBuffer(fBuffer, fSize, size); + + if (bitmap == NULL) + bitmap = _LoadBitmapFromBuffer(fBuffer, fSize); - return NULL; + return bitmap; } @@ -176,6 +183,50 @@ SharedBitmap::_CreateBitmapFromMimeType(int32 size) const } +BBitmap* +SharedBitmap::_LoadBitmapFromBuffer(const void* buffer, size_t size) const +{ + BMemoryIO stream(buffer, size); + + // Try to read as an archived bitmap. + BMessage archive; + status_t status = archive.Unflatten(&stream); + if (status != B_OK) + return NULL; + + BBitmap* bitmap = new BBitmap(&archive); + + status = bitmap->InitCheck(); + if (status != B_OK) { + delete bitmap; + bitmap = NULL; + } + + return bitmap; +} + + +BBitmap* +SharedBitmap::_LoadIconFromBuffer(const void* data, size_t dataSize, + int32 size) const +{ + BBitmap* bitmap = new BBitmap(BRect(0, 0, size - 1, size - 1), 0, + B_RGBA32); + status_t status = bitmap->InitCheck(); + if (status == B_OK) { + status = BIconUtils::GetVectorIcon( + reinterpret_cast<const uint8*>(data), dataSize, bitmap); + }; + + if (status != B_OK) { + delete bitmap; + bitmap = NULL; + } + + return bitmap; +} + + // #pragma mark - UserInfo diff --git a/src/apps/haikudepot/PackageInfo.h b/src/apps/haikudepot/PackageInfo.h index d57429f..23a61ec 100644 --- a/src/apps/haikudepot/PackageInfo.h +++ b/src/apps/haikudepot/PackageInfo.h @@ -16,6 +16,7 @@ class BBitmap; +class BMallocIO; class SharedBitmap : public BReferenceable { @@ -30,16 +31,25 @@ public: SharedBitmap(BBitmap* bitmap); SharedBitmap(int32 resourceID); SharedBitmap(const char* mimeType); + SharedBitmap(const BMallocIO& data); ~SharedBitmap(); const BBitmap* Bitmap(Size which); private: BBitmap* _CreateBitmapFromResource(int32 size) const; + BBitmap* _CreateBitmapFromBuffer(int32 size) const; BBitmap* _CreateBitmapFromMimeType(int32 size) const; + BBitmap* _LoadBitmapFromBuffer(const void* buffer, + size_t dataSize) const; + BBitmap* _LoadIconFromBuffer(const void* buffer, + size_t dataSize, int32 size) const; + private: int32 fResourceID; + uint8* fBuffer; + size_t fSize; BString fMimeType; BBitmap* fBitmap[3]; }; ############################################################################ Commit: b34f1a8b118d0f595a1dadaec05431d8ba8bce96 URL: http://cgit.haiku-os.org/haiku/commit/?id=b34f1a8 Author: Stephan Aßmus <superstippi@xxxxxx> Date: Fri Mar 28 22:44:44 2014 UTC HaikuDepot: Refactored setting title and icon in listview... ... so that it is also done when a package state change notification is received that has the icon bit set. ---------------------------------------------------------------------------- diff --git a/src/apps/haikudepot/PackageListView.cpp b/src/apps/haikudepot/PackageListView.cpp index 9be0d83..725bac2 100644 --- a/src/apps/haikudepot/PackageListView.cpp +++ b/src/apps/haikudepot/PackageListView.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2013, Stephan Aßmus <superstippi@xxxxxx>. + * Copyright 2013-2014, Stephan Aßmus <superstippi@xxxxxx>. * Copyright 2013, Rene Gollent, <rene@xxxxxxxxxxx>. * All rights reserved. Distributed under the terms of the MIT License. */ @@ -123,6 +123,7 @@ public: const PackageInfoRef& Package() const { return fPackage; } + void UpdateTitle(); void UpdateState(); void UpdateRating(); @@ -466,10 +467,7 @@ PackageRow::PackageRow(const PackageInfoRef& packageRef, // Package icon and title // NOTE: The icon BBitmap is referenced by the fPackage member. - const BBitmap* icon = NULL; - if (package.Icon().Get() != NULL) - icon = package.Icon()->Bitmap(SharedBitmap::SIZE_16); - SetField(new BBitmapStringField(icon, package.Title()), kTitleColumn); + UpdateTitle(); // Rating UpdateRating(); @@ -482,7 +480,6 @@ PackageRow::PackageRow(const PackageInfoRef& packageRef, SetField(new BStringField("0 KiB"), kSizeColumn); // Status - // TODO: Fetch info about installed/deactivated/uninstalled/... SetField(new BStringField(package_state_to_string(fPackage)), kStatusColumn); @@ -498,6 +495,19 @@ PackageRow::~PackageRow() void +PackageRow::UpdateTitle() +{ + if (fPackage.Get() == NULL) + return; + + const BBitmap* icon = NULL; + if (fPackage->Icon().Get() != NULL) + icon = fPackage->Icon()->Bitmap(SharedBitmap::SIZE_16); + SetField(new BBitmapStringField(icon, fPackage->Title()), kTitleColumn); +} + + +void PackageRow::UpdateState() { if (fPackage.Get() == NULL) @@ -670,6 +680,8 @@ PackageListView::MessageReceived(BMessage* message) row->UpdateRating(); if ((changes & PKG_CHANGED_STATE) != 0) row->UpdateState(); + if ((changes & PKG_CHANGED_ICON) != 0) + row->UpdateTitle(); } break; } ############################################################################ Revision: hrev47067 Commit: 5bd5f161e896a560c55776fbbada27b47e0794c8 URL: http://cgit.haiku-os.org/haiku/commit/?id=5bd5f16 Author: Stephan Aßmus <superstippi@xxxxxx> Date: Fri Mar 28 22:46:01 2014 UTC HaikuDepot: Populate package icons from web app. * Transformed ConnectionTest into WebAppInterface * Added methods to Model to trigger the population of all packages with additional information that is needed in the list view. * This launches a thread which tries to retrieve icons for all known packages from depot.haiku-os.org. This is uncached and very slow. I guess it could even be fast enough with a change to the protocol where icons are not retrieved one at a time. ---------------------------------------------------------------------------- diff --git a/src/apps/haikudepot/ConnectionTest.cpp b/src/apps/haikudepot/ConnectionTest.cpp deleted file mode 100644 index 717d326..0000000 --- a/src/apps/haikudepot/ConnectionTest.cpp +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright 2014, Stephan Aßmus <superstippi@xxxxxx>. - * All rights reserved. Distributed under the terms of the MIT License. - */ - -#include "ConnectionTest.h" - -#include <stdio.h> - -#include <mail_encoding.h> - -#include <File.h> -#include <HttpHeaders.h> -#include <HttpRequest.h> -#include <Url.h> -#include <UrlContext.h> -#include <UrlProtocolListener.h> -#include <UrlProtocolRoster.h> - - -class ProtocolListener : public BUrlProtocolListener { -public: - ProtocolListener::ProtocolListener() - : - fDownloadIO(NULL) - { - } - - virtual void ConnectionOpened(BUrlRequest* caller) - { - printf("ConnectionOpened(%p)\n", caller); - } - - virtual void HostnameResolved(BUrlRequest* caller, const char* ip) - { - printf("HostnameResolved(%p): %s\n", caller, ip); - } - - virtual void ResponseStarted(BUrlRequest* caller) - { - printf("ResponseStarted(%p)\n", caller); - } - - virtual void HeadersReceived(BUrlRequest* caller) - { - printf("HeadersReceived(%p)\n", caller); - } - - virtual void DataReceived(BUrlRequest* caller, const char* data, - ssize_t size) - { - printf("DataReceived(%p): %ld bytes\n", caller, size); - - if (fDownloadIO != NULL) - fDownloadIO->Write(data, size); - } - - virtual void DownloadProgress(BUrlRequest* caller, ssize_t bytesReceived, - ssize_t bytesTotal) - { - printf("DownloadProgress(%p): %ld/%ld\n", caller, bytesReceived, - bytesTotal); - } - - virtual void UploadProgress(BUrlRequest* caller, ssize_t bytesSent, - ssize_t bytesTotal) - { - printf("UploadProgress(%p): %ld/%ld\n", caller, bytesSent, bytesTotal); - } - - virtual void RequestCompleted(BUrlRequest* caller, bool success) - { - printf("RequestCompleted(%p): %d\n", caller, success); - } - - virtual void DebugMessage(BUrlRequest* caller, - BUrlProtocolDebugMessage type, const char* text) - { - printf("DebugMessage(%p): %s\n", caller, text); - } - - void SetDownloadIO(BDataIO* downloadIO) - { - fDownloadIO = downloadIO; - } - -private: - BDataIO* fDownloadIO; -}; - - -ConnectionTest::ConnectionTest(const char* username, const char* password) - : - BApplication("application/x-vnd.Haiku-HaikuDepot-ConnectionTest"), - fUsername(username), - fPassword(password) -{ -} - - -ConnectionTest::~ConnectionTest() -{ -} - - -void -ConnectionTest::ReadyToRun() -{ - printf("Connecting...\n"); - - _TestDownloadIcon(); - - PostMessage(B_QUIT_REQUESTED, this); -} - - -void -ConnectionTest::_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); -} - - -void -ConnectionTest::_TestDownloadIcon() -{ - BUrl url("https://depot.haiku-os.org/pkgicon/wonderbrush_x86_gcc2.hvif";); - - BFile file("/boot/home/Desktop/wonderbrush.hvif", - B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE); - - ProtocolListener listener; - listener.SetDownloadIO(&file); - - // Content-Type - BHttpRequest request(url, true, "HTTP", &listener); - request.SetMethod(B_HTTP_GET); - - thread_id thread = request.Run(); - wait_for_thread(thread, NULL); -} - - -int -main(int argc, char* argv[]) -{ - const char* username = ""; - const char* password = ""; - - for (int i = 1; i < argc; i++) { - if (strcmp("-u", argv[i]) == 0 && i < argc - 1) - username = argv[++i]; - else if (strcmp("-p", argv[i]) == 0 && i < argc - 1) - password = argv[++i]; - } - - printf("Using username: %s, password: %s\n", username, password); - - ConnectionTest(username, password).Run(); - return 0; -} - - diff --git a/src/apps/haikudepot/ConnectionTest.h b/src/apps/haikudepot/ConnectionTest.h deleted file mode 100644 index 24c7454..0000000 --- a/src/apps/haikudepot/ConnectionTest.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2014, Stephan Aßmus <superstippi@xxxxxx>. - * All rights reserved. Distributed under the terms of the MIT License. - */ -#ifndef CONNECTION_TEST_H -#define CONNECTION_TEST_H - - -#include <Application.h> -#include <String.h> - - -class ConnectionTest : public BApplication { -public: - ConnectionTest(const char* username, - const char* password); - virtual ~ConnectionTest(); - - virtual void ReadyToRun(); - -private: - void _TestGetPackage(); - void _TestDownloadIcon(); -private: - BString fUsername; - BString fPassword; -}; - - -#endif // CONNECTION_TEST_H diff --git a/src/apps/haikudepot/Jamfile b/src/apps/haikudepot/Jamfile index 9ac8a9d..0c9bbe1 100644 --- a/src/apps/haikudepot/Jamfile +++ b/src/apps/haikudepot/Jamfile @@ -53,6 +53,7 @@ Application HaikuDepot : PackageManager.cpp RatePackageWindow.cpp support.cpp + WebAppInterface.cpp # package_daemon ProblemWindow.cpp @@ -61,7 +62,7 @@ Application HaikuDepot : # text view stuff $(textDocumentSources) - : be package translation libcolumnlistview.a libshared.a + : be package netapi translation libcolumnlistview.a libshared.a $(TARGET_LIBSTDC++) $(TARGET_LIBSUPC++) localestub : HaikuDepot.rdef ; @@ -85,9 +86,3 @@ Application TextDocumentTest : : be translation libshared.a $(TARGET_LIBSUPC++) ; - -Application ConnectionTest : - ConnectionTest.cpp - - : be netapi translation libshared.a $(TARGET_LIBSUPC++) -; diff --git a/src/apps/haikudepot/MainWindow.cpp b/src/apps/haikudepot/MainWindow.cpp index e81df5b..6bc18df 100644 --- a/src/apps/haikudepot/MainWindow.cpp +++ b/src/apps/haikudepot/MainWindow.cpp @@ -580,6 +580,9 @@ MainWindow::_RefreshPackageList() fModel.AddDepot(it->second); } + // start retrieving package icons and average ratings + fModel.PopulateAllPackages(); + // compute the OS package dependencies try { // create the solver diff --git a/src/apps/haikudepot/Model.cpp b/src/apps/haikudepot/Model.cpp index 7360124..1cee127 100644 --- a/src/apps/haikudepot/Model.cpp +++ b/src/apps/haikudepot/Model.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2013, Stephan Aßmus <superstippi@xxxxxx>. + * Copyright 2013-2014, Stephan Aßmus <superstippi@xxxxxx>. * Copyright 2014, Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>. * All rights reserved. Distributed under the terms of the MIT License. */ @@ -12,6 +12,8 @@ #include <Autolock.h> #include <Catalog.h> +#include "WebAppInterface.h" + #undef B_TRANSLATION_CONTEXT #define B_TRANSLATION_CONTEXT "Model" @@ -281,7 +283,10 @@ Model::Model() fSearchTermsFilter(PackageFilterRef(new AnyFilter(), true)), fShowSourcePackages(false), - fShowDevelopPackages(false) + fShowDevelopPackages(false), + + fPopulateAllPackagesThread(-1), + fStopPopulatingAllPackages(false) { // Don't forget to add new categories to this list: fCategories.Add(fCategoryAudio); @@ -327,6 +332,12 @@ Model::Model() } +Model::~Model() +{ + StopPopulatingAllPackages(); +} + + PackageList Model::CreatePackageList() const { @@ -368,6 +379,7 @@ Model::AddDepot(const DepotInfo& depot) void Model::Clear() { + StopPopulatingAllPackages(); fDepots.Clear(); } @@ -520,3 +532,91 @@ Model::PopulatePackage(const PackageInfoRef& package, uint32 flags) } } + + +void +Model::PopulateAllPackages() +{ + StopPopulatingAllPackages(); + + fStopPopulatingAllPackages = false; + + fPopulateAllPackagesThread = spawn_thread(&_PopulateAllPackagesEntry, + "Package populator", B_NORMAL_PRIORITY, this); + if (fPopulateAllPackagesThread >= 0) + resume_thread(fPopulateAllPackagesThread); +} + + +void +Model::StopPopulatingAllPackages() +{ + if (fPopulateAllPackagesThread < 0) + return; + + fStopPopulatingAllPackages = true; + wait_for_thread(fPopulateAllPackagesThread, NULL); + fPopulateAllPackagesThread = -1; +} + + +int32 +Model::_PopulateAllPackagesEntry(void* cookie) +{ + Model* model = static_cast<Model*>(cookie); + model->_PopulateAllPackagesThread(); + return 0; +} + + +void +Model::_PopulateAllPackagesThread() +{ + int32 depotIndex = 0; + int32 packageIndex = 0; + + while (!fStopPopulatingAllPackages) { + // Obtain PackageInfoRef while keeping the depot and package lists + // locked. + PackageInfoRef package; + { + BAutolock locker(&fLock); + + if (depotIndex >= fDepots.CountItems()) + break; + const DepotInfo& depot = fDepots.ItemAt(depotIndex); + + const PackageList& packages = depot.Packages(); + if (packageIndex >= packages.CountItems()) { + // Need the next depot + packageIndex = 0; + depotIndex++; + continue; + } + + package = packages.ItemAt(packageIndex); + packageIndex++; + } + + if (package.Get() == NULL) + continue; + + _PopulatePackageIcon(package); + // TODO: Average user rating. It needs to be shown in the + // list view, so without the user clicking the package. + } +} + + +void +Model::_PopulatePackageIcon(const PackageInfoRef& package) +{ + WebAppInterface interface; + BMallocIO buffer; + + status_t status = interface.RetrievePackageIcon(package->Title(), &buffer); + if (status == B_OK) { + BitmapRef bitmapRef(new(std::nothrow)SharedBitmap(buffer), true); + package->SetIcon(bitmapRef); + } +} diff --git a/src/apps/haikudepot/Model.h b/src/apps/haikudepot/Model.h index 950a444..a03b667 100644 --- a/src/apps/haikudepot/Model.h +++ b/src/apps/haikudepot/Model.h @@ -1,5 +1,5 @@ /* - * Copyright 2013, Stephan Aßmus <superstippi@xxxxxx>. + * Copyright 2013-2014, Stephan Aßmus <superstippi@xxxxxx>. * All rights reserved. Distributed under the terms of the MIT License. */ #ifndef MODEL_H @@ -24,6 +24,7 @@ typedef BReference<PackageFilter> PackageFilterRef; class Model { public: Model(); + virtual ~Model(); BLocker* Lock() { return &fLock; } @@ -85,6 +86,15 @@ public: void PopulatePackage(const PackageInfoRef& package, uint32 flags); + void PopulateAllPackages(); + void StopPopulatingAllPackages(); + +private: + static int32 _PopulateAllPackagesEntry(void* cookie); + void _PopulateAllPackagesThread(); + + void _PopulatePackageIcon( + const PackageInfoRef& package); private: BLocker fLock; @@ -117,6 +127,9 @@ private: bool fShowSourcePackages; bool fShowDevelopPackages; + + thread_id fPopulateAllPackagesThread; + volatile bool fStopPopulatingAllPackages; }; diff --git a/src/apps/haikudepot/WebAppInterface.cpp b/src/apps/haikudepot/WebAppInterface.cpp new file mode 100644 index 0000000..bf05e11 --- /dev/null +++ b/src/apps/haikudepot/WebAppInterface.cpp @@ -0,0 +1,196 @@ +/* + * Copyright 2014, Stephan Aßmus <superstippi@xxxxxx>. + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#include "WebAppInterface.h" + +#include <stdio.h> + +#include <File.h> +#include <HttpHeaders.h> +#include <HttpRequest.h> +#include <Url.h> +#include <UrlContext.h> +#include <UrlProtocolListener.h> +#include <UrlProtocolRoster.h> + +#include "PackageInfo.h" + + +class ProtocolListener : public BUrlProtocolListener { +public: + ProtocolListener::ProtocolListener() + : + fDownloadIO(NULL) + { + } + + virtual void ConnectionOpened(BUrlRequest* caller) + { +// printf("ConnectionOpened(%p)\n", caller); + } + + virtual void HostnameResolved(BUrlRequest* caller, const char* ip) + { +// printf("HostnameResolved(%p): %s\n", caller, ip); + } + + virtual void ResponseStarted(BUrlRequest* caller) + { +// printf("ResponseStarted(%p)\n", caller); + } + + virtual void HeadersReceived(BUrlRequest* caller) + { +// printf("HeadersReceived(%p)\n", caller); + } + + virtual void DataReceived(BUrlRequest* caller, const char* data, + ssize_t size) + { +// printf("DataReceived(%p): %ld bytes\n", caller, size); + + if (fDownloadIO != NULL) + fDownloadIO->Write(data, size); + } + + virtual void DownloadProgress(BUrlRequest* caller, ssize_t bytesReceived, + ssize_t bytesTotal) + { +// printf("DownloadProgress(%p): %ld/%ld\n", caller, bytesReceived, +// bytesTotal); + } + + virtual void UploadProgress(BUrlRequest* caller, ssize_t bytesSent, + ssize_t bytesTotal) + { +// printf("UploadProgress(%p): %ld/%ld\n", caller, bytesSent, bytesTotal); + } + + virtual void RequestCompleted(BUrlRequest* caller, bool success) + { +// printf("RequestCompleted(%p): %d\n", caller, success); + } + + virtual void DebugMessage(BUrlRequest* caller, + BUrlProtocolDebugMessage type, const char* text) + { +// printf("DebugMessage(%p): %s\n", caller, text); + } + + void SetDownloadIO(BDataIO* downloadIO) + { + fDownloadIO = downloadIO; + } + +private: + BDataIO* fDownloadIO; +}; + + +WebAppInterface::WebAppInterface() +{ +} + + +WebAppInterface::~WebAppInterface() +{ +} + + +void +WebAppInterface::SetAuthorization(const BString& username, + const BString& password) +{ + fUsername = username; + fPassword = password; +} + + +//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::RetrievePackageIcon(const BString& packageName, + BDataIO* stream) +{ + BString urlString = "https://depot.haiku-os.org/pkgicon/";; + urlString << packageName << ".hvif"; + + BUrl url(urlString); + + ProtocolListener listener; + listener.SetDownloadIO(stream); + + BHttpRequest request(url, true, "HTTP", &listener); + request.SetMethod(B_HTTP_GET); + + 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; + + return B_ERROR; +} diff --git a/src/apps/haikudepot/WebAppInterface.h b/src/apps/haikudepot/WebAppInterface.h new file mode 100644 index 0000000..5635f47 --- /dev/null +++ b/src/apps/haikudepot/WebAppInterface.h @@ -0,0 +1,34 @@ +/* + * Copyright 2014, Stephan Aßmus <superstippi@xxxxxx>. + * All rights reserved. Distributed under the terms of the MIT License. + */ +#ifndef WEB_APP_INTERFACE_H +#define WEB_APP_INTERFACE_H + + +#include <Application.h> +#include <String.h> + + +class BDataIO; + + +class WebAppInterface { +public: + WebAppInterface(); + virtual ~WebAppInterface(); + + void SetAuthorization(const BString& username, + const BString& password); + + status_t RetrievePackageIcon( + const BString& packageName, + BDataIO* stream); + +private: + BString fUsername; + BString fPassword; +}; + + +#endif // WEB_APP_INTERFACE_H