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