/* ______________ //````````````\\ 😀 Thank you for choosing Pudding Customs for your business 😀 //~~~~~~~~~~~~~~\\ //================\\ Custom pudding code provided by 0eggxactly ........... [http://0eggxactly.itch.io] // \\ Available for copy, modification and redistribution .. [http://git.shampoo.ooo/pudding] // ''CUSTOM PUDDING'' \\ Updates .............................................. [http://twitter.com/diskmem] //______________________\\ `````````````````````````` */ #include "Pudding.hpp" int main() { Pudding pudding = Pudding(); pudding.run(); pudding.quit(); return 0; } Pudding::Pudding() { load_sdl_context(); } void Pudding::load_sdl_context() { super::load_sdl_context(); } void Pudding::curl_get_bytes(std::string url, std::vector* storage, std::string user_agent) { CURL *curl; CURLcode result; result = curl_global_init(CURL_GLOBAL_DEFAULT); if (result != CURLE_OK) { std::cout << "curl initialization failed " << curl_easy_strerror(result) << std::endl; } else { curl = curl_easy_init(); if (curl) { curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, Pudding::store_curl_response); std::vector food_barcode_response; curl_easy_setopt(curl, CURLOPT_WRITEDATA, storage); curl_easy_setopt(curl, CURLOPT_USERAGENT, user_agent.c_str()); result = curl_easy_perform(curl); if (result != CURLE_OK) { std::cout << "curl request failed " << curl_easy_strerror(result) << std::endl; } } else { std::cout << "curl initialization failed" << std::endl; } curl_easy_cleanup(curl); } curl_global_cleanup(); } nlohmann::json Pudding::food_json_from_barcode(std::string barcode) { std::string url = "https://world.openfoodfacts.org/api/v0/product/" + barcode; std::vector storage; curl_get_bytes(url, &storage, USER_AGENT); nlohmann::json food_json; food_json = nlohmann::json::parse(storage); if (get_configuration()["scan"]["json-save"] && !is_food_json_empty(food_json)) { fs::path path = get_configuration()["scan"]["json-save-directory"]; if (!fs::exists(path)) { fs::create_directories(path); } std::string prefix = ""; if (food_json.contains("product")) { if (food_json["product"].value("brands", "") != "") { prefix += food_json["product"]["brands"].get() + "_"; } if (food_json["product"].value("product_name", "") != "") { prefix += food_json["product"]["product_name"].get() + "_"; } } if (prefix == "") { prefix = "Unknown_"; } std::replace_if(prefix.begin(), prefix.end(), [](char c) { return !std::isalnum(c); }, '_'); path /= prefix + barcode + ".json"; std::ofstream out(path); out << std::setw(4) << food_json << std::endl; SDL_Log("Saved JSON to %s", path.c_str()); } return food_json; } size_t Pudding::store_curl_response(std::uint8_t* buffer, size_t size, size_t count, std::vector* storage) { size_t total_size = size * count; storage->insert(storage->end(), buffer, buffer + total_size); return total_size; } bool Pudding::is_food_json_empty(nlohmann::json food_json) { return !food_json.value("status", 0) || !food_json.contains("product"); } SDL_Texture* Pudding::texture_from_image_url(std::string url) { std::vector storage; curl_get_bytes(url, &storage, USER_AGENT); if (!storage.empty()) { SDL_RWops* rw = SDL_RWFromConstMem(storage.data(), storage.size()); return IMG_LoadTexture_RW(get_renderer(), rw, 0); } else { return nullptr; } } void Pudding::refresh() { nlohmann::json food_json = food_json_from_barcode(get_configuration()["scan"]["barcode"]); if (!is_food_json_empty(food_json)) { if (food_json["product"].value("image_url", "") != "") { std::string url = food_json["product"]["image_url"]; SDL_Texture* texture = texture_from_image_url(url); SDL_Log("looking up image at %s", url.c_str()); if (texture != nullptr) { image.unload(); image.add_frames(texture); image.add_wrap(true, true); } } } } void Pudding::update() { get_root()->configuration.load("config.json"); get_root()->configuration.merge(); if (current_barcode != get_configuration()["scan"]["barcode"]) { current_barcode = get_configuration()["scan"]["barcode"]; refresh(); } image.move_weighted(glm::vec2(1.681, 1)); image.update(); }