mason/src2/download.h
2023-09-25 17:15:24 -03:00

91 lines
2.5 KiB
C++

#pragma once
#include <mutex>
#include <memory>
#include <string>
#include <vector>
#include <string_view>
#include <filesystem>
#include <optional>
#include <exception>
#include <curl/curl.h>
#include <nlohmann/json.hpp>
#include <archive.h>
#include <archive_entry.h>
#include "atomicmutex.h"
#include "loggable.h"
class Collection;
class Download : protected Loggable {
struct RepoInfo;
struct CurlDeleter {
void operator() (CURL* curl) const;
};
struct FileDeleter {
void operator() (FILE* file) const;
};
class CurlError;
class FileError;
public:
explicit Download(
const std::string& url,
const std::filesystem::path& destination,
const std::shared_ptr<Logger>& logger
);
~Download();
void proceed();
std::optional<std::filesystem::path> getLocation() const;
private:
std::optional<RepoInfo> testRepo() const;
std::optional<std::filesystem::path> downloadAsRepo(const RepoInfo& repo);
std::optional<nlohmann::json> repoInfoGiteaApi1(const RepoInfo& repo);
std::optional<std::filesystem::path> downloadRepoGiteaApi1(const RepoInfo& repo, const std::string& branch);
bool extract(const std::filesystem::path& source, const std::filesystem::path& destination) const;
int copy(struct archive *ar, struct archive *aw) const;
CURLcode httpGet(const std::string& url, std::string& result, const std::vector<std::string_view>& headers = {});
CURLcode httpDownload(const std::string& url, const std::filesystem::path& path, const std::vector<std::string_view>& headers = {});
void setHeaders (const std::vector<std::string_view>& headers);
static size_t writeString(void* data, size_t size, size_t nmemb, void* mem);
static int trace(CURL *handle, curl_infotype type, char *data, size_t size, void *clientp);
void createCurl();
private:
static AtomicMutex amx;
static unsigned int instances;
std::unique_ptr<CURL, CurlDeleter> curl;
std::string url;
std::filesystem::path destination;
std::optional<std::filesystem::path> location;
};
struct Download::RepoInfo {
std::string protocol;
std::string host;
std::string owner;
std::string name;
std::string origin() const;
std::string project() const;
};
class Download::CurlError : public std::runtime_error {
public:
explicit CurlError(const std::string& message);
};
class Download::FileError : public std::runtime_error {
public:
explicit FileError(const std::string& message);
};