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:
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright 2013-2014, Stephan Aßmus <[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.
|
||||
*/
|
||||
|
||||
@@ -463,12 +464,19 @@ Model::AddDepot(const DepotInfo& depot)
|
||||
|
||||
bool
|
||||
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--) {
|
||||
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
|
||||
|
||||
|
||||
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
|
||||
Model::_UpdateIsFeaturedFilter()
|
||||
{
|
||||
@@ -987,83 +1048,101 @@ Model::_PopulatePackageInfos(PackageList& packages, bool fromCacheOnly,
|
||||
|
||||
StringList packageNames;
|
||||
StringList packageArchitectures;
|
||||
StringList repositoryCodes;
|
||||
|
||||
for (int i = 0; i < packages.CountItems(); i++) {
|
||||
const PackageInfoRef& package = packages.ItemAtFast(i);
|
||||
packageNames.Add(package->Name());
|
||||
packageArchitectures.Add(package->Architecture());
|
||||
}
|
||||
|
||||
status_t status = fWebAppInterface.RetrieveBulkPackageInfo(packageNames,
|
||||
packageArchitectures, info);
|
||||
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;
|
||||
if (!packageArchitectures.Contains(package->Architecture()))
|
||||
packageArchitectures.Add(package->Architecture());
|
||||
|
||||
BString pkgName;
|
||||
if (pkgInfo.FindString("name", &pkgName) != B_OK)
|
||||
continue;
|
||||
const DepotInfo *depot = DepotForName(package->DepotName());
|
||||
|
||||
// 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);
|
||||
if (depot != NULL) {
|
||||
BString repositoryCode = depot->WebAppRepositoryCode();
|
||||
|
||||
// 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());
|
||||
if (repositoryCode.Length() != 0
|
||||
&& !repositoryCodes.Contains(repositoryCode)) {
|
||||
repositoryCodes.Add(repositoryCode);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
printf("Error sending request: %s\n", strerror(status));
|
||||
int count = packages.CountItems();
|
||||
if (count >= 4) {
|
||||
// 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);
|
||||
}
|
||||
|
||||
if (repositoryCodes.CountItems() != 0) {
|
||||
status_t status = fWebAppInterface.RetrieveBulkPackageInfo(packageNames,
|
||||
packageArchitectures, repositoryCodes, info);
|
||||
|
||||
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;
|
||||
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 {
|
||||
while (packages.CountItems() > 0) {
|
||||
const PackageInfoRef& package = packages.ItemAtFast(0);
|
||||
_PopulatePackageInfo(package, fromCacheOnly);
|
||||
packages.Remove(0);
|
||||
printf("Error sending request: %s\n", strerror(status));
|
||||
int count = packages.CountItems();
|
||||
if (count >= 4) {
|
||||
// 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)
|
||||
return;
|
||||
|
||||
// Retrieve info from web-app
|
||||
BMessage info;
|
||||
BString repositoryCode;
|
||||
const DepotInfo* depot = DepotForName(package->DepotName());
|
||||
|
||||
status_t status = fWebAppInterface.RetrievePackageInfo(package->Name(),
|
||||
package->Architecture(), info);
|
||||
if (status == B_OK) {
|
||||
// Parse message
|
||||
// info.PrintToStream();
|
||||
BMessage result;
|
||||
if (info.FindMessage("result", &result) == B_OK)
|
||||
_PopulatePackageInfo(package, result);
|
||||
if (depot != NULL) {
|
||||
repositoryCode = depot->WebAppRepositoryCode();
|
||||
|
||||
if (repositoryCode.Length() > 0) {
|
||||
// Retrieve info from web-app
|
||||
BMessage info;
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
|
||||
BString changelog;
|
||||
if (data.FindString("pkgChangelogContent", &changelog) == B_OK) {
|
||||
package->SetChangelog(changelog);
|
||||
@@ -1380,4 +1476,3 @@ Model::_NotifyAuthorizationChanged()
|
||||
listener->AuthorizationChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2013-2014, Stephan Aßmus <superstippi@gmx.de>.
|
||||
* Copyright 2016, Andrew Lindesay <apl@lindesay.co.nz>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef MODEL_H
|
||||
@@ -56,6 +57,7 @@ public:
|
||||
bool HasDepot(const BString& name) const;
|
||||
const DepotList& Depots() const
|
||||
{ return fDepots; }
|
||||
const DepotInfo* DepotForName(const BString& name) const;
|
||||
bool SyncDepot(const DepotInfo& depot);
|
||||
|
||||
void Clear();
|
||||
@@ -115,6 +117,9 @@ public:
|
||||
bool ShowDevelopPackages() const
|
||||
{ return fShowDevelopPackages; }
|
||||
|
||||
void PopulateWebAppRepositoryCode(
|
||||
DepotInfo& depotInfo);
|
||||
|
||||
// Retrieve package information
|
||||
static const uint32 POPULATE_CACHED_RATING = 1 << 0;
|
||||
static const uint32 POPULATE_CACHED_ICON = 1 << 1;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright 2013-2014, Stephan Aßmus <superstippi@gmx.de>.
|
||||
* Copyright 2013, Rene Gollent <rene@gollent.com>.
|
||||
* Copyright 2016, Andrew Lindesay <apl@lindesay.co.nz>.
|
||||
* 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
|
||||
PackageInfo::AddListener(const PackageInfoListenerRef& listener)
|
||||
{
|
||||
@@ -982,7 +990,8 @@ PackageInfo::_NotifyListeners(uint32 changes)
|
||||
DepotInfo::DepotInfo()
|
||||
:
|
||||
fName(),
|
||||
fPackages()
|
||||
fPackages(),
|
||||
fWebAppRepositoryCode()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -990,7 +999,8 @@ DepotInfo::DepotInfo()
|
||||
DepotInfo::DepotInfo(const BString& name)
|
||||
:
|
||||
fName(name),
|
||||
fPackages()
|
||||
fPackages(),
|
||||
fWebAppRepositoryCode()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -998,7 +1008,9 @@ DepotInfo::DepotInfo(const BString& name)
|
||||
DepotInfo::DepotInfo(const DepotInfo& other)
|
||||
:
|
||||
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;
|
||||
fPackages = other.fPackages;
|
||||
fBaseURL = other.fBaseURL;
|
||||
fWebAppRepositoryCode = other.fWebAppRepositoryCode;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2013-2014, Stephan Aßmus <superstippi@gmx.de>.
|
||||
* Copyright 2016, Andrew Lindesay <apl@lindesay.co.nz>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef PACKAGE_INFO_H
|
||||
@@ -340,6 +341,10 @@ public:
|
||||
int64 Size() const
|
||||
{ return fSize; }
|
||||
|
||||
void SetDepotName(const BString& depotName);
|
||||
const BString& DepotName() const
|
||||
{ return fDepotName; }
|
||||
|
||||
bool AddListener(
|
||||
const PackageInfoListenerRef& listener);
|
||||
void RemoveListener(
|
||||
@@ -376,6 +381,7 @@ private:
|
||||
BString fLocalFilePath;
|
||||
BString fFileName;
|
||||
int64 fSize;
|
||||
BString fDepotName;
|
||||
|
||||
static BitmapRef sDefaultIcon;
|
||||
};
|
||||
@@ -407,9 +413,19 @@ public:
|
||||
|
||||
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:
|
||||
BString fName;
|
||||
PackageList fPackages;
|
||||
BString fWebAppRepositoryCode;
|
||||
BString fBaseURL;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2014, Stephan Aßmus <superstippi@gmx.de>.
|
||||
* Copyright 2016, Andrew Lindesay <apl@lindesay.co.nz>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
@@ -26,7 +27,6 @@
|
||||
#include "PackageInfo.h"
|
||||
|
||||
|
||||
#define CODE_REPOSITORY_DEFAULT "haikuports"
|
||||
#define BASEURL_DEFAULT "https://depot.haiku-os.org"
|
||||
#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
|
||||
WebAppInterface::RetrievePackageInfo(const BString& packageName,
|
||||
const BString& architecture, BMessage& message)
|
||||
const BString& architecture, const BString& repositoryCode,
|
||||
BMessage& message)
|
||||
{
|
||||
BString jsonString = JsonBuilder()
|
||||
.AddValue("jsonrpc", "2.0")
|
||||
@@ -449,7 +474,7 @@ WebAppInterface::RetrievePackageInfo(const BString& packageName,
|
||||
.AddValue("name", packageName)
|
||||
.AddValue("architectureCode", architecture)
|
||||
.AddValue("naturalLanguageCode", fLanguage)
|
||||
.AddValue("repositoryCode", CODE_REPOSITORY_DEFAULT)
|
||||
.AddValue("repositoryCode", repositoryCode)
|
||||
.AddValue("versionType", "NONE")
|
||||
.EndObject()
|
||||
.EndArray()
|
||||
@@ -461,7 +486,8 @@ WebAppInterface::RetrievePackageInfo(const BString& packageName,
|
||||
|
||||
status_t
|
||||
WebAppInterface::RetrieveBulkPackageInfo(const StringList& packageNames,
|
||||
const StringList& packageArchitectures, BMessage& message)
|
||||
const StringList& packageArchitectures,
|
||||
const StringList& repositoryCodes, BMessage& message)
|
||||
{
|
||||
BString jsonString = JsonBuilder()
|
||||
.AddValue("jsonrpc", "2.0")
|
||||
@@ -476,7 +502,7 @@ WebAppInterface::RetrieveBulkPackageInfo(const StringList& packageNames,
|
||||
.AddStrings(packageArchitectures)
|
||||
.EndArray()
|
||||
.AddArray("repositoryCodes")
|
||||
.AddItem(CODE_REPOSITORY_DEFAULT)
|
||||
.AddStrings(repositoryCodes)
|
||||
.EndArray()
|
||||
.AddValue("naturalLanguageCode", fLanguage)
|
||||
.AddValue("versionType", "LATEST")
|
||||
@@ -552,7 +578,8 @@ WebAppInterface::RetrieveUserRatings(const BString& packageName,
|
||||
status_t
|
||||
WebAppInterface::RetrieveUserRating(const BString& packageName,
|
||||
const BPackageVersion& version, const BString& architecture,
|
||||
const BString& username, BMessage& message)
|
||||
const BString &repositoryCode, const BString& username,
|
||||
BMessage& message)
|
||||
{
|
||||
BString jsonString = JsonBuilder()
|
||||
.AddValue("jsonrpc", "2.0")
|
||||
@@ -568,7 +595,7 @@ WebAppInterface::RetrieveUserRating(const BString& packageName,
|
||||
.AddValue("pkgVersionMicro", version.Micro(), true)
|
||||
.AddValue("pkgVersionPreRelease", version.PreRelease(), true)
|
||||
.AddValue("pkgVersionRevision", (int)version.Revision())
|
||||
.AddValue("repositoryCode", CODE_REPOSITORY_DEFAULT)
|
||||
.AddValue("repositoryCode", repositoryCode)
|
||||
.EndObject()
|
||||
.EndArray()
|
||||
.End();
|
||||
@@ -579,9 +606,9 @@ WebAppInterface::RetrieveUserRating(const BString& packageName,
|
||||
|
||||
status_t
|
||||
WebAppInterface::CreateUserRating(const BString& packageName,
|
||||
const BString& architecture, const BString& languageCode,
|
||||
const BString& comment, const BString& stability, int rating,
|
||||
BMessage& message)
|
||||
const BString& architecture, const BString& repositoryCode,
|
||||
const BString& languageCode, const BString& comment,
|
||||
const BString& stability, int rating, BMessage& message)
|
||||
{
|
||||
BString jsonString = JsonBuilder()
|
||||
.AddValue("jsonrpc", "2.0")
|
||||
@@ -596,7 +623,7 @@ WebAppInterface::CreateUserRating(const BString& packageName,
|
||||
.AddValue("rating", rating)
|
||||
.AddValue("userRatingStabilityCode", stability, true)
|
||||
.AddValue("comment", comment)
|
||||
.AddValue("repositoryCode", CODE_REPOSITORY_DEFAULT)
|
||||
.AddValue("repositoryCode", repositoryCode)
|
||||
.AddValue("naturalLanguageCode", languageCode)
|
||||
.EndObject()
|
||||
.EndArray()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2014, Stephan Aßmus <superstippi@gmx.de>.
|
||||
* Copyright 2016, Andrew Lindesay <apl@lindesay.co.nz>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef WEB_APP_INTERFACE_H
|
||||
@@ -37,14 +38,20 @@ public:
|
||||
void SetPreferredLanguage(const BString& language);
|
||||
void SetArchitecture(const BString& architecture);
|
||||
|
||||
status_t RetrieveRepositoriesForSourceBaseURLs(
|
||||
const StringList& repositorySourceBaseURL,
|
||||
BMessage& message);
|
||||
|
||||
status_t RetrievePackageInfo(
|
||||
const BString& packageName,
|
||||
const BString& architecture,
|
||||
const BString& repositoryCode,
|
||||
BMessage& message);
|
||||
|
||||
status_t RetrieveBulkPackageInfo(
|
||||
const StringList& packageNames,
|
||||
const StringList& packageArchitectures,
|
||||
const StringList& repositoryCodes,
|
||||
BMessage& message);
|
||||
|
||||
status_t RetrievePackageIcon(
|
||||
@@ -61,12 +68,14 @@ public:
|
||||
const BString& packageName,
|
||||
const BPackageVersion& version,
|
||||
const BString& architecture,
|
||||
const BString& repositoryCode,
|
||||
const BString& username,
|
||||
BMessage& message);
|
||||
|
||||
status_t CreateUserRating(
|
||||
const BString& packageName,
|
||||
const BString& architecture,
|
||||
const BString& repositoryCode,
|
||||
const BString& languageCode,
|
||||
const BString& comment,
|
||||
const BString& stability,
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* Copyright 2013-2014, Stephan Aßmus <superstippi@gmx.de>.
|
||||
* Copyright 2013, Rene Gollent, rene@gollent.com.
|
||||
* Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Copyright 2016, Andrew Lindesay <apl@lindesay.co.nz>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
@@ -834,7 +835,27 @@ MainWindow::_RefreshPackageList(bool force)
|
||||
DepotInfoMap depots;
|
||||
for (int32 i = 0; i < repositoryNames.CountStrings(); 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);
|
||||
@@ -891,6 +912,7 @@ MainWindow::_RefreshPackageList(bool force)
|
||||
for (int32 i = 0; i < packages.CountItems(); i++) {
|
||||
BSolverPackage* package = packages.ItemAt(i);
|
||||
const BPackageInfo& repoPackageInfo = package->Info();
|
||||
const BString repositoryName = package->Repository()->Name();
|
||||
PackageInfoRef modelInfo;
|
||||
PackageInfoMap::iterator it = foundPackages.find(
|
||||
repoPackageInfo.Name());
|
||||
@@ -904,6 +926,8 @@ MainWindow::_RefreshPackageList(bool force)
|
||||
if (modelInfo.Get() == NULL)
|
||||
return;
|
||||
|
||||
modelInfo->SetDepotName(repositoryName);
|
||||
|
||||
foundPackages[repoPackageInfo.Name()] = modelInfo;
|
||||
}
|
||||
|
||||
@@ -1244,4 +1268,3 @@ MainWindow::_ShowScreenshot()
|
||||
|
||||
fScreenshotWindow->Unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2014, Stephan Aßmus <superstippi@gmx.de>.
|
||||
* Copyright 2016, Andrew Lindesay <apl@lindesay.co.nz>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
@@ -408,64 +409,74 @@ RatePackageWindow::_QueryRatingThread()
|
||||
|
||||
WebAppInterface interface;
|
||||
BMessage info;
|
||||
const DepotInfo* depot = fModel.DepotForName(package->DepotName());
|
||||
BString repositoryCode;
|
||||
|
||||
status_t status = interface.RetrieveUserRating(
|
||||
package->Name(), package->Version(), package->Architecture(),
|
||||
username, info);
|
||||
if (depot != NULL)
|
||||
repositoryCode = depot->WebAppRepositoryCode();
|
||||
|
||||
// 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();
|
||||
if (repositoryCode.Length() == 0) {
|
||||
printf("unable to obtain the repository code for depot; %s\n",
|
||||
package->DepotName().String());
|
||||
} else {
|
||||
fprintf(stderr, "rating query: Failed response: %s\n",
|
||||
strerror(status));
|
||||
if (!info.IsEmpty())
|
||||
info.PrintToStream();
|
||||
status_t status = interface.RetrieveUserRating(
|
||||
package->Name(), package->Version(), package->Architecture(),
|
||||
repositoryCode, username, info);
|
||||
|
||||
// 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);
|
||||
@@ -491,6 +502,7 @@ RatePackageWindow::_SendRatingThread()
|
||||
|
||||
BString package = fPackage->Name();
|
||||
BString architecture = fPackage->Architecture();
|
||||
BString repositoryCode;
|
||||
int rating = (int)fRating;
|
||||
BString stability = fStability;
|
||||
BString comment = fRatingText->Text();
|
||||
@@ -498,10 +510,22 @@ RatePackageWindow::_SendRatingThread()
|
||||
BString ratingID = fRatingID;
|
||||
bool active = fRatingActive;
|
||||
|
||||
const DepotInfo* depot = fModel.DepotForName(fPackage->DepotName());
|
||||
|
||||
if (depot != NULL)
|
||||
repositoryCode = depot->WebAppRepositoryCode();
|
||||
|
||||
WebAppInterface interface = fModel.GetWebAppInterface();
|
||||
|
||||
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")
|
||||
stability = "";
|
||||
|
||||
@@ -512,7 +536,7 @@ RatePackageWindow::_SendRatingThread()
|
||||
languageCode, comment, stability, rating, active, info);
|
||||
} else {
|
||||
status = interface.CreateUserRating(package, architecture,
|
||||
languageCode, comment, stability, rating, info);
|
||||
repositoryCode, languageCode, comment, stability, rating, info);
|
||||
}
|
||||
|
||||
BString error = B_TRANSLATE(
|
||||
|
||||
Reference in New Issue
Block a user