repository_infos: Enable automatic updates on the main Haiku repostiory.
[haiku.git] / src / apps / haikudepot / server / PkgDataUpdateProcess.cpp
blob961f8a447a6866270148be16485ee6e4b8957fee
1 /*
2 * Copyright 2017, Andrew Lindesay <apl@lindesay.co.nz>.
3 * All rights reserved. Distributed under the terms of the MIT License.
4 */
6 #include "PkgDataUpdateProcess.h"
8 #include <stdio.h>
9 #include <sys/stat.h>
10 #include <time.h>
12 #include <Autolock.h>
13 #include <FileIO.h>
14 #include <Url.h>
16 #include "Logger.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 {
31 public:
32 PackageFillingPkgListener(
33 const PackageList& packages,
34 const CategoryList& categories,
35 BLocker& lock);
36 virtual ~PackageFillingPkgListener();
38 virtual void Handle(DumpExportPkg* item);
39 virtual void Complete();
41 private:
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;
49 BLocker& fLock;
55 PackageFillingPkgListener::PackageFillingPkgListener(
56 const PackageList& packages, const CategoryList& categories,
57 BLocker& lock)
59 fPackages(packages),
60 fCategories(categories),
61 fLock(lock)
66 PackageFillingPkgListener::~PackageFillingPkgListener()
71 // TODO; performance could be improved by not needing the linear search
73 int32
74 PackageFillingPkgListener::IndexOfPackageByName(
75 const BString& name) const
77 int32 i;
79 for (i = 0; i < fPackages.CountItems(); i++) {
80 const PackageInfoRef& packageInfo = fPackages.ItemAt(i);
82 if (packageInfo->Name() == name)
83 return i;
86 return -1;
90 // TODO; performance could be improved by not needing the linear search
92 int32
93 PackageFillingPkgListener::IndexOfCategoryByName(
94 const BString& name) const
96 int32 i;
98 for (i = 0; i < fCategories.CountItems(); i++) {
99 const CategoryRef categoryRef = fCategories.ItemAtFast(i);
101 if (categoryRef->Name() == name)
102 return i;
105 return -1;
109 void
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());
118 } else {
119 int32 i;
120 const PackageInfoRef& packageInfo = fPackages.ItemAt(packageIndex);
122 if (0 != pkg->CountPkgVersions()) {
124 // this makes the assumption that the only version will be the
125 // latest one.
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());
150 } else {
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());
187 void
188 PackageFillingPkgListener::Complete()
193 PkgDataUpdateProcess::PkgDataUpdateProcess(
194 const BPath& localFilePath,
195 BLocker& lock,
196 BString repositorySourceCode,
197 BString naturalLanguageCode,
198 const PackageList& packages,
199 const CategoryList& categories)
201 fLocalFilePath(localFilePath),
202 fNaturalLanguageCode(naturalLanguageCode),
203 fRepositorySourceCode(repositorySourceCode),
204 fPackages(packages),
205 fCategories(categories),
206 fLock(lock)
211 PkgDataUpdateProcess::~PkgDataUpdateProcess()
216 status_t
217 PkgDataUpdateProcess::Run()
219 printf("will fetch packages' data\n");
221 BString urlPath;
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),
228 0, 0);
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();
238 switch (result) {
239 case B_OK:
240 printf("did process packages' data\n");
241 break;
242 default:
243 MoveDamagedFileAside(fLocalFilePath);
244 break;
248 return result;
252 status_t
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);
263 if (B_OK != result)
264 return result;
266 return listener->ErrorStatus();
270 void
271 PkgDataUpdateProcess::GetStandardMetaDataPath(BPath& path) const
273 path.SetTo(fLocalFilePath.Path());
277 void
278 PkgDataUpdateProcess::GetStandardMetaDataJsonPath(
279 BString& jsonPath) const
281 jsonPath.SetTo("$.info");
285 const char*
286 PkgDataUpdateProcess::LoggingName() const
288 return "pkg-data-update";