1
0
Fork 0
mirror of https://github.com/HamletDuFromage/aio-switch-updater.git synced 2024-11-24 18:42:05 +00:00

Check for available size

This commit is contained in:
flb 2021-06-03 18:47:35 +02:00
parent 6459ab4ae1
commit aeef0afe63
7 changed files with 104 additions and 45 deletions

View file

@ -22,7 +22,7 @@ DATA := data
INCLUDES := include lib/zipper/include /lib/borealis/library/include/borealis/extern/nlohmann
APP_TITLE := All-in-One Switch Updater
APP_AUTHOR := HamletDuFromage
APP_VERSION := 2.5.2
APP_VERSION := 2.5.3
TARGET := $(notdir $(CURDIR))
ROMFS := resources

View file

@ -12,5 +12,6 @@ namespace fs
bool copyFile(const std::string& from, const std::string& to);
std::string copyFiles(const std::string& path);
void createTree(std::string path);
std::set<std::string> readLineByLine(const std::string& path);
std::set<std::string> readLineByLine(const std::string& path);
Result getFreeStorageSD(s64& free);
}

View file

@ -159,6 +159,9 @@
"net": {
"title": "Internet settings"
},
"errors": {
"unsufficient_storage": "There isn't enough space available on your SD card to perform this operation."
},
"language": {
"system_default": "System default",
"en-US": "American English (en-US)",

View file

@ -154,6 +154,9 @@ ChangelogPage::ChangelogPage() : AppletFrame(true, true)
verTitles.push_back("v2.5.2");
changes.push_back("\uE016 Updated Japanese and Traditional Chinese translations (thanks to yyoossk and qazrfv1234).\n\uE016 Updated payload so that it doesn't throw errors if the bootloader folder is missing.\n\uE016 Minor code changes that may or may not result in performace improvements.");
verTitles.push_back("v2.5.3");
changes.push_back("\uE016 Check available size before downloading and extracting files.\n\uE016 Now displaying a message when the custom payload is running.");
for(int i = verTitles.size() -1 ; i >= 0; i--){
listItem = new brls::ListItem(verTitles[i]);
change = changes[i];

View file

@ -1,16 +1,18 @@
#include "download.hpp"
#include "utils.hpp"
#include "progress_event.hpp"
#include "fs.hpp"
#include <switch.h>
#include <algorithm>
#include <time.h>
#include <math.h>
#include <curl/curl.h>
#include <chrono>
#include <string>
#include <regex>
#include <switch.h>
#include "progress_event.hpp"
namespace i18n = brls::i18n;
using namespace i18n::literals;
constexpr const char API_AGENT[] = "HamletDuFromage";
constexpr int _1MiB = 0x100000;
@ -98,6 +100,24 @@ namespace download {
return realsize;
}
bool checkSize(CURL* curl, const std::string& url) {
curl_off_t dl;
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_USERAGENT, API_AGENT);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
curl_easy_perform(curl);
auto res = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &dl);
if(!res) {
s64 freeStorage;
if(R_SUCCEEDED(fs::getFreeStorageSD(freeStorage)) && dl * 1.1 > freeStorage) {
return false;
}
}
return true;
}
}
std::vector<std::uint8_t> downloadFile(const std::string& url, const char* output, int api)
@ -107,6 +127,7 @@ std::vector<std::uint8_t> downloadFile(const std::string& url, const char* outpu
ntwrk_struct_t chunk = {0};
time_old = std::chrono::steady_clock::now();
dlold = 0.0f;
bool can_download = true;
if (curl)
{
FILE *fp = fopen(output, "wb");
@ -116,39 +137,51 @@ std::vector<std::uint8_t> downloadFile(const std::string& url, const char* outpu
chunk.data_size = _1MiB;
chunk.out = fp;
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_USERAGENT, API_AGENT);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
// write calls
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &chunk);
if (api == OFF)
{
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, download_progress);
if(*output != 0) {
can_download = checkSize(curl, url);
}
curl_easy_perform(curl);
if (fp && chunk.offset)
fwrite(chunk.data, 1, chunk.offset, fp);
curl_easy_cleanup(curl);
ProgressEvent::instance().setStep(ProgressEvent::instance().getMax());
if(can_download) {
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_USERAGENT, API_AGENT);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_NOBODY, 0L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &chunk);
if (api == OFF)
{
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, download_progress);
}
curl_easy_perform(curl);
if (fp && chunk.offset && can_download)
fwrite(chunk.data, 1, chunk.offset, fp);
curl_easy_cleanup(curl);
ProgressEvent::instance().setStep(ProgressEvent::instance().getMax());
}
}
}
fclose(chunk.out);
if(!can_download) {
brls::Application::crash("menus/errors/unsufficient_storage"_i18n);
usleep(2000000);
brls::Application::quit();
return (std::vector<std::uint8_t>){};
}
if (*output == 0) {
std::vector<std::uint8_t> res(chunk.data, chunk.data + chunk.offset);
free(chunk.data);
fclose(chunk.out);
return res;
}
else {
free(chunk.data);
fclose(chunk.out);
return (std::vector<std::uint8_t>){};
}

View file

@ -1,4 +1,9 @@
#include "extract.hpp"
#include "progress_event.hpp"
#include "utils.hpp"
#include "download.hpp"
#include "fs.hpp"
#include "main_frame.hpp"
#include <string>
#include <vector>
#include <sstream>
@ -9,10 +14,6 @@
#include <fstream>
#include <set>
#include <unzipper.h>
#include "progress_event.hpp"
#include "utils.hpp"
#include "download.hpp"
#include "fs.hpp"
namespace i18n = brls::i18n;
using namespace i18n::literals;
@ -23,16 +24,34 @@ namespace extract {
bool caselessCompare (const std::string& a, const std::string& b){
return strcasecmp(a.c_str(), b.c_str()) < 0;
}
void preWork(zipper::Unzipper& unzipper, const std::string& workingPath, std::vector<zipper::ZipEntry>& entries) {
chdir(workingPath.c_str());
entries = unzipper.entries();
s64 uncompressedSize = 0;
s64 freeStorage;
for (const auto& entry: entries)
uncompressedSize += entry.uncompressedSize;
if(R_SUCCEEDED(fs::getFreeStorageSD(freeStorage))) {
if(uncompressedSize * 1.1 > freeStorage) {
unzipper.close();
brls::Application::crash("menus/errors/unsufficient_storage"_i18n);
usleep(2000000);
brls::Application::quit();
}
}
ProgressEvent::instance().reset();
ProgressEvent::instance().setStep(1);
ProgressEvent::instance().setTotalSteps(entries.size() + 1);
}
}
void extract(const std::string& filename, const std::string& workingPath, int overwriteInis){
ProgressEvent::instance().reset();
ProgressEvent::instance().setStep(1);
chdir(workingPath.c_str());
std::set<std::string> ignoreList = fs::readLineByLine(FILES_IGNORE);
zipper::Unzipper unzipper(filename);
std::vector<zipper::ZipEntry> entries = unzipper.entries();
ProgressEvent::instance().setTotalSteps(entries.size() + 1);
std::vector<zipper::ZipEntry> entries;
preWork(unzipper, workingPath, entries);
std::set<std::string> ignoreList = fs::readLineByLine(FILES_IGNORE);
for (const auto& entry : entries) {
if((overwriteInis == 0 && entry.name.substr(entry.name.length() - 4) == ".ini")
|| find_if(ignoreList.begin(), ignoreList.end(), [&entry](std::string ignored) {
@ -60,14 +79,11 @@ void extract(const std::string& filename, const std::string& workingPath, int o
}
void extract(const std::string& filename, const std::string& workingPath, const std::string& toExclude){
ProgressEvent::instance().reset();
ProgressEvent::instance().setStep(1);
chdir(workingPath.c_str());
zipper::Unzipper unzipper(filename);
std::vector<zipper::ZipEntry> entries;
preWork(unzipper, workingPath, entries);
std::set<std::string> ignoreList = fs::readLineByLine(FILES_IGNORE);
ignoreList.insert(toExclude);
zipper::Unzipper unzipper(filename);
std::vector<zipper::ZipEntry> entries = unzipper.entries();
ProgressEvent::instance().setTotalSteps(entries.size() + 1);
for (const auto& entry : entries) {
if(find_if(ignoreList.begin(), ignoreList.end(), [&entry](std::string ignored) {
u8 res = ("/" + entry.name).find(ignored);

View file

@ -1,9 +1,8 @@
#include "fs.hpp"
#include "constants.hpp"
#include <borealis.hpp>
#include <fstream>
#include <filesystem>
#include "constants.hpp"
namespace i18n = brls::i18n;
using namespace i18n::literals;
@ -101,7 +100,7 @@ namespace fs {
return error;
}
std::set<std::string> readLineByLine(const std::string& path){
std::set<std::string> readLineByLine(const std::string& path){
std::set<std::string> titles;
std::string str;
std::ifstream in(path);
@ -116,4 +115,8 @@ namespace fs {
return titles;
}
Result getFreeStorageSD(s64& free) {
return nsGetFreeSpaceSize(NcmStorageId_SdCard, &free);
}
}