2 * Copyright 2017, Andrew Lindesay <apl@lindesay.co.nz>.
3 * All rights reserved. Distributed under the terms of the MIT License.
6 #include "PkgDataUpdateProcess.h"
17 #include "ServerSettings.h"
18 #include "StorageUtils.h"
19 #include "DumpExportPkg.h"
20 #include "DumpExportPkgCategory.h"
21 #include "DumpExportPkgJsonListener.h"
22 #include "DumpExportPkgScreenshot.h"
23 #include "DumpExportPkgVersion.h"
26 /*! This package listener (not at the JSON level) is feeding in the
27 packages as they are parsed and processing them.
30 class PackageFillingPkgListener
: public DumpExportPkgListener
{
32 PackageFillingPkgListener(
33 const PackageList
& packages
,
34 const CategoryList
& categories
,
36 virtual ~PackageFillingPkgListener();
38 virtual void Handle(DumpExportPkg
* item
);
39 virtual void Complete();
42 int32
IndexOfPackageByName(const BString
& name
) const;
43 int32
IndexOfCategoryByName(
44 const BString
& name
) const;
45 int32
IndexOfCategoryByCode(
46 const BString
& code
) const;
47 const PackageList
& fPackages
;
48 const CategoryList
& fCategories
;
55 PackageFillingPkgListener::PackageFillingPkgListener(
56 const PackageList
& packages
, const CategoryList
& categories
,
60 fCategories(categories
),
66 PackageFillingPkgListener::~PackageFillingPkgListener()
71 // TODO; performance could be improved by not needing the linear search
74 PackageFillingPkgListener::IndexOfPackageByName(
75 const BString
& name
) const
79 for (i
= 0; i
< fPackages
.CountItems(); i
++) {
80 const PackageInfoRef
& packageInfo
= fPackages
.ItemAt(i
);
82 if (packageInfo
->Name() == name
)
90 // TODO; performance could be improved by not needing the linear search
93 PackageFillingPkgListener::IndexOfCategoryByName(
94 const BString
& name
) const
98 for (i
= 0; i
< fCategories
.CountItems(); i
++) {
99 const CategoryRef categoryRef
= fCategories
.ItemAtFast(i
);
101 if (categoryRef
->Name() == name
)
110 PackageFillingPkgListener::Handle(DumpExportPkg
* pkg
)
112 BAutolock
locker(fLock
); // lock from the model.
113 int32 packageIndex
= IndexOfPackageByName(*(pkg
->Name()));
115 if (packageIndex
== -1) {
116 printf("unable to find package data for pkg name [%s]\n",
117 pkg
->Name()->String());
120 const PackageInfoRef
& packageInfo
= fPackages
.ItemAt(packageIndex
);
122 if (0 != pkg
->CountPkgVersions()) {
124 // this makes the assumption that the only version will be the
127 DumpExportPkgVersion
* pkgVersion
= pkg
->PkgVersionsItemAt(0);
129 if (!pkgVersion
->TitleIsNull())
130 packageInfo
->SetTitle(*(pkgVersion
->Title()));
132 if (!pkgVersion
->SummaryIsNull())
133 packageInfo
->SetShortDescription(*(pkgVersion
->Summary()));
135 if (!pkgVersion
->DescriptionIsNull()) {
136 packageInfo
->SetFullDescription(*(pkgVersion
->Description()));
139 if (!pkgVersion
->PayloadLengthIsNull())
140 packageInfo
->SetSize(pkgVersion
->PayloadLength());
143 for (i
= 0; i
< pkg
->CountPkgCategories(); i
++) {
144 BString
* categoryCode
= pkg
->PkgCategoriesItemAt(i
)->Code();
145 int categoryIndex
= IndexOfCategoryByName(*(categoryCode
));
147 if (categoryIndex
== -1) {
148 printf("unable to find the category for [%s]\n",
149 categoryCode
->String());
151 packageInfo
->AddCategory(
152 fCategories
.ItemAtFast(categoryIndex
));
156 if (!pkg
->DerivedRatingIsNull()) {
157 RatingSummary summary
;
158 summary
.averageRating
= pkg
->DerivedRating();
159 packageInfo
->SetRatingSummary(summary
);
162 if (!pkg
->ProminenceOrderingIsNull()) {
163 packageInfo
->SetProminence(pkg
->ProminenceOrdering());
166 if (!pkg
->PkgChangelogContentIsNull()) {
167 packageInfo
->SetChangelog(*(pkg
->PkgChangelogContent()));
170 for (i
= 0; i
< pkg
->CountPkgScreenshots(); i
++) {
171 DumpExportPkgScreenshot
* screenshot
= pkg
->PkgScreenshotsItemAt(i
);
172 packageInfo
->AddScreenshotInfo(ScreenshotInfo(
173 *(screenshot
->Code()),
174 static_cast<int32
>(screenshot
->Width()),
175 static_cast<int32
>(screenshot
->Height()),
176 static_cast<int32
>(screenshot
->Length())
180 if (Logger::IsDebugEnabled()) {
181 printf("did populate data for [%s]\n", pkg
->Name()->String());
188 PackageFillingPkgListener::Complete()
193 PkgDataUpdateProcess::PkgDataUpdateProcess(
194 const BPath
& localFilePath
,
196 BString repositorySourceCode
,
197 BString naturalLanguageCode
,
198 const PackageList
& packages
,
199 const CategoryList
& categories
)
201 fLocalFilePath(localFilePath
),
202 fNaturalLanguageCode(naturalLanguageCode
),
203 fRepositorySourceCode(repositorySourceCode
),
205 fCategories(categories
),
211 PkgDataUpdateProcess::~PkgDataUpdateProcess()
217 PkgDataUpdateProcess::Run()
219 printf("will fetch packages' data\n");
222 urlPath
.SetToFormat("/__pkg/all-%s-%s.json.gz",
223 fRepositorySourceCode
.String(),
224 fNaturalLanguageCode
.String());
226 status_t result
= DownloadToLocalFile(fLocalFilePath
,
227 ServerSettings::CreateFullUrl(urlPath
),
230 if (result
== B_OK
|| result
== APP_ERR_NOT_MODIFIED
) {
231 printf("did fetch packages' data\n");
233 // now load the data in and process it.
235 printf("will process packages' data\n");
236 result
= PopulateDataToDepots();
240 printf("did process packages' data\n");
243 MoveDamagedFileAside(fLocalFilePath
);
253 PkgDataUpdateProcess::PopulateDataToDepots()
255 PackageFillingPkgListener
* itemListener
=
256 new PackageFillingPkgListener(fPackages
, fCategories
, fLock
);
258 BulkContainerDumpExportPkgJsonListener
* listener
=
259 new BulkContainerDumpExportPkgJsonListener(itemListener
);
261 status_t result
= ParseJsonFromFileWithListener(listener
, fLocalFilePath
);
266 return listener
->ErrorStatus();
271 PkgDataUpdateProcess::GetStandardMetaDataPath(BPath
& path
) const
273 path
.SetTo(fLocalFilePath
.Path());
278 PkgDataUpdateProcess::GetStandardMetaDataJsonPath(
279 BString
& jsonPath
) const
281 jsonPath
.SetTo("$.info");
286 PkgDataUpdateProcess::LoggingName() const
288 return "pkg-data-update";