mirror of
https://github.com/HamletDuFromage/aio-switch-updater.git
synced 2024-12-28 18:36:02 +00:00
Check for available size
This commit is contained in:
parent
6459ab4ae1
commit
aeef0afe63
7 changed files with 104 additions and 45 deletions
2
Makefile
2
Makefile
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)",
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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>){};
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue