* Copyright 2016-2024, Andrew Lindesay <apl@lindesay.co.nz>.
* Copyright 2013-2014, Stephan Aßmus <superstippi@gmx.de>.
* All rights reserved. Distributed under the terms of the MIT License.
*
* Note that this file included code earlier from `Model.cpp` and
* copyrights have been latterly been carried across in 2024.
*/
#include "PopulatePkgUserRatingsFromServerProcess.h"
#include <Autolock.h>
#include <Catalog.h>
#include "Logger.h"
#include "ServerHelper.h"
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "PopulatePkgUserRatingsFromServerProcess"
PopulatePkgUserRatingsFromServerProcess::PopulatePkgUserRatingsFromServerProcess(
PackageInfoRef packageInfo, Model* model)
:
fModel(model),
fPackageInfo(packageInfo)
{
}
PopulatePkgUserRatingsFromServerProcess::~PopulatePkgUserRatingsFromServerProcess()
{
}
const char*
PopulatePkgUserRatingsFromServerProcess::Name() const
{
return "PopulatePkgUserRatingsFromServerProcess";
}
const char*
PopulatePkgUserRatingsFromServerProcess::Description() const
{
return B_TRANSLATE("Fetching user ratings for package");
}
status_t
PopulatePkgUserRatingsFromServerProcess::RunInternal()
{
BMessage info;
BString packageName;
BString webAppRepositoryCode;
BString webAppRepositorySourceCode;
{
BAutolock locker(&fLock);
packageName = fPackageInfo->Name();
const DepotInfo* depot = fModel->DepotForName(fPackageInfo->DepotName());
if (depot != NULL) {
webAppRepositoryCode = depot->WebAppRepositoryCode();
webAppRepositorySourceCode = depot->WebAppRepositorySourceCode();
}
}
status_t status = fModel->GetWebAppInterface()->RetrieveUserRatingsForPackageForDisplay(
packageName, webAppRepositoryCode, webAppRepositorySourceCode, 0,
PACKAGE_INFO_MAX_USER_RATINGS, info);
if (status == B_OK) {
BMessage result;
BMessage items;
status = info.FindMessage("result", &result);
if (status == B_OK) {
if (result.FindMessage("items", &items) == B_OK) {
BAutolock locker(&fLock);
fPackageInfo->ClearUserRatings();
int32 index = 0;
while (true) {
BString name;
name << index++;
BMessage item;
if (items.FindMessage(name, &item) != B_OK)
break;
BString code;
if (item.FindString("code", &code) != B_OK) {
HDERROR("corrupt user rating at index %" B_PRIi32, index);
continue;
}
BString user;
BMessage userInfo;
if (item.FindMessage("user", &userInfo) != B_OK
|| userInfo.FindString("nickname", &user) != B_OK) {
HDERROR("ignored user rating [%s] without a user nickname", code.String());
continue;
}
BString languageCode;
BString comment;
double rating;
item.FindString("naturalLanguageCode", &languageCode);
item.FindString("comment", &comment);
if (item.FindDouble("rating", &rating) != B_OK)
rating = -1;
if (comment.Length() == 0 && rating == -1) {
HDERROR("rating [%s] has no comment or rating so will"
" be ignored",
code.String());
continue;
}
BString major = "?";
BString minor = "?";
BString micro = "";
double revision = -1;
BString architectureCode = "";
BMessage version;
if (item.FindMessage("pkgVersion", &version) == B_OK) {
version.FindString("major", &major);
version.FindString("minor", &minor);
version.FindString("micro", µ);
version.FindDouble("revision", &revision);
version.FindString("architectureCode", &architectureCode);
}
BString versionString = major;
versionString << ".";
versionString << minor;
if (!micro.IsEmpty()) {
versionString << ".";
versionString << micro;
}
if (revision > 0) {
versionString << "-";
versionString << (int)revision;
}
if (!architectureCode.IsEmpty()) {
versionString << " " << STR_MDASH << " ";
versionString << architectureCode;
}
double createTimestamp;
item.FindDouble("createTimestamp", &createTimestamp);
UserRatingRef userRating(
new UserRating(UserInfo(user), rating, comment, languageCode,
versionString, (uint64) createTimestamp),
true);
fPackageInfo->AddUserRating(userRating);
HDDEBUG("rating [%s] retrieved from server", code.String());
}
fPackageInfo->SetDidPopulateUserRatings();
HDDEBUG("did retrieve %" B_PRIi32 " user ratings for [%s]", index - 1,
packageName.String());
}
} else {
int32 errorCode = WebAppInterface::ErrorCodeFromResponse(info);
if (errorCode != ERROR_CODE_NONE)
ServerHelper::NotifyServerJsonRpcError(info);
}
} else {
ServerHelper::NotifyTransportError(status);
}
return status;
}