Make things work #1
|
@ -20,8 +20,14 @@ FetchContent_Declare(
|
||||||
GIT_TAG 1.11.0
|
GIT_TAG 1.11.0
|
||||||
GIT_SHALLOW TRUE
|
GIT_SHALLOW TRUE
|
||||||
)
|
)
|
||||||
|
FetchContent_Declare(
|
||||||
|
glaze
|
||||||
|
GIT_REPOSITORY https://github.com/stephenberry/glaze.git
|
||||||
|
GIT_TAG main
|
||||||
|
GIT_SHALLOW TRUE
|
||||||
|
)
|
||||||
|
|
||||||
FetchContent_MakeAvailable(ctre cpr)
|
FetchContent_MakeAvailable(ctre cpr glaze)
|
||||||
|
|
||||||
add_executable(
|
add_executable(
|
||||||
nutri
|
nutri
|
||||||
|
@ -30,6 +36,5 @@ add_executable(
|
||||||
src/Helpers/Utility.cpp
|
src/Helpers/Utility.cpp
|
||||||
src/Helpers/Utility.hpp
|
src/Helpers/Utility.hpp
|
||||||
src/Helpers/WolframAlpha.hpp
|
src/Helpers/WolframAlpha.hpp
|
||||||
src/Helpers/WolframAlpha.cpp)
|
)
|
||||||
|
target_link_libraries(nutri PRIVATE cpr::cpr nlohmann_json::nlohmann_json ctre::ctre glaze::glaze)
|
||||||
target_link_libraries(nutri PRIVATE cpr::cpr nlohmann_json::nlohmann_json ctre::ctre)
|
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
#include "WolframAlpha.hpp"
|
|
||||||
|
|
||||||
#include "Utility.hpp"
|
|
||||||
#include <cpr/cpr.h>
|
|
||||||
#include <ctre.hpp>
|
|
||||||
#include <nlohmann/json.hpp>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
WolframAlpha::WolframAlpha(const std::string& query, double amount) : m_json(fetchJson(query)), m_amount(amount) {}
|
|
||||||
|
|
||||||
double WolframAlpha::getCalories() {
|
|
||||||
if (auto match = ctre::search<R"((?<=total calories\s)\d+)">(getPod())) {
|
|
||||||
return std::stod(match.data()) * m_amount;
|
|
||||||
}
|
|
||||||
throw std::runtime_error("Calorie information not found.");
|
|
||||||
}
|
|
||||||
|
|
||||||
double WolframAlpha::getProtein() {
|
|
||||||
auto m = ctre::search<"(?<=protein\\s)(\\d+)\\s*(\\w+)">(getPod());
|
|
||||||
double d = m.get<1>().to_number();
|
|
||||||
std::string u = m.get<2>().to_string();
|
|
||||||
return u == "g" ? d : d / 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
double WolframAlpha::getCarbs() {
|
|
||||||
auto m = ctre::search<"(?<=total carbohydrates\\s)(\\d+)\\s*(\\w+)">(getPod());
|
|
||||||
double d = m.get<1>().to_number();
|
|
||||||
std::string u = m.get<2>().to_string();
|
|
||||||
return u == "g" ? d : d / 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
double WolframAlpha::getFat() {
|
|
||||||
auto m = ctre::search<"(?<=total fat\\s)(\\d+)\\s*(\\w+)">(getPod());
|
|
||||||
double d = m.get<1>().to_number();
|
|
||||||
std::string u = m.get<2>().to_string();
|
|
||||||
return u == "g" ? d : d / 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
nlohmann::json WolframAlpha::fetchJson(const std::string& query) {
|
|
||||||
const auto WOLFRAM_KEY = utl::getEnv("NUTRI_WA_KEY");
|
|
||||||
cpr::Response json = Get(cpr::Url{"https://api.wolframalpha.com/v2/query"},
|
|
||||||
cpr::Parameters{{"input", query + "100g nutrition"}, {"appid", WOLFRAM_KEY}, {"output", "JSON"}, {"format", "plaintext"}});
|
|
||||||
return nlohmann::json::parse(json.text);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string WolframAlpha::getPod() {
|
|
||||||
return to_string(m_json["queryresult"]["pods"][1]["subpods"][0]["plaintext"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
nlohmann::json m_json{};
|
|
||||||
double m_amount{};
|
|
|
@ -1,21 +1,80 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include "Utility.hpp"
|
||||||
|
#include "ctll/fixed_string.hpp"
|
||||||
|
#include <cpr/cpr.h>
|
||||||
|
#include <ctll.hpp>
|
||||||
|
#include <ctre.hpp>
|
||||||
|
#include <glaze/glaze.hpp>
|
||||||
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
// Example regex patern: (?<=protein\s)(\d+)\s(\w)
|
||||||
|
|
||||||
|
struct Data {
|
||||||
|
double cals{};
|
||||||
|
double proteins{};
|
||||||
|
double carbs{};
|
||||||
|
double fats{};
|
||||||
|
};
|
||||||
|
|
||||||
class WolframAlpha {
|
class WolframAlpha {
|
||||||
public:
|
public:
|
||||||
explicit WolframAlpha(const std::string& query, double amount);
|
WolframAlpha(const std::string& query, double amount) : m_plaintext{getData(query)}, m_amount{amount / 100} {}
|
||||||
|
|
||||||
double getCalories();
|
//debug
|
||||||
double getProtein();
|
std::string getPlain() {
|
||||||
double getCarbs();
|
return m_plaintext;
|
||||||
double getFat();
|
}
|
||||||
|
|
||||||
|
Data getNutrition() {
|
||||||
|
return m_data;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nlohmann::json fetchJson(const std::string& query);
|
void getMacro() {
|
||||||
std::string getPod();
|
static constexpr ctll::fixed_string calories_regex{R"((?<=total calories\s)\d+)"};
|
||||||
|
static constexpr ctll::fixed_string proteins_regex{R"((?<=protein\s)(\d+)\s(\w))"};
|
||||||
|
static constexpr ctll::fixed_string carbs_regex{R"((?<=total carbohydrates\s)(\d+)\s(\w))"};
|
||||||
|
static constexpr ctll::fixed_string fats_regex{R"((?<=total fat\s)(\d+)\s(\w))"};
|
||||||
|
|
||||||
nlohmann::json m_json{};
|
const auto convertToGrams = [this](const auto& match, const std::string& unit) -> double {
|
||||||
double m_amount{};
|
const double value = (unit == "g") ? match.to_number() : match.to_number() / 1000;
|
||||||
|
return value * m_amount;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (auto match = ctre::search<proteins_regex>(m_plaintext); match) {
|
||||||
|
m_data.proteins = convertToGrams(match.get<1>(), match.get<2>().to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto match = ctre::search<carbs_regex>(m_plaintext); match) {
|
||||||
|
m_data.carbs = convertToGrams(match.get<1>(), match.get<2>().to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto match = ctre::search<fats_regex>(m_plaintext); match) {
|
||||||
|
m_data.fats = convertToGrams(match.get<1>(), match.get<2>().to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto match = ctre::search<calories_regex>(m_plaintext); match) {
|
||||||
|
m_data.cals = match.get<0>().to_number();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::string getData(const std::string& query) {
|
||||||
|
const auto WOLFRAM_KEY = utl::getEnv("NUTRI_WA_KEY");
|
||||||
|
cpr::Response response = Get(cpr::Url{"https://api.wolframalpha.com/v2/query"},
|
||||||
|
cpr::Parameters{{"input", query + "100g nutrition"}, {"appid", WOLFRAM_KEY}, {"output", "JSON"}, {"format", "plaintext"}});
|
||||||
|
|
||||||
|
glz::json_t json{};
|
||||||
|
// Pretty sure this is wrong and i always is false
|
||||||
|
if (glz::read_json(json, response.text)) {
|
||||||
|
throw std::runtime_error("Failed to parse the JSON");
|
||||||
|
} else {
|
||||||
|
return json["queryresult"]["pods"][1]["subpods"][0]["plaintext"].get<std::string>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Data m_data{};
|
||||||
|
std::string m_pod{};
|
||||||
|
std::string m_plaintext{};
|
||||||
|
double m_amount{};
|
||||||
};
|
};
|
||||||
|
|
11
src/main.cpp
11
src/main.cpp
|
@ -1,13 +1,10 @@
|
||||||
#include "ArgParser.hpp"
|
#include "ArgParser.hpp"
|
||||||
#include "Helpers/WolframAlpha.hpp"
|
#include "Helpers/WolframAlpha.hpp"
|
||||||
#include <ctre.hpp>
|
|
||||||
#include <nlohmann/json.hpp>
|
|
||||||
#include <print>
|
#include <print>
|
||||||
|
|
||||||
int main(const int argc, char* argv[]) {
|
int main(const int argc, char* argv[]) {
|
||||||
try {
|
try {
|
||||||
ArgParser args;
|
ArgParser args;
|
||||||
args.addArg("-s", "--source", "Specify the source of the data (Wolfram|OpenFoodFacts)");
|
|
||||||
args.addArg("-f", "--food", "Specify the food item");
|
args.addArg("-f", "--food", "Specify the food item");
|
||||||
args.addArg("-a", "--amount", "Specify the amount (in grams)");
|
args.addArg("-a", "--amount", "Specify the amount (in grams)");
|
||||||
args.addArg("-h", "--help", "Print help", false);
|
args.addArg("-h", "--help", "Print help", false);
|
||||||
|
@ -16,10 +13,10 @@ int main(const int argc, char* argv[]) {
|
||||||
const auto food = args.get<std::string>("--food");
|
const auto food = args.get<std::string>("--food");
|
||||||
const double amount = args.get<double>("--amount") / 100;
|
const double amount = args.get<double>("--amount") / 100;
|
||||||
|
|
||||||
if (!args.has("--source") || args.get<std::string>("--source") == "Wolfram") {
|
WolframAlpha wa(food, amount);
|
||||||
WolframAlpha wa(food, amount);
|
|
||||||
std::println("Calories: {:.2f} kcal\nProtein: {:.2f} g\nCarbs: {:.2f} g\nFat: {:.2f} g", wa.getCalories(), wa.getProtein(), wa.getCarbs(), wa.getFat());
|
auto a = wa.getNutrition();
|
||||||
}
|
std::println("cals: {}\nprotein: {}\ncarbs: {}\nfat: {}", a.cals, a.proteins, a.carbs, a.fats);
|
||||||
|
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
std::println(stderr, "Error: {}", e.what());
|
std::println(stderr, "Error: {}", e.what());
|
||||||
|
|
Loading…
Reference in New Issue