xref: /haiku/src/apps/haikudepot/server/ServerReferenceDataUpdateProcess.cpp (revision 9f3bdf3d039430b5172c424def20ce5d9f7367d4)
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()->ID());
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 from %" B_PRId32 " possible natural languages",
127 		Name(), data->CountNaturalLanguages());
128 	AutoLocker<BLocker> locker(fModel->Lock());
129 	LanguageModel* languageModel = fModel->Language();
130 	languageModel->ClearSupportedLanguages();
131 	int32 count = 0;
132 
133 	for (int32 i = 0; i < data->CountNaturalLanguages(); i++) {
134 		DumpExportReferenceNaturalLanguage* naturalLanguage =
135 			data->NaturalLanguagesItemAt(i);
136 		languageModel->AddSupportedLanguage(LanguageRef(
137 			new Language(
138 				*(naturalLanguage->Code()),
139 				*(naturalLanguage->Name()),
140 				naturalLanguage->IsPopular()
141 			),
142 			true)
143 		);
144 		count++;
145 	}
146 
147 	languageModel->SetPreferredLanguageToSystemDefault();
148 
149 	HDINFO("[%s] did add %" B_PRId32 " supported languages",
150 		Name(), count);
151 
152 	return B_OK;
153 }
154 
155 
156 status_t
157 ServerReferenceDataUpdateProcess::_ProcessPkgCategories(
158 	DumpExportReference* data)
159 {
160 	HDINFO("[%s] will populate %" B_PRId32 " pkg categories",
161 		Name(), data->CountPkgCategories());
162 
163 	std::vector<CategoryRef> assembledCategories;
164 
165 	for (int32 i = 0; i < data->CountPkgCategories(); i++) {
166 		DumpExportReferencePkgCategory* pkgCategory =
167 			data->PkgCategoriesItemAt(i);
168 		assembledCategories.push_back(CategoryRef(
169 			new PackageCategory(
170 				*(pkgCategory->Code()),
171 				*(pkgCategory->Name())
172 			),
173 			true));
174 	}
175 
176 	{
177 		AutoLocker<BLocker> locker(fModel->Lock());
178 		fModel->AddCategories(assembledCategories);
179 	}
180 
181 	return B_OK;
182 }
183 
184 
185 status_t
186 ServerReferenceDataUpdateProcess::_ProcessRatingStabilities(
187 	DumpExportReference* data)
188 {
189 	HDINFO("[%s] will populate %" B_PRId32 " rating stabilities",
190 		Name(), data->CountUserRatingStabilities());
191 
192 	std::vector<RatingStabilityRef> assembledRatingStabilities;
193 
194 	for (int32 i = 0; i < data->CountUserRatingStabilities(); i++) {
195 		DumpExportReferenceUserRatingStability* ratingStability =
196 			data->UserRatingStabilitiesItemAt(i);
197 		assembledRatingStabilities.push_back(RatingStabilityRef(
198 			new RatingStability(
199 				*(ratingStability->Code()),
200 				*(ratingStability->Name()),
201 				ratingStability->Ordering()
202 			),
203 			true));
204 	}
205 
206 	{
207 		AutoLocker<BLocker> locker(fModel->Lock());
208 		fModel->AddRatingStabilities(assembledRatingStabilities);
209 	}
210 
211 	return B_OK;
212 }
213 
214 
215 status_t
216 ServerReferenceDataUpdateProcess::GetStandardMetaDataPath(BPath& path) const
217 {
218 	return GetLocalPath(path);
219 }
220 
221 
222 void
223 ServerReferenceDataUpdateProcess::GetStandardMetaDataJsonPath(
224 	BString& jsonPath) const
225 {
226 	jsonPath.SetTo("$.info");
227 }
228