HaikuDepot: Handling for communications with application server over multiple repositories

This change allows for the HaikuDepot desktop application to query the server application
over HTTP for data regarding packages across the various repositories that the have been
configured on the desktop environment.  Previously it was 'hard-coded' to only
communicate about the HaikuPorts repository.
This commit is contained in:
Andrew Lindesay
2016-10-20 23:03:10 +13:00
parent 4da6cf8403
commit ebb1a01c48
8 changed files with 379 additions and 153 deletions
+176 -81
View File
@@ -1,6 +1,7 @@
/* /*
* Copyright 2013-2014, Stephan Aßmus <[email protected]>. * Copyright 2013-2014, Stephan Aßmus <[email protected]>.
* Copyright 2014, Axel Dörfler <[email protected]>. * Copyright 2014, Axel Dörfler <[email protected]>.
* Copyright 2016, Andrew Lindesay <[email protected]>.
* All rights reserved. Distributed under the terms of the MIT License. * All rights reserved. Distributed under the terms of the MIT License.
*/ */
@@ -463,12 +464,19 @@ Model::AddDepot(const DepotInfo& depot)
bool bool
Model::HasDepot(const BString& name) const Model::HasDepot(const BString& name) const
{
return NULL != DepotForName(name);
}
const DepotInfo*
Model::DepotForName(const BString& name) const
{ {
for (int32 i = fDepots.CountItems() - 1; i >= 0; i--) { for (int32 i = fDepots.CountItems() - 1; i >= 0; i--) {
if (fDepots.ItemAtFast(i).Name() == name) if (fDepots.ItemAtFast(i).Name() == name)
return true; return &fDepots.ItemAtFast(i);
} }
return false; return NULL;
} }
@@ -826,6 +834,59 @@ Model::SetAuthorization(const BString& username, const BString& password,
// #pragma mark - private // #pragma mark - private
void
Model::PopulateWebAppRepositoryCode(DepotInfo& depotInfo)
{
if (depotInfo.BaseURL().Length() > 0) {
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());
}
}
void void
Model::_UpdateIsFeaturedFilter() Model::_UpdateIsFeaturedFilter()
{ {
@@ -987,83 +1048,101 @@ Model::_PopulatePackageInfos(PackageList& packages, bool fromCacheOnly,
StringList packageNames; StringList packageNames;
StringList packageArchitectures; StringList packageArchitectures;
StringList repositoryCodes;
for (int i = 0; i < packages.CountItems(); i++) { for (int i = 0; i < packages.CountItems(); i++) {
const PackageInfoRef& package = packages.ItemAtFast(i); const PackageInfoRef& package = packages.ItemAtFast(i);
packageNames.Add(package->Name()); packageNames.Add(package->Name());
packageArchitectures.Add(package->Architecture());
}
status_t status = fWebAppInterface.RetrieveBulkPackageInfo(packageNames, if (!packageArchitectures.Contains(package->Architecture()))
packageArchitectures, info); packageArchitectures.Add(package->Architecture());
if (status == B_OK) {
// Parse message
// info.PrintToStream();
BMessage result;
BMessage pkgs;
if (info.FindMessage("result", &result) == B_OK
&& result.FindMessage("pkgs", &pkgs) == B_OK) {
int32 index = 0;
while (true) {
if (fStopPopulatingAllPackages)
return;
BString name;
name << index++;
BMessage pkgInfo;
if (pkgs.FindMessage(name, &pkgInfo) != B_OK)
break;
BString pkgName; const DepotInfo *depot = DepotForName(package->DepotName());
if (pkgInfo.FindString("name", &pkgName) != B_OK)
continue;
// Find the PackageInfoRef if (depot != NULL) {
bool found = false; BString repositoryCode = depot->WebAppRepositoryCode();
for (int i = 0; i < packages.CountItems(); i++) {
const PackageInfoRef& package = packages.ItemAtFast(i);
if (pkgName == package->Name()) {
_PopulatePackageInfo(package, pkgInfo);
if (_HasNativeIcon(pkgInfo))
packagesWithIcons.Add(package);
// Store in cache if (repositoryCode.Length() != 0
BFile file; && !repositoryCodes.Contains(repositoryCode)) {
BPath path; repositoryCodes.Add(repositoryCode);
BString fileName(package->Name());
fileName << ".info";
if (_GetCacheFile(path, file, B_USER_CACHE_DIRECTORY,
"HaikuDepot", fileName,
B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE)) {
pkgInfo.Flatten(&file);
}
packages.Remove(i);
found = true;
break;
}
}
if (!found)
printf("No matching package for %s\n", pkgName.String());
} }
} }
} else { }
printf("Error sending request: %s\n", strerror(status));
int count = packages.CountItems(); if (repositoryCodes.CountItems() != 0) {
if (count >= 4) { status_t status = fWebAppInterface.RetrieveBulkPackageInfo(packageNames,
// Retry in smaller chunks packageArchitectures, repositoryCodes, info);
PackageList firstHalf;
PackageList secondHalf; if (status == B_OK) {
for (int i = 0; i < count / 2; i++) // Parse message
firstHalf.Add(packages.ItemAtFast(i)); // info.PrintToStream();
for (int i = count / 2; i < count; i++) BMessage result;
secondHalf.Add(packages.ItemAtFast(i)); BMessage pkgs;
packages.Clear(); if (info.FindMessage("result", &result) == B_OK
_PopulatePackageInfos(firstHalf, fromCacheOnly, packagesWithIcons); && result.FindMessage("pkgs", &pkgs) == B_OK) {
_PopulatePackageInfos(secondHalf, fromCacheOnly, packagesWithIcons); int32 index = 0;
while (true) {
if (fStopPopulatingAllPackages)
return;
BString name;
name << index++;
BMessage pkgInfo;
if (pkgs.FindMessage(name, &pkgInfo) != B_OK)
break;
BString pkgName;
if (pkgInfo.FindString("name", &pkgName) != B_OK)
continue;
// Find the PackageInfoRef
bool found = false;
for (int i = 0; i < packages.CountItems(); i++) {
const PackageInfoRef& package = packages.ItemAtFast(i);
if (pkgName == package->Name()) {
_PopulatePackageInfo(package, pkgInfo);
if (_HasNativeIcon(pkgInfo))
packagesWithIcons.Add(package);
// Store in cache
BFile file;
BPath path;
BString fileName(package->Name());
fileName << ".info";
if (_GetCacheFile(path, file, B_USER_CACHE_DIRECTORY,
"HaikuDepot", fileName,
B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE)) {
pkgInfo.Flatten(&file);
}
packages.Remove(i);
found = true;
break;
}
}
if (!found)
printf("No matching package for %s\n", pkgName.String());
}
}
} else { } else {
while (packages.CountItems() > 0) { printf("Error sending request: %s\n", strerror(status));
const PackageInfoRef& package = packages.ItemAtFast(0); int count = packages.CountItems();
_PopulatePackageInfo(package, fromCacheOnly); if (count >= 4) {
packages.Remove(0); // Retry in smaller chunks
PackageList firstHalf;
PackageList secondHalf;
for (int i = 0; i < count / 2; i++)
firstHalf.Add(packages.ItemAtFast(i));
for (int i = count / 2; i < count; i++)
secondHalf.Add(packages.ItemAtFast(i));
packages.Clear();
_PopulatePackageInfos(firstHalf, fromCacheOnly, packagesWithIcons);
_PopulatePackageInfos(secondHalf, fromCacheOnly, packagesWithIcons);
} else {
while (packages.CountItems() > 0) {
const PackageInfoRef& package = packages.ItemAtFast(0);
_PopulatePackageInfo(package, fromCacheOnly);
packages.Remove(0);
}
} }
} }
} }
@@ -1083,17 +1162,34 @@ Model::_PopulatePackageInfo(const PackageInfoRef& package, bool fromCacheOnly)
if (fromCacheOnly) if (fromCacheOnly)
return; return;
// Retrieve info from web-app BString repositoryCode;
BMessage info; const DepotInfo* depot = DepotForName(package->DepotName());
status_t status = fWebAppInterface.RetrievePackageInfo(package->Name(), if (depot != NULL) {
package->Architecture(), info); repositoryCode = depot->WebAppRepositoryCode();
if (status == B_OK) {
// Parse message if (repositoryCode.Length() > 0) {
// info.PrintToStream(); // Retrieve info from web-app
BMessage result; BMessage info;
if (info.FindMessage("result", &result) == B_OK)
_PopulatePackageInfo(package, result); status_t status = fWebAppInterface.RetrievePackageInfo(
package->Name(), package->Architecture(), repositoryCode,
info);
if (status == B_OK) {
// Parse message
// info.PrintToStream();
BMessage result;
if (info.FindMessage("result", &result) == B_OK)
_PopulatePackageInfo(package, result);
}
} else {
printf("unable to find the web app repository code for depot; %s\n",
package->DepotName().String());
}
} else {
printf("no depot for name; %s\n",
package->DepotName().String());
} }
} }
@@ -1189,7 +1285,7 @@ Model::_PopulatePackageInfo(const PackageInfoRef& package, const BMessage& data)
append_word_list(foundInfo, "prominence"); append_word_list(foundInfo, "prominence");
} }
BString changelog; BString changelog;
if (data.FindString("pkgChangelogContent", &changelog) == B_OK) { if (data.FindString("pkgChangelogContent", &changelog) == B_OK) {
package->SetChangelog(changelog); package->SetChangelog(changelog);
@@ -1380,4 +1476,3 @@ Model::_NotifyAuthorizationChanged()
listener->AuthorizationChanged(); listener->AuthorizationChanged();
} }
} }
+5
View File
@@ -1,5 +1,6 @@
/* /*
* Copyright 2013-2014, Stephan Aßmus <[email protected]>. * Copyright 2013-2014, Stephan Aßmus <[email protected]>.
* Copyright 2016, Andrew Lindesay <[email protected]>.
* All rights reserved. Distributed under the terms of the MIT License. * All rights reserved. Distributed under the terms of the MIT License.
*/ */
#ifndef MODEL_H #ifndef MODEL_H
@@ -56,6 +57,7 @@ public:
bool HasDepot(const BString& name) const; bool HasDepot(const BString& name) const;
const DepotList& Depots() const const DepotList& Depots() const
{ return fDepots; } { return fDepots; }
const DepotInfo* DepotForName(const BString& name) const;
bool SyncDepot(const DepotInfo& depot); bool SyncDepot(const DepotInfo& depot);
void Clear(); void Clear();
@@ -115,6 +117,9 @@ public:
bool ShowDevelopPackages() const bool ShowDevelopPackages() const
{ return fShowDevelopPackages; } { return fShowDevelopPackages; }
void PopulateWebAppRepositoryCode(
DepotInfo& depotInfo);
// Retrieve package information // Retrieve package information
static const uint32 POPULATE_CACHED_RATING = 1 << 0; static const uint32 POPULATE_CACHED_RATING = 1 << 0;
static const uint32 POPULATE_CACHED_ICON = 1 << 1; static const uint32 POPULATE_CACHED_ICON = 1 << 1;
+30 -3
View File
@@ -1,6 +1,7 @@
/* /*
* Copyright 2013-2014, Stephan Aßmus <[email protected]>. * Copyright 2013-2014, Stephan Aßmus <[email protected]>.
* Copyright 2013, Rene Gollent <[email protected]>. * Copyright 2013, Rene Gollent <[email protected]>.
* Copyright 2016, Andrew Lindesay <[email protected]>.
* All rights reserved. Distributed under the terms of the MIT License. * All rights reserved. Distributed under the terms of the MIT License.
*/ */
@@ -931,6 +932,13 @@ PackageInfo::SetSize(int64 size)
} }
void
PackageInfo::SetDepotName(const BString& depotName)
{
fDepotName = depotName;
}
bool bool
PackageInfo::AddListener(const PackageInfoListenerRef& listener) PackageInfo::AddListener(const PackageInfoListenerRef& listener)
{ {
@@ -982,7 +990,8 @@ PackageInfo::_NotifyListeners(uint32 changes)
DepotInfo::DepotInfo() DepotInfo::DepotInfo()
: :
fName(), fName(),
fPackages() fPackages(),
fWebAppRepositoryCode()
{ {
} }
@@ -990,7 +999,8 @@ DepotInfo::DepotInfo()
DepotInfo::DepotInfo(const BString& name) DepotInfo::DepotInfo(const BString& name)
: :
fName(name), fName(name),
fPackages() fPackages(),
fWebAppRepositoryCode()
{ {
} }
@@ -998,7 +1008,9 @@ DepotInfo::DepotInfo(const BString& name)
DepotInfo::DepotInfo(const DepotInfo& other) DepotInfo::DepotInfo(const DepotInfo& other)
: :
fName(other.fName), fName(other.fName),
fPackages(other.fPackages) fPackages(other.fPackages),
fWebAppRepositoryCode(other.fWebAppRepositoryCode),
fBaseURL(other.fBaseURL)
{ {
} }
@@ -1008,6 +1020,8 @@ DepotInfo::operator=(const DepotInfo& other)
{ {
fName = other.fName; fName = other.fName;
fPackages = other.fPackages; fPackages = other.fPackages;
fBaseURL = other.fBaseURL;
fWebAppRepositoryCode = other.fWebAppRepositoryCode;
return *this; return *this;
} }
@@ -1071,3 +1085,16 @@ DepotInfo::SyncPackages(const PackageList& otherPackages)
} }
} }
void
DepotInfo::SetBaseURL(const BString& baseURL)
{
fBaseURL = baseURL;
}
void
DepotInfo::SetWebAppRepositoryCode(const BString& code)
{
fWebAppRepositoryCode = code;
}
+16
View File
@@ -1,5 +1,6 @@
/* /*
* Copyright 2013-2014, Stephan Aßmus <[email protected]>. * Copyright 2013-2014, Stephan Aßmus <[email protected]>.
* Copyright 2016, Andrew Lindesay <[email protected]>.
* All rights reserved. Distributed under the terms of the MIT License. * All rights reserved. Distributed under the terms of the MIT License.
*/ */
#ifndef PACKAGE_INFO_H #ifndef PACKAGE_INFO_H
@@ -340,6 +341,10 @@ public:
int64 Size() const int64 Size() const
{ return fSize; } { return fSize; }
void SetDepotName(const BString& depotName);
const BString& DepotName() const
{ return fDepotName; }
bool AddListener( bool AddListener(
const PackageInfoListenerRef& listener); const PackageInfoListenerRef& listener);
void RemoveListener( void RemoveListener(
@@ -376,6 +381,7 @@ private:
BString fLocalFilePath; BString fLocalFilePath;
BString fFileName; BString fFileName;
int64 fSize; int64 fSize;
BString fDepotName;
static BitmapRef sDefaultIcon; static BitmapRef sDefaultIcon;
}; };
@@ -407,9 +413,19 @@ public:
void SyncPackages(const PackageList& packages); void SyncPackages(const PackageList& packages);
void SetBaseURL(const BString& baseURL);
const BString& BaseURL() const
{ return fBaseURL; }
void SetWebAppRepositoryCode(const BString& code);
const BString& WebAppRepositoryCode() const
{ return fWebAppRepositoryCode; }
private: private:
BString fName; BString fName;
PackageList fPackages; PackageList fPackages;
BString fWebAppRepositoryCode;
BString fBaseURL;
}; };
+38 -11
View File
@@ -1,5 +1,6 @@
/* /*
* Copyright 2014, Stephan Aßmus <[email protected]>. * Copyright 2014, Stephan Aßmus <[email protected]>.
* Copyright 2016, Andrew Lindesay <[email protected]>.
* All rights reserved. Distributed under the terms of the MIT License. * All rights reserved. Distributed under the terms of the MIT License.
*/ */
@@ -26,7 +27,6 @@
#include "PackageInfo.h" #include "PackageInfo.h"
#define CODE_REPOSITORY_DEFAULT "haikuports"
#define BASEURL_DEFAULT "https://depot.haiku-os.org" #define BASEURL_DEFAULT "https://depot.haiku-os.org"
#define USERAGENT_FALLBACK_VERSION "0.0.0" #define USERAGENT_FALLBACK_VERSION "0.0.0"
@@ -436,9 +436,34 @@ WebAppInterface::SetPreferredLanguage(const BString& language)
} }
status_t
WebAppInterface::RetrieveRepositoriesForSourceBaseURLs(
const StringList& repositorySourceBaseURLs,
BMessage& message)
{
BString jsonString = JsonBuilder()
.AddValue("jsonrpc", "2.0")
.AddValue("id", ++fRequestIndex)
.AddValue("method", "searchRepositories")
.AddArray("params")
.AddObject()
.AddArray("repositorySourceSearchUrls")
.AddStrings(repositorySourceBaseURLs)
.EndArray()
.AddValue("offset", 0)
.AddValue("limit", 1000) // effectively a safety limit
.EndObject()
.EndArray()
.End();
return _SendJsonRequest("repository", jsonString, 0, message);
}
status_t status_t
WebAppInterface::RetrievePackageInfo(const BString& packageName, WebAppInterface::RetrievePackageInfo(const BString& packageName,
const BString& architecture, BMessage& message) const BString& architecture, const BString& repositoryCode,
BMessage& message)
{ {
BString jsonString = JsonBuilder() BString jsonString = JsonBuilder()
.AddValue("jsonrpc", "2.0") .AddValue("jsonrpc", "2.0")
@@ -449,7 +474,7 @@ WebAppInterface::RetrievePackageInfo(const BString& packageName,
.AddValue("name", packageName) .AddValue("name", packageName)
.AddValue("architectureCode", architecture) .AddValue("architectureCode", architecture)
.AddValue("naturalLanguageCode", fLanguage) .AddValue("naturalLanguageCode", fLanguage)
.AddValue("repositoryCode", CODE_REPOSITORY_DEFAULT) .AddValue("repositoryCode", repositoryCode)
.AddValue("versionType", "NONE") .AddValue("versionType", "NONE")
.EndObject() .EndObject()
.EndArray() .EndArray()
@@ -461,7 +486,8 @@ WebAppInterface::RetrievePackageInfo(const BString& packageName,
status_t status_t
WebAppInterface::RetrieveBulkPackageInfo(const StringList& packageNames, WebAppInterface::RetrieveBulkPackageInfo(const StringList& packageNames,
const StringList& packageArchitectures, BMessage& message) const StringList& packageArchitectures,
const StringList& repositoryCodes, BMessage& message)
{ {
BString jsonString = JsonBuilder() BString jsonString = JsonBuilder()
.AddValue("jsonrpc", "2.0") .AddValue("jsonrpc", "2.0")
@@ -476,7 +502,7 @@ WebAppInterface::RetrieveBulkPackageInfo(const StringList& packageNames,
.AddStrings(packageArchitectures) .AddStrings(packageArchitectures)
.EndArray() .EndArray()
.AddArray("repositoryCodes") .AddArray("repositoryCodes")
.AddItem(CODE_REPOSITORY_DEFAULT) .AddStrings(repositoryCodes)
.EndArray() .EndArray()
.AddValue("naturalLanguageCode", fLanguage) .AddValue("naturalLanguageCode", fLanguage)
.AddValue("versionType", "LATEST") .AddValue("versionType", "LATEST")
@@ -552,7 +578,8 @@ WebAppInterface::RetrieveUserRatings(const BString& packageName,
status_t status_t
WebAppInterface::RetrieveUserRating(const BString& packageName, WebAppInterface::RetrieveUserRating(const BString& packageName,
const BPackageVersion& version, const BString& architecture, const BPackageVersion& version, const BString& architecture,
const BString& username, BMessage& message) const BString &repositoryCode, const BString& username,
BMessage& message)
{ {
BString jsonString = JsonBuilder() BString jsonString = JsonBuilder()
.AddValue("jsonrpc", "2.0") .AddValue("jsonrpc", "2.0")
@@ -568,7 +595,7 @@ WebAppInterface::RetrieveUserRating(const BString& packageName,
.AddValue("pkgVersionMicro", version.Micro(), true) .AddValue("pkgVersionMicro", version.Micro(), true)
.AddValue("pkgVersionPreRelease", version.PreRelease(), true) .AddValue("pkgVersionPreRelease", version.PreRelease(), true)
.AddValue("pkgVersionRevision", (int)version.Revision()) .AddValue("pkgVersionRevision", (int)version.Revision())
.AddValue("repositoryCode", CODE_REPOSITORY_DEFAULT) .AddValue("repositoryCode", repositoryCode)
.EndObject() .EndObject()
.EndArray() .EndArray()
.End(); .End();
@@ -579,9 +606,9 @@ WebAppInterface::RetrieveUserRating(const BString& packageName,
status_t status_t
WebAppInterface::CreateUserRating(const BString& packageName, WebAppInterface::CreateUserRating(const BString& packageName,
const BString& architecture, const BString& languageCode, const BString& architecture, const BString& repositoryCode,
const BString& comment, const BString& stability, int rating, const BString& languageCode, const BString& comment,
BMessage& message) const BString& stability, int rating, BMessage& message)
{ {
BString jsonString = JsonBuilder() BString jsonString = JsonBuilder()
.AddValue("jsonrpc", "2.0") .AddValue("jsonrpc", "2.0")
@@ -596,7 +623,7 @@ WebAppInterface::CreateUserRating(const BString& packageName,
.AddValue("rating", rating) .AddValue("rating", rating)
.AddValue("userRatingStabilityCode", stability, true) .AddValue("userRatingStabilityCode", stability, true)
.AddValue("comment", comment) .AddValue("comment", comment)
.AddValue("repositoryCode", CODE_REPOSITORY_DEFAULT) .AddValue("repositoryCode", repositoryCode)
.AddValue("naturalLanguageCode", languageCode) .AddValue("naturalLanguageCode", languageCode)
.EndObject() .EndObject()
.EndArray() .EndArray()
@@ -1,5 +1,6 @@
/* /*
* Copyright 2014, Stephan Aßmus <[email protected]>. * Copyright 2014, Stephan Aßmus <[email protected]>.
* Copyright 2016, Andrew Lindesay <[email protected]>.
* All rights reserved. Distributed under the terms of the MIT License. * All rights reserved. Distributed under the terms of the MIT License.
*/ */
#ifndef WEB_APP_INTERFACE_H #ifndef WEB_APP_INTERFACE_H
@@ -37,14 +38,20 @@ public:
void SetPreferredLanguage(const BString& language); void SetPreferredLanguage(const BString& language);
void SetArchitecture(const BString& architecture); void SetArchitecture(const BString& architecture);
status_t RetrieveRepositoriesForSourceBaseURLs(
const StringList& repositorySourceBaseURL,
BMessage& message);
status_t RetrievePackageInfo( status_t RetrievePackageInfo(
const BString& packageName, const BString& packageName,
const BString& architecture, const BString& architecture,
const BString& repositoryCode,
BMessage& message); BMessage& message);
status_t RetrieveBulkPackageInfo( status_t RetrieveBulkPackageInfo(
const StringList& packageNames, const StringList& packageNames,
const StringList& packageArchitectures, const StringList& packageArchitectures,
const StringList& repositoryCodes,
BMessage& message); BMessage& message);
status_t RetrievePackageIcon( status_t RetrievePackageIcon(
@@ -61,12 +68,14 @@ public:
const BString& packageName, const BString& packageName,
const BPackageVersion& version, const BPackageVersion& version,
const BString& architecture, const BString& architecture,
const BString& repositoryCode,
const BString& username, const BString& username,
BMessage& message); BMessage& message);
status_t CreateUserRating( status_t CreateUserRating(
const BString& packageName, const BString& packageName,
const BString& architecture, const BString& architecture,
const BString& repositoryCode,
const BString& languageCode, const BString& languageCode,
const BString& comment, const BString& comment,
const BString& stability, const BString& stability,
+25 -2
View File
@@ -3,6 +3,7 @@
* Copyright 2013-2014, Stephan Aßmus <[email protected]>. * Copyright 2013-2014, Stephan Aßmus <[email protected]>.
* Copyright 2013, Rene Gollent, [email protected]. * Copyright 2013, Rene Gollent, [email protected].
* Copyright 2013, Ingo Weinhold, [email protected]. * Copyright 2013, Ingo Weinhold, [email protected].
* Copyright 2016, Andrew Lindesay <[email protected]>.
* All rights reserved. Distributed under the terms of the MIT License. * All rights reserved. Distributed under the terms of the MIT License.
*/ */
@@ -834,7 +835,27 @@ MainWindow::_RefreshPackageList(bool force)
DepotInfoMap depots; DepotInfoMap depots;
for (int32 i = 0; i < repositoryNames.CountStrings(); i++) { for (int32 i = 0; i < repositoryNames.CountStrings(); i++) {
const BString& repoName = repositoryNames.StringAt(i); const BString& repoName = repositoryNames.StringAt(i);
depots[repoName] = DepotInfo(repoName); DepotInfo depotInfo = DepotInfo(repoName);
BRepositoryConfig repoConfig;
status_t getRepositoryConfigStatus = roster.GetRepositoryConfig(
repoName, &repoConfig);
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",
repoName.String(), strerror(getRepositoryConfigStatus));
}
depots[repoName] = depotInfo;
} }
PackageManager manager(B_PACKAGE_INSTALLATION_LOCATION_HOME); PackageManager manager(B_PACKAGE_INSTALLATION_LOCATION_HOME);
@@ -891,6 +912,7 @@ MainWindow::_RefreshPackageList(bool force)
for (int32 i = 0; i < packages.CountItems(); i++) { for (int32 i = 0; i < packages.CountItems(); i++) {
BSolverPackage* package = packages.ItemAt(i); BSolverPackage* package = packages.ItemAt(i);
const BPackageInfo& repoPackageInfo = package->Info(); const BPackageInfo& repoPackageInfo = package->Info();
const BString repositoryName = package->Repository()->Name();
PackageInfoRef modelInfo; PackageInfoRef modelInfo;
PackageInfoMap::iterator it = foundPackages.find( PackageInfoMap::iterator it = foundPackages.find(
repoPackageInfo.Name()); repoPackageInfo.Name());
@@ -904,6 +926,8 @@ MainWindow::_RefreshPackageList(bool force)
if (modelInfo.Get() == NULL) if (modelInfo.Get() == NULL)
return; return;
modelInfo->SetDepotName(repositoryName);
foundPackages[repoPackageInfo.Name()] = modelInfo; foundPackages[repoPackageInfo.Name()] = modelInfo;
} }
@@ -1244,4 +1268,3 @@ MainWindow::_ShowScreenshot()
fScreenshotWindow->Unlock(); fScreenshotWindow->Unlock();
} }
+80 -56
View File
@@ -1,5 +1,6 @@
/* /*
* Copyright 2014, Stephan Aßmus <[email protected]>. * Copyright 2014, Stephan Aßmus <[email protected]>.
* Copyright 2016, Andrew Lindesay <[email protected]>.
* All rights reserved. Distributed under the terms of the MIT License. * All rights reserved. Distributed under the terms of the MIT License.
*/ */
@@ -408,64 +409,74 @@ RatePackageWindow::_QueryRatingThread()
WebAppInterface interface; WebAppInterface interface;
BMessage info; BMessage info;
const DepotInfo* depot = fModel.DepotForName(package->DepotName());
BString repositoryCode;
status_t status = interface.RetrieveUserRating( if (depot != NULL)
package->Name(), package->Version(), package->Architecture(), repositoryCode = depot->WebAppRepositoryCode();
username, info);
// info.PrintToStream(); if (repositoryCode.Length() == 0) {
printf("unable to obtain the repository code for depot; %s\n",
BMessage result; package->DepotName().String());
if (status == B_OK && info.FindMessage("result", &result) == B_OK
&& Lock()) {
result.FindString("code", &fRatingID);
result.FindBool("active", &fRatingActive);
BString comment;
if (result.FindString("comment", &comment) == B_OK) {
MarkupParser parser;
fRatingText = parser.CreateDocumentFromMarkup(comment);
fTextView->SetTextDocument(fRatingText);
}
if (result.FindString("userRatingStabilityCode",
&fStability) == B_OK) {
int32 index = 0;
for (int32 i = fStabilityCodes.CountItems() - 1; i >= 0; i--) {
const StabilityRating& stability
= fStabilityCodes.ItemAtFast(i);
if (stability.Name() == fStability) {
index = i;
break;
}
}
BMenuItem* item = fStabilityField->Menu()->ItemAt(index);
if (item != NULL)
item->SetMarked(true);
}
if (result.FindString("naturalLanguageCode",
&fCommentLanguage) == B_OK) {
BMenuItem* item = fCommentLanguageField->Menu()->ItemAt(
fModel.SupportedLanguages().IndexOf(fCommentLanguage));
if (item != NULL)
item->SetMarked(true);
}
double rating;
if (result.FindDouble("rating", &rating) == B_OK) {
fRating = (float)rating;
fSetRatingView->SetPermanentRating(fRating);
}
fRatingActiveCheckBox->SetValue(fRatingActive);
fRatingActiveCheckBox->Show();
fSendButton->SetLabel(B_TRANSLATE("Update"));
Unlock();
} else { } else {
fprintf(stderr, "rating query: Failed response: %s\n", status_t status = interface.RetrieveUserRating(
strerror(status)); package->Name(), package->Version(), package->Architecture(),
if (!info.IsEmpty()) repositoryCode, username, info);
info.PrintToStream();
// info.PrintToStream();
BMessage result;
if (status == B_OK && info.FindMessage("result", &result) == B_OK
&& Lock()) {
result.FindString("code", &fRatingID);
result.FindBool("active", &fRatingActive);
BString comment;
if (result.FindString("comment", &comment) == B_OK) {
MarkupParser parser;
fRatingText = parser.CreateDocumentFromMarkup(comment);
fTextView->SetTextDocument(fRatingText);
}
if (result.FindString("userRatingStabilityCode",
&fStability) == B_OK) {
int32 index = 0;
for (int32 i = fStabilityCodes.CountItems() - 1; i >= 0; i--) {
const StabilityRating& stability
= fStabilityCodes.ItemAtFast(i);
if (stability.Name() == fStability) {
index = i;
break;
}
}
BMenuItem* item = fStabilityField->Menu()->ItemAt(index);
if (item != NULL)
item->SetMarked(true);
}
if (result.FindString("naturalLanguageCode",
&fCommentLanguage) == B_OK) {
BMenuItem* item = fCommentLanguageField->Menu()->ItemAt(
fModel.SupportedLanguages().IndexOf(fCommentLanguage));
if (item != NULL)
item->SetMarked(true);
}
double rating;
if (result.FindDouble("rating", &rating) == B_OK) {
fRating = (float)rating;
fSetRatingView->SetPermanentRating(fRating);
}
fRatingActiveCheckBox->SetValue(fRatingActive);
fRatingActiveCheckBox->Show();
fSendButton->SetLabel(B_TRANSLATE("Update"));
Unlock();
} else {
fprintf(stderr, "rating query: Failed response: %s\n",
strerror(status));
if (!info.IsEmpty())
info.PrintToStream();
}
} }
_SetWorkerThread(-1); _SetWorkerThread(-1);
@@ -491,6 +502,7 @@ RatePackageWindow::_SendRatingThread()
BString package = fPackage->Name(); BString package = fPackage->Name();
BString architecture = fPackage->Architecture(); BString architecture = fPackage->Architecture();
BString repositoryCode;
int rating = (int)fRating; int rating = (int)fRating;
BString stability = fStability; BString stability = fStability;
BString comment = fRatingText->Text(); BString comment = fRatingText->Text();
@@ -498,10 +510,22 @@ RatePackageWindow::_SendRatingThread()
BString ratingID = fRatingID; BString ratingID = fRatingID;
bool active = fRatingActive; bool active = fRatingActive;
const DepotInfo* depot = fModel.DepotForName(fPackage->DepotName());
if (depot != NULL)
repositoryCode = depot->WebAppRepositoryCode();
WebAppInterface interface = fModel.GetWebAppInterface(); WebAppInterface interface = fModel.GetWebAppInterface();
Unlock(); Unlock();
if (repositoryCode.Length() == 0) {
printf("unable to find the web app repository code for the local "
"depot %s\n",
fPackage->DepotName().String());
return;
}
if (stability == "unspecified") if (stability == "unspecified")
stability = ""; stability = "";
@@ -512,7 +536,7 @@ RatePackageWindow::_SendRatingThread()
languageCode, comment, stability, rating, active, info); languageCode, comment, stability, rating, active, info);
} else { } else {
status = interface.CreateUserRating(package, architecture, status = interface.CreateUserRating(package, architecture,
languageCode, comment, stability, rating, info); repositoryCode, languageCode, comment, stability, rating, info);
} }
BString error = B_TRANSLATE( BString error = B_TRANSLATE(