2 * Copyright 2017, Andrew Lindesay <apl@lindesay.co.nz>.
3 * All rights reserved. Distributed under the terms of the MIT License.
6 #include "RepositoryDataUpdateProcess.h"
15 #include "ServerSettings.h"
16 #include "StorageUtils.h"
17 #include "DumpExportRepository.h"
18 #include "DumpExportRepositorySource.h"
19 #include "DumpExportRepositoryJsonListener.h"
22 /*! This repository listener (not at the JSON level) is feeding in the
23 repositories as they are parsed and processing them. Processing
24 includes finding the matching depot record and coupling the data
25 from the server with the data about the depot.
28 class DepotMatchingRepositoryListener
: public DumpExportRepositoryListener
{
30 DepotMatchingRepositoryListener(
31 DepotList
* depotList
);
32 virtual ~DepotMatchingRepositoryListener();
34 virtual void Handle(DumpExportRepository
* item
);
35 virtual void Complete();
38 void NormalizeUrl(BUrl
& url
) const;
39 bool IsUnassociatedDepotByUrl(
40 const DepotInfo
& depotInfo
,
41 const BString
& urlStr
) const;
43 int32
IndexOfUnassociatedDepotByUrl(
44 const BString
& url
) const;
46 DepotList
* fDepotList
;
51 DepotMatchingRepositoryListener::DepotMatchingRepositoryListener(
54 fDepotList
= depotList
;
58 DepotMatchingRepositoryListener::~DepotMatchingRepositoryListener()
64 DepotMatchingRepositoryListener::NormalizeUrl(BUrl
& url
) const
66 if (url
.Protocol() == "https")
67 url
.SetProtocol("http");
69 BString
path(url
.Path());
71 if (path
.EndsWith("/"))
72 url
.SetPath(path
.Truncate(path
.Length() - 1));
77 DepotMatchingRepositoryListener::IsUnassociatedDepotByUrl(
78 const DepotInfo
& depotInfo
, const BString
& urlStr
) const
80 if (depotInfo
.BaseURL().Length() > 0
81 && depotInfo
.WebAppRepositorySourceCode().Length() == 0) {
82 BUrl
depotInfoBaseUrl(depotInfo
.BaseURL());
85 NormalizeUrl(depotInfoBaseUrl
);
88 if (depotInfoBaseUrl
== url
)
97 DepotMatchingRepositoryListener::IndexOfUnassociatedDepotByUrl(
98 const BString
& url
) const
102 for (i
= 0; i
< fDepotList
->CountItems(); i
++) {
103 const DepotInfo
& depot
= fDepotList
->ItemAt(i
);
105 if (IsUnassociatedDepotByUrl(depot
, url
))
114 DepotMatchingRepositoryListener::Handle(DumpExportRepository
* repository
)
118 for (i
= 0; i
< repository
->CountRepositorySources(); i
++) {
119 DumpExportRepositorySource
*repositorySource
=
120 repository
->RepositorySourcesItemAt(i
);
121 int32 depotIndex
= IndexOfUnassociatedDepotByUrl(
122 *(repositorySource
->Url()));
124 if (depotIndex
>= 0) {
125 DepotInfo
modifiedDepotInfo(fDepotList
->ItemAt(depotIndex
));
126 modifiedDepotInfo
.SetWebAppRepositoryCode(
127 BString(*(repository
->Code())));
128 modifiedDepotInfo
.SetWebAppRepositorySourceCode(
129 BString(*(repositorySource
->Code())));
130 fDepotList
->Replace(depotIndex
, modifiedDepotInfo
);
132 printf("associated depot [%s] with server"
133 " repository source [%s]\n", modifiedDepotInfo
.Name().String(),
134 repositorySource
->Code()->String());
141 DepotMatchingRepositoryListener::Complete()
145 for (i
= 0; i
< fDepotList
->CountItems(); i
++) {
146 const DepotInfo
& depot
= fDepotList
->ItemAt(i
);
148 if (depot
.WebAppRepositoryCode().Length() == 0) {
149 printf("depot [%s]", depot
.Name().String());
151 if (depot
.BaseURL().Length() > 0)
152 printf(" (%s)", depot
.BaseURL().String());
154 printf(" correlates with no repository in the haiku"
155 "depot server system\n");
161 RepositoryDataUpdateProcess::RepositoryDataUpdateProcess(
162 const BPath
& localFilePath
,
163 DepotList
* depotList
)
165 fLocalFilePath
= localFilePath
;
166 fDepotList
= depotList
;
170 RepositoryDataUpdateProcess::~RepositoryDataUpdateProcess()
176 RepositoryDataUpdateProcess::Run()
178 printf("will fetch repositories data\n");
180 // TODO: add language ISO code to the path; just 'en' for now.
181 status_t result
= DownloadToLocalFile(fLocalFilePath
,
182 ServerSettings::CreateFullUrl("/__repository/all-en.json.gz"),
185 if (result
== B_OK
|| result
== APP_ERR_NOT_MODIFIED
) {
186 printf("did fetch repositories data\n");
188 // now load the data in and process it.
190 printf("will process repository data and match to depots\n");
191 result
= PopulateDataToDepots();
195 printf("did process repository data and match to depots\n");
198 MoveDamagedFileAside(fLocalFilePath
);
203 printf("an error has arisen downloading the repositories' data\n");
211 RepositoryDataUpdateProcess::PopulateDataToDepots()
213 DepotMatchingRepositoryListener
* itemListener
=
214 new DepotMatchingRepositoryListener(fDepotList
);
216 BulkContainerDumpExportRepositoryJsonListener
* listener
=
217 new BulkContainerDumpExportRepositoryJsonListener(itemListener
);
219 status_t result
= ParseJsonFromFileWithListener(listener
, fLocalFilePath
);
224 return listener
->ErrorStatus();
229 RepositoryDataUpdateProcess::GetStandardMetaDataPath(BPath
& path
) const
231 path
.SetTo(fLocalFilePath
.Path());
236 RepositoryDataUpdateProcess::GetStandardMetaDataJsonPath(
237 BString
& jsonPath
) const
239 jsonPath
.SetTo("$.info");
244 RepositoryDataUpdateProcess::LoggingName() const
246 return "repo-data-update";