From c5282a5767b2ee7853020c2c4aef27ae7c3151fd Mon Sep 17 00:00:00 2001 From: StackZ <47382115+SuperSaiyajinStackZ@users.noreply.github.com> Date: Sat, 31 Oct 2020 07:48:29 +0100 Subject: [PATCH] WIP: Copy Progressbar. Also: More MaxWidth & DownloadRelease JSON accept check. --- include/utils/animation.hpp | 4 +- include/utils/download.hpp | 1 - source/utils/animation.cpp | 91 ++++++++++++++++++++++++++++++ source/utils/cia.cpp | 2 +- source/utils/download.cpp | 104 +++++++---------------------------- source/utils/extract.cpp | 2 +- source/utils/fileBrowse.cpp | 19 ++++--- source/utils/scriptUtils.cpp | 24 ++++++-- 8 files changed, 145 insertions(+), 102 deletions(-) diff --git a/include/utils/animation.hpp b/include/utils/animation.hpp index c843f85..204557f 100644 --- a/include/utils/animation.hpp +++ b/include/utils/animation.hpp @@ -33,11 +33,13 @@ enum class ProgressBar { Downloading, Extracting, - Installing + Installing, + Copying }; namespace Animation { void DrawProgressBar(const u64 ¤tProgress, const u64 &totalProgress); + void displayProgressBar(); }; #endif \ No newline at end of file diff --git a/include/utils/download.hpp b/include/utils/download.hpp index 883d46a..a07cb29 100644 --- a/include/utils/download.hpp +++ b/include/utils/download.hpp @@ -65,7 +65,6 @@ void notImplemented(void); */ void doneMsg(void); -void displayProgressBar(); bool IsUpdateAvailable(const std::string &URL, const int &revCurrent); bool DownloadUniStore(const std::string &URL, const int ¤tRev, std::string &fl, const bool &isDownload = false, const bool &isUDB = false); bool DownloadSpriteSheet(const std::string &URL, const std::string &file); diff --git a/source/utils/animation.cpp b/source/utils/animation.cpp index 602dbc8..fa83fd0 100644 --- a/source/utils/animation.cpp +++ b/source/utils/animation.cpp @@ -26,6 +26,21 @@ #include "animation.hpp" #include "common.hpp" +#include "stringutils.hpp" +#include + +extern int filesExtracted, extractFilesCount; +extern std::string extractingFile; +char progressBarMsg[128] = ""; +bool showProgressBar = false; +ProgressBar progressbarType = ProgressBar::Downloading; + +extern u32 extractSize, writeOffset; +extern u32 installSize, installOffset; +extern u32 copyOffset, copySize; + +extern curl_off_t downloadTotal; +extern curl_off_t downloadNow; /* Draw the progressbar. @@ -36,4 +51,80 @@ void Animation::DrawProgressBar(const u64 ¤tProgress, const u64 &totalProgress) { Gui::Draw_Rect(30, 120, 340, 30, PROGRESSBAR_OUT_COLOR); Gui::Draw_Rect(31, 121, (int)(((float)currentProgress / (float)totalProgress) * 338.0f), 28, PROGRESSBAR_IN_COLOR); +} + +/* + Display the progressbar. +*/ +void Animation::displayProgressBar() { + char str[256]; + + while(showProgressBar) { + switch(progressbarType) { + case ProgressBar::Downloading: + if (downloadTotal < 1.0f) downloadTotal = 1.0f; + if (downloadTotal < downloadNow) downloadTotal = downloadNow; + + snprintf(str, sizeof(str), "%s / %s (%.2f%%)", + StringUtils::formatBytes(downloadNow).c_str(), + StringUtils::formatBytes(downloadTotal).c_str(), + ((float)downloadNow/(float)downloadTotal) * 100.0f); + break; + + case ProgressBar::Extracting: + snprintf(str, sizeof(str), "%s / %s (%.2f%%)", + StringUtils::formatBytes(writeOffset).c_str(), + StringUtils::formatBytes(extractSize).c_str(), + ((float)writeOffset/(float)extractSize) * 100.0f); + break; + + case ProgressBar::Installing: + snprintf(str, sizeof(str), "%s / %s (%.2f%%)", + StringUtils::formatBytes(installOffset).c_str(), + StringUtils::formatBytes(installSize).c_str(), + ((float)installOffset/(float)installSize) * 100.0f); + break; + + case ProgressBar::Copying: + snprintf(str, sizeof(str), "%s / %s (%.2f%%)", + StringUtils::formatBytes(copyOffset).c_str(), + StringUtils::formatBytes(copySize).c_str(), + ((float)copyOffset/(float)copySize) * 100.0f); + break; + } + + Gui::clearTextBufs(); + C3D_FrameBegin(C3D_FRAME_SYNCDRAW); + C2D_TargetClear(Top, TRANSPARENT); + C2D_TargetClear(Bottom, TRANSPARENT); + GFX::DrawTop(); + Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, progressBarMsg, 390); + + switch(progressbarType) { + case ProgressBar::Downloading: + Gui::DrawStringCentered(0, 80, 0.6f, TEXT_COLOR, str, 390); + Animation::DrawProgressBar(downloadNow, downloadTotal); + break; + + case ProgressBar::Extracting: + Gui::DrawStringCentered(0, 180, 0.6f, TEXT_COLOR, str, 390); + Gui::DrawStringCentered(0, 100, 0.6f, TEXT_COLOR, std::to_string(filesExtracted) + " / " + std::to_string(extractFilesCount) + " " + (filesExtracted == 1 ? (Lang::get("FILE_EXTRACTED")).c_str() :(Lang::get("FILES_EXTRACTED"))), 390); + Gui::DrawStringCentered(0, 40, 0.6f, TEXT_COLOR, Lang::get("CURRENTLY_EXTRACTING") + "\n" + extractingFile, 390); + Animation::DrawProgressBar(writeOffset, extractSize); + break; + + case ProgressBar::Installing: + Gui::DrawStringCentered(0, 80, 0.6f, TEXT_COLOR, str, 390); + Animation::DrawProgressBar(installOffset, installSize); + break; + + case ProgressBar::Copying: + Gui::DrawStringCentered(0, 80, 0.6f, TEXT_COLOR, str, 390); + Animation::DrawProgressBar(copyOffset, copySize); + break; + } + + GFX::DrawBottom(); + C3D_FrameEnd(0); + } } \ No newline at end of file diff --git a/source/utils/cia.cpp b/source/utils/cia.cpp index 47f7c4f..5856ac7 100644 --- a/source/utils/cia.cpp +++ b/source/utils/cia.cpp @@ -91,7 +91,7 @@ FS_MediaType getTitleDestination(const u64 &titleId) { return platform == 0x0003 || (platform == 0x0004 && ((category & 0x8011) != 0 || (category == 0x0000 && variation == 0x02))) ? MEDIATYPE_NAND : MEDIATYPE_SD; } -u64 installSize = 0, installOffset = 0; +u32 installSize = 0, installOffset = 0; Result installCia(const char *ciaPath, const bool &updatingSelf) { u32 bytes_read = 0, bytes_written; diff --git a/source/utils/download.cpp b/source/utils/download.cpp index 5c80a90..758ca01 100644 --- a/source/utils/download.cpp +++ b/source/utils/download.cpp @@ -68,15 +68,6 @@ static bool killThread = false; static bool writeError = false; #define FILE_ALLOC_SIZE 0x60000 -extern int filesExtracted, extractFilesCount; -extern std::string extractingFile; -char progressBarMsg[128] = ""; -bool showProgressBar = false; -ProgressBar progressbarType = ProgressBar::Downloading; - -extern u64 extractSize, writeOffset; -extern u64 installSize, installOffset; - static int curlProgress(CURL *hnd, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow) @@ -372,22 +363,31 @@ Result downloadFromRelease(const std::string &url, const std::string &asset, con printf("Looking for asset with matching name:\n%s\n", asset.c_str()); std::string assetUrl; - nlohmann::json parsedAPI = nlohmann::json::parse(result_buf); - if (parsedAPI.size() == 0) return -2; // All were prereleases and those are being ignored. - if (includePrereleases) parsedAPI = parsedAPI[0]; + if (nlohmann::json::accept(result_buf)) { + nlohmann::json parsedAPI = nlohmann::json::parse(result_buf); - if (parsedAPI["assets"].is_array()) { - for (auto jsonAsset : parsedAPI["assets"]) { - if (jsonAsset.is_object() && jsonAsset["name"].is_string() && jsonAsset["browser_download_url"].is_string()) { - std::string assetName = jsonAsset["name"]; + if (parsedAPI.size() == 0) ret = -2; // All were prereleases and those are being ignored. - if (ScriptUtils::matchPattern(asset, assetName)) { - assetUrl = jsonAsset["browser_download_url"]; - break; + if (ret != -2) { + if (includePrereleases) parsedAPI = parsedAPI[0]; + + if (parsedAPI["assets"].is_array()) { + for (auto jsonAsset : parsedAPI["assets"]) { + if (jsonAsset.is_object() && jsonAsset["name"].is_string() && jsonAsset["browser_download_url"].is_string()) { + std::string assetName = jsonAsset["name"]; + + if (ScriptUtils::matchPattern(asset, assetName)) { + assetUrl = jsonAsset["browser_download_url"]; + break; + } + } } } } + + } else { + ret = -3; } socExit(); @@ -397,7 +397,7 @@ Result downloadFromRelease(const std::string &url, const std::string &asset, con result_sz = 0; result_written = 0; - if (assetUrl.empty()) { + if (assetUrl.empty() || ret != 0) { ret = DL_ERROR_GIT; } else { @@ -429,70 +429,6 @@ void doneMsg(void) { Msg::waitMsg(Lang::get("DONE")); } void notConnectedMsg(void) { Msg::waitMsg(Lang::get("CONNECT_WIFI")); } -/* - Display the progressbar. -*/ -void displayProgressBar() { - char str[256]; - - while(showProgressBar) { - switch(progressbarType) { - case ProgressBar::Downloading: - if (downloadTotal < 1.0f) downloadTotal = 1.0f; - if (downloadTotal < downloadNow) downloadTotal = downloadNow; - - snprintf(str, sizeof(str), "%s / %s (%.2f%%)", - StringUtils::formatBytes(downloadNow).c_str(), - StringUtils::formatBytes(downloadTotal).c_str(), - ((float)downloadNow/(float)downloadTotal) * 100.0f); - break; - - case ProgressBar::Extracting: - snprintf(str, sizeof(str), "%s / %s (%.2f%%)", - StringUtils::formatBytes(writeOffset).c_str(), - StringUtils::formatBytes(extractSize).c_str(), - ((float)writeOffset/(float)extractSize) * 100.0f); - break; - - case ProgressBar::Installing: - snprintf(str, sizeof(str), "%s / %s (%.2f%%)", - StringUtils::formatBytes(installOffset).c_str(), - StringUtils::formatBytes(installSize).c_str(), - ((float)installOffset/(float)installSize) * 100.0f); - break; - } - - Gui::clearTextBufs(); - C3D_FrameBegin(C3D_FRAME_SYNCDRAW); - C2D_TargetClear(Top, TRANSPARENT); - C2D_TargetClear(Bottom, TRANSPARENT); - GFX::DrawTop(); - Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, progressBarMsg, 400); - - switch(progressbarType) { - case ProgressBar::Downloading: - Gui::DrawStringCentered(0, 80, 0.6f, TEXT_COLOR, str, 400); - Animation::DrawProgressBar(downloadNow, downloadTotal); - break; - - case ProgressBar::Extracting: - Gui::DrawStringCentered(0, 180, 0.6f, TEXT_COLOR, str, 400); - Gui::DrawStringCentered(0, 100, 0.6f, TEXT_COLOR, std::to_string(filesExtracted) + " / " + std::to_string(extractFilesCount) + " " + (filesExtracted == 1 ? (Lang::get("FILE_EXTRACTED")).c_str() :(Lang::get("FILES_EXTRACTED"))), 400); - Gui::DrawStringCentered(0, 40, 0.6f, TEXT_COLOR, Lang::get("CURRENTLY_EXTRACTING") + "\n" + extractingFile, 400); - Animation::DrawProgressBar(writeOffset, extractSize); - break; - - case ProgressBar::Installing: - Gui::DrawStringCentered(0, 80, 0.6f, TEXT_COLOR, str, 400); - Animation::DrawProgressBar(installOffset, installSize); - break; - } - - GFX::DrawBottom(); - C3D_FrameEnd(0); - } -} - /* Return, if an update is available. diff --git a/source/utils/extract.cpp b/source/utils/extract.cpp index 59817cd..58a496d 100644 --- a/source/utils/extract.cpp +++ b/source/utils/extract.cpp @@ -34,7 +34,7 @@ int filesExtracted = 0, extractFilesCount = 0; std::string extractingFile = ""; /* That are our File Progressbar variable. */ -u64 extractSize = 0, writeOffset = 0; +u32 extractSize = 0, writeOffset = 0; Result getExtractedSize(const std::string &archivePath, const std::string &wantedFile) { extractSize = 0, writeOffset = 0, filesExtracted = 0, extractFilesCount = 0; diff --git a/source/utils/fileBrowse.cpp b/source/utils/fileBrowse.cpp index fc5b1cf..f71d34a 100644 --- a/source/utils/fileBrowse.cpp +++ b/source/utils/fileBrowse.cpp @@ -193,6 +193,7 @@ void dirCopy(DirEntry *entry, const char *destinationPath, const char *sourcePat if (((int)dirContents.size()) != 1) fcopy((sourcePath + ("/" + entry->name)).c_str(), (destinationPath + ("/" + entry->name)).c_str()); } +u32 copyOffset = 0, copySize = 0; /* The copy operation. @@ -200,6 +201,8 @@ void dirCopy(DirEntry *entry, const char *destinationPath, const char *sourcePat const char *sourcePath: Pointer to the source path. */ int fcopy(const char *sourcePath, const char *destinationPath) { + copyOffset = 0, copySize = 0; + DIR *isDir = opendir(sourcePath); if (isDir != NULL) { @@ -227,10 +230,11 @@ int fcopy(const char *sourcePath, const char *destinationPath) { /* Source path is a file. */ FILE *sourceFile = fopen(sourcePath, "rb"); - off_t fsize = 0; + copySize = 0, copyOffset = 0; + if (sourceFile) { fseek(sourceFile, 0, SEEK_END); - fsize = ftell(sourceFile); // Get source file's size. + copySize = ftell(sourceFile); // Get source file's size. fseek(sourceFile, 0, SEEK_SET); } else { @@ -238,7 +242,7 @@ int fcopy(const char *sourcePath, const char *destinationPath) { return -1; } - FILE* destinationFile = fopen(destinationPath, "wb"); + FILE *destinationFile = fopen(destinationPath, "wb"); //if (destinationFile) { fseek(destinationFile, 0, SEEK_SET); /*} else { @@ -247,7 +251,6 @@ int fcopy(const char *sourcePath, const char *destinationPath) { return -1; }*/ - off_t offset = 0; int numr; while(1) { scanKeys(); @@ -261,19 +264,19 @@ int fcopy(const char *sourcePath, const char *destinationPath) { printf("\x1b[16;0H"); printf("Progress:\n"); - printf("%i/%i Bytes ", (int)offset, (int)fsize); + printf("%i/%i Bytes ", (int)copyOffset, (int)copySize); /* Copy file to destination path. */ numr = fread(copyBuf, 2, copyBufSize, sourceFile); fwrite(copyBuf, 2, numr, destinationFile); - offset += copyBufSize; + copyOffset += copyBufSize; - if (offset > fsize) { + if (copyOffset > copySize) { fclose(sourceFile); fclose(destinationFile); printf("\x1b[17;0H"); - printf("%i/%i Bytes ", (int)fsize, (int)fsize); + printf("%i/%i Bytes ", (int)copyOffset, (int)copySize); for(int i = 0; i < 30; i++) gspWaitForVBlank(); return 1; diff --git a/source/utils/scriptUtils.cpp b/source/utils/scriptUtils.cpp index 215c03c..e8fb61b 100644 --- a/source/utils/scriptUtils.cpp +++ b/source/utils/scriptUtils.cpp @@ -104,11 +104,23 @@ Result ScriptUtils::copyFile(const std::string &source, const std::string &desti _dest = std::regex_replace(_dest, std::regex("%3DSX%"), config->_3dsxPath()); _dest = std::regex_replace(_dest, std::regex("%NDS%"), config->ndsPath()); - Msg::DisplayMsg(message); + snprintf(progressBarMsg, sizeof(progressBarMsg), message.c_str()); + showProgressBar = true; + progressbarType = ProgressBar::Copying; + + s32 prio = 0; + svcGetThreadPriority(&prio, CUR_THREAD_HANDLE); + thread = threadCreate((ThreadFunc)Animation::displayProgressBar, NULL, 64 * 1024, prio - 1, -2, false); /* If destination does not exist, create dirs. */ if (access(_dest.c_str(), F_OK) != 0) makeDirs(_dest.c_str()); - fcopy(_source.c_str(), _dest.c_str()); + ret = fcopy(_source.c_str(), _dest.c_str()); + + if (ret == -1) ret = COPY_ERROR; + else if (ret == 1) ret = NONE; + showProgressBar = false; + threadJoin(thread, U64_MAX); + threadFree(thread); return ret; } @@ -153,7 +165,7 @@ Result ScriptUtils::downloadRelease(const std::string &repo, const std::string & s32 prio = 0; svcGetThreadPriority(&prio, CUR_THREAD_HANDLE); - thread = threadCreate((ThreadFunc)displayProgressBar, NULL, 64 * 1024, prio - 1, -2, false); + thread = threadCreate((ThreadFunc)Animation::displayProgressBar, NULL, 64 * 1024, prio - 1, -2, false); if (downloadFromRelease("https://github.com/" + repo, file, out, includePrereleases) != 0) { showProgressBar = false; @@ -186,7 +198,7 @@ Result ScriptUtils::downloadFile(const std::string &file, const std::string &out s32 prio = 0; svcGetThreadPriority(&prio, CUR_THREAD_HANDLE); - thread = threadCreate((ThreadFunc)displayProgressBar, NULL, 64 * 1024, prio - 1, -2, false); + thread = threadCreate((ThreadFunc)Animation::displayProgressBar, NULL, 64 * 1024, prio - 1, -2, false); if (downloadToFile(file, out) != 0) { showProgressBar = false; @@ -218,7 +230,7 @@ void ScriptUtils::installFile(const std::string &file, const bool &updatingSelf, s32 prio = 0; svcGetThreadPriority(&prio, CUR_THREAD_HANDLE); - thread = threadCreate((ThreadFunc)displayProgressBar, NULL, 64 * 1024, prio - 1, -2, false); + thread = threadCreate((ThreadFunc)Animation::displayProgressBar, NULL, 64 * 1024, prio - 1, -2, false); installCia(in.c_str(), updatingSelf); showProgressBar = false; @@ -245,7 +257,7 @@ void ScriptUtils::extractFile(const std::string &file, const std::string &input, s32 prio = 0; svcGetThreadPriority(&prio, CUR_THREAD_HANDLE); - thread = threadCreate((ThreadFunc)displayProgressBar, NULL, 64 * 1024, prio - 1, -2, false); + thread = threadCreate((ThreadFunc)Animation::displayProgressBar, NULL, 64 * 1024, prio - 1, -2, false); getExtractedSize(in, input); extractArchive(in, input, out);