xref: /haiku/src/apps/haikudepot/server/ServerReferenceDataUpdateProcess.cpp (revision 21258e2674226d6aa732321b6f8494841895af5f)
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 	return result;
117 }
118 
119 
120 status_t
121 ServerReferenceDataUpdateProcess::_ProcessNaturalLanguages(
122 	DumpExportReference* data)
123 {
124 	HDINFO("[%s] will populate %" B_PRId32 " natural languages",
125 		Name(), data->CountNaturalLanguages());
126 	AutoLocker<BLocker> locker(fModel->Lock());
127 	LanguageModel* languageModel = fModel->Language();
128 	int32 count = 0;
129 
130 	for (int32 i = 0; i < data->CountNaturalLanguages(); i++) {
131 		DumpExportReferenceNaturalLanguage* naturalLanguage =
132 			data->NaturalLanguagesItemAt(i);
133 		languageModel->AddSupportedLanguage(LanguageRef(
134 			new Language(
135 				*(naturalLanguage->Code()),
136 				*(naturalLanguage->Name()),
137 				naturalLanguage->IsPopular()
138 			),
139 			true)
140 		);
141 		count++;
142 	}
143 
144 	languageModel->SetPreferredLanguageToSystemDefault();
145 
146 	HDINFO("[%s] did add %" B_PRId32 " supported languages",
147 		Name(), count);
148 
149 	return B_OK;
150 }
151 
152 
153 status_t
154 ServerReferenceDataUpdateProcess::_ProcessPkgCategories(
155 	DumpExportReference* data)
156 {
157 	HDINFO("[%s] will populate %" B_PRId32 " pkg categories",
158 		Name(), data->CountPkgCategories());
159 
160 	CategoryList result;
161 
162 	for (int32 i = 0; i < data->CountPkgCategories(); i++) {
163 		DumpExportReferencePkgCategory* pkgCategory =
164 			data->PkgCategoriesItemAt(i);
165 		result.Add(CategoryRef(
166 			new PackageCategory(
167 				*(pkgCategory->Code()),
168 				*(pkgCategory->Name())
169 			),
170 			true));
171 	}
172 
173 	{
174 		AutoLocker<BLocker> locker(fModel->Lock());
175 		fModel->AddCategories(result);
176 	}
177 
178 	return B_OK;
179 }
180 
181 
182 status_t
183 ServerReferenceDataUpdateProcess::GetStandardMetaDataPath(BPath& path) const
184 {
185 	return GetLocalPath(path);
186 }
187 
188 
189 void
190 ServerReferenceDataUpdateProcess::GetStandardMetaDataJsonPath(
191 	BString& jsonPath) const
192 {
193 	jsonPath.SetTo("$.info");
194 }
195