Google Drive support by file ID

This commit is contained in:
Huntereb 2019-11-13 20:01:35 -05:00
parent cb09f65295
commit 962124facf
10 changed files with 129 additions and 47 deletions

View file

@ -21,6 +21,6 @@ SOFTWARE.
*/
namespace netInstStuff {
void installNspLan(std::vector<std::string> ourUrlList, int ourStorage);
void installNspLan(std::vector<std::string> ourUrlList, int ourStorage, std::vector<std::string> urlListAltNames);
std::vector<std::string> OnSelected();
}

View file

@ -15,6 +15,7 @@ namespace inst::ui {
private:
static std::vector<std::string> ourUrls;
static std::vector<std::string> selectedUrls;
static std::vector<std::string> alternativeNames;
TextBlock::Ref butText;
Rectangle::Ref topRect;
Rectangle::Ref infoRect;

View file

@ -3,6 +3,7 @@
namespace inst::config {
extern const std::string appDir;
extern const std::string configPath;
extern const std::string gAuthKey;
extern std::string sigPatchesUrl;
extern bool ignoreReqVers;
extern bool deletePrompt;

View file

@ -2,4 +2,5 @@
namespace inst::curl {
bool downloadFile(const std::string ourUrl, const char *pagefilename);
std::string downloadToBuffer (const std::string ourUrl);
}

View file

@ -12,4 +12,6 @@ namespace inst::util {
std::string formatUrlString(std::string ourString);
std::string shortenString(std::string ourString, int ourLength, bool isFile);
std::string readTextFromFile(std::string ourFile);
std::string softwareKeyboard(std::string guideText, std::string initialText, int LenMax);
std::string getDriveFileName(std::string fileId);
}

View file

@ -112,7 +112,7 @@ namespace netInstStuff{
curl_global_cleanup();
}
void installNspLan(std::vector<std::string> ourUrlList, int ourStorage)
void installNspLan(std::vector<std::string> ourUrlList, int ourStorage, std::vector<std::string> urlListAltNames)
{
inst::util::initInstallServices();
if (appletGetAppletType() == AppletType_Application || appletGetAppletType() == AppletType_SystemApplication) appletBeginBlockingHomeButton(0);
@ -123,9 +123,20 @@ namespace netInstStuff{
if (ourStorage) m_destStorageId = FsStorageId_NandUser;
unsigned int urlItr;
std::vector<std::string> urlNames;
if (urlListAltNames.size() > 0) {
for (long unsigned int i = 0; i < urlListAltNames.size(); i++) {
urlNames.push_back(inst::util::shortenString(urlListAltNames[i], 42, true));
}
} else {
for (long unsigned int i = 0; i < ourUrlList.size(); i++) {
urlNames.push_back(inst::util::shortenString(inst::util::formatUrlString(ourUrlList[i]), 42, true));
}
}
try {
for (urlItr = 0; urlItr < ourUrlList.size(); urlItr++) {
inst::ui::setTopInstInfoText("Installing " + inst::util::shortenString(inst::util::formatUrlString(ourUrlList[urlItr]), 42, true));
inst::ui::setTopInstInfoText("Installing " + urlNames[urlItr]);
tin::install::nsp::HTTPNSP httpNSP(ourUrlList[urlItr]);
@ -143,9 +154,9 @@ namespace netInstStuff{
printf("Failed to install");
printf("%s", e.what());
fprintf(stdout, "%s", e.what());
inst::ui::setInstInfoText("Failed to install " + inst::util::shortenString(inst::util::formatUrlString(ourUrlList[urlItr]), 42, true));
inst::ui::setInstInfoText("Failed to install " + urlNames[urlItr]);
inst::ui::setInstBarPerc(0);
inst::ui::mainApp->CreateShowDialog("Failed to install " + inst::util::shortenString(inst::util::formatUrlString(ourUrlList[urlItr]), 42, true) + "!", "Partially installed contents can be removed from the System Settings applet.\n\n" + (std::string)e.what(), {"OK"}, true);
inst::ui::mainApp->CreateShowDialog("Failed to install " + urlNames[urlItr] + "!", "Partially installed contents can be removed from the System Settings applet.\n\n" + (std::string)e.what(), {"OK"}, true);
nspInstalled = false;
}
@ -158,7 +169,7 @@ namespace netInstStuff{
inst::ui::setInstInfoText("Install complete");
inst::ui::setInstBarPerc(100);
if (ourUrlList.size() > 1) inst::ui::mainApp->CreateShowDialog(std::to_string(ourUrlList.size()) + " files installed successfully!", nspInstStuff::finishedMessage(), {"OK"}, true);
else inst::ui::mainApp->CreateShowDialog(inst::util::shortenString(inst::util::formatUrlString(ourUrlList[0]), 42, true) + " installed!", nspInstStuff::finishedMessage(), {"OK"}, true);
else inst::ui::mainApp->CreateShowDialog(urlNames[0] + " installed!", nspInstStuff::finishedMessage(), {"OK"}, true);
}
printf("Done");

View file

@ -4,6 +4,8 @@
#include "ui/mainPage.hpp"
#include "ui/netInstPage.hpp"
#include "util/util.hpp"
#include "util/config.hpp"
#include "util/curl.hpp"
#include "netInstall.hpp"
#define COLOR(hex) pu::ui::Color::FromHex(hex)
@ -13,6 +15,7 @@ namespace inst::ui {
std::vector<std::string> netInstPage::ourUrls;
std::vector<std::string> netInstPage::selectedUrls;
std::vector<std::string> netInstPage::alternativeNames;
netInstPage::netInstPage() : Layout::Layout() {
this->SetBackgroundColor(COLOR("#670000FF"));
@ -39,6 +42,7 @@ namespace inst::ui {
void netInstPage::drawMenuItems(bool clearItems) {
if (clearItems) netInstPage::selectedUrls = {};
if (clearItems) netInstPage::alternativeNames = {};
this->menu->ClearItems();
for (auto& url: netInstPage::ourUrls) {
pu::String itm = inst::util::shortenString(inst::util::formatUrlString(url), 56, true);
@ -65,7 +69,7 @@ namespace inst::ui {
void netInstPage::startNetwork() {
this->pageInfoText->SetText("");
this->butText->SetText("\ue0e3 Install From URL \ue0e2 Help \ue0e1 Cancel ");
this->butText->SetText("\ue0e3 Install Over Internet \ue0e2 Help \ue0e1 Cancel ");
this->menu->SetVisible(false);
this->menu->ClearItems();
mainApp->LoadLayout(mainApp->netinstPage);
@ -74,30 +78,34 @@ namespace inst::ui {
mainApp->LoadLayout(mainApp->mainPage);
return;
} else if (netInstPage::ourUrls[0] == "supplyUrl") {
Result rc=0;
SwkbdConfig kbd;
char tmpoutstr[128] = {0};
rc = swkbdCreate(&kbd, 0);
if (R_SUCCEEDED(rc)) {
swkbdConfigMakePresetDefault(&kbd);
swkbdConfigSetGuideText(&kbd, "Enter the Internet address of a NSP file");
swkbdConfigSetInitialText(&kbd, "https://");
rc = swkbdShow(&kbd, tmpoutstr, sizeof(tmpoutstr));
swkbdClose(&kbd);
if (R_SUCCEEDED(rc) && tmpoutstr[0] != 0) {
if (inst::util::formatUrlString(tmpoutstr) == "" || tmpoutstr == (char *)"https://" || tmpoutstr == (char *)"http://") {
mainApp->CreateShowDialog("The URL specified is invalid!", "", {"OK"}, false);
netInstPage::startNetwork();
std::string keyboardResult;
switch (mainApp->CreateShowDialog("Where do you want to install from?", "Press B to cancel", {"URL", "Google Drive"}, false)) {
case 0:
keyboardResult = inst::util::softwareKeyboard("Enter the Internet address of a file", "https://", 500);
if (keyboardResult.size() > 0) {
if (inst::util::formatUrlString(keyboardResult) == "" || keyboardResult == "https://" || keyboardResult == "http://") {
mainApp->CreateShowDialog("The URL specified is invalid!", "", {"OK"}, false);
break;
}
netInstPage::selectedUrls = {keyboardResult};
netInstPage::startInstall(true);
return;
}
netInstPage::selectedUrls = {tmpoutstr};
netInstPage::startInstall(true);
return;
} else {
netInstPage::startNetwork();
return;
}
break;
case 1:
keyboardResult = inst::util::softwareKeyboard("Enter the file ID of a public Google Drive file", "", 50);
if (keyboardResult.size() > 0) {
std::string fileName = inst::util::getDriveFileName(keyboardResult);
if (fileName.size() > 0) netInstPage::alternativeNames = {fileName};
else netInstPage::alternativeNames = {"Google Drive File"};
netInstPage::selectedUrls = {"https://www.googleapis.com/drive/v3/files/" + keyboardResult + "?key=" + inst::config::gAuthKey + "&alt=media"};
netInstPage::startInstall(true);
return;
}
break;
}
netInstPage::startNetwork();
return;
} else {
this->pageInfoText->SetText("Select NSP files to install from the server, then press the Plus button!");
this->butText->SetText("\ue0e0 Select NSP \ue0e3 Select All \ue0ef Install NSP(s) \ue0e1 Cancel ");
@ -110,14 +118,17 @@ namespace inst::ui {
void netInstPage::startInstall(bool urlMode) {
int dialogResult = -1;
if (netInstPage::selectedUrls.size() == 1) {
dialogResult = mainApp->CreateShowDialog("Where should " + inst::util::shortenString(inst::util::formatUrlString(netInstPage::selectedUrls[0]), 32, true) + " be installed to?", "Press B to cancel", {"SD Card", "Internal Storage"}, false);
std::string ourUrlString;
if (netInstPage::alternativeNames.size() > 0) ourUrlString = inst::util::shortenString(netInstPage::alternativeNames[0], 32, true);
else ourUrlString = inst::util::shortenString(inst::util::formatUrlString(netInstPage::selectedUrls[0]), 32, true);
dialogResult = mainApp->CreateShowDialog("Where should " + ourUrlString + " be installed to?", "Press B to cancel", {"SD Card", "Internal Storage"}, false);
} else dialogResult = mainApp->CreateShowDialog("Where should the selected " + std::to_string(netInstPage::selectedUrls.size()) + " files be installed to?", "Press B to cancel", {"SD Card", "Internal Storage"}, false);
if (dialogResult == -1 && !urlMode) return;
else if (dialogResult == -1 && urlMode) {
netInstPage::startNetwork();
return;
}
netInstStuff::installNspLan(netInstPage::selectedUrls, dialogResult);
netInstStuff::installNspLan(netInstPage::selectedUrls, dialogResult, netInstPage::alternativeNames);
return;
}

View file

@ -6,6 +6,7 @@
namespace inst::config {
const std::string appDir = "sdmc:/switch/Awoo-Installer";
const std::string configPath = appDir + "/config.ini";
const std::string gAuthKey = {0x41,0x49,0x7a,0x61,0x53,0x79,0x42,0x4d,0x71,0x76,0x34,0x64,0x58,0x6e,0x54,0x4a,0x4f,0x47,0x51,0x74,0x5a,0x5a,0x53,0x33,0x43,0x42,0x6a,0x76,0x66,0x37,0x34,0x38,0x51,0x76,0x78,0x53,0x7a,0x46,0x30};
std::string sigPatchesUrl = "https://github.com/Huntereb/Awoo-Installer/releases/download/SignaturePatches/patches.zip";
bool ignoreReqVers = true;
bool deletePrompt = true;

View file

@ -1,12 +1,22 @@
#include "util/curl.hpp"
#include "util/config.hpp"
#include <curl/curl.h>
#include <string>
#include <sstream>
#include <iostream>
static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream) {
static size_t writeDataFile(void *ptr, size_t size, size_t nmemb, void *stream) {
size_t written = fwrite(ptr, size, nmemb, (FILE *)stream);
return written;
}
size_t writeDataBuffer(char *ptr, size_t size, size_t nmemb, void *userdata) {
std::ostringstream *stream = (std::ostringstream*)userdata;
size_t count = size * nmemb;
stream->write(ptr, count);
return count;
}
namespace inst::curl {
bool downloadFile (const std::string ourUrl, const char *pagefilename) {
CURL *curl_handle;
@ -14,38 +24,23 @@ namespace inst::curl {
FILE *pagefile;
curl_global_init(CURL_GLOBAL_ALL);
/* init the curl session */
curl_handle = curl_easy_init();
/* set URL to get here */
curl_easy_setopt(curl_handle, CURLOPT_URL, ourUrl.c_str());
/* Misc variables */
curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 0L);
curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT_MS, 1000L);
curl_easy_setopt(curl_handle, CURLOPT_CONNECTTIMEOUT_MS, 1000L);
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, writeDataFile);
/* send all data to this function */
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);
/* open the file */
pagefile = fopen(pagefilename, "wb");
/* write the page body to this file handle */
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, pagefile);
/* get it! */
result = curl_easy_perform(curl_handle);
/* cleanup curl stuff */
curl_easy_cleanup(curl_handle);
curl_global_cleanup();
/* close the header file */
fclose(pagefile);
if (result == CURLE_OK) return true;
@ -54,4 +49,34 @@ namespace inst::curl {
return false;
}
}
std::string downloadToBuffer (const std::string ourUrl) {
CURL *curl_handle;
CURLcode result;
std::ostringstream stream;
curl_global_init(CURL_GLOBAL_ALL);
curl_handle = curl_easy_init();
curl_easy_setopt(curl_handle, CURLOPT_URL, ourUrl.c_str());
curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 0L);
curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT_MS, 1000L);
curl_easy_setopt(curl_handle, CURLOPT_CONNECTTIMEOUT_MS, 1000L);
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, writeDataBuffer);
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &stream);
result = curl_easy_perform(curl_handle);
curl_easy_cleanup(curl_handle);
curl_global_cleanup();
if (result == CURLE_OK) return stream.str();
else {
printf(curl_easy_strerror(result));
return "";
}
}
}

View file

@ -4,11 +4,13 @@
#include <fstream>
#include <unistd.h>
#include <curl/curl.h>
#include <json-c/json.h>
#include "switch.h"
#include "util/util.hpp"
#include "nx/ipc/tin_ipc.h"
#include "util/INIReader.h"
#include "util/config.hpp"
#include "util/curl.hpp"
namespace inst::util {
void initApp () {
@ -132,4 +134,31 @@ namespace inst::util {
}
return "";
}
std::string softwareKeyboard(std::string guideText, std::string initialText, int LenMax) {
Result rc=0;
SwkbdConfig kbd;
char tmpoutstr[LenMax + 1] = {0};
rc = swkbdCreate(&kbd, 0);
if (R_SUCCEEDED(rc)) {
swkbdConfigMakePresetDefault(&kbd);
swkbdConfigSetGuideText(&kbd, guideText.c_str());
swkbdConfigSetInitialText(&kbd, initialText.c_str());
swkbdConfigSetStringLenMax(&kbd, LenMax);
rc = swkbdShow(&kbd, tmpoutstr, sizeof(tmpoutstr));
swkbdClose(&kbd);
if (R_SUCCEEDED(rc) && tmpoutstr[0] != 0) return(((std::string)(tmpoutstr)));
}
return "";
}
std::string getDriveFileName(std::string fileId) {
std::string jsonData = inst::curl::downloadToBuffer("https://www.googleapis.com/drive/v3/files/" + fileId + "?key=" + inst::config::gAuthKey + "&fields=name");
if (jsonData.size() > 0) {
struct json_object *parsed_json = json_tokener_parse(jsonData.c_str());
struct json_object *name;
if (json_object_object_get_ex(parsed_json, "name", &name)) return json_object_get_string(name);
}
return "";
}
}