Sync AI2 Folder to Google Drive Folder
INTRO
Had this one on my long list for a while....
In simple terms, I have a folder on my device, in the application specific directory (ASD), and a folder on my Google Drive (it can be public or private). Whatever files are in either of these folders can be synchronised with the other, and I can add or delete files in the device folder, and this will also be synchronised.
This is an ideal example of making use of my GD Connector (MIT Forum Topic), which would allow any user to sync with a folder on their OWN google drive. All the functions required for this are there, just would need coding with blocks. To keep things simple, the demonstration here uses the developer's google drive, which in itself could be useful for multiple users as a shared file repository.
Files can be added or removed from either folder "outside" of the app, if this is done, then I can synchronise the folders to restore the balance. I have used two way synchronisation, which means that both folders will be equivalent once synchronised. Other methods could be adopted.
You will see that for each routine involving the web component I use a variable "control" to tell the Web1.GotText what to do. For downloading files from google drive, the file is converted to base64 in the webapp, so that it can be downloaded as text. This alows me to use only one web component, and also allows for the google drive folder to remain private.
Requirements:
Google account
Google Apps Script Web App (standalone)
Extensions: (credits to all extension creators listed below)
FileTools and Filey by vknow360 (for file listings and base64 encode/decode)
TableView by Ken (you could use listviews)
SETUP
In Google Drive, create your folder and get its ID. Set this ID as a variable in AI2
The folder can be private (accessible only by you) or public (anyone with the link can view)
Create a standalone Google Apps Script project:
Put in the script code below, replacing the <FOLDER ID HERE> with the ID of your folder
Publish as a web app, run by your account, accessible to anyone, even anonymous
Get the /exec url for the script, and set this as a variable in AI2
(Remember, any changes to the script will require you to publish a new version!!)
Create the basic UI in the AI2 app:
5 buttons in a horizontal arrangement for Lists, Sync, Add, Delete, and Clear
A vertical scrolling arrangement to hold the two table views
Two listviews for adding and deleting selections
A label for information/feedback
A web component
A notifier
SCRIPT
function doGet(e) {
//return list of filenames and ids
if ( e.parameter.func == "list" ) {
return listFiles();
//trash file in folder
} else if (e.parameter.func == "del") {
DriveApp.getFileById(e.parameter.fileID).setTrashed(true);
return listFiles();
// download file from google drive sync folder
} else if ( e.parameter.func = "dn" ) {
var imgID = e.parameter.imgID;
var bytes = DriveApp.getFileById(imgID).getBlob().getBytes();
return ContentService.createTextOutput(Utilities.base64Encode(bytes));
}
}
function doPost(e) {
// upload file to google drive sync folder
if ( e.parameter.func = "up" ) {
var data = Utilities.base64Decode(e.parameters.data);
var blob = Utilities.newBlob(data, e.parameters.mimetype, e.parameters.filename);
var fileID = DriveApp.getFolderById('<FOLDER ID HERE>').createFile(blob).getId();
return listFiles();
}
}
function listFiles() {
var folderID = "<FOLDER ID HERE>";
var folder = DriveApp.getFolderById(folderID);
var files = folder.getFiles();
var myList = [];
while(files.hasNext()) {
var file = files.next();
myList.push( file.getName() + "," + file.getId() );
}
return ContentService.createTextOutput(JSON.stringify(myList)).setMimeType(ContentService.MimeType.JSON);
}
WORKFLOW
There are just over 600 blocks in this demonstration, I will attempt to show the most useful routines as I explain the workflow. Full view of all blocks is available below, along with the aia project.
The apps starts off by creating/setting the ASD and the sync folder to be used within it:
Having done this the lists for what files are in the respective sync folders are fetched. Then there is a lot of procedural jiggery pokery to extract and sort the file names, then convert from lists to csv tables, in order to display the outputs in adjacent tableviews - it would have been easier to use listviews but I wanted to "push" Tableview to see what it could do, and it didn't let me down! I end up with a sorted list of files for each folder in a table view, and then these are checked for any files that need to be synchronised. A message is displayed.
As you can see the folders here are synchronised :) If they weren't, then the next step would be to press the "Sync" button. This would set off the routine to check each of the folder lists against each other, resulting in a list created for each side of the files it needed. Then the upload and download routines would be run, using the fileByFile approach, followed by a final check that all was well and that the folders were back in sync. Please look in the BLOCKS under SYNC and SYNC2 for how this is done.
If I want to add a file, by pressing on the Add button, I get presented with a listview of folders on the device from root (/storage/emulated/0). I can then traverse the directory structure from here until I find the file I need. Once selected, the file is added to the device folder, the folders are then synchronised (the file is uploaded to google drive) See the BLOCKS under ADD.
In the images below I have added Afghanistan.png
If I want to remove a file, then I press the "Del" button, and I am offered a listview of the device's sync folder. On selecting a file, it is removed from the device's sync folder and from the google drive folder. See the BLOCKS under REMOVE.
In the images below I have removed Cayman Islands.png
When viewing the device and google drive lists, I can click on any item, and the respective file paths / IDs will be returned for that file. If it does not exist in one of the folders, the message will tell you. This can be useful for longer lists, and for quick refrence or use of the info.
In the blocks below I have removed Armenia.png from Google Drive.
BLOCKS
VIDEO
Well, that just about wraps this one up, I hope it helps you to see how to synchronise a device folder with a google drive folder, and the work required to setup a useable UI in the app to handle things.