mirror of
https://github.com/J-D-K/JKSV.git
synced 2026-09-13 21:15:38 -05:00
More refactoring. Start to completely implement remote storage.
This commit is contained in:
@@ -3,20 +3,33 @@
|
||||
#include "config.hpp"
|
||||
#include "error.hpp"
|
||||
#include "fs/fs.hpp"
|
||||
#include "logger.hpp"
|
||||
#include "remote/remote.hpp"
|
||||
#include "strings.hpp"
|
||||
#include "stringutil.hpp"
|
||||
#include "ui/PopMessageManager.hpp"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr const char *STRING_ZIP_EXT = ".zip";
|
||||
}
|
||||
|
||||
void tasks::backup::create_new_backup(sys::ProgressTask *task,
|
||||
data::User *user,
|
||||
data::TitleInfo *titleInfo,
|
||||
fslib::Path target,
|
||||
BackupMenuState *spawningState)
|
||||
BackupMenuState *spawningState,
|
||||
bool killTask)
|
||||
{
|
||||
const bool exportZip = config::get_by_key(config::keys::EXPORT_TO_ZIP);
|
||||
const bool autoUpload = config::get_by_key(config::keys::AUTO_UPLOAD);
|
||||
const bool hasZipExt = std::strstr(target.full_path(), ".zip");
|
||||
const const bool uint64_t applicationID = titleInfo->get_application_id();
|
||||
const FsSaveDataInfo *saveInfo = user->get_save_info_by_id(applicationID);
|
||||
if (error::is_null(task)) { return; }
|
||||
static constexpr size_t SIZE_SAVE_META = sizeof(fs::SaveMetaData);
|
||||
|
||||
const bool autoUpload = config::get_by_key(config::keys::AUTO_UPLOAD);
|
||||
const bool hasZipExt = std::strstr(target.full_path(), STRING_ZIP_EXT);
|
||||
const uint64_t applicationID = titleInfo->get_application_id();
|
||||
const FsSaveDataInfo *saveInfo = user->get_save_info_by_id(applicationID);
|
||||
if (error::is_null(saveInfo))
|
||||
{
|
||||
task->finished();
|
||||
@@ -25,4 +38,177 @@ void tasks::backup::create_new_backup(sys::ProgressTask *task,
|
||||
|
||||
fs::SaveMetaData saveMeta{};
|
||||
const bool hasValidMeta = fs::fill_save_meta_data(saveInfo, saveMeta);
|
||||
if (hasZipExt) // At this point, this should have the zip extension appended if needed.
|
||||
{
|
||||
fs::MiniZip zip{target};
|
||||
if (!zip.is_open())
|
||||
{
|
||||
task->finished();
|
||||
return;
|
||||
}
|
||||
|
||||
const bool openMeta = hasValidMeta && zip.open_new_file(fs::NAME_SAVE_META);
|
||||
if (openMeta)
|
||||
{
|
||||
zip.write(&saveMeta, SIZE_SAVE_META);
|
||||
zip.close_current_file();
|
||||
}
|
||||
fs::copy_directory_to_zip(fs::DEFAULT_SAVE_ROOT, zip, task);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hasValidMeta)
|
||||
{
|
||||
const fslib::Path saveMetaPath{target / fs::NAME_SAVE_META};
|
||||
fslib::File saveMetaFile{saveMetaPath, FsOpenMode_Create | FsOpenMode_Write, SIZE_SAVE_META};
|
||||
if (saveMetaFile.is_open()) { saveMetaFile.write(&saveMeta, SIZE_SAVE_META); }
|
||||
}
|
||||
fs::copy_directory(fs::DEFAULT_SAVE_ROOT, target, task);
|
||||
}
|
||||
spawningState->refresh();
|
||||
if (killTask) { task->finished(); }
|
||||
}
|
||||
|
||||
void tasks::backup::overwrite_backup(sys::ProgressTask *task, BackupMenuState::TaskData taskData)
|
||||
{
|
||||
if (error::is_null(task)) { return; }
|
||||
|
||||
data::User *user = taskData->user;
|
||||
data::TitleInfo *titleInfo = taskData->titleInfo;
|
||||
const fslib::Path &target = taskData->path;
|
||||
BackupMenuState *spawningState = taskData->spawningState;
|
||||
|
||||
const bool isDirectory = fslib::directory_exists(target);
|
||||
const bool dirFailed = isDirectory && error::fslib(fslib::delete_directory_recursively(target));
|
||||
const bool fileFailed = !isDirectory && error::fslib(fslib::delete_file(target));
|
||||
if (dirFailed && fileFailed)
|
||||
{
|
||||
task->finished();
|
||||
return;
|
||||
}
|
||||
create_new_backup(task, user, titleInfo, target, spawningState);
|
||||
}
|
||||
|
||||
void tasks::backup::restore_backup(sys::ProgressTask *task, BackupMenuState::TaskData taskData)
|
||||
{
|
||||
static constexpr size_t SIZE_META = sizeof(fs::SaveMetaData);
|
||||
|
||||
if (error::is_null(task)) { return; }
|
||||
|
||||
data::User *user = taskData->user;
|
||||
data::TitleInfo *titleInfo = taskData->titleInfo;
|
||||
const fslib::Path &target = taskData->path;
|
||||
BackupMenuState *spawningState = taskData->spawningState;
|
||||
|
||||
const uint64_t applicationID = titleInfo->get_application_id();
|
||||
const FsSaveDataInfo *saveInfo = user->get_save_info_by_id(applicationID);
|
||||
const uint8_t saveType = user->get_account_save_type();
|
||||
const uint64_t journalSize = titleInfo->get_journal_size(saveType);
|
||||
|
||||
const bool autoBackup = config::get_by_key(config::keys::AUTO_BACKUP_ON_RESTORE);
|
||||
const bool exportZip = config::get_by_key(config::keys::EXPORT_TO_ZIP) || config::get_by_key(config::keys::AUTO_UPLOAD);
|
||||
const bool isDir = fslib::directory_exists(target);
|
||||
const bool hasZipExt = std::strstr(target.full_path(), STRING_ZIP_EXT);
|
||||
|
||||
const int popTicks = ui::PopMessageManager::DEFAULT_MESSAGE_TICKS;
|
||||
const char *popErrorResetting = strings::get_by_name(strings::names::BACKUPMENU_POPS, 2);
|
||||
const char *popErrorCreating = strings::get_by_name(strings::names::BACKUPMENU_POPS, 5);
|
||||
const char *popErrorOpenZip = strings::get_by_name(strings::names::EXTRASMENU_POPS, 7);
|
||||
|
||||
if (autoBackup)
|
||||
{
|
||||
fslib::Path autoTarget{};
|
||||
const size_t lastSlash = target.find_last_of('/');
|
||||
if (lastSlash == target.NOT_FOUND)
|
||||
{
|
||||
ui::PopMessageManager::push_message(popTicks, popErrorCreating);
|
||||
task->finished();
|
||||
return;
|
||||
}
|
||||
|
||||
const char *safeNickname = user->get_path_safe_nickname();
|
||||
autoTarget = target.sub_path(lastSlash) / "AUTO - " + safeNickname + " - " + stringutil::get_date_string();
|
||||
if (exportZip) { autoTarget += ".zip"; };
|
||||
|
||||
tasks::backup::create_new_backup(task, user, titleInfo, autoTarget, spawningState, false);
|
||||
}
|
||||
|
||||
const bool resetError = error::fslib(fslib::delete_directory_recursively(fs::DEFAULT_SAVE_ROOT));
|
||||
const bool commitError = error::fslib(fslib::commit_data_to_file_system(fs::DEFAULT_SAVE_MOUNT));
|
||||
if (resetError || commitError)
|
||||
{
|
||||
ui::PopMessageManager::push_message(popTicks, popErrorResetting);
|
||||
task->finished();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isDir && hasZipExt)
|
||||
{
|
||||
fs::MiniUnzip unzip{target};
|
||||
if (!unzip.is_open())
|
||||
{
|
||||
ui::PopMessageManager::push_message(popTicks, popErrorOpenZip);
|
||||
task->finished();
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
fs::SaveMetaData metaData{};
|
||||
const bool hasMeta = unzip.locate_file(fs::NAME_SAVE_META);
|
||||
const bool readMeta = hasMeta && unzip.read(&metaData, SIZE_META) == SIZE_META;
|
||||
if (readMeta) { fs::process_save_meta_data(saveInfo, metaData); };
|
||||
}
|
||||
// To do: Maybe use the meta instead of what the NACP has?
|
||||
fs::copy_zip_to_directory(unzip, fs::DEFAULT_SAVE_ROOT, journalSize, fs::DEFAULT_SAVE_MOUNT, task);
|
||||
}
|
||||
else if (isDir)
|
||||
{
|
||||
{
|
||||
fs::SaveMetaData metaData{};
|
||||
const fslib::Path metaPath{target / fs::NAME_SAVE_META};
|
||||
fslib::File metaFile{metaPath, FsOpenMode_Read};
|
||||
const bool metaRead = metaFile.is_open() && metaFile.read(&metaData, SIZE_META) == SIZE_META;
|
||||
if (metaRead) { fs::process_save_meta_data(saveInfo, metaData); }
|
||||
}
|
||||
// To do: Same here?
|
||||
fs::copy_directory(target, fs::DEFAULT_SAVE_ROOT, task, journalSize, fs::DEFAULT_SAVE_MOUNT);
|
||||
}
|
||||
else { fs::copy_file(target, fs::DEFAULT_SAVE_ROOT, task, journalSize, fs::DEFAULT_SAVE_MOUNT); }
|
||||
|
||||
task->finished();
|
||||
}
|
||||
|
||||
void tasks::backup::delete_backup(sys::Task *task, BackupMenuState::TaskData taskData)
|
||||
{
|
||||
if (error::is_null(task)) { return; }
|
||||
const fslib::Path &path = taskData->path;
|
||||
BackupMenuState *spawningState = taskData->spawningState;
|
||||
const int popTicks = ui::PopMessageManager::DEFAULT_MESSAGE_TICKS;
|
||||
const char *statusTemplate = strings::get_by_name(strings::names::IO_STATUSES, 3);
|
||||
const char *popFailed = strings::get_by_name(strings::names::BACKUPMENU_POPS, 4);
|
||||
|
||||
{
|
||||
const std::string status = stringutil::get_formatted_string(statusTemplate, path.full_path());
|
||||
task->set_status(status);
|
||||
}
|
||||
|
||||
const bool isDir = fslib::directory_exists(path);
|
||||
const bool dirError = isDir && error::fslib(fslib::delete_directory_recursively(path));
|
||||
const bool fileError = !isDir && error::fslib(fslib::delete_file(path));
|
||||
if (dirError || fileError) { ui::PopMessageManager::push_message(popTicks, popFailed); }
|
||||
spawningState->refresh();
|
||||
task->finished();
|
||||
}
|
||||
|
||||
void tasks::backup::upload_backup(sys::ProgressTask *task, BackupMenuState::TaskData taskData)
|
||||
{
|
||||
remote::Storage *remote = remote::get_remote_storage();
|
||||
if (error::is_null(task) || error::is_null(remote)) { return; }
|
||||
|
||||
// The backup menu should've made sure the remote is pointing to the correct location.
|
||||
const fslib::Path &path = taskData->path;
|
||||
|
||||
remote->upload_file(path, task);
|
||||
|
||||
task->finished();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user