Plan cloud transfer requests
This commit is contained in:
53
src/app.cpp
53
src/app.cpp
@@ -11,6 +11,7 @@
|
||||
#include "app_core/app_startup.h"
|
||||
#include "app_core/app_thread.h"
|
||||
#include "app_core/canvas_tool_ui.h"
|
||||
#include "app_core/document_cloud.h"
|
||||
#include "app_core/document_recording.h"
|
||||
#include "app_core/document_route.h"
|
||||
#include "app_core/document_session.h"
|
||||
@@ -272,16 +273,28 @@ void App::initLog()
|
||||
int progress_callback_download(void *clientp, curl_off_t dltotal,
|
||||
curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
|
||||
{
|
||||
std::function<void(float)> progress = *(std::function<void(float)>*)clientp;
|
||||
progress((float)dlnow / (float)dltotal);
|
||||
(void)ultotal;
|
||||
(void)ulnow;
|
||||
auto* progress = static_cast<std::function<void(float)>*>(clientp);
|
||||
const auto plan = pp::app::plan_cloud_transfer_progress(
|
||||
static_cast<std::int64_t>(dltotal),
|
||||
static_cast<std::int64_t>(dlnow));
|
||||
if (progress != nullptr && *progress && plan.notify)
|
||||
(*progress)(plan.fraction);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int progress_callback_upload(void *clientp, curl_off_t dltotal,
|
||||
curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
|
||||
{
|
||||
std::function<void(float)> progress = *(std::function<void(float)>*)clientp;
|
||||
progress((float)ulnow / (float)ultotal);
|
||||
(void)dltotal;
|
||||
(void)dlnow;
|
||||
auto* progress = static_cast<std::function<void(float)>*>(clientp);
|
||||
const auto plan = pp::app::plan_cloud_transfer_progress(
|
||||
static_cast<std::int64_t>(ultotal),
|
||||
static_cast<std::int64_t>(ulnow));
|
||||
if (progress != nullptr && *progress && plan.notify)
|
||||
(*progress)(plan.fraction);
|
||||
return 0;
|
||||
}
|
||||
#endif //CURL
|
||||
@@ -289,17 +302,32 @@ int progress_callback_upload(void *clientp, curl_off_t dltotal,
|
||||
void App::download(std::string url, std::string dest_filepath, std::function<void(float)> progress)
|
||||
{
|
||||
#if WITH_CURL
|
||||
const auto plan = pp::app::plan_cloud_download_transfer(
|
||||
url,
|
||||
dest_filepath,
|
||||
progress != nullptr,
|
||||
disables_network_tls_verification());
|
||||
if (plan.action != pp::app::CloudTransferAction::start_transfer) {
|
||||
LOG("download skipped: invalid transfer request");
|
||||
return;
|
||||
}
|
||||
|
||||
CURL *curl = curl_easy_init();
|
||||
if (curl)
|
||||
{
|
||||
FILE* fp = fopen(dest_filepath.c_str(), "wb");
|
||||
if (fp == nullptr) {
|
||||
LOG("download failed to open destination %s", dest_filepath.c_str());
|
||||
curl_easy_cleanup(curl);
|
||||
return;
|
||||
}
|
||||
LOG("download %s to %s", url.c_str(), dest_filepath.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_data_write);
|
||||
if (disables_network_tls_verification())
|
||||
if (plan.disable_tls_verification)
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
if (progress)
|
||||
if (plan.enable_progress)
|
||||
{
|
||||
curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, progress_callback_download);
|
||||
curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &progress);
|
||||
@@ -349,6 +377,15 @@ bool App::check_license()
|
||||
void App::upload(std::string filename, std::string name, std::function<void(float)> progress)
|
||||
{
|
||||
#if WITH_CURL
|
||||
const auto plan = pp::app::plan_cloud_upload_transfer(
|
||||
filename,
|
||||
progress != nullptr,
|
||||
disables_network_tls_verification());
|
||||
if (plan.action != pp::app::CloudTransferAction::start_transfer) {
|
||||
LOG("upload skipped: invalid transfer request");
|
||||
return;
|
||||
}
|
||||
|
||||
CURL *curl;
|
||||
|
||||
struct curl_httppost *formpost = NULL;
|
||||
@@ -372,9 +409,9 @@ void App::upload(std::string filename, std::string name, std::function<void(floa
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &res);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_data_handler);
|
||||
if (disables_network_tls_verification())
|
||||
if (plan.disable_tls_verification)
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
if (progress)
|
||||
if (plan.enable_progress)
|
||||
{
|
||||
curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, progress_callback_upload);
|
||||
curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &progress);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "foundation/result.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
@@ -25,6 +26,17 @@ enum class CloudDownloadSelectionAction {
|
||||
start_download,
|
||||
};
|
||||
|
||||
enum class CloudTransferDirection {
|
||||
download,
|
||||
upload,
|
||||
};
|
||||
|
||||
enum class CloudTransferAction {
|
||||
reject_missing_source,
|
||||
reject_missing_destination,
|
||||
start_transfer,
|
||||
};
|
||||
|
||||
struct CloudUploadPlan {
|
||||
CloudUploadAction action = CloudUploadAction::unavailable_no_canvas;
|
||||
bool save_before_upload = false;
|
||||
@@ -42,6 +54,18 @@ struct CloudDownloadRequest {
|
||||
std::string selected_name;
|
||||
};
|
||||
|
||||
struct CloudTransferPlan {
|
||||
CloudTransferDirection direction = CloudTransferDirection::download;
|
||||
CloudTransferAction action = CloudTransferAction::reject_missing_source;
|
||||
bool enable_progress = false;
|
||||
bool disable_tls_verification = false;
|
||||
};
|
||||
|
||||
struct CloudTransferProgressPlan {
|
||||
bool notify = false;
|
||||
float fraction = 0.0F;
|
||||
};
|
||||
|
||||
class CloudServices {
|
||||
public:
|
||||
virtual ~CloudServices() = default;
|
||||
@@ -98,6 +122,77 @@ public:
|
||||
};
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr CloudTransferPlan plan_cloud_download_transfer(
|
||||
std::string_view url,
|
||||
std::string_view destination_path,
|
||||
bool has_progress_callback,
|
||||
bool disables_tls_verification) noexcept
|
||||
{
|
||||
if (url.empty()) {
|
||||
return {
|
||||
CloudTransferDirection::download,
|
||||
CloudTransferAction::reject_missing_source,
|
||||
false,
|
||||
false,
|
||||
};
|
||||
}
|
||||
|
||||
if (destination_path.empty()) {
|
||||
return {
|
||||
CloudTransferDirection::download,
|
||||
CloudTransferAction::reject_missing_destination,
|
||||
false,
|
||||
false,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
CloudTransferDirection::download,
|
||||
CloudTransferAction::start_transfer,
|
||||
has_progress_callback,
|
||||
disables_tls_verification,
|
||||
};
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr CloudTransferPlan plan_cloud_upload_transfer(
|
||||
std::string_view filename,
|
||||
bool has_progress_callback,
|
||||
bool disables_tls_verification) noexcept
|
||||
{
|
||||
if (filename.empty()) {
|
||||
return {
|
||||
CloudTransferDirection::upload,
|
||||
CloudTransferAction::reject_missing_source,
|
||||
false,
|
||||
false,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
CloudTransferDirection::upload,
|
||||
CloudTransferAction::start_transfer,
|
||||
has_progress_callback,
|
||||
disables_tls_verification,
|
||||
};
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr CloudTransferProgressPlan plan_cloud_transfer_progress(
|
||||
std::int64_t total,
|
||||
std::int64_t current) noexcept
|
||||
{
|
||||
if (total <= 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto clamped_current = current < 0
|
||||
? std::int64_t { 0 }
|
||||
: (current > total ? total : current);
|
||||
return {
|
||||
true,
|
||||
static_cast<float>(static_cast<double>(clamped_current) / static_cast<double>(total)),
|
||||
};
|
||||
}
|
||||
|
||||
[[nodiscard]] inline pp::foundation::Status execute_cloud_upload_plan(
|
||||
const CloudUploadPlan& plan,
|
||||
CloudServices& services)
|
||||
|
||||
Reference in New Issue
Block a user