mirror of
https://github.com/davidallendj/gdpm.git
synced 2025-12-19 19:17:01 -07:00
Initial commit
First commit with most of the main features implemented. May still need some bug fixes here and there.
This commit is contained in:
commit
1893c7c36b
26 changed files with 2839 additions and 0 deletions
25
include/cache.hpp
Normal file
25
include/cache.hpp
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
#include <sqlite3.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace gdpm::package_manager{
|
||||
struct package_info;
|
||||
}
|
||||
|
||||
namespace gdpm::cache{
|
||||
using namespace package_manager;
|
||||
int create_package_database();
|
||||
int insert_package_info(const std::vector<package_info>& package);
|
||||
std::vector<package_info> get_package_info_by_id(const std::vector<size_t>& package_ids);
|
||||
std::vector<package_info> get_package_info_by_title(const std::vector<std::string>& package_titles);
|
||||
std::vector<package_info> get_installed_packages();
|
||||
int update_package_info(const std::vector<package_info>& packages);
|
||||
int update_sync_info(const std::vector<std::string>& download_urls);
|
||||
int delete_packages(const std::vector<std::string>& package_titles);
|
||||
int delete_packages(const std::vector<size_t>& package_ids);
|
||||
int drop_package_database();
|
||||
|
||||
std::string to_values(const package_info& package);
|
||||
std::string to_values(const std::vector<package_info>& packages);
|
||||
}
|
||||
45
include/colors.hpp
Normal file
45
include/colors.hpp
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
|
||||
#if GDPM_ENABLE_COLORS == 1
|
||||
#define GDPM_COLOR_BLACK "\033[0;30m"
|
||||
#define GDPM_COLOR_BLUE "\033[0;34m"
|
||||
#define GDPM_COLOR_GREEN "\033[0;32m"
|
||||
#define GDPM_COLOR_CYAN "\033[0;36m"
|
||||
#define GDPM_COLOR_RED "\033[0;31m"
|
||||
#define GDPM_COLOR_PURPLE "\033[0;35m"
|
||||
#define GDPM_COLOR_BROWN "\033[0;33m"
|
||||
#define GDPM_COLOR_GRAY "\033[0;37m"
|
||||
#define GDPM_COLOR_DARK_GRAY "\033[0;30m"
|
||||
#define GDPM_COLOR_LIGHT_BLUE "\033[0;34m"
|
||||
#define GDPM_COLOR_LIGHT_GREEN "\033[0;32m"
|
||||
#define GDPM_COLOR_LIGHT_CYAN "\033[0;36m"
|
||||
#define GDPM_COLOR_LIGHT_RED "\033[0;31m"
|
||||
#define GDPM_COLOR_LIGHT_PURPLE "\033[0;35m"
|
||||
#define GDPM_COLOR_YELLOW "\033[0;33m"
|
||||
#define GDPM_COLOR_WHITE "\033[0;37m"
|
||||
|
||||
#else
|
||||
#define GDPM_COLOR_BLACK
|
||||
#define GDPM_COLOR_BLUE
|
||||
#define GDPM_COLOR_GREEN
|
||||
#define GDPM_COLOR_CYAN
|
||||
#define GDPM_COLOR_RED
|
||||
#define GDPM_COLOR_PURPLE
|
||||
#define GDPM_COLOR_BROWN
|
||||
#define GDPM_COLOR_GRAY
|
||||
#define GDPM_COLOR_DARK_GRAY
|
||||
#define GDPM_COLOR_LIGHT_BLUE
|
||||
#define GDPM_COLOR_LIGHT_GREEN
|
||||
#define GDPM_COLOR_LIGHT_CYAN
|
||||
#define GDPM_COLOR_LIGHT_RED
|
||||
#define GDPM_COLOR_LIGHT_PURPLE
|
||||
#define GDPM_COLOR_YELLOW
|
||||
#define GDPM_COLOR_WHITE
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#define GDPM_COLOR_LOG_RESET GDPM_COLOR_WHITE
|
||||
#define GDPM_COLOR_LOG_INFO GDPM_COLOR_LOG_RESET
|
||||
#define GDPM_COLOR_LOG_ERROR GDPM_COLOR_RED
|
||||
#define GDPM_COLOR_LOG_DEBUG GDPM_COLOR_YELLOW
|
||||
#define GDPM_COLOR_LOG_WARNING GDPM_COLOR_YELLOW
|
||||
32
include/config.hpp
Normal file
32
include/config.hpp
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#pragma once
|
||||
|
||||
#include "constants.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <filesystem>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace gdpm::config{
|
||||
struct config_context{
|
||||
std::string username;
|
||||
std::string password;
|
||||
std::string path;
|
||||
std::string token;
|
||||
std::string godot_version;
|
||||
std::string packages_dir;
|
||||
std::string tmp_dir;
|
||||
std::vector<std::string> remote_sources;
|
||||
size_t threads;
|
||||
size_t timeout;
|
||||
bool enable_sync;
|
||||
bool enable_file_logging;
|
||||
int verbose;
|
||||
};
|
||||
std::string to_json(const config_context& params);
|
||||
config_context load(std::filesystem::path path, int verbose = 0);
|
||||
int save(const config_context& config, int verbose = 0);
|
||||
config_context make_config(const std::string& username = GDPM_CONFIG_USERNAME, const std::string& password = GDPM_CONFIG_PASSWORD, const std::string& path = GDPM_CONFIG_PATH, const std::string& token = GDPM_CONFIG_TOKEN, const std::string& godot_version = GDPM_CONFIG_GODOT_VERSION, const std::string& packages_dir = GDPM_CONFIG_LOCAL_PACKAGES_DIR, const std::string& tmp_dir = GDPM_CONFIG_LOCAL_TMP_DIR, const std::vector<std::string>& remote_sources = {GDPM_CONFIG_REMOTE_SOURCES}, size_t threads = GDPM_CONFIG_THREADS, size_t timeout = 0, bool enable_sync = GDPM_CONFIG_ENABLE_SYNC, bool enable_file_logging = GDPM_CONFIG_ENABLE_FILE_LOGGING, int verbose = GDPM_CONFIG_VERBOSE);
|
||||
|
||||
extern config_context config;
|
||||
}
|
||||
74
include/constants.hpp
Normal file
74
include/constants.hpp
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace gdpm::constants{
|
||||
constexpr const char *ConfigPath = "config.ini";
|
||||
constexpr const char *LocalPackagesDir = "$HOME/.config/gdpm";
|
||||
constexpr const char *UserAgent = "libcurl-agent/1.0";
|
||||
constexpr const char *AssetRepo = "https://godotengine.org/asset-library/api/asset";
|
||||
constexpr const char *HostUrl = "https://godotengine.org/asset-library/api";
|
||||
constexpr const char *LockfilePath = "$HOME/.config/gdpm/gdpm.lck";
|
||||
constexpr const char *TmpPath = "$HOME/.config/gdpm/tmp";
|
||||
}
|
||||
|
||||
/* Defines to set when building with -DGPM_* */
|
||||
#define GDPM_CONFIG_USERNAME ""
|
||||
#define GDPM_CONFIG_PASSWORD ""
|
||||
#define GDPM_CONFIG_PATH "config.json"
|
||||
#define GDPM_CONFIG_TOKEN ""
|
||||
#define GDPM_CONFIG_GODOT_VERSION "3.4"
|
||||
#define GDPM_CONFIG_LOCAL_PACKAGES_DIR "tests/gdpm/packages"
|
||||
#define GDPM_CONFIG_LOCAL_TMP_DIR "tests/gdpm/.tmp"
|
||||
#define GDPM_CONFIG_REMOTE_SOURCES constants::HostUrl
|
||||
#define GDPM_CONFIG_THREADS 1
|
||||
#define GDPM_CONFIG_TIMEOUT_MS 30000
|
||||
#define GDPM_CONFIG_ENABLE_SYNC 1
|
||||
#define GDPM_CONFIG_ENABLE_FILE_LOGGING 0
|
||||
#define GDPM_CONFIG_VERBOSE 0
|
||||
|
||||
/* Defines package cache for local storage */
|
||||
#define GDPM_PACKAGE_CACHE_ENABLE 1
|
||||
#define GDPM_PACKAGE_CACHE_PATH "tests/gdpm/packages.db"
|
||||
#define GDPM_PACKAGE_CACHE_TABLENAME "cache"
|
||||
#define GDPM_PACKAGE_CACHE_COLNAMES "asset_id, type, title, author, author_id, version, godot_version, cost, description, modify_date, support_level, category, remote_source, download_url, download_hash, is_installed, install_path"
|
||||
|
||||
/* Defines to set default assets API params */
|
||||
#define GDPM_DEFAULT_ASSET_TYPE any
|
||||
#define GDPM_DEFAULT_ASSET_CATEGORY 0
|
||||
#define GDPM_DEFAULT_ASSET_SUPPORT all
|
||||
#define GDPM_DEFAULT_ASSET_FILTER ""
|
||||
#define GDPM_DEFAULT_ASSET_USER ""
|
||||
#define GDPM_DEFAULT_ASSET_GODOT_VERSION ""
|
||||
#define GDPM_DEFAULT_ASSET_MAX_RESULTS 500
|
||||
#define GDPM_DEFAULT_ASSET_PAGE 0
|
||||
#define GDPM_DEFAULT_ASSET_SORT none
|
||||
#define GDPM_DEFAULT_ASSET_REVERSE false
|
||||
#define GDPM_DEFAULT_ASSET_VERBOSE 0
|
||||
|
||||
/* Define misc. macros */
|
||||
#if defined(_WIN32)
|
||||
#define GDPM_DLL_EXPORT __declspec(dllexport)
|
||||
#define GDPM_DLL_IMPORT __declspec(dllimport)
|
||||
#else
|
||||
#define GDPM_DLL_EXPORT
|
||||
#define GDPM_DLL_IMPORT
|
||||
#endif
|
||||
#define GDPM_READFILE_IMPL 1
|
||||
#define GDPM_DELAY_HTTP_REQUESTS 1
|
||||
|
||||
#ifndef GDPM_REQUEST_DELAY
|
||||
#define GDPM_REQUEST_DELAY 200ms
|
||||
#endif
|
||||
|
||||
#ifndef GDPM_ENABLE_COLORS
|
||||
#define GDPM_ENABLE_COLORS 1
|
||||
#endif
|
||||
|
||||
#ifndef GDPM_LOG_LEVEL
|
||||
#define GDPM_LOG_LEVEL 1
|
||||
#endif
|
||||
|
||||
#ifndef GDPM_ENABLE_TIMESTAMPS
|
||||
#define GDPM_ENABLE_TIMESTAMPS 1
|
||||
#endif
|
||||
18
include/http.hpp
Normal file
18
include/http.hpp
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include "constants.hpp"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
namespace gdpm::http{
|
||||
struct response{
|
||||
long code = 0;
|
||||
std::string body{};
|
||||
std::unordered_map<std::string, std::string> headers{};
|
||||
};
|
||||
|
||||
response request_get(const std::string& url, size_t timeout = GDPM_CONFIG_TIMEOUT_MS);
|
||||
response request_post(const std::string& url, const char *post_fields="", size_t timeout = GDPM_CONFIG_TIMEOUT_MS);
|
||||
response download_file(const std::string& url, const std::string& storage_path, size_t timeout = GDPM_CONFIG_TIMEOUT_MS);
|
||||
|
||||
}
|
||||
81
include/log.hpp
Normal file
81
include/log.hpp
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "utils.hpp"
|
||||
#include "colors.hpp"
|
||||
#include <fmt/core.h>
|
||||
|
||||
#if __cplusplus > 201703L
|
||||
// #include <format>
|
||||
#else
|
||||
#endif
|
||||
#include <fmt/printf.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
namespace gdpm::log
|
||||
{
|
||||
template <typename...Args> concept RequireMinArgs = requires (std::size_t min){ sizeof...(Args) > min; };
|
||||
|
||||
static void vlog(fmt::string_view format, fmt::format_args args){
|
||||
fmt::vprint(format, args);
|
||||
}
|
||||
|
||||
static void vlog(FILE *fp, fmt::string_view format, fmt::format_args args){
|
||||
fmt::vprint(fp, format, args);
|
||||
}
|
||||
|
||||
template <typename S, typename...Args>
|
||||
static constexpr void info(const S& format, Args&&...args){
|
||||
#if GDPM_LOG_LEVEL > 0
|
||||
vlog(
|
||||
fmt::format(GDPM_COLOR_LOG_INFO "[INFO {}] {}\n" GDPM_COLOR_LOG_RESET, utils::timestamp(), format),
|
||||
fmt::make_args_checked<Args...>(format, args...)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename S, typename...Args>
|
||||
static constexpr void info_n(const S& format, Args&&...args){
|
||||
vlog(
|
||||
fmt::format(GDPM_COLOR_LOG_INFO "[INFO {}] {}" GDPM_COLOR_LOG_RESET, utils::timestamp(), format),
|
||||
fmt::make_args_checked<Args...>(format, args...)
|
||||
);
|
||||
}
|
||||
|
||||
template <typename S, typename...Args>
|
||||
static constexpr void error(const S& format, Args&&...args){
|
||||
#if GDPM_LOG_LEVEL > 1
|
||||
vlog(
|
||||
fmt::format(GDPM_COLOR_LOG_ERROR "[ERROR {}] {}\n" GDPM_COLOR_LOG_RESET, utils::timestamp(), format),
|
||||
fmt::make_args_checked<Args...>(format, args...)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename S, typename...Args>
|
||||
static constexpr void debug(const S& format, Args&&...args){
|
||||
#if GDPM_LOG_LEVEL > 1
|
||||
vlog(
|
||||
fmt::format(GDPM_COLOR_LOG_DEBUG "[DEBUG {}] {}\n" GDPM_COLOR_LOG_RESET, utils::timestamp(), format),
|
||||
fmt::make_args_checked<Args...>(format, args...)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename S, typename...Args>
|
||||
static constexpr void print(const S& format, Args&&...args){
|
||||
vlog(
|
||||
fmt::format("{}", format),
|
||||
fmt::make_args_checked<Args...>(format, args...)
|
||||
);
|
||||
}
|
||||
|
||||
template <typename S, typename...Args>
|
||||
static constexpr void println(const S& format, Args&&...args){
|
||||
vlog(
|
||||
fmt::format("{}\n", format),
|
||||
fmt::make_args_checked<Args...>(format, args...)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
83
include/package_manager.hpp
Normal file
83
include/package_manager.hpp
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
#pragma once
|
||||
|
||||
#include "config.hpp"
|
||||
#include <cstdio>
|
||||
#include <cxxopts.hpp>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <rapidjson/document.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
namespace gdpm::package_manager{
|
||||
extern std::vector<std::string> repo_sources;
|
||||
extern CURL *curl;
|
||||
extern CURLcode res;
|
||||
extern config::config_context config;
|
||||
|
||||
struct package_info{
|
||||
size_t asset_id;
|
||||
std::string type;
|
||||
std::string title;
|
||||
std::string author;
|
||||
size_t author_id;
|
||||
std::string version;
|
||||
std::string godot_version;
|
||||
std::string cost;
|
||||
std::string description;
|
||||
std::string modify_date;
|
||||
std::string support_level;
|
||||
std::string category;
|
||||
std::string remote_source;
|
||||
std::string download_url;
|
||||
std::string download_hash;
|
||||
bool is_installed;
|
||||
std::string install_path;
|
||||
};
|
||||
|
||||
struct cxxargs{
|
||||
cxxopts::ParseResult result;
|
||||
cxxopts::Options options;
|
||||
};
|
||||
|
||||
enum command_e{
|
||||
install,
|
||||
remove,
|
||||
update,
|
||||
search,
|
||||
list,
|
||||
link,
|
||||
clone,
|
||||
clean,
|
||||
sync,
|
||||
add_remote,
|
||||
delete_remote,
|
||||
help,
|
||||
none
|
||||
};
|
||||
|
||||
GDPM_DLL_EXPORT int initialize(int argc, char **argv);
|
||||
GDPM_DLL_EXPORT int execute();
|
||||
GDPM_DLL_EXPORT void finalize();
|
||||
GDPM_DLL_EXPORT void install_packages(const std::vector<std::string>& package_titles);
|
||||
GDPM_DLL_EXPORT void remove_packages(const std::vector<std::string>& package_titles);
|
||||
GDPM_DLL_EXPORT void update_packages(const std::vector<std::string>& package_titles);
|
||||
GDPM_DLL_EXPORT void search_for_packages(const std::vector<std::string>& package_titles);
|
||||
GDPM_DLL_EXPORT void list_installed_packages();
|
||||
GDPM_DLL_EXPORT void read_package_contents(const std::string& package_title);
|
||||
GDPM_DLL_EXPORT void clean_temporary(const std::vector<std::string>& package_titles);
|
||||
GDPM_DLL_EXPORT void link_packages(const std::vector<std::string>& package_titles, const std::vector<std::string>& paths);
|
||||
GDPM_DLL_EXPORT void clone_packages(const std::vector<std::string>& package_titles, const std::vector<std::string>& paths);
|
||||
GDPM_DLL_EXPORT void add_remote_repository(const std::string& repository, ssize_t offset = -1);
|
||||
GDPM_DLL_EXPORT void delete_remote_repository(const std::string& repository);
|
||||
GDPM_DLL_EXPORT void delete_remote_repository(ssize_t index);
|
||||
|
||||
GDPM_DLL_EXPORT cxxargs parse_arguments(int argc, char **argv);
|
||||
GDPM_DLL_EXPORT void handle_arguments(const cxxargs& args);
|
||||
GDPM_DLL_EXPORT void run_command(command_e command, const std::vector<std::string>& package_titles, const std::vector<std::string>& opts);
|
||||
GDPM_DLL_EXPORT void print_package_list(const rapidjson::Document& json);
|
||||
GDPM_DLL_EXPORT void print_package_list(const std::vector<package_info>& packages);
|
||||
|
||||
GDPM_DLL_EXPORT std::vector<package_info> synchronize_database(const std::vector<std::string>& package_titles);
|
||||
}
|
||||
16
include/plugin.hpp
Normal file
16
include/plugin.hpp
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace towk::plugin{
|
||||
struct info{
|
||||
std::string name;
|
||||
std::string description;
|
||||
std::string version;
|
||||
};
|
||||
extern int init(int argc, char **argv);
|
||||
extern int set_name(const char *name);
|
||||
extern int set_description(const char *description);
|
||||
extern int set_version(const char *version);
|
||||
extern int finalize();
|
||||
}
|
||||
59
include/progress_bar.hpp
Normal file
59
include/progress_bar.hpp
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
#include <cmath>
|
||||
#include <iomanip>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
class progress_bar
|
||||
{
|
||||
static const auto overhead = sizeof " [100%]";
|
||||
|
||||
std::ostream& os;
|
||||
const std::size_t bar_width;
|
||||
std::string message;
|
||||
const std::string full_bar;
|
||||
|
||||
public:
|
||||
progress_bar(std::ostream& os, std::size_t line_width,
|
||||
std::string message_, const char symbol = '.')
|
||||
: os{os},
|
||||
bar_width{line_width - overhead},
|
||||
message{std::move(message_)},
|
||||
full_bar{std::string(bar_width, symbol) + std::string(bar_width, ' ')}
|
||||
{
|
||||
if (message.size()+1 >= bar_width || message.find('\n') != message.npos) {
|
||||
os << message << '\n';
|
||||
message.clear();
|
||||
} else {
|
||||
message += ' ';
|
||||
}
|
||||
write(0.0);
|
||||
}
|
||||
|
||||
// not copyable
|
||||
progress_bar(const progress_bar&) = delete;
|
||||
progress_bar& operator=(const progress_bar&) = delete;
|
||||
|
||||
~progress_bar()
|
||||
{
|
||||
write(1.0);
|
||||
os << '\n';
|
||||
}
|
||||
|
||||
void write(double fraction);
|
||||
};
|
||||
|
||||
void progress_bar::write(double fraction)
|
||||
{
|
||||
// clamp fraction to valid range [0,1]
|
||||
if (fraction < 0)
|
||||
fraction = 0;
|
||||
else if (fraction > 1)
|
||||
fraction = 1;
|
||||
|
||||
auto width = bar_width - message.size();
|
||||
auto offset = bar_width - static_cast<unsigned>(width * fraction);
|
||||
|
||||
os << '\r' << message;
|
||||
os.write(full_bar.data() + offset, width);
|
||||
os << " [" << std::setw(3) << static_cast<int>(100*fraction) << "%] " << std::flush;
|
||||
}
|
||||
88
include/rest_api.hpp
Normal file
88
include/rest_api.hpp
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
|
||||
#include "constants.hpp"
|
||||
#include <rapidjson/document.h>
|
||||
#include <rapidjson/writer.h>
|
||||
#include <rapidjson/stringbuffer.h>
|
||||
#include <rapidjson/prettywriter.h>
|
||||
|
||||
namespace gdpm::rest_api{
|
||||
// See GitHub reference: https://github.com/godotengine/godot-asset-library/blob/master/API.md
|
||||
namespace endpoints{
|
||||
constexpr const char *POST_Register = "/register";
|
||||
constexpr const char *POST_Login = "/login";
|
||||
constexpr const char *POST_Logout = "/logout";
|
||||
constexpr const char *POST_ChangePassword = "/change_password";
|
||||
constexpr const char *GET_Configure = "/configure";
|
||||
constexpr const char *GET_Asset_NoParams = "/asset";
|
||||
constexpr const char *GET_Asset = "/asset?";
|
||||
constexpr const char *GET_AssetId = "/asset/{id}"; // ...find_replace
|
||||
constexpr const char *POST_AssetIdDelete = "/asset/{id}/delete";
|
||||
constexpr const char *POST_AssetIdUndelete = "/asset/{id}/delete";
|
||||
constexpr const char *POST_AssetSupportLevel = "/asset/{id}/support_level";
|
||||
constexpr const char *POST_Asset = "/asset";
|
||||
constexpr const char *POST_AssetId = "/asset/{id}";
|
||||
constexpr const char *POST_AssetEditId = "/asset/edit/{id}";
|
||||
}
|
||||
|
||||
bool register_account(const std::string& username, const std::string& password, const std::string& email);
|
||||
bool login(const std::string& username, const std::string& password);
|
||||
bool logout();
|
||||
// bool change_password()
|
||||
|
||||
enum type_e { any, addon, project };
|
||||
enum support_e { all, official, community, testing };
|
||||
enum sort_e { none, rating, cost, name, updated };
|
||||
|
||||
struct asset_list_context{
|
||||
type_e type;
|
||||
int category;
|
||||
support_e support;
|
||||
std::string filter;
|
||||
std::string user;
|
||||
std::string godot_version;
|
||||
int max_results;
|
||||
int page;
|
||||
sort_e sort;
|
||||
bool reverse;
|
||||
int verbose;
|
||||
};
|
||||
|
||||
asset_list_context make_context(type_e type = GDPM_DEFAULT_ASSET_TYPE, int category = GDPM_DEFAULT_ASSET_CATEGORY, support_e support = GDPM_DEFAULT_ASSET_SUPPORT, const std::string& filter = GDPM_DEFAULT_ASSET_FILTER, const std::string& user = GDPM_DEFAULT_ASSET_USER, const std::string& godot_version = GDPM_DEFAULT_ASSET_GODOT_VERSION, int max_results = GDPM_DEFAULT_ASSET_MAX_RESULTS, int page = GDPM_DEFAULT_ASSET_PAGE, sort_e sort = GDPM_DEFAULT_ASSET_SORT, bool reverse = GDPM_DEFAULT_ASSET_REVERSE, int verbose = GDPM_DEFAULT_ASSET_VERBOSE);
|
||||
|
||||
rapidjson::Document _parse_json(const std::string& r, int verbose = 0);
|
||||
std::string _get_type_string(type_e type);
|
||||
std::string _get_support_string(support_e support);
|
||||
std::string _get_sort_string(sort_e sort);
|
||||
void _print_params(const asset_list_context& params);
|
||||
|
||||
bool register_account(const std::string& username, const std::string& password, const std::string& email);
|
||||
bool login(const std::string& username, const std::string& password);
|
||||
bool logout();
|
||||
|
||||
rapidjson::Document configure(const std::string& url = constants::HostUrl, type_e type = any, int verbose = 0);
|
||||
rapidjson::Document get_assets_list(const std::string& url = constants::HostUrl, type_e type = GDPM_DEFAULT_ASSET_TYPE, int category = GDPM_DEFAULT_ASSET_CATEGORY, support_e support = GDPM_DEFAULT_ASSET_SUPPORT, const std::string& filter = GDPM_DEFAULT_ASSET_FILTER, const std::string& user = GDPM_DEFAULT_ASSET_USER, const std::string& godot_version = GDPM_DEFAULT_ASSET_GODOT_VERSION, int max_results = GDPM_DEFAULT_ASSET_MAX_RESULTS, int page = GDPM_DEFAULT_ASSET_PAGE, sort_e sort = GDPM_DEFAULT_ASSET_SORT, bool reverse = GDPM_DEFAULT_ASSET_REVERSE, int verbose = GDPM_DEFAULT_ASSET_VERBOSE);
|
||||
rapidjson::Document get_assets_list(const std::string& url, const asset_list_context& params);
|
||||
rapidjson::Document get_asset(const std::string& url, int asset_id, int verbose = GDPM_DEFAULT_ASSET_VERBOSE);
|
||||
bool delete_asset(int asset_id); // ...for moderators
|
||||
bool undelete_asset(int asset_id); // ...for moderators
|
||||
bool set_support_level(int asset_id); // ...for moderators
|
||||
|
||||
/*
|
||||
POST /asset
|
||||
POST /asset/{id}
|
||||
POST /asset/edit/{id}
|
||||
*/
|
||||
void edit_asset(/* need input parameters... */);
|
||||
|
||||
/* GET /asset/{id} */
|
||||
void get_asset_edit(int asset_id);
|
||||
|
||||
/* POST /asset/edit/{id}/review */
|
||||
std::string review_asset_edit(int asset_id);
|
||||
|
||||
/* POST /asset/edit/{id}/accept */
|
||||
std::string accept_asset_edit(int asset_id); // ...for moderators
|
||||
|
||||
/* POST /asset/edit/{id}/reject */
|
||||
std::string reject_asset_edit(int asset_id);
|
||||
}
|
||||
104
include/utils.hpp
Normal file
104
include/utils.hpp
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
#pragma once
|
||||
|
||||
#include "constants.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <string_view>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <chrono>
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <fmt/chrono.h>
|
||||
|
||||
namespace gdpm::utils{
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
struct memory_buffer{
|
||||
char *addr = nullptr;
|
||||
size_t size = 0;
|
||||
};
|
||||
|
||||
static memory_buffer make_buffer(){
|
||||
return memory_buffer{
|
||||
.addr = (char*)malloc(1), /* ...will grow as needed in curl_write_to_stream */
|
||||
.size = 0
|
||||
};
|
||||
}
|
||||
|
||||
static void free_buffer(memory_buffer& buf){
|
||||
free(buf.addr);
|
||||
}
|
||||
|
||||
static size_t curl_write_to_buffer(char *contents, size_t size, size_t nmemb, void *userdata){
|
||||
|
||||
size_t realsize = size * nmemb;
|
||||
struct memory_buffer *m = (struct memory_buffer*)userdata;
|
||||
|
||||
m->addr = (char*)realloc(m->addr, m->size + realsize + 1);
|
||||
if(m->addr == nullptr){
|
||||
/* Out of memory */
|
||||
fprintf(stderr, "Not enough memory (realloc returned NULL)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(&(m->addr[m->size]), contents, realsize);
|
||||
m->size += realsize;
|
||||
m->addr[m->size] = 0;
|
||||
|
||||
return realsize;
|
||||
}
|
||||
|
||||
static size_t curl_write_to_stream(char *ptr, size_t size, size_t nmemb, void *userdata){
|
||||
if(nmemb == 0)
|
||||
return 0;
|
||||
return fwrite(ptr, size, nmemb, (FILE*)userdata);
|
||||
}
|
||||
|
||||
static inline auto timestamp(const std::string& format = ":%I:%M:%S %p; %Y-%m-%d"){
|
||||
time_t t = std::time(nullptr);
|
||||
#if GDPM_ENABLE_TIMESTAMPS == 1
|
||||
return fmt::format(fmt::runtime("{"+format+"}"), fmt::localtime(t));
|
||||
#else
|
||||
return "";
|
||||
#endif
|
||||
// return fmt::format(format, std::chrono::system_clock::now());
|
||||
}
|
||||
|
||||
template <typename T, typename...Args>
|
||||
void push_back(std::vector<T>& v, Args&&...args)
|
||||
{
|
||||
static_assert((std::is_constructible_v<T, Args&&>&& ...));
|
||||
(v.emplace_back(std::forward<Args>(args)), ...);
|
||||
}
|
||||
|
||||
// A make_tuple wrapper for enforcing certain requirements
|
||||
template <typename... Args>
|
||||
auto range(Args...args)
|
||||
{
|
||||
// Limit number of args to only 2
|
||||
static_assert(sizeof...(Args) != 1, "Ranges requires only 2 arguments");
|
||||
return std::make_tuple(std::forward<Args>(args)...);
|
||||
}
|
||||
template <class T, class F>
|
||||
void move_if_not(std::vector<T>& from, std::vector<T>& to, F pred){
|
||||
auto part = std::partition(from.begin(), from.end(), pred);
|
||||
std::move(part, from.end(), std::back_inserter(from));
|
||||
from.erase(part);
|
||||
}
|
||||
|
||||
std::string readfile(const std::string& path);
|
||||
void to_lower(std::string& s);
|
||||
std::vector<std::string> parse_lines(const std::string& s);
|
||||
std::string replace_first(std::string& s, const std::string& from, const std::string& to);
|
||||
std::string replace_all(std::string& s, const std::string& from, const std::string& to);
|
||||
int extract_zip(const char *archive, const char *dest, int verbose = 0);
|
||||
std::string prompt_user(const char *message);
|
||||
bool prompt_user_yn(const char *message);
|
||||
void delay(std::chrono::milliseconds milliseconds = GDPM_REQUEST_DELAY);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue