This commit is contained in:
Mars 2024-06-02 06:03:21 -04:00
parent 6e5045f1f4
commit 693fa17d10
Signed by: pupbrained
GPG key ID: 0FF5B8826803F895
266 changed files with 60543 additions and 1000 deletions

View file

@ -1,9 +1,10 @@
#include "config.h"
#include <fmt/core.h>
#include <toml++/toml.h>
#include <unistd.h>
#include <rfl.hpp>
#include <rfl/toml.hpp>
#include <toml++/toml.h>
#include <unistd.h>
#include "config.h"
#define DEFINE_GETTER(class_name, type, name) \
type class_name::get##name() const { \
@ -79,126 +80,3 @@ ConfigImpl ConfigImpl::from_class(const Config& config) noexcept {
Config ConfigImpl::to_class() const {
return {general, now_playing, weather};
}
boost::json::object Weather::getWeatherInfo() const {
using namespace std;
using namespace cpr;
using namespace boost;
using namespace std::chrono;
const Location loc = this->m_Location;
const string apiKey = this->m_ApiKey;
const string units = this->m_Units;
// Define cache file and cache duration
const string cacheFile = "/tmp/weather_cache.json";
constexpr minutes cacheDuration = minutes(10);
logi("Cache file: {}", cacheFile);
logi("Cache duration: {} minutes",
duration_cast<minutes>(cacheDuration).count());
// Function to read cache from file
auto readCacheFromFile =
[&]() -> optional<pair<json::object, system_clock::time_point>> {
ifstream ifs(cacheFile);
if (!ifs.is_open()) {
logi("Cache file not found.");
return nullopt;
}
logi("Reading from cache file...");
json::object cachedData;
system_clock::time_point timestamp;
try {
json::value val;
ifs >> val;
cachedData = val.as_object();
string tsStr = cachedData["timestamp"].as_string().c_str();
timestamp = system_clock::time_point(milliseconds(stoll(tsStr)));
cachedData.erase("timestamp");
} catch (...) {
loge("Failed to read from cache file.");
return nullopt;
}
logi("Successfully read from cache file.");
return make_pair(cachedData, timestamp);
};
// Function to write cache to file
auto writeCacheToFile = [&](const json::object& data) {
fmt::println("Writing to cache file...");
ofstream ofs(cacheFile);
if (!ofs.is_open()) {
loge("Failed to open cache file for writing.");
return;
}
json::object dataToWrite = data;
dataToWrite["timestamp"] = to_string(
duration_cast<milliseconds>(system_clock::now().time_since_epoch())
.count());
ofs << json::serialize(dataToWrite);
logi("Successfully wrote to cache file.");
};
// Check if cache is valid
if (auto cachedData = readCacheFromFile()) {
auto [data, timestamp] = *cachedData;
if (system_clock::now() - timestamp < cacheDuration) {
logi("Cache is valid. Returning cached data.");
return data;
}
logi("Cache is expired.");
} else {
logi("No valid cache found.");
}
json::object result;
if (holds_alternative<string>(loc)) {
const string city = get<string>(loc);
const char* location = curl_easy_escape(nullptr, city.c_str(),
static_cast<int>(city.length()));
logi("City: {}", location);
logi("Making API request for city: {}", city);
const Response res =
Get(Url {fmt::format("https://api.openweathermap.org/data/2.5/"
"weather?q={}&appid={}&units={}",
location, apiKey, units)});
logi("Received response from API.");
json::value json = json::parse(res.text);
result = json.as_object();
} else {
const auto [lat, lon] = get<Coords>(loc);
logi("Coordinates: lat = {:.3f}, lon = {:.3f}", lat, lon);
logi("Making API request for coordinates.");
const Response res =
Get(Url {fmt::format("https://api.openweathermap.org/data/2.5/"
"weather?lat={:.3f}&lon={:.3f}&appid={}&units={}",
lat, lon, apiKey, units)});
logi("Received response from API.");
json::value json = json::parse(res.text);
result = json.as_object();
}
// Update the cache with the new data
writeCacheToFile(result);
logi("Returning new data.");
return result;
}

View file

@ -1,26 +1,26 @@
#pragma once
#include <boost/json.hpp>
#include <cpr/cpr.h>
#include <fmt/core.h>
#include <fmtlog.h>
#include <toml++/toml.h>
#include <unistd.h>
#include <boost/json.hpp>
#include <rfl.hpp>
#include <string>
#include <toml++/impl/parser.hpp>
#include <toml++/toml.h>
#include <unistd.h>
#include <variant>
using std::string;
struct Coords {
double lat;
double lon;
};
using Location = std::variant<string, Coords>;
class Weather {
public:
struct Coords {
double lat;
double lon;
};
using Location = std::variant<string, Coords>;
private:
Location m_Location;
string m_ApiKey;
@ -36,7 +36,7 @@ class Weather {
};
struct WeatherImpl {
Location location;
Weather::Location location;
string api_key;
string units;
@ -68,7 +68,7 @@ class NowPlaying {
bool m_Enabled;
public:
NowPlaying(bool enable);
NowPlaying(bool enabled);
[[nodiscard]] bool getEnabled() const;
};
@ -107,6 +107,7 @@ struct ConfigImpl {
[[nodiscard]] Config to_class() const;
};
// Parsers for Config classes
namespace rfl::parsing {
template <class ReaderType, class WriterType, class ProcessorsType>
struct Parser<ReaderType, WriterType, Weather, ProcessorsType>

137
src/config/weather.cpp Normal file
View file

@ -0,0 +1,137 @@
#include <rfl.hpp>
#include <rfl/toml.hpp>
#include <toml++/toml.h>
#include <unistd.h>
#include "config.h"
using namespace std;
using namespace chrono;
using namespace boost;
// Function to read cache from file
optional<pair<json::object, system_clock::time_point>> ReadCacheFromFile() {
const string cacheFile = "/tmp/weather_cache.json";
ifstream ifs(cacheFile);
if (!ifs.is_open()) {
fmt::println("Cache file not found.");
return nullopt;
}
fmt::println("Reading from cache file...");
json::object cachedData;
system_clock::time_point timestamp;
try {
json::value val;
ifs >> val;
cachedData = val.as_object();
string tsStr = cachedData["timestamp"].as_string().c_str();
timestamp = system_clock::time_point(milliseconds(stoll(tsStr)));
cachedData.erase("timestamp");
} catch (...) {
fmt::println(stderr, "Failed to read from cache file.");
return nullopt;
}
fmt::println("Successfully read from cache file.");
return make_pair(cachedData, timestamp);
}
// Function to write cache to file
void WriteCacheToFile(const json::object& data) {
const string cacheFile = "/tmp/weather_cache.json";
fmt::println("Writing to cache file...");
ofstream ofs(cacheFile);
if (!ofs.is_open()) {
fmt::println(stderr, "Failed to open cache file for writing.");
return;
}
json::object dataToWrite = data;
dataToWrite["timestamp"] = to_string(
duration_cast<milliseconds>(system_clock::now().time_since_epoch())
.count());
ofs << json::serialize(dataToWrite);
fmt::println("Successfully wrote to cache file.");
}
// Function to make API request
json::object MakeApiRequest(const string& url) {
using namespace cpr;
fmt::println("Making API request...");
const Response res = Get(Url {url});
fmt::println("Received response from API.");
json::value json = json::parse(res.text);
return json.as_object();
}
// Core function to get weather information
json::object Weather::getWeatherInfo() const {
using namespace cpr;
const Location loc = m_Location;
const string apiKey = m_ApiKey;
const string units = m_Units;
// Check if cache is valid
if (auto cachedData = ReadCacheFromFile()) {
auto [data, timestamp] = *cachedData;
if (system_clock::now() - timestamp <
minutes(10)) { // Assuming cache duration is always 10 minutes
fmt::println("Cache is valid. Returning cached data.");
return data;
}
fmt::println("Cache is expired.");
} else {
fmt::println("No valid cache found.");
}
json::object result;
if (holds_alternative<string>(loc)) {
const string city = get<string>(loc);
const char* location = curl_easy_escape(nullptr, city.c_str(),
static_cast<int>(city.length()));
fmt::println("City: {}", location);
const string apiUrl = format(
"https://api.openweathermap.org/data/2.5/"
"weather?q={}&appid={}&units={}",
location, apiKey, units);
result = MakeApiRequest(apiUrl);
} else {
const auto [lat, lon] = get<Coords>(loc);
fmt::println("Coordinates: lat = {:.3f}, lon = {:.3f}", lat, lon);
const string apiUrl = format(
"https://api.openweathermap.org/data/2.5/"
"weather?lat={:.3f}&lon={:.3f}&appid={}&units={}",
lat, lon, apiKey, units);
result = MakeApiRequest(apiUrl);
}
// Update the cache with the new data
WriteCacheToFile(result);
fmt::println("Returning new data.");
return result;
}

View file

@ -1,18 +1,17 @@
#include <boost/json/src.hpp>
#include <cpr/cpr.h>
#include <ctime>
#include <curl/curl.h>
#include <fmt/chrono.h>
#include <fmt/core.h>
#include <fmt/format.h>
#include <boost/json/src.hpp>
#include <ctime>
#include <rfl.hpp>
#include <rfl/toml.hpp>
#include <rfl/toml/load.hpp>
#include <rfl/toml/read.hpp>
#include <toml++/toml.hpp>
#include <variant>
#include "config/config.h"
#include "fmtlog.h"
#include "os/os.h"
using std::string;
@ -69,9 +68,8 @@ int main() {
auto trimStart = [](std::string& str) {
auto start = str.begin();
while (start != str.end() && std::isspace(*start)) {
start++;
}
while (start != str.end() && std::isspace(*start))
++start;
str.erase(str.begin(), start);
};