diff --git a/src/apps/haikudepot/Jamfile b/src/apps/haikudepot/Jamfile index 182dc0e92d..885d3f9e19 100644 --- a/src/apps/haikudepot/Jamfile +++ b/src/apps/haikudepot/Jamfile @@ -4,7 +4,7 @@ UsePrivateHeaders interface shared storage package support net ; # source directories local sourceDirs = - edits_generic model textview ui ui_generic server tar util + edits_generic model textview ui ui_generic server server/dumpexportrepository tar util ; local sourceDir ; @@ -74,10 +74,16 @@ Application HaikuDepot : SharedBitmap.cpp UserLoginWindow.cpp + # network + server - model + DumpExportRepository.cpp + DumpExportRepositorySource.cpp + DumpExportRepositoryJsonListener.cpp + # network + server AbstractServerProcess.cpp ServerSettings.cpp WebAppInterface.cpp + RepositoryDataUpdateProcess.cpp ServerIconExportUpdateProcess.cpp StandardMetaDataJsonEventListener.cpp StandardMetaData.cpp diff --git a/src/apps/haikudepot/model/Model.cpp b/src/apps/haikudepot/model/Model.cpp index 5845a7f3e4..7d67e6fb02 100644 --- a/src/apps/haikudepot/model/Model.cpp +++ b/src/apps/haikudepot/model/Model.cpp @@ -6,6 +6,7 @@ */ #include "Model.h" +#include "RepositoryDataUpdateProcess.h" #include "StorageUtils.h" #include @@ -834,59 +835,47 @@ Model::SetAuthorization(const BString& username, const BString& password, // #pragma mark - private +/*! When bulk repository data comes down from the server, it will + arrive as a json.gz payload. This is stored locally as a cache + and this method will provide the on-disk storage location for + this file. +*/ -void -Model::PopulateWebAppRepositoryCode(DepotInfo& depotInfo) +status_t +Model::_DumpExportRepositoryDataPath(BPath& path) const { - if (depotInfo.BaseURL().Length() > 0) { + BPath repoDataPath; - BMessage repositoriesEnvelope; - BMessage result; - double total; - StringList repositorySourceBaseURLs; - - repositorySourceBaseURLs.Add(depotInfo.BaseURL()); - - // TODO; better API call handling around errors. - - if (fWebAppInterface.RetrieveRepositoriesForSourceBaseURLs( - repositorySourceBaseURLs, repositoriesEnvelope) == B_OK - && repositoriesEnvelope.FindMessage("result", &result) == B_OK - && result.FindDouble("total", &total) == B_OK) { - - if ((int64)total > 0) { - BMessage repositories; - BMessage repository; - BString repositoryCode; - - if (result.FindMessage("items", &repositories) == B_OK - && repositories.FindMessage("0", &repository) == B_OK - && repository.FindString("code", &repositoryCode) == B_OK) { - - depotInfo.SetWebAppRepositoryCode(repositoryCode); - - printf("did assign web app repository code '%s' to local " - "depot '%s'\n", - depotInfo.WebAppRepositoryCode().String(), - depotInfo.Name().String()); - } else { - printf("unable to find the 'code' in the api response for " - "local depot '%s'\n", - depotInfo.Name().String()); - } - } else { - printf("unable to find a repository code for '%s'\n", - depotInfo.BaseURL().String()); - } - } else { - printf("unexpected result obtaining repository code for '%s'\n", - depotInfo.BaseURL().String()); - } - } else { - printf("missing base url for depot info %s --> will not obtain web app " - "repository code\n", - depotInfo.Name().String()); + if (find_directory(B_USER_CACHE_DIRECTORY, &repoDataPath) == B_OK + && repoDataPath.Append("HaikuDepot") == B_OK + && create_directory(repoDataPath.Path(), 0777) == B_OK + && repoDataPath.Append("repository-all_en.json.gz") == B_OK) { + path.SetTo(repoDataPath.Path()); + return B_OK; } + + path.Unset(); + fprintf(stdout, "unable to find the user cache file for repositories'" + " data"); + return B_ERROR; +} + + +status_t +Model::PopulateWebAppRepositoryCodes() +{ + status_t result = B_OK; + BPath dataPath; + + result = _DumpExportRepositoryDataPath(dataPath); + + if (result != B_OK) + return result; + + RepositoryDataUpdateProcess process(dataPath, &fDepots); + result = process.Run(); + + return result; } diff --git a/src/apps/haikudepot/model/Model.h b/src/apps/haikudepot/model/Model.h index a7d6459f7f..ba73bfcf2d 100644 --- a/src/apps/haikudepot/model/Model.h +++ b/src/apps/haikudepot/model/Model.h @@ -118,8 +118,7 @@ public: bool ShowDevelopPackages() const { return fShowDevelopPackages; } - void PopulateWebAppRepositoryCode( - DepotInfo& depotInfo); + status_t PopulateWebAppRepositoryCodes(); // Retrieve package information static const uint32 POPULATE_CACHED_RATING = 1 << 0; @@ -152,6 +151,8 @@ public: private: + status_t _DumpExportRepositoryDataPath( + BPath& path) const; void _UpdateIsFeaturedFilter(); static int32 _PopulateAllPackagesEntry(void* cookie); diff --git a/src/apps/haikudepot/server/AbstractServerProcess.cpp b/src/apps/haikudepot/server/AbstractServerProcess.cpp index 2fb761f3f5..96185099cc 100644 --- a/src/apps/haikudepot/server/AbstractServerProcess.cpp +++ b/src/apps/haikudepot/server/AbstractServerProcess.cpp @@ -4,9 +4,240 @@ */ #include "AbstractServerProcess.h" +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "ServerSettings.h" +#include "StandardMetaDataJsonEventListener.h" +#include "ToFileUrlProtocolListener.h" + + +#define MAX_REDIRECTS 3 +#define MAX_FAILURES 2 + +#define HTTP_STATUS_FOUND 302 +#define HTTP_STATUS_NOT_MODIFIED 304 + +// 30 seconds +#define TIMEOUT_MICROSECONDS 3e+7 + status_t -AbstractServerProcess::Run() +AbstractServerProcess::IfModifiedSinceHeaderValue(BString& headerValue) const { + BPath metaDataPath; + BString jsonPath; + + GetStandardMetaDataPath(metaDataPath); + GetStandardMetaDataJsonPath(jsonPath); + + return IfModifiedSinceHeaderValue(headerValue, metaDataPath, jsonPath); +} + + +status_t +AbstractServerProcess::IfModifiedSinceHeaderValue(BString& headerValue, + const BPath& metaDataPath, const BString& jsonPath) const +{ + headerValue.SetTo(""); + struct stat s; + + if (-1 == stat(metaDataPath.Path(), &s)) { + if (ENOENT != errno) + return B_ERROR; + + return B_FILE_NOT_FOUND; + } + + if (s.st_size == 0) + return B_BAD_VALUE; + + StandardMetaData metaData; + status_t result = PopulateMetaData(metaData, metaDataPath, jsonPath); + + if (result == B_OK) { + + // An example of this output would be; 'Fri, 24 Oct 2014 19:32:27 +0000' + + BDateTime modifiedDateTime = metaData + .GetDataModifiedTimestampAsDateTime(); + BPrivate::BHttpTime modifiedHttpTime(modifiedDateTime); + headerValue.SetTo(modifiedHttpTime + .ToString(BPrivate::B_HTTP_TIME_FORMAT_COOKIE)); + } else { + fprintf(stderr, "unable to parse the meta-data date and time -" + " cannot set the 'If-Modified-Since' header\n"); + } + + return result; +} + + +status_t +AbstractServerProcess::PopulateMetaData( + StandardMetaData& metaData, const BPath& path, + const BString& jsonPath) const +{ + StandardMetaDataJsonEventListener listener(jsonPath, metaData); + status_t result = ParseJsonFromFileWithListener(&listener, path); + + if (result != B_OK) + return result; + + result = listener.ErrorStatus(); + + if (result != B_OK) + return result; + + if (!metaData.IsPopulated()) { + fprintf(stderr, "the meta data was read from [%s], but no values " + "were extracted\n", path.Path()); + return B_BAD_DATA; + } + return B_OK; } + + +bool +AbstractServerProcess::LooksLikeGzip(const char *pathStr) const +{ + int l = strlen(pathStr); + return l > 4 && 0 == strncmp(&pathStr[l - 3], ".gz", 3); +} + + +/*! Note that a B_OK return code from this method may not indicate that the + listening process went well. One has to see if there was an error in + the listener. +*/ + +status_t +AbstractServerProcess::ParseJsonFromFileWithListener( + BJsonEventListener *listener, + const BPath& path) const +{ + const char* pathStr = path.Path(); + FILE* file = fopen(pathStr, "rb"); + + if (file == NULL) { + fprintf(stderr, "unable to find the meta data file at [%s]\n", + path.Path()); + return B_FILE_NOT_FOUND; + } + + BFileIO rawInput(file, true); // takes ownership + + // if the file extension ends with '.gz' then the data will be + // compressed and the algorithm needs to decompress the data as + // it is parsed. + + if (LooksLikeGzip(pathStr)) { + BDataIO* gzDecompressedInput = NULL; + BZlibDecompressionParameters* zlibDecompressionParameters + = new BZlibDecompressionParameters(); + + status_t result = BZlibCompressionAlgorithm() + .CreateDecompressingInputStream(&rawInput, + zlibDecompressionParameters, gzDecompressedInput); + + if (B_OK != result) + return result; + + ObjectDeleter gzDecompressedInputDeleter(gzDecompressedInput); + BPrivate::BJson::Parse(gzDecompressedInput, listener); + } else { + BPrivate::BJson::Parse(&rawInput, listener); + } + + return B_OK; +} + + +status_t +AbstractServerProcess::DownloadToLocalFile(const BPath& targetFilePath, + const BUrl& url, uint32 redirects, uint32 failures) +{ + if (redirects > MAX_REDIRECTS) { + fprintf(stdout, "exceeded %d redirects --> failure\n", MAX_REDIRECTS); + return B_IO_ERROR; + } + + if (failures > MAX_FAILURES) { + fprintf(stdout, "exceeded %d failures\n", MAX_FAILURES); + return B_IO_ERROR; + } + + fprintf(stdout, "will stream '%s' to [%s]\n", url.UrlString().String(), + targetFilePath.Path()); + + ToFileUrlProtocolListener listener(targetFilePath, LoggingName(), + ServerSettings::UrlConnectionTraceLoggingEnabled()); + + BHttpHeaders headers; + ServerSettings::AugmentHeaders(headers); + + BString ifModifiedSinceHeader; + status_t ifModifiedSinceHeaderStatus = IfModifiedSinceHeaderValue( + ifModifiedSinceHeader); + + if (ifModifiedSinceHeaderStatus == B_OK && + ifModifiedSinceHeader.Length() > 0) { + headers.AddHeader("If-Modified-Since", ifModifiedSinceHeader); + } + + BHttpRequest *request = dynamic_cast( + BUrlProtocolRoster::MakeRequest(url, &listener)); + ObjectDeleter requestDeleter(request); + request->SetHeaders(headers); + request->SetMaxRedirections(0); + request->SetTimeout(TIMEOUT_MICROSECONDS); + + thread_id thread = request->Run(); + wait_for_thread(thread, NULL); + + const BHttpResult& result = dynamic_cast( + request->Result()); + + int32 statusCode = result.StatusCode(); + + if (BHttpRequest::IsSuccessStatusCode(statusCode)) { + fprintf(stdout, "did complete streaming data\n"); + return B_OK; + } else if (statusCode == HTTP_STATUS_NOT_MODIFIED) { + fprintf(stdout, "remote data has not changed since [%s]\n", + ifModifiedSinceHeader.String()); + return APP_ERR_NOT_MODIFIED; + } else if (BHttpRequest::IsRedirectionStatusCode(statusCode)) { + const BHttpHeaders responseHeaders = result.Headers(); + const char *locationValue = responseHeaders["Location"]; + + if (locationValue != NULL && strlen(locationValue) != 0) { + BUrl location(result.Url(), locationValue); + fprintf(stdout, "will redirect to; %s\n", + location.UrlString().String()); + return DownloadToLocalFile(targetFilePath, location, redirects + 1, 0); + } + + fprintf(stdout, "unable to find 'Location' header for redirect\n"); + return B_IO_ERROR; + } else { + if (statusCode == 0 || (statusCode / 100) == 5) { + fprintf(stdout, "error response from server; %" B_PRId32 " --> " + "retry...\n", statusCode); + return DownloadToLocalFile(targetFilePath, url, redirects, failures + 1); + } + + fprintf(stdout, "unexpected response from server; %" B_PRId32 "\n", + statusCode); + return B_IO_ERROR; + } +} \ No newline at end of file diff --git a/src/apps/haikudepot/server/AbstractServerProcess.h b/src/apps/haikudepot/server/AbstractServerProcess.h index 8264742f98..f6679a38c0 100644 --- a/src/apps/haikudepot/server/AbstractServerProcess.h +++ b/src/apps/haikudepot/server/AbstractServerProcess.h @@ -6,11 +6,51 @@ #ifndef ABSTRACT_SERVER_PROCESS_H #define ABSTRACT_SERVER_PROCESS_H +#include #include +#include + +#include "StandardMetaData.h" + + +#define APP_ERR_NOT_MODIFIED (B_APP_ERROR_BASE + 452) + class AbstractServerProcess { public: - status_t Run(); + virtual status_t Run() = 0; + +protected: + virtual void GetStandardMetaDataPath( + BPath& path) const = 0; + virtual void GetStandardMetaDataJsonPath( + BString& jsonPath) const = 0; + virtual const char* LoggingName() const = 0; + + status_t IfModifiedSinceHeaderValue( + BString& headerValue) const; + status_t IfModifiedSinceHeaderValue( + BString& headerValue, + const BPath& metaDataPath, + const BString& jsonPath) const; + + status_t PopulateMetaData( + StandardMetaData& metaData, + const BPath& path, + const BString& jsonPath) const; + + status_t ParseJsonFromFileWithListener( + BJsonEventListener *listener, + const BPath& path) const; + + status_t DownloadToLocalFile( + const BPath& targetFilePath, + const BUrl& url, + uint32 redirects, uint32 failures); + +private: + bool LooksLikeGzip(const char *pathStr) const; + }; #endif // ABSTRACT_SERVER_PROCESS_H diff --git a/src/apps/haikudepot/server/RepositoryDataUpdateProcess.cpp b/src/apps/haikudepot/server/RepositoryDataUpdateProcess.cpp index 826433335f..be41a54d15 100644 --- a/src/apps/haikudepot/server/RepositoryDataUpdateProcess.cpp +++ b/src/apps/haikudepot/server/RepositoryDataUpdateProcess.cpp @@ -177,7 +177,7 @@ RepositoryDataUpdateProcess::Run() // TODO: add language ISO code to the path; just 'en' for now. status_t result = DownloadToLocalFile(fLocalFilePath, - ServerSettings::CreateFullUrl("/__repository/all_en.json.gz"), + ServerSettings::CreateFullUrl("/__repository/all-en.json.gz"), 0, 0); if (result == B_OK) { diff --git a/src/apps/haikudepot/server/ServerIconExportUpdateProcess.cpp b/src/apps/haikudepot/server/ServerIconExportUpdateProcess.cpp index 6466b3e04e..d2444a3f40 100644 --- a/src/apps/haikudepot/server/ServerIconExportUpdateProcess.cpp +++ b/src/apps/haikudepot/server/ServerIconExportUpdateProcess.cpp @@ -5,38 +5,16 @@ #include "ServerIconExportUpdateProcess.h" -#include #include #include #include -#include #include -#include -#include -#include -#include -#include #include #include "ServerSettings.h" -#include "StandardMetaDataJsonEventListener.h" #include "StorageUtils.h" #include "TarArchiveService.h" -#include "ToFileUrlProtocolListener.h" - - -#define MAX_REDIRECTS 3 -#define MAX_FAILURES 2 - -#define HTTP_STATUS_OK 200 -#define HTTP_STATUS_FOUND 302 -#define HTTP_STATUS_NOT_MODIFIED 304 - -#define APP_ERR_NOT_MODIFIED (B_APP_ERROR_BASE + 452) - -// 30 seconds -#define TIMEOUT_MICROSECONDS 3e+7 /*! This constructor will locate the cached data in a standardized location */ @@ -48,6 +26,11 @@ ServerIconExportUpdateProcess::ServerIconExportUpdateProcess( } +ServerIconExportUpdateProcess::~ServerIconExportUpdateProcess() +{ +} + + status_t ServerIconExportUpdateProcess::Run() { @@ -56,7 +39,7 @@ ServerIconExportUpdateProcess::Run() fprintf(stdout, "will start fetching icons\n"); - result = _Download(tarGzFilePath); + result = Download(tarGzFilePath); if (result != APP_ERR_NOT_MODIFIED) { if (result != B_OK) @@ -96,168 +79,33 @@ ServerIconExportUpdateProcess::Run() } -status_t -ServerIconExportUpdateProcess::_IfModifiedSinceHeaderValue(BString& headerValue, - BPath& iconMetaDataPath) const +void +ServerIconExportUpdateProcess::GetStandardMetaDataPath(BPath& path) const { - headerValue.SetTo(""); - struct stat s; - - if (-1 == stat(iconMetaDataPath.Path(), &s)) { - if (ENOENT != errno) - return B_ERROR; - - return B_FILE_NOT_FOUND; - } - - StandardMetaData iconMetaData; - status_t result = _PopulateIconMetaData(iconMetaData, iconMetaDataPath); - - if (result == B_OK) { - - // An example of this output would be; 'Fri, 24 Oct 2014 19:32:27 +0000' - - BDateTime modifiedDateTime = iconMetaData - .GetDataModifiedTimestampAsDateTime(); - BPrivate::BHttpTime modifiedHttpTime(modifiedDateTime); - headerValue.SetTo(modifiedHttpTime - .ToString(BPrivate::B_HTTP_TIME_FORMAT_COOKIE)); - } else { - fprintf(stderr, "unable to parse the icon meta-data date and time -" - " cannot set the 'If-Modified-Since' header\n"); - } - - return result; + path.SetTo(fLocalStorageDirectoryPath.Path()); + path.Append("hicn/info.json"); } -status_t -ServerIconExportUpdateProcess::_IfModifiedSinceHeaderValue(BString& headerValue) - const +void +ServerIconExportUpdateProcess::GetStandardMetaDataJsonPath( + BString& jsonPath) const { - BPath iconMetaDataPath(fLocalStorageDirectoryPath); - iconMetaDataPath.Append("hicn/info.json"); - return _IfModifiedSinceHeaderValue(headerValue, iconMetaDataPath); -} - - -status_t -ServerIconExportUpdateProcess::_Download(BPath& tarGzFilePath) -{ - return _Download(tarGzFilePath, - ServerSettings::CreateFullUrl("/__pkgicon/all.tar.gz"), 0, 0); -} - - -status_t -ServerIconExportUpdateProcess::_Download(BPath& tarGzFilePath, const BUrl& url, - uint32 redirects, uint32 failures) -{ - if (redirects > MAX_REDIRECTS) { - fprintf(stdout, "exceeded %d redirects --> failure\n", MAX_REDIRECTS); - return B_IO_ERROR; - } - - if (failures > MAX_FAILURES) { - fprintf(stdout, "exceeded %d failures\n", MAX_FAILURES); - return B_IO_ERROR; - } - - fprintf(stdout, "will stream '%s' to [%s]\n", url.UrlString().String(), - tarGzFilePath.Path()); - - ToFileUrlProtocolListener listener(tarGzFilePath, "icon-export", - ServerSettings::UrlConnectionTraceLoggingEnabled()); - - BHttpHeaders headers; - ServerSettings::AugmentHeaders(headers); - - BString ifModifiedSinceHeader; - status_t ifModifiedSinceHeaderStatus = _IfModifiedSinceHeaderValue( - ifModifiedSinceHeader); - - if (ifModifiedSinceHeaderStatus == B_OK && - ifModifiedSinceHeader.Length() > 0) { - headers.AddHeader("If-Modified-Since", ifModifiedSinceHeader); - } - - BHttpRequest *request = dynamic_cast( - BUrlProtocolRoster::MakeRequest(url, &listener)); - ObjectDeleter requestDeleter(request); - request->SetHeaders(headers); - request->SetMaxRedirections(0); - request->SetTimeout(TIMEOUT_MICROSECONDS); - - thread_id thread = request->Run(); - wait_for_thread(thread, NULL); - - const BHttpResult& result = dynamic_cast( - request->Result()); - - int32 statusCode = result.StatusCode(); - - if (BHttpRequest::IsSuccessStatusCode(statusCode)) { - fprintf(stdout, "did complete streaming data\n"); - return B_OK; - } else if (statusCode == HTTP_STATUS_NOT_MODIFIED) { - fprintf(stdout, "remote data has not changed since [%s]\n", - ifModifiedSinceHeader.String()); - return APP_ERR_NOT_MODIFIED; - } else if (BHttpRequest::IsRedirectionStatusCode(statusCode)) { - const BHttpHeaders responseHeaders = result.Headers(); - const char *locationValue = responseHeaders["Location"]; - - if (locationValue != NULL && strlen(locationValue) != 0) { - BUrl location(result.Url(), locationValue); - fprintf(stdout, "will redirect to; %s\n", - location.UrlString().String()); - return _Download(tarGzFilePath, location, redirects + 1, 0); - } - - fprintf(stdout, "unable to find 'Location' header for redirect\n"); - return B_IO_ERROR; - } else { - if (statusCode == 0 || (statusCode / 100) == 5) { - fprintf(stdout, "error response from server; %" B_PRId32 " --> " - "retry...\n", statusCode); - return _Download(tarGzFilePath, url, redirects, failures + 1); - } - - fprintf(stdout, "unexpected response from server; %" B_PRId32 "\n", - statusCode); - return B_IO_ERROR; - } -} - - -status_t -ServerIconExportUpdateProcess::_PopulateIconMetaData( - StandardMetaData& iconMetaData, BPath& path) const -{ - FILE *file = fopen(path.Path(), "rb"); - - if (file == NULL) { - fprintf(stderr, "unable to find the icon meta data file at [%s]\n", - path.Path()); - return B_FILE_NOT_FOUND; - } - - BFileIO iconMetaDataFile(file, true); // takes ownership // the "$" here indicates that the data is at the top level. - StandardMetaDataJsonEventListener listener("$", iconMetaData); - BPrivate::BJson::Parse(&iconMetaDataFile, &listener); - - status_t result = listener.ErrorStatus(); - - if (result != B_OK) - return result; - - if (!iconMetaData.IsPopulated()) { - fprintf(stderr, "the icon meta data was read from [%s], but no values " - "were extracted\n", path.Path()); - return B_BAD_DATA; - } - - return B_OK; + jsonPath.SetTo("$"); } + +const char* +ServerIconExportUpdateProcess::LoggingName() const +{ + return "icon-export-update"; +} + + +status_t +ServerIconExportUpdateProcess::Download(BPath& tarGzFilePath) +{ + return DownloadToLocalFile(tarGzFilePath, + ServerSettings::CreateFullUrl("/__pkgicon/all.tar.gz"), 0, 0); +} \ No newline at end of file diff --git a/src/apps/haikudepot/server/ServerIconExportUpdateProcess.h b/src/apps/haikudepot/server/ServerIconExportUpdateProcess.h index 9bcc67cff7..f91c806801 100644 --- a/src/apps/haikudepot/server/ServerIconExportUpdateProcess.h +++ b/src/apps/haikudepot/server/ServerIconExportUpdateProcess.h @@ -3,8 +3,8 @@ * All rights reserved. Distributed under the terms of the MIT License. */ -#ifndef SERVER_ICON_PROCESS_H -#define SERVER_ICON_PROCESS_H +#ifndef SERVER_ICON_EXPORT_UPDATE_PROCESS_H +#define SERVER_ICON_EXPORT_UPDATE_PROCESS_H #include "AbstractServerProcess.h" @@ -14,35 +14,28 @@ #include #include -#include "StandardMetaData.h" - class ServerIconExportUpdateProcess : public AbstractServerProcess { public: ServerIconExportUpdateProcess( const BPath& localStorageDirectoryPath); + virtual ~ServerIconExportUpdateProcess(); status_t Run(); +protected: + void GetStandardMetaDataPath(BPath& path) const; + void GetStandardMetaDataJsonPath( + BString& jsonPath) const; + const char* LoggingName() const; + + private: - status_t _Download(BPath& tarGzFilePath); - status_t _Download(BPath& tarGzFilePath, const BUrl& url, - uint32 redirects, uint32 failures); - BString _FormFullUrl(const BString& suffix) const; - status_t _IfModifiedSinceHeaderValue( - BString& headerValue) const; - status_t _IfModifiedSinceHeaderValue( - BString& headerValue, - BPath& iconMetaDataPath) const; + status_t Download(BPath& tarGzFilePath); - status_t _PopulateIconMetaData( - StandardMetaData& iconMetaData, BPath& path) - const; - - BString fBaseUrl; BPath fLocalStorageDirectoryPath; }; -#endif // SERVER_ICON_PROCESS_H +#endif // SERVER_ICON_EXPORT_UPDATE_PROCESS_H diff --git a/src/apps/haikudepot/ui/MainWindow.cpp b/src/apps/haikudepot/ui/MainWindow.cpp index f24fe38c00..f92a136f5c 100644 --- a/src/apps/haikudepot/ui/MainWindow.cpp +++ b/src/apps/haikudepot/ui/MainWindow.cpp @@ -851,12 +851,6 @@ MainWindow::_RefreshPackageList(bool force) if (getRepositoryConfigStatus == B_OK) { depotInfo.SetBaseURL(repoConfig.BaseURL()); - - // it would be nice if this could be more logically located such as - // when the repository is added to the model, but that is probably - // a bigger change. - - fModel.PopulateWebAppRepositoryCode(depotInfo); } else { printf("unable to obtain the repository config for local " "repository '%s'; %s\n", @@ -1000,6 +994,8 @@ MainWindow::_RefreshPackageList(bool force) fModel.AddDepot(it->second); } + fModel.PopulateWebAppRepositoryCodes(); + // start retrieving package icons and average ratings if (force || wasEmpty) fModel.PopulateAllPackages(); diff --git a/src/tests/apps/haikudepot/HaikuDepotTestAddon.cpp b/src/tests/apps/haikudepot/HaikuDepotTestAddon.cpp index f996a93a58..c2af027417 100644 --- a/src/tests/apps/haikudepot/HaikuDepotTestAddon.cpp +++ b/src/tests/apps/haikudepot/HaikuDepotTestAddon.cpp @@ -7,7 +7,7 @@ #include #include "StandardMetaDataJsonEventListenerTest.h" - +#include "DumpExportRepositoryJsonListenerTest.h" BTestSuite* getTestSuite() @@ -15,6 +15,7 @@ getTestSuite() BTestSuite* suite = new BTestSuite("HaikuDepot"); StandardMetaDataJsonEventListenerTest::AddTests(*suite); + DumpExportRepositoryJsonListenerTest::AddTests(*suite); return suite; } diff --git a/src/tests/apps/haikudepot/Jamfile b/src/tests/apps/haikudepot/Jamfile index b621a12dfa..a8cbe67ec9 100644 --- a/src/tests/apps/haikudepot/Jamfile +++ b/src/tests/apps/haikudepot/Jamfile @@ -3,13 +3,20 @@ SubDir HAIKU_TOP src tests apps haikudepot ; SetSubDirSupportedPlatformsBeOSCompatible ; AddSubDirSupportedPlatforms libbe_test ; +SubDirHdrs [ FDirName $(HAIKU_TOP) src apps haikudepot ] ; SubDirHdrs [ FDirName $(HAIKU_TOP) src apps haikudepot server ] ; +SubDirHdrs [ FDirName $(HAIKU_TOP) src apps haikudepot server dumpexportrepository ] ; UsePrivateHeaders shared ; UnitTestLib haikudepottest.so : HaikuDepotTestAddon.cpp + DumpExportRepositorySource.cpp + DumpExportRepository.cpp + DumpExportRepositoryJsonListener.cpp + DumpExportRepositoryJsonListenerTest.cpp + StandardMetaData.cpp StandardMetaDataJsonEventListener.cpp StandardMetaDataJsonEventListenerTest.cpp @@ -18,4 +25,7 @@ UnitTestLib haikudepottest.so : ; SEARCH on [ FGristFiles StandardMetaData.cpp StandardMetaDataJsonEventListener.cpp ] - = [ FDirName $(HAIKU_TOP) src apps haikudepot server ] ; \ No newline at end of file + = [ FDirName $(HAIKU_TOP) src apps haikudepot server ] ; + +SEARCH on [ FGristFiles DumpExportRepositorySource.cpp DumpExportRepository.cpp DumpExportRepositoryJsonListener.cpp ] + = [ FDirName $(HAIKU_TOP) src apps haikudepot server dumpexportrepository ] ; \ No newline at end of file