Serenity Operating System
at master 74 lines 2.5 kB view raw
1/* 2 * Copyright (c) 2021, Dex♪ <dexes.ttp@gmail.com> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/DeprecatedString.h> 8#include <AK/JsonArray.h> 9#include <AK/JsonObject.h> 10#include <AK/Vector.h> 11#include <LibCore/DeprecatedFile.h> 12#include <LibCore/File.h> 13#include <LibCore/StandardPaths.h> 14#include <LibGUI/CommonLocationsProvider.h> 15#include <unistd.h> 16 17namespace GUI { 18 19static bool s_initialized = false; 20static Vector<CommonLocationsProvider::CommonLocation> s_common_locations; 21 22static void initialize_if_needed() 23{ 24 if (s_initialized) 25 return; 26 27 auto user_config = DeprecatedString::formatted("{}/CommonLocations.json", Core::StandardPaths::config_directory()); 28 if (Core::DeprecatedFile::exists(user_config)) { 29 auto maybe_error = CommonLocationsProvider::load_from_json(user_config); 30 if (!maybe_error.is_error()) 31 return; 32 dbgln("Unable to read Common Locations file: {}", maybe_error.error()); 33 dbgln("Using the default set instead."); 34 } 35 36 // Fallback : If the user doesn't have custom locations, use some default ones. 37 s_common_locations.append({ "Root", "/" }); 38 s_common_locations.append({ "Home", Core::StandardPaths::home_directory() }); 39 s_common_locations.append({ "Downloads", Core::StandardPaths::downloads_directory() }); 40 s_initialized = true; 41} 42 43ErrorOr<void> CommonLocationsProvider::load_from_json(StringView json_path) 44{ 45 auto file = TRY(Core::File::open(json_path, Core::File::OpenMode::Read)); 46 auto json = JsonValue::from_string(TRY(file->read_until_eof())); 47 if (json.is_error()) 48 return Error::from_string_literal("File is not a valid JSON"); 49 if (!json.value().is_array()) 50 return Error::from_string_literal("File must contain a JSON array"); 51 52 s_common_locations.clear(); 53 auto const& contents = json.value().as_array(); 54 for (size_t i = 0; i < contents.size(); ++i) { 55 auto entry_value = contents.at(i); 56 if (!entry_value.is_object()) 57 continue; 58 auto entry = entry_value.as_object(); 59 auto name = entry.get_deprecated_string("name"sv).value_or({}); 60 auto path = entry.get_deprecated_string("path"sv).value_or({}); 61 TRY(s_common_locations.try_append({ name, path })); 62 } 63 64 s_initialized = true; 65 return {}; 66} 67 68Vector<CommonLocationsProvider::CommonLocation> const& CommonLocationsProvider::common_locations() 69{ 70 initialize_if_needed(); 71 return s_common_locations; 72} 73 74}