xref: /haiku/src/apps/haikudepot/server/ServerReferenceDataUpdateProcess.cpp (revision a5061ecec55353a5f394759473f1fd6df04890da)
1 /*
2  * Copyright 2019-2020, Andrew Lindesay <apl@lindesay.co.nz>.
3  * All rights reserved. Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include "ServerReferenceDataUpdateProcess.h"
8 
9 #include <stdio.h>
10 #include <sys/stat.h>
11 #include <time.h>
12 
13 #include <AutoDeleter.h>
14 #include <AutoLocker.h>
15 #include <Catalog.h>
16 #include <FileIO.h>
17 #include <Url.h>
18 
19 #include "ServerSettings.h"
20 #include "StorageUtils.h"
21 #include "Logger.h"
22 #include "DumpExportReference.h"
23 #include "DumpExportReferenceNaturalLanguage.h"
24 #include "DumpExportReferencePkgCategory.h"
25 #include "DumpExportReferenceUserRatingStability.h"
26 #include "DumpExportReferenceCountry.h"
27 #include "DumpExportReferenceJsonListener.h"
28 
29 
30 #undef B_TRANSLATION_CONTEXT
31 #define B_TRANSLATION_CONTEXT "ServerReferenceDataUpdateProcess"
32 
33 
34 ServerReferenceDataUpdateProcess::ServerReferenceDataUpdateProcess(
35 	Model* model,
36 	uint32 serverProcessOptions)
37 	:
38 	AbstractSingleFileServerProcess(serverProcessOptions),
39 	fModel(model)
40 {
41 }
42 
43 
44 ServerReferenceDataUpdateProcess::~ServerReferenceDataUpdateProcess()
45 {
46 }
47 
48 
49 const char*
50 ServerReferenceDataUpdateProcess::Name() const
51 {
52 	return "ServerReferenceDataUpdateProcess";
53 }
54 
55 
56 const char*
57 ServerReferenceDataUpdateProcess::Description() const
58 {
59 	return B_TRANSLATE("Synchronizing reference data from server");
60 }
61 
62 
63 BString
64 ServerReferenceDataUpdateProcess::UrlPathComponent()
65 {
66 	BString result;
67 	AutoLocker<BLocker> locker(fModel->Lock());
68 	result.SetToFormat("/__reference/all-%s.json.gz",
69 		fModel->Language()->PreferredLanguage()->Code());
70 	return result;
71 }
72 
73 
74 status_t
75 ServerReferenceDataUpdateProcess::GetLocalPath(BPath& path) const
76 {
77 	AutoLocker<BLocker> locker(fModel->Lock());
78 	return fModel->DumpExportReferenceDataPath(path);
79 }
80 
81 
82 status_t
83 ServerReferenceDataUpdateProcess::ProcessLocalData()
84 {
85 	SingleDumpExportReferenceJsonListener* listener =
86 		new SingleDumpExportReferenceJsonListener();
87 
88 	BPath localPath;
89 	status_t result = GetLocalPath(localPath);
90 
91 	if (result != B_OK)
92 		return result;
93 
94 	result = ParseJsonFromFileWithListener(listener, localPath);
95 
96 	if (result != B_OK)
97 		return result;
98 
99 	result = listener->ErrorStatus();
100 
101 	if (result != B_OK)
102 		return result;
103 
104 	return _ProcessData(listener->Target());
105 }
106 
107 
108 status_t
109 ServerReferenceDataUpdateProcess::_ProcessData(DumpExportReference* data)
110 {
111 	status_t result = B_OK;
112 	if (result == B_OK)
113 		result = _ProcessNaturalLanguages(data);
114 	if (result == B_OK)
115 		result = _ProcessPkgCategories(data);
116 	if (result == B_OK)
117 		result = _ProcessRatingStabilities(data);
118 	return result;
119 }
120 
121 
122 status_t
123 ServerReferenceDataUpdateProcess::_ProcessNaturalLanguages(
124 	DumpExportReference* data)
125 {
126 	HDINFO("[%s] will populate %" B_PRId32 " natural languages",
127 		Name(), data->CountNaturalLanguages());
128 	AutoLocker<BLocker> locker(fModel->Lock());
129 	LanguageModel* languageModel = fModel->Language();
130 	int32 count = 0;
131 
132 	for (int32 i = 0; i < data->CountNaturalLanguages(); i++) {
133 		DumpExportReferenceNaturalLanguage* naturalLanguage =
134 			data->NaturalLanguagesItemAt(i);
135 		languageModel->AddSupportedLanguage(LanguageRef(
136 			new Language(
137 				*(naturalLanguage->Code()),
138 				*(naturalLanguage->Name()),
139 				naturalLanguage->IsPopular()
140 			),
141 			true)
142 		);
143 		count++;
144 	}
145 
146 	languageModel->SetPreferredLanguageToSystemDefault();
147 
148 	HDINFO("[%s] did add %" B_PRId32 " supported languages",
149 		Name(), count);
150 
151 	return B_OK;
152 }
153 
154 
155 status_t
156 ServerReferenceDataUpdateProcess::_ProcessPkgCategories(
157 	DumpExportReference* data)
158 {
159 	HDINFO("[%s] will populate %" B_PRId32 " pkg categories",
160 		Name(), data->CountPkgCategories());
161 
162 	std::vector<CategoryRef> assembledCategories;
163 
164 	for (int32 i = 0; i < data->CountPkgCategories(); i++) {
165 		DumpExportReferencePkgCategory* pkgCategory =
166 			data->PkgCategoriesItemAt(i);
167 		assembledCategories.push_back(CategoryRef(
168 			new PackageCategory(
169 				*(pkgCategory->Code()),
170 				*(pkgCategory->Name())
171 			),
172 			true));
173 	}
174 
175 	{
176 		AutoLocker<BLocker> locker(fModel->Lock());
177 		fModel->AddCategories(assembledCategories);
178 	}
179 
180 	return B_OK;
181 }
182 
183 
184 status_t
185 ServerReferenceDataUpdateProcess::_ProcessRatingStabilities(
186 	DumpExportReference* data)
187 {
188 	HDINFO("[%s] will populate %" B_PRId32 " rating stabilities",
189 		Name(), data->CountUserRatingStabilities());
190 
191 	std::vector<RatingStabilityRef> assembledRatingStabilities;
192 
193 	for (int32 i = 0; i < data->CountUserRatingStabilities(); i++) {
194 		DumpExportReferenceUserRatingStability* ratingStability =
195 			data->UserRatingStabilitiesItemAt(i);
196 		assembledRatingStabilities.push_back(RatingStabilityRef(
197 			new RatingStability(
198 				*(ratingStability->Code()),
199 				*(ratingStability->Name()),
200 				ratingStability->Ordering()
201 			),
202 			true));
203 	}
204 
205 	{
206 		AutoLocker<BLocker> locker(fModel->Lock());
207 		fModel->AddRatingStabilities(assembledRatingStabilities);
208 	}
209 
210 	return B_OK;
211 }
212 
213 
214 status_t
215 ServerReferenceDataUpdateProcess::GetStandardMetaDataPath(BPath& path) const
216 {
217 	return GetLocalPath(path);
218 }
219 
220 
221 void
222 ServerReferenceDataUpdateProcess::GetStandardMetaDataJsonPath(
223 	BString& jsonPath) const
224 {
225 	jsonPath.SetTo("$.info");
226 }
227