| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * This file is part of the Falcon Player (FPP) and is Copyright (C) | ||
| 3 | * 2013-2022 by the Falcon Player Developers. | ||
| 4 | * | ||
| 5 | * The Falcon Player (FPP) is free software, and is covered under | ||
| 6 | * multiple Open Source licenses. Please see the included 'LICENSES' | ||
| 7 | * file for descriptions of what files are covered by each license. | ||
| 8 | * | ||
| 9 | * This source file is covered under the LGPL v2.1 as described in the | ||
| 10 | * included LICENSE.LGPL file. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include "fpp-pch.h" | ||
| 14 | |||
| 15 | #include "fpp-json.h" | ||
| 16 | |||
| 17 | #include <sys/stat.h> | ||
| 18 | |||
| 19 | #include "common.h" | ||
| 20 | #include "settings.h" | ||
| 21 | #include "commands/Commands.h" | ||
| 22 | |||
| 23 | #include "FPPLocale.h" | ||
| 24 | |||
| 25 | Json::Value LocaleHolder::locale; | ||
| 26 | std::mutex LocaleHolder::localeLock; | ||
| 27 | std::string LocaleHolder::localeKey; | ||
| 28 | |||
| 29 | // The cache is rebuilt whenever what it was built from changes, whoever | ||
| 30 | // changed it: the holiday editor writes user-holidays.json through the | ||
| 31 | // config file API, and Locale can change from the UI, an upload or a | ||
| 32 | // restored backup. Only clearing it on request left fppd scheduling with the | ||
| 33 | // old holidays until it restarted. | ||
| 34 | 43813 | static std::string LocaleSourceKey(const std::string& localeName, const std::string& userHolidaysFile) { | |
| 35 |
1/2✓ Branch 0 taken 43813 times.
✗ Branch 1 not taken.
|
43813 | std::string key = localeName; |
| 36 | struct stat st; | ||
| 37 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 43811 times.
|
43813 | if (stat(userHolidaysFile.c_str(), &st) == 0) { |
| 38 | #ifdef PLATFORM_OSX | ||
| 39 | const struct timespec& mt = st.st_mtimespec; | ||
| 40 | #else | ||
| 41 | 2 | const struct timespec& mt = st.st_mtim; | |
| 42 | #endif | ||
| 43 |
3/6✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
|
4 | key += "|" + std::to_string((long long)st.st_size) + "|" + |
| 44 |
6/12✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
|
6 | std::to_string((long long)mt.tv_sec) + "." + std::to_string((long long)mt.tv_nsec); |
| 45 | } | ||
| 46 | 43813 | return key; | |
| 47 | ✗ | } | |
| 48 | |||
| 49 | 43813 | Json::Value LocaleHolder::GetLocale() { | |
| 50 |
1/2✓ Branch 0 taken 43813 times.
✗ Branch 1 not taken.
|
43813 | std::unique_lock<std::mutex> lock(localeLock); |
| 51 | |||
| 52 |
1/2✓ Branch 0 taken 43813 times.
✗ Branch 1 not taken.
|
43813 | std::string localeName = getSetting("Locale"); |
| 53 | |||
| 54 |
2/4✓ Branch 0 taken 43813 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 43813 times.
|
43813 | if (localeName == "") |
| 55 | ✗ | localeName = "Global"; | |
| 56 | |||
| 57 |
3/6✓ Branch 0 taken 43813 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 43813 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 43813 times.
✗ Branch 5 not taken.
|
43813 | std::string userHolidaysFile = FPP_DIR_CONFIG("/user-holidays.json"); |
| 58 |
1/2✓ Branch 0 taken 43813 times.
✗ Branch 1 not taken.
|
43813 | std::string key = LocaleSourceKey(localeName, userHolidaysFile); |
| 59 |
7/8✓ Branch 0 taken 43813 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 43754 times.
✓ Branch 3 taken 59 times.
✓ Branch 4 taken 43752 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 43752 times.
✓ Branch 7 taken 61 times.
|
43813 | if (locale.size() && key == localeKey) |
| 60 |
1/2✓ Branch 0 taken 43752 times.
✗ Branch 1 not taken.
|
43752 | return locale; |
| 61 |
1/2✓ Branch 0 taken 61 times.
✗ Branch 1 not taken.
|
61 | locale.clear(); |
| 62 |
1/2✓ Branch 0 taken 61 times.
✗ Branch 1 not taken.
|
61 | localeKey = key; |
| 63 | |||
| 64 | // From fppd's own tree, not /opt/fpp: an install anywhere else (macOS, a | ||
| 65 | // test tree) found no locale file, so every holiday name in the schedule | ||
| 66 | // was unknown. | ||
| 67 |
3/6✓ Branch 0 taken 61 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 61 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 61 times.
✗ Branch 5 not taken.
|
61 | std::string localeFile = getFPPDDir("/etc/locale/" + localeName + ".json"); |
| 68 | |||
| 69 |
2/4✓ Branch 0 taken 61 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 61 times.
|
61 | if (!FileExists(localeFile)) { |
| 70 | ✗ | localeFile = getFPPDDir("/etc/locale/Global.json"); | |
| 71 | } | ||
| 72 | |||
| 73 |
1/2✓ Branch 0 taken 61 times.
✗ Branch 1 not taken.
|
61 | bool result = LoadJsonFromFile(localeFile, locale, JsonRoot::Object); |
| 74 | |||
| 75 |
1/2✓ Branch 0 taken 61 times.
✗ Branch 1 not taken.
|
61 | if (result) { |
| 76 | // Load user-defined holidays and merge them with locale holidays | ||
| 77 |
3/4✓ Branch 0 taken 61 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 60 times.
|
61 | if (FileExists(userHolidaysFile)) { |
| 78 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | Json::Value userHolidays; |
| 79 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | if (LoadJsonFromFile(userHolidaysFile, userHolidays, JsonRoot::Array)) { |
| 80 |
5/10✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
|
1 | if (userHolidays.isArray() && userHolidays.size() > 0) { |
| 81 | // Ensure the locale has a holidays array | ||
| 82 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
1 | if (!locale.isMember("holidays")) { |
| 83 | ✗ | locale["holidays"] = Json::Value(Json::arrayValue); | |
| 84 | } | ||
| 85 | |||
| 86 | // Append user-defined holidays to the locale holidays | ||
| 87 |
3/4✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
|
2 | for (Json::ArrayIndex i = 0; i < userHolidays.size(); i++) { |
| 88 |
3/6✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | locale["holidays"].append(userHolidays[i]); |
| 89 | } | ||
| 90 | } | ||
| 91 | } | ||
| 92 | 1 | } | |
| 93 |
1/2✓ Branch 0 taken 61 times.
✗ Branch 1 not taken.
|
61 | return locale; |
| 94 | } | ||
| 95 | |||
| 96 | ✗ | Json::Value empty; | |
| 97 | |||
| 98 | ✗ | return empty; | |
| 99 | 43813 | } | |
| 100 | |||
| 101 | ✗ | void LocaleHolder::ClearCache() { | |
| 102 | ✗ | std::unique_lock<std::mutex> lock(localeLock); | |
| 103 | ✗ | locale.clear(); | |
| 104 | ✗ | localeKey.clear(); | |
| 105 | ✗ | } | |
| 106 | |||
| 107 | /**********************************************************************/ | ||
| 108 | // Command to clear the locale cache | ||
| 109 | class ClearLocaleCacheCommand : public Command { | ||
| 110 | public: | ||
| 111 |
2/4✓ Branch 0 taken 1887 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1887 times.
✗ Branch 3 not taken.
|
3774 | ClearLocaleCacheCommand() : Command("Clear Locale Cache") { |
| 112 |
6/12✓ Branch 0 taken 1887 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1887 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1887 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1887 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1887 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1887 times.
✗ Branch 11 not taken.
|
11322 | args.push_back(CommandArg("force", "bool", "Force Clear").setDefaultValue("true")); |
| 113 | 1887 | } | |
| 114 | |||
| 115 | ✗ | virtual std::unique_ptr<Command::Result> run(const std::vector<std::string>& args) override { | |
| 116 | ✗ | LocaleHolder::ClearCache(); | |
| 117 | ✗ | return std::make_unique<Command::Result>("Locale cache cleared"); | |
| 118 | } | ||
| 119 | }; | ||
| 120 | |||
| 121 | 1887 | void LocaleHolder::RegisterCommands() { | |
| 122 |
6/12✓ Branch 0 taken 1887 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1887 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1887 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1727 times.
✓ Branch 7 taken 160 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 1727 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
2207 | CommandManager::INSTANCE.addCategorizedCommand(new ClearLocaleCacheCommand(), "System", 3); |
| 123 | 1887 | } | |
| 124 |