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