From 220a21ccc1c9c866725b9b6b8dc12c5c253938e9 Mon Sep 17 00:00:00 2001 From: Ardis Lu Date: Thu, 26 Aug 2021 22:50:04 -0700 Subject: [PATCH] Add uploadToBackblaze functionality --- Code.gs | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 10 ++++++++- 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/Code.gs b/Code.gs index efc0c69..6316633 100644 --- a/Code.gs +++ b/Code.gs @@ -2,12 +2,15 @@ const UI = SpreadsheetApp.getUi(); const WORKBOOK = SpreadsheetApp.getActive(); const FILE_ID = PropertiesService.getScriptProperties().getProperty('FILE_ID'); +const BACKBLAZE_ID = PropertiesService.getScriptProperties().getProperty('BACKBLAZE_ID'); +const BACKBLAZE_KEY = PropertiesService.getScriptProperties().getProperty('BACKBLAZE_KEY'); function onOpen() { const ui = SpreadsheetApp.getUi(); ui.createMenu('SQLite') .addItem('Help', 'showHelp') .addItem('Generate SQLite database query', 'generateDatabaseQuery') + .addItem('Upload to Backblaze', 'uploadToBackblaze') .addToUi(); } @@ -105,3 +108,63 @@ function generateDatabaseQuery() { UI.alert('Success!', `Query generated! Download here: https://drive.google.com/u/0/uc?id=${FILE_ID}&export=download`, UI.ButtonSet.OK); } + +function uploadToBackblaze() { + // b2_authorize_account + const credentials = `Basic ${Utilities.base64Encode(`${BACKBLAZE_ID}:${BACKBLAZE_KEY}`)}`; + const authOptions = { + 'headers': { + 'Authorization': credentials + } + }; + const authResponse = UrlFetchApp.fetch('https://api.backblazeb2.com/b2api/v2/b2_authorize_account', authOptions); + const authJson = JSON.parse(authResponse.getContentText()); + const apiUrl = authJson['apiUrl']; // Must use this host for the next API call + let authToken = authJson['authorizationToken']; // This token can change after calling b2_get_upload_url + const bucketId = authJson['allowed']['bucketId']; + + // b2_get_upload_url + const getUploadUrlOptions = { + 'method': 'POST', + 'headers': { + 'Authorization': `${authToken}` + }, + 'payload': JSON.stringify({ + 'bucketId': `${bucketId}` + }) + }; + const getUploadUrlResponse = UrlFetchApp.fetch(`${apiUrl}/b2api/v2/b2_get_upload_url`, getUploadUrlOptions); + const getUploadUrlJson = JSON.parse(getUploadUrlResponse.getContentText()); + authToken = getUploadUrlJson['authorizationToken']; + const uploadUrl = getUploadUrlJson['uploadUrl']; + + // b2_upload_file + const file = DriveApp.getFileById(FILE_ID); + const fileName = file.getName(); + const mimeType = file.getMimeType(); + const contentLength = file.getSize(); + const data = file.getBlob(); + const digest = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_1, data.getBytes()); + let sha1 = ''; + for (let byte of digest) { + if (byte < 0) { + byte += 256; // Negative values are 8-bit overflows, need to add 256 + } + sha1 += byte.toString(16).padStart(2, '0'); + } + + const uploadOptions = { + 'method': 'POST', + 'headers': { + 'Authorization': authToken, + 'X-Bz-File-Name': fileName, + 'Content-Type': mimeType, + 'X-Bz-Content-Sha1': sha1 + }, + 'contentLength': contentLength, + 'payload': data + } + const uploadResponse = UrlFetchApp.fetch(`${uploadUrl}`, uploadOptions); + + UI.alert('Success!', `Google Drive file was successfully uploaded to Backblaze.`, UI.ButtonSet.OK); +} diff --git a/README.md b/README.md index 7a40cff..585cc7b 100644 --- a/README.md +++ b/README.md @@ -27,9 +27,17 @@ These steps only need to be completed once. 5. Copy `Code.gs` into the GAS project and save. If you copied the demo Google Sheet, this code should already be there. 6. **(IMPORTANT)** In `Code.gs`, there is a reference to a [Google Apps Script property](https://developers.google.com/apps-script/guides/properties) (environment variable) named `FILE_ID`. Use the GAS user interface to set `FILE_ID` to the file ID noted in Step 2. +## Setting up "Upload to Backblaze" + +If you use Backblaze as a storage provider, you can use the "Upload to Backblaze" button to upload the SQL query directly to Backblaze. + +7. In [Backblaze](https://backblaze.com), create a new application key with write access to the storage bucket where you want to upload the SQL query to. +8. Set the GAS properties `BACKBLAZE_ID` and `BACKBLAZE_KEY` to the ID and key, respectively. + # Usage 1. Refresh the Google Sheet to load the GAS code. 2. See the new custom menu button `SQLite`. Press `SQLite > Help` for end-user instructions. 3. Press `SQLite > Generate SQLite database query` to generate the database generation SQL query. -4. In your favorite SQLite client (example: [sqliteviz](https://lana-k.github.io/sqliteviz/#/workspace)), paste in the SQL query and run it. +4. (Optional) Press `SQLite > Upload to Backblaze` to upload the database generation SQL query to Backblaze. +5. In your favorite SQLite client (example: [sqliteviz](https://lana-k.github.io/sqliteviz/#/workspace)), paste in the SQL query and run it. -- 2.47.3