This commit is contained in:
Mars 2024-06-05 19:04:53 -04:00
parent 693fa17d10
commit 500138ce67
Signed by: pupbrained
GPG key ID: 874E22DF2F9DFCB5
331 changed files with 12348 additions and 60593 deletions

View file

@ -1,9 +1,3 @@
#include <fmt/core.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) \
@ -21,9 +15,11 @@ DEFINE_GETTER(Weather, const string, ApiKey)
DEFINE_GETTER(Weather, const string, Units)
const Config& Config::getInstance() {
static const Config& INSTANCE =
*new Config(rfl::toml::load<Config>("./config.toml").value());
return INSTANCE;
static const auto* INSTANCE =
new Config(rfl::toml::load<Config>("./config.toml").value());
static std::once_flag Flag;
std::call_once(Flag, [] { std::atexit([] { delete INSTANCE; }); });
return *INSTANCE;
}
Config::Config(General general, NowPlaying now_playing, Weather weather)

View file

@ -1,13 +1,9 @@
#pragma once
#include <boost/json.hpp>
#include <co/json.h>
#include <cpr/cpr.h>
#include <fmt/core.h>
#include <rfl.hpp>
#include <rfl/toml.hpp>
#include <string>
#include <toml++/impl/parser.hpp>
#include <toml++/toml.h>
#include <unistd.h>
#include <variant>
using std::string;
@ -29,7 +25,7 @@ class Weather {
public:
Weather(Location location, string api_key, string units);
[[nodiscard]] boost::json::object getWeatherInfo() const;
[[nodiscard]] co::Json getWeatherInfo() const;
[[nodiscard]] const Location getLocation() const;
[[nodiscard]] const string getApiKey() const;
[[nodiscard]] const string getUnits() const;

View file

@ -1,83 +1,77 @@
#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() {
std::optional<std::pair<co::Json, std::chrono::system_clock::time_point>>
ReadCacheFromFile() {
const string cacheFile = "/tmp/weather_cache.json";
ifstream ifs(cacheFile);
std::ifstream ifs(cacheFile);
if (!ifs.is_open()) {
fmt::println("Cache file not found.");
return nullopt;
return std::nullopt;
}
fmt::println("Reading from cache file...");
json::object cachedData;
system_clock::time_point timestamp;
co::Json val;
std::chrono::system_clock::time_point timestamp;
try {
json::value val;
ifs >> val;
cachedData = val.as_object();
std::stringstream buf;
buf << ifs.rdbuf();
string tsStr = cachedData["timestamp"].as_string().c_str();
timestamp = system_clock::time_point(milliseconds(stoll(tsStr)));
val.parse_from(buf.str());
cachedData.erase("timestamp");
string tsStr = val["timestamp"].as_string().c_str();
timestamp = std::chrono::system_clock::time_point(
std::chrono::milliseconds(stoll(tsStr)));
val.erase("timestamp");
} catch (...) {
fmt::println(stderr, "Failed to read from cache file.");
return nullopt;
return std::nullopt;
}
fmt::println("Successfully read from cache file.");
return make_pair(cachedData, timestamp);
return make_pair(val, timestamp);
}
// Function to write cache to file
void WriteCacheToFile(const json::object& data) {
void WriteCacheToFile(const co::Json& data) {
const string cacheFile = "/tmp/weather_cache.json";
fmt::println("Writing to cache file...");
ofstream ofs(cacheFile);
std::ofstream ofs(cacheFile);
if (!ofs.is_open()) {
fmt::println(stderr, "Failed to open cache file for writing.");
return;
}
json::object dataToWrite = data;
data["timestamp"] =
std::to_string(duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch())
.count());
dataToWrite["timestamp"] = to_string(
duration_cast<milliseconds>(system_clock::now().time_since_epoch())
.count());
ofs << json::serialize(dataToWrite);
ofs << data.as_string();
fmt::println("Successfully wrote to cache file.");
}
// Function to make API request
json::object MakeApiRequest(const string& url) {
co::Json 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();
co::Json json = json::parse(res.text);
return json;
}
// Core function to get weather information
json::object Weather::getWeatherInfo() const {
co::Json Weather::getWeatherInfo() const {
using namespace cpr;
const Location loc = m_Location;
@ -86,10 +80,11 @@ json::object Weather::getWeatherInfo() const {
// Check if cache is valid
if (auto cachedData = ReadCacheFromFile()) {
auto [data, timestamp] = *cachedData;
auto& [data, timestamp] = *cachedData;
if (system_clock::now() - timestamp <
minutes(10)) { // Assuming cache duration is always 10 minutes
if (std::chrono::system_clock::now() - timestamp <
std::chrono::minutes(
10)) { // Assuming cache duration is always 10 minutes
fmt::println("Cache is valid. Returning cached data.");
return data;
}
@ -99,7 +94,7 @@ json::object Weather::getWeatherInfo() const {
fmt::println("No valid cache found.");
}
json::object result;
co::Json result;
if (holds_alternative<string>(loc)) {
const string city = get<string>(loc);

View file

@ -1,17 +1,10 @@
#include <boost/json/src.hpp>
#include <cpr/cpr.h>
#include <co/log.h>
#include <ctime>
#include <curl/curl.h>
#include <fmt/chrono.h>
#include <fmt/core.h>
#include <fmt/format.h>
#include <rfl.hpp>
#include <rfl/toml.hpp>
#include <rfl/toml/load.hpp>
#include <rfl/toml/read.hpp>
#include <toml++/toml.hpp>
#include "config/config.h"
#include "os/macos/NowPlayingBridge.h"
#include "os/os.h"
using std::string;
@ -49,9 +42,10 @@ DateNum ParseDate(string const& input) {
return Default;
}
int main() {
using boost::json::object;
using std::time_t;
int main(int argc, char** argv) {
flag::parse(argc, argv);
LOG << "hello " << 23;
const Config& config = Config::getInstance();
@ -97,12 +91,13 @@ int main() {
fmt::println("{:%B} {}, {:%-I:%0M %p}", localTime, date, localTime);
object json = config.getWeather().getWeatherInfo();
co::Json json = config.getWeather().getWeatherInfo();
const int temp = json.get("main", "temp").as_int();
const char* townName =
json["name"].is_string() ? json["name"].as_string().c_str() : "Unknown";
fmt::println("{}", townName);
fmt::println("It is {}°F in {}", temp, townName);
return 0;
}

View file

@ -1,8 +1,9 @@
#ifdef __linux__
#include <fmt/core.h>
#include <playerctl/playerctl.h>
#include <fstream>
#include <playerctl/playerctl.h>
#include "os.h"
using std::string;

View file

@ -1,12 +1,14 @@
#ifdef __APPLE__
#include <sys/sysctl.h>
#include <string>
#include <sys/sysctl.h>
#include "macos/NowPlayingBridge.h"
#include "os.h"
uint64_t GetMemInfo() {
uint64_t mem = 0;
size_t size = sizeof(mem);
size_t size = sizeof(mem);
sysctlbyname("hw.memsize", &mem, &size, nullptr, 0);
@ -14,7 +16,7 @@ uint64_t GetMemInfo() {
}
std::string GetNowPlaying() {
return "";
return getCurrentPlayingTitle();
}
#endif

View file

@ -0,0 +1,14 @@
// NowPlayingBridge.h
#ifdef __OBJC__
#import <Foundation/Foundation.h>
@interface NowPlayingBridge : NSObject
+ (NSDictionary*)currentPlayingMetadata;
@end
#else
extern "C" {
const char* getCurrentPlayingTitle();
const char* getCurrentPlayingArtist();
}
#endif

View file

@ -0,0 +1,90 @@
// NowPlayingBridge.mm
#import "NowPlayingBridge.h"
#import <Foundation/Foundation.h>
#import <dispatch/dispatch.h>
#import <objc/runtime.h>
typedef void (*MRMediaRemoteGetNowPlayingInfoFunction)(
dispatch_queue_t queue, void (^handler)(NSDictionary *information));
@implementation NowPlayingBridge
+ (NSDictionary *)currentPlayingMetadata {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wold-style-cast"
CFURLRef ref = (__bridge CFURLRef)
[NSURL fileURLWithPath:
@"/System/Library/PrivateFrameworks/MediaRemote.framework"];
#pragma clang diagnostic pop
CFBundleRef bundle = CFBundleCreate(kCFAllocatorDefault, ref);
if (!bundle) {
NSLog(@"Failed to load MediaRemote framework");
return nil;
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wold-style-cast"
MRMediaRemoteGetNowPlayingInfoFunction MRMediaRemoteGetNowPlayingInfo =
(MRMediaRemoteGetNowPlayingInfoFunction)CFBundleGetFunctionPointerForName(
bundle, CFSTR("MRMediaRemoteGetNowPlayingInfo"));
#pragma clang diagnostic pop
if (!MRMediaRemoteGetNowPlayingInfo) {
NSLog(@"Failed to get function pointer for MRMediaRemoteGetNowPlayingInfo");
CFRelease(bundle);
return nil;
}
__block NSDictionary *nowPlayingInfo = nil;
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
MRMediaRemoteGetNowPlayingInfo(
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
^(NSDictionary *information) {
nowPlayingInfo = [information copy];
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
CFRelease(bundle);
return nowPlayingInfo;
}
@end
extern "C" {
const char *getCurrentPlayingTitle() {
NSDictionary *metadata = [NowPlayingBridge currentPlayingMetadata];
if (metadata == nil) {
return nullptr;
}
NSString *title =
[metadata objectForKey:@"kMRMediaRemoteNowPlayingInfoTitle"];
if (title) {
return strdup([title UTF8String]);
}
return nullptr;
}
const char *getCurrentPlayingArtist() {
NSDictionary *metadata = [NowPlayingBridge currentPlayingMetadata];
if (metadata == nil) {
return nullptr;
}
NSString *artist =
[metadata objectForKey:@"kMRMediaRemoteNowPlayingInfoArtist"];
if (artist) {
return strdup([artist UTF8String]);
}
return nullptr;
}
}