blegh
This commit is contained in:
parent
a24f19d16b
commit
8db3dae6f1
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
Language: Cpp
|
||||
BasedOnStyle: LLVM
|
||||
BasedOnStyle: Chromium
|
||||
IndentCaseBlocks: true
|
||||
IndentCaseLabels: true
|
||||
IndentCaseLabels: true
|
||||
|
||||
|
|
|
@ -1,33 +1,37 @@
|
|||
cmake_minimum_required(VERSION 3.5)
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
cmake_minimum_required(VERSION 3.28.1)
|
||||
set(CMAKE_CXX_STANDARD 26)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
|
||||
set(CMAKE_CXX_SCAN_FOR_MODULES 1)
|
||||
|
||||
project(draconis++ C CXX)
|
||||
project(draconis++)
|
||||
|
||||
set(sources )
|
||||
set(sources)
|
||||
|
||||
list(APPEND sources src/main.cpp)
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(MACOSX TRUE)
|
||||
set(MACOSX TRUE)
|
||||
endif ()
|
||||
|
||||
if (MACOSX)
|
||||
list(APPEND sources src/os/macos.cpp)
|
||||
list(APPEND sources src/os/macos.cpp)
|
||||
elseif (LINUX)
|
||||
list(APPEND sources src/os/linux.cpp)
|
||||
list(APPEND sources src/os/linux.cpp)
|
||||
endif ()
|
||||
|
||||
add_executable(${PROJECT_NAME} ${sources})
|
||||
add_executable(${PROJECT_NAME})
|
||||
target_sources(${PROJECT_NAME} PUBLIC src/main.cpp)
|
||||
target_sources(${PROJECT_NAME} PUBLIC FILE_SET all_my_modules TYPE CXX_MODULES FILES src/os/linux.cpp)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
find_package(cpr REQUIRED)
|
||||
find_package(Boost REQUIRED)
|
||||
|
||||
if (MACOSX)
|
||||
pkg_check_modules(${PROJECT_NAME} REQUIRED IMPORTED_TARGET fmt tomlplusplus)
|
||||
pkg_check_modules(${PROJECT_NAME} REQUIRED IMPORTED_TARGET fmt tomlplusplus)
|
||||
else ()
|
||||
pkg_check_modules(${PROJECT_NAME} REQUIRED IMPORTED_TARGET fmt playerctl tomlplusplus)
|
||||
pkg_check_modules(${PROJECT_NAME} REQUIRED IMPORTED_TARGET fmt playerctl tomlplusplus)
|
||||
endif ()
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE PkgConfig::${PROJECT_NAME} cpr::cpr Boost::boost)
|
||||
|
||||
|
|
11
flake.nix
11
flake.nix
|
@ -21,7 +21,7 @@
|
|||
ccacheWrapper = super.ccacheWrapper.override {
|
||||
extraConfig = ''
|
||||
export CCACHE_COMPRESS=1
|
||||
export CCACHE_DIR="/nix/var/cache/ccache"
|
||||
export CCACHE_DIR="/var/cache/ccache"
|
||||
export CCACHE_UMASK=007
|
||||
if [ ! -d "$CCACHE_DIR" ]; then
|
||||
echo "====="
|
||||
|
@ -73,6 +73,7 @@
|
|||
|
||||
nativeBuildInputs = [
|
||||
cmake
|
||||
ninja
|
||||
pkg-config
|
||||
];
|
||||
|
||||
|
@ -96,8 +97,8 @@
|
|||
++ darwinPkgs;
|
||||
|
||||
buildPhase = ''
|
||||
cmake .
|
||||
make
|
||||
cmake -GNinja .
|
||||
ninja
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
|
@ -113,15 +114,15 @@
|
|||
packages = with pkgs;
|
||||
[
|
||||
# builder
|
||||
gnumake
|
||||
cmake
|
||||
ninja
|
||||
pkg-config
|
||||
|
||||
# debugger
|
||||
lldb
|
||||
|
||||
# fix headers not found
|
||||
clang-tools
|
||||
clang-tools_18
|
||||
|
||||
# LSP and compiler
|
||||
llvm.libstdcxxClang
|
||||
|
|
173
src/main.cpp
173
src/main.cpp
|
@ -1,27 +1,114 @@
|
|||
#include "os/os.h"
|
||||
#include <boost/json/src.hpp>
|
||||
#include <cpr/cpr.h>
|
||||
#include <curl/curl.h>
|
||||
#include <fmt/chrono.h>
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
#include <fstream>
|
||||
#include <sys/sysctl.h>
|
||||
#include <boost/json/src.hpp>
|
||||
#include <toml++/toml.hpp>
|
||||
#include <unistd.h>
|
||||
|
||||
using fmt::format;
|
||||
using fmt::formatter;
|
||||
import OS;
|
||||
|
||||
using std::string;
|
||||
|
||||
struct b_to_gib {
|
||||
struct General {
|
||||
string name;
|
||||
};
|
||||
|
||||
struct NowPlaying {
|
||||
bool enable;
|
||||
};
|
||||
|
||||
struct LatLon {
|
||||
double lat;
|
||||
double lon;
|
||||
};
|
||||
|
||||
struct Location {
|
||||
enum { coords, city } type;
|
||||
union {
|
||||
LatLon coords;
|
||||
const char* city;
|
||||
} data;
|
||||
};
|
||||
|
||||
void use_location(const Location& l) {
|
||||
switch (l.type) {
|
||||
case Location::city:
|
||||
{
|
||||
char* c = const_cast<char*>(l.data.city);
|
||||
puts(c);
|
||||
free(c);
|
||||
break;
|
||||
}
|
||||
case Location::coords:
|
||||
{
|
||||
const auto [lat, lon] = l.data.coords;
|
||||
printf("%.f, %.f", lon, lat);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Weather {
|
||||
Location location;
|
||||
string api_key;
|
||||
string units;
|
||||
};
|
||||
|
||||
struct Config {
|
||||
General general;
|
||||
NowPlaying now_playing;
|
||||
Weather weather;
|
||||
|
||||
explicit Config(auto toml) {
|
||||
general = General{.name = toml["general"]["name"].value_or(getlogin())};
|
||||
|
||||
now_playing =
|
||||
NowPlaying{.enable = toml["now_playing"]["enable"].value_or(false)};
|
||||
|
||||
const char* location = toml["weather"]["location"].value_or("");
|
||||
|
||||
const size_t len = strlen(location);
|
||||
char* loc = new char[len + 1];
|
||||
strncpy(loc, location, len);
|
||||
loc[len] = '\0';
|
||||
|
||||
if (toml["weather"]["location"].is_string()) {
|
||||
weather = Weather{
|
||||
.location = Location{.type = Location::city, .data = {.city = loc}},
|
||||
.api_key = toml["weather"]["api_key"].value_or(""),
|
||||
.units = toml["weather"]["units"].value_or("metric"),
|
||||
};
|
||||
} else {
|
||||
weather = Weather{
|
||||
.location =
|
||||
Location{
|
||||
.type = Location::coords,
|
||||
.data = {.coords =
|
||||
LatLon{
|
||||
toml["weather"]["location"]["lat"].value_or(
|
||||
0.0),
|
||||
toml["weather"]["location"]["lon"].value_or(
|
||||
0.0)}}},
|
||||
.api_key = toml["weather"]["api_key"].value_or(""),
|
||||
.units = toml["weather"]["units"].value_or("metric"),
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static Config CONFIG = Config(toml::parse_file("./config.toml"));
|
||||
|
||||
struct BytesToGiB {
|
||||
uint64_t value;
|
||||
};
|
||||
|
||||
template <> struct formatter<b_to_gib> : formatter<double> {
|
||||
template <>
|
||||
struct fmt::formatter<BytesToGiB> : formatter<double> {
|
||||
template <typename FormatContext>
|
||||
auto format(const b_to_gib b, FormatContext &ctx) {
|
||||
auto format(const BytesToGiB b, FormatContext& ctx) {
|
||||
auto out = formatter<double>::format(
|
||||
b.value / std::pow(1024, 3), ctx); // NOLINT(*-narrowing-conversions);
|
||||
b.value / pow(1024, 3), ctx); // NOLINT(*-narrowing-conversions);
|
||||
*out++ = 'G';
|
||||
*out++ = 'i';
|
||||
*out++ = 'B';
|
||||
|
@ -31,14 +118,14 @@ template <> struct formatter<b_to_gib> : formatter<double> {
|
|||
|
||||
enum date_num { Ones, Twos, Threes, Default };
|
||||
|
||||
date_num parse_date(string const &inString) {
|
||||
if (inString == "1" || inString == "21" || inString == "31")
|
||||
date_num parse_date(string const& input) {
|
||||
if (input == "1" || input == "21" || input == "31")
|
||||
return Ones;
|
||||
|
||||
if (inString == "2" || inString == "22")
|
||||
if (input == "2" || input == "22")
|
||||
return Twos;
|
||||
|
||||
if (inString == "3" || inString == "23")
|
||||
if (input == "3" || input == "23")
|
||||
return Threes;
|
||||
|
||||
return Default;
|
||||
|
@ -47,36 +134,50 @@ date_num parse_date(string const &inString) {
|
|||
boost::json::object get_weather() {
|
||||
using namespace cpr;
|
||||
using namespace boost::json;
|
||||
using namespace fmt;
|
||||
|
||||
Response r = Get(Url{format("https://api.openweathermap.org/data/2.5/"
|
||||
"weather?lat={}&lon={}&appid={}&units={}",
|
||||
"39.9537", "-74.1979",
|
||||
"be387ee0e0d79c03368c52e0e3fe4f5b", "imperial")});
|
||||
if (CONFIG.weather.location.type == Location::city) {
|
||||
const char* location =
|
||||
curl_easy_escape(nullptr, CONFIG.weather.location.data.city,
|
||||
strlen(CONFIG.weather.location.data.city));
|
||||
const char* api_key = CONFIG.weather.api_key.c_str();
|
||||
const char* units = CONFIG.weather.units.c_str();
|
||||
|
||||
value json = parse(r.text);
|
||||
const Response r =
|
||||
Get(Url{format("https://api.openweathermap.org/data/2.5/"
|
||||
"weather?q={}&appid={}&units={}",
|
||||
location, api_key, units)});
|
||||
|
||||
return json.as_object();
|
||||
value json = parse(r.text);
|
||||
|
||||
return json.as_object();
|
||||
} else {
|
||||
const auto [lat, lon] = CONFIG.weather.location.data.coords;
|
||||
const char* api_key = CONFIG.weather.api_key.c_str();
|
||||
const char* units = CONFIG.weather.units.c_str();
|
||||
|
||||
const Response r =
|
||||
Get(Url{format("https://api.openweathermap.org/data/2.5/"
|
||||
"weather?lat={}&lon={}&appid={}&units={}",
|
||||
lat, lon, api_key, units)});
|
||||
|
||||
value json = parse(r.text);
|
||||
|
||||
return json.as_object();
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
const toml::parse_result config = toml::parse_file("./config.toml");
|
||||
const auto toml = toml::parse_file("./config.toml");
|
||||
|
||||
const char *name = config["general"]["name"].value_or(getlogin());
|
||||
if (CONFIG.now_playing.enable)
|
||||
fmt::println("{}", get_nowplaying());
|
||||
|
||||
#ifdef __linux__
|
||||
if (config["playerctl"]["enable"].value_or(false)) {
|
||||
if (PlayerctlPlayer *current_player = init_playerctl()) {
|
||||
gchar *song_title = playerctl_player_get_title(current_player, nullptr);
|
||||
fmt::println("Now playing: {}", song_title);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
fmt::println("Hello {}!", name);
|
||||
fmt::println("Hello {}!", CONFIG.general.name);
|
||||
|
||||
const uint64_t meminfo = get_meminfo();
|
||||
|
||||
fmt::println("{:.2f}", b_to_gib{meminfo});
|
||||
fmt::println("{:.2f}", BytesToGiB{meminfo});
|
||||
|
||||
const std::time_t t = std::time(nullptr);
|
||||
|
||||
|
@ -103,9 +204,9 @@ int main() {
|
|||
fmt::println("{:%B} {}, {:%-I:%0M %p}", fmt::localtime(t), date,
|
||||
fmt::localtime(t));
|
||||
|
||||
auto json = get_weather();
|
||||
boost::json::object json = get_weather();
|
||||
|
||||
auto town_name =
|
||||
const char* town_name =
|
||||
json["name"].is_string() ? json["name"].as_string().c_str() : "Unknown";
|
||||
|
||||
fmt::println("{}", town_name);
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
#include "os.h"
|
||||
#include <fstream>
|
||||
module;
|
||||
|
||||
#include <fmt/core.h>
|
||||
#include <playerctl/playerctl.h>
|
||||
#include <fstream>
|
||||
|
||||
export module OS;
|
||||
|
||||
using std::string;
|
||||
|
||||
uint64_t parse_line_as_number(const string &input) {
|
||||
uint64_t parse_line_as_number(const string& input) {
|
||||
// Find the first number
|
||||
string::size_type start = 0;
|
||||
|
||||
|
@ -36,17 +40,17 @@ uint64_t meminfo_parse(std::ifstream is) {
|
|||
return num;
|
||||
}
|
||||
|
||||
uint64_t get_meminfo() {
|
||||
export uint64_t get_meminfo() {
|
||||
return meminfo_parse(std::ifstream("/proc/meminfo")) * 1024;
|
||||
}
|
||||
|
||||
PlayerctlPlayer *init_playerctl() {
|
||||
PlayerctlPlayer* init_playerctl() {
|
||||
// Create a player manager
|
||||
PlayerctlPlayerManager *const player_manager =
|
||||
PlayerctlPlayerManager* const player_manager =
|
||||
playerctl_player_manager_new(nullptr);
|
||||
|
||||
// Create an empty player list
|
||||
GList *available_players = nullptr;
|
||||
GList* available_players = nullptr;
|
||||
|
||||
// Get the list of available players and put it in the player list
|
||||
g_object_get(player_manager, "player-names", &available_players, nullptr);
|
||||
|
@ -57,10 +61,10 @@ PlayerctlPlayer *init_playerctl() {
|
|||
|
||||
// Get the first player
|
||||
const auto player_name =
|
||||
static_cast<PlayerctlPlayerName *>(available_players->data);
|
||||
static_cast<PlayerctlPlayerName*>(available_players->data);
|
||||
|
||||
// Create the player
|
||||
PlayerctlPlayer *const current_player =
|
||||
PlayerctlPlayer* const current_player =
|
||||
playerctl_player_new_from_name(player_name, nullptr);
|
||||
|
||||
// If no player is available, return nullptr
|
||||
|
@ -75,3 +79,11 @@ PlayerctlPlayer *init_playerctl() {
|
|||
|
||||
return current_player;
|
||||
}
|
||||
|
||||
export string get_nowplaying() {
|
||||
if (PlayerctlPlayer* current_player = init_playerctl()) {
|
||||
return playerctl_player_get_title(current_player, nullptr);
|
||||
}
|
||||
|
||||
return "Could not get now playing info";
|
||||
}
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
#include "os.h"
|
||||
module;
|
||||
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
uint64_t get_meminfo() {
|
||||
export module OS;
|
||||
|
||||
export uint64_t get_meminfo() {
|
||||
uint64_t mem = 0;
|
||||
size_t size = sizeof(mem);
|
||||
|
||||
|
@ -9,3 +12,7 @@ uint64_t get_meminfo() {
|
|||
|
||||
return mem;
|
||||
}
|
||||
|
||||
export string get_nowplaying() {
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
#include <inttypes.h>
|
||||
#include <string>
|
||||
|
||||
using std::string;
|
||||
|
||||
uint64_t get_meminfo();
|
||||
string get_nowplaying();
|
Loading…
Reference in a new issue