Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/msbuild.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ on:
env:
# Path to the solution file relative to the root of the project.
SOLUTION_FILE_PATH: spotify-volume-controller-cpp.sln
VCPKG_COMMIT: "16ee2ecb31788c336ace8bb14c21801efb6836e4"
VCPKG_COMMIT: "b02e341c927f16d991edbd915d8ea43eac52096c"

# Configuration type to build.
# You can convert this to a build matrix if you need coverage of multiple configuration types.
Expand Down
23 changes: 23 additions & 0 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,16 @@
"CMAKE_SHARED_LINKER_FLAGS": "-Wl,--allow-shlib-undefined,--as-needed,-z,noexecstack,-z,relro,-z,now,-z,nodlopen"
}
},
{
"name": "flags-windows-gcc-clang",
"description": "These flags are supported by both GCC and Clang",
"hidden": true,
"cacheVariables": {
"CMAKE_CXX_FLAGS": "-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3 -D_GLIBCXX_ASSERTIONS=1 -fstack-protector-strong -fcf-protection=full -fstack-clash-protection -Wall -Wextra -Wpedantic -Wconversion -Wsign-conversion -Wcast-qual -Wformat=2 -Wundef -Werror=float-equal -Wshadow -Wcast-align -Wunused -Wnull-dereference -Wdouble-promotion -Wimplicit-fallthrough -Wextra-semi -Woverloaded-virtual -Wnon-virtual-dtor -Wold-style-cast",
"CMAKE_EXE_LINKER_FLAGS": "-Wl,--allow-shlib-undefined,--as-needed",
"CMAKE_SHARED_LINKER_FLAGS": "-Wl,--allow-shlib-undefined,--as-needed"
}
},
{
"name": "flags-appleclang",
"hidden": true,
Expand Down Expand Up @@ -106,6 +116,19 @@
"architecture": "x64",
"hidden": true
},
{
"name": "ci-win-mingw64",
"inherits": ["flags-windows-gcc-clang", "ci-std"],
"generator": "Ninja",
"hidden": true
},
{
"name": "vcpkg-mingw64-static",
"hidden": true,
"cacheVariables": {
"VCPKG_TARGET_TRIPLET": "x64-mingw-static"
}
},
{
"name": "coverage-linux",
"binaryDir": "${sourceDir}/build/coverage",
Expand Down
3 changes: 1 addition & 2 deletions source/Client.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

#include <map>

#include <fmt/format.h>
#include <cpr/cpr.h>
#include <fmt/format.h>
#include <nlohmann/json.hpp>

#include "Config.h"
Expand All @@ -21,7 +21,6 @@ class Client
[[nodiscard]] cpr::Response api_request(const std::string_view endpoint);
[[nodiscard]] cpr::Response put_api_request(const std::string_view endpoint, const cpr::Payload& parameters);


// Makes a request to the device endpoint
[[nodiscard]] std::optional<json> get_devices();

Expand Down
89 changes: 56 additions & 33 deletions source/Config.cpp
Original file line number Diff line number Diff line change
@@ -1,16 +1,33 @@
#include <chrono>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <string>
#include <string_view>

#include "Config.h"

#include <fmt/format.h>

constexpr std::string_view VOLUME_INCREMENT_KEY = "volume_increment";
#include "data_types.h"

namespace spotify_volume_controller
{

constexpr std::string_view client_id_key = "client_id";
constexpr std::string_view client_secret_key = "client_secret";
constexpr std::string_view hide_window_key = "hide_window";
constexpr std::string_view redirect_url_key = "redirect_url";
constexpr std::string_view print_keys_key = "print_keys";
constexpr std::string_view volume_increment_key = "volume_increment";
constexpr std::string_view volume_up_key = "volume_up";
constexpr std::string_view volume_down_key = "volume_down";
constexpr std::string_view batch_delay_key = "batch_delay_ms";

constexpr std::chrono::milliseconds default_batch_delay {100};
constexpr uint32_t default_volume_increment = 1;

Config::Config()
{
parse_config_file("config.json");
Expand Down Expand Up @@ -40,98 +57,99 @@ void Config::parse_config_file(const std::filesystem::path& path)
std::string input {};

get_user_input("Please enter your spotify client id", input, true);
config["client_id"] = input;
config[client_id_key] = input;

get_user_input("Please enter your spotify client secret", input, true);
config["client_secret"] = input;
config[client_secret_key] = input;

get_user_input(fmt::format("Enter callback url, or leave empty for default ({}).", Config::DEFAULT_CALLBACK_URL),
input);
if (input.empty()) {
config["redirect_url"] = Config::DEFAULT_CALLBACK_URL;
config[redirect_url_key] = Config::DEFAULT_CALLBACK_URL;
} else {
config["redirect_url"] = input;
config[redirect_url_key] = input;
}

get_user_input("Enter volume up virtual keycode as a number, or leave empty for default", input);
if (input.empty()) {
config["volume_up"] = "default";
config[volume_up_key] = "default";
} else {
config["volume_up"] = input;
config[volume_up_key] = input;
}
get_user_input("Enter volume down virtual keycode as a number, or leave empty for default", input);
if (input.empty()) {
config["volume_down"] = "default";
config[volume_down_key] = "default";
} else {
config["volume_down"] = input;
config[volume_down_key] = input;
}
config["print_keys"] = false;
config["hide_window"] = false;
config[print_keys_key] = false;
config[hide_window_key] = false;

config[VOLUME_INCREMENT_KEY.data()] = 1;
config[volume_increment_key] = default_volume_increment;
config[batch_delay_key] = default_batch_delay.count();

new_config_file << config;
new_config_file.close();
}

std::string Config::get_client_id() const
{
return config.at("client_id").template get<std::string>();
return config.at(client_id_key).template get<std::string>();
}
std::string Config::get_client_secret() const
{
return config.at("client_secret").template get<std::string>();
return config.at(client_secret_key).template get<std::string>();
}
std::string Config::get_redirect_url() const
{
return config.at("redirect_url").template get<std::string>();
return config.at(redirect_url_key).template get<std::string>();
}

bool Config::should_print_keys() const
{
return config.at("print_keys").template get<bool>();
return config.at(print_keys_key).template get<bool>();
}

keycode Config::get_volume_up() const
{
if (!config.contains("volume_up")) {
throw std::runtime_error("Missing volume_up config");
if (!config.contains(volume_up_key)) {
throw std::runtime_error(std::format("Missing {} config", volume_up_key));
}
json v_up = config.at("volume_up");
json v_up = config.at(volume_down_key);
if (!v_up.is_number_integer()) {
throw std::runtime_error("volume_up config is not a valid keycode");
throw std::runtime_error(fmt::format("{} config is not a valid keycode", volume_up_key));
}
return v_up.template get<keycode>();
}

keycode Config::get_volume_down() const
{
if (!config.contains("volume_down")) {
throw std::runtime_error("Missing volume_down config");
if (!config.contains(volume_down_key)) {
throw std::runtime_error(fmt::format("Missing {} config", volume_down_key));
}
json v_down = config.at("volume_down");
json v_down = config.at(volume_down_key);

if (!v_down.is_number_integer()) {
throw std::runtime_error("volume_down config is not a valid keycode");
throw std::runtime_error(std::format("{} config is not a valid keycode", volume_down_key));
}
return v_down.template get<keycode>();
}

bool Config::is_default_down() const
{
if (!config.contains("volume_down")) {
if (!config.contains(volume_down_key)) {
return false;
}
json v_down = config.at("volume_down");
json v_down = config.at(volume_down_key);
return v_down.is_string() && v_down.template get<std::string>() == "default";
}

bool Config::is_default_up() const
{
if (!config.contains("volume_up")) {
if (!config.contains(volume_down_key)) {
return false;
}
json v_up = config.at("volume_up");
json v_up = config.at(volume_down_key);
return v_up.is_string() && v_up.template get<std::string>() == "default";
}

Expand All @@ -142,11 +160,11 @@ bool Config::is_valid() const

bool Config::hide_window() const
{
if (!config.contains("hide_window")) {
if (!config.contains(hide_window_key)) {
return false;
}

return config.at("hide_window").template get<bool>();
return config.at(hide_window_key).template get<bool>();
}

[[nodiscard]] std::filesystem::path Config::config_directory() const
Expand All @@ -156,11 +174,16 @@ bool Config::hide_window() const

volume Config::volume_increment() const
{
if (!config.contains(VOLUME_INCREMENT_KEY.data())) {
return 1;
if (!config.contains(volume_increment_key.data())) {
return default_volume_increment;
}

return config.at(VOLUME_INCREMENT_KEY.data()).template get<volume_t>();
return config.at(volume_increment_key.data()).template get<volume_t>();
}

std::chrono::milliseconds Config::batch_delay() const
{
return std::chrono::milliseconds(config.value(batch_delay_key, default_batch_delay.count()));
}

void Config::get_user_input(const std::string_view prompt, std::string& input, bool not_empty) const
Expand Down
6 changes: 4 additions & 2 deletions source/Config.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
#pragma once
#include <chrono>
#include <filesystem>

#include <nlohmann/json.hpp>

#include "data_types.h"

// for convenience
using json = nlohmann::json;
namespace spotify_volume_controller
{
// for convenience
using json = nlohmann::json;

class Config
{
Expand All @@ -24,6 +25,7 @@ class Config
keycode get_volume_up() const;
keycode get_volume_down() const;
volume volume_increment() const;
std::chrono::milliseconds batch_delay() const;

bool is_default_down() const;
bool is_default_up() const;
Expand Down
Loading
Loading