I installed Vidar’s script and works very well for files, but wouldn't reset permissions on folders. So, I changed a little bit the code to make the folders also inherite the permissions from their upper folder.
Two important disclaimers:
- I don't know if the original intention was to leave folders unchanged. Or even if it worked well for everybody but me, and this solutions was unnecesary. It worked for me.
- This is the first script I do, so it is very likely that it is not very efficient and may content some errors. Please feel free to correct it and improve it.
I only changed the doResetPermissions
function, but I paste all the code for simplicity reasons.
var selectedFolder;
var dialog;
function doGet() {
var app = UiApp.createApplication();
var heading = app.createHTML("<h1>Folders for</h1>");
app.add(heading);
var allFoldersIterator = DriveApp.getFolders();
var text = app.createTextArea().setName("text").setId("output");
app.add(text);
var tree = app.createTree();
var rootFolder = DriveApp.getRootFolder();
var treeRoot = app.createTreeItem(rootFolder.getName()).setId(rootFolder.getId());
var handler = app.createServerHandler("folderSelected");
tree.addItem(treeRoot);
tree.addSelectionHandler(handler);
treeRoot.setState(true);
createBranch(rootFolder, treeRoot, app);
app.add(tree);
var selectedFolderIdBox = app.createTextBox().setName("selectedFolderIdBox").setId("selectedFolderIdBox");
app.add(selectedFolderIdBox);
return app;
}
function createBranch(folder, branch, app) {
var children = folder.getFolders();
while (children.hasNext()) {
child = children.next();
Logger.log("Folder id: " + child.getId());
var subBranch = app.createTreeItem(child.getName()).setId(child.getId());
branch.addItem(subBranch);
createBranch(child, subBranch, app);
}
}
function folderSelected(eventInfo) {
var app = UiApp.getActiveApplication();
var parameter = eventInfo.parameter;
Logger.log("Selected " + eventInfo.parameter.selected);
selectedFolder = DriveApp.getFolderById(eventInfo.parameter.selected);
var selectedFolderIdBox = app.getElementById("selectedFolderIdBox");
selectedFolderIdBox.setValue(eventInfo.parameter.selected);
var okHandler = app.createServerHandler("okResetPermissions");
okHandler.addCallbackElement(selectedFolderIdBox);
dialog = app.createDialogBox(true, true);
var panel = app.createFlowPanel();
dialog.add(panel);
dialog.setId("confirmationDialog");
dialog.setPopupPosition(100, 100).setSize(500, 500);
panel.add(app.createLabel("Do you want to reset permissions for all files found in folder " + selectedFolder.getName() + " and its subfolders?\n (Click outside of the dialog box to cancel)"));
panel.add(app.createButton("Do it!", okHandler));
dialog.show();
return app;
}
function okResetPermissions(eventInfo) {
var selectedFolderId = eventInfo.parameter.selectedFolderIdBox;
var selectedFolder = DriveApp.getFolderById(selectedFolderId);
Logger.log("Resetting permissions on " + selectedFolder.getName());
var app = UiApp.getActiveApplication();
app.getElementById("confirmationDialog").hide();
Logger.log("Confirmation dialog hidden");
var progressIndicator = app.createDialogBox(false, true);
progressIndicator.setId("progressIndicator");
progressIndicator.setPopupPosition(100, 100).setSize(500, 500);
var label = app.createLabel("Working ...");
progressIndicator.add(label);
progressIndicator.show();
doResetPermissions(selectedFolder, function() {
var app = UiApp.getActiveApplication();
var progressIndicator = app.getElementById("progressIndicator");
progressIndicator.hide();
return app;
});
return app;
}
function doResetPermissions(selectedFolder, callback) {
Logger.log("Resetting permissions on folder " + selectedFolder.getName());
var sharingAccess = selectedFolder.getSharingAccess();
var sharingPermission = selectedFolder.getSharingPermission();
var viewersfolder = selectedFolder.getViewers();
Logger.log("Number of Viewers in folder: " + selectedFolder.getName() + " = " + viewersfolder.length);
for (var i = 0; i < viewersfolder.length; i++) {
Logger.log(" Removing viewer " + viewersfolder[i].getEmail());
selectedFolder.removeViewer(viewersfolder[i]);
}
var editorsfolder = selectedFolder.getEditors();
Logger.log("Number of Editors in folder: " + selectedFolder.getName() + " = " + editorsfolder.length);
for (var i = 0; i < editorsfolder.length; i++) {
Logger.log(" Removing editor " + editorsfolder[i].getEmail());
selectedFolder.removeEditor(editorsfolder[i]);
}
var files = selectedFolder.getFiles();
while (files.hasNext()) {
var file = files.next();
Logger.log(" Resetting permissions on file " + file.getName());
file.setSharing(sharingAccess, sharingPermission);
var viewers = file.getViewers();
Logger.log("Number of Viewers in file: " + file.getName() + " = " + viewers.length);
for (var i = 0; i < viewers.length; i++) {
Logger.log(" Removing viewer " + viewers[i].getEmail());
file.removeViewer(viewers[i]);
}
var editors = file.getEditors();
Logger.log("Number of editors in file: " + file.getName() + " = " + editors.length);
for (var i = 0; i < editors.length; i++) {
Logger.log(" Removing editor " + editors[i].getEmail());
file.removeEditor(editors[i]);
}
}
var children = selectedFolder.getFolders();
while (children.hasNext()) {
var child = children.next();
doResetPermissions(child);
}
if (callback) {
callback();
}
}
The following is a recipe for a comparison based on filenames alone, not based on file modification times or even content checksums. But it's a start :) Also, the below is to compare two directories that are both on Google Drive, but you can easily adapt it by generating a list of your local files instead with some call to ls
. (So obviously, the below is a recipe for Linux.)
1. Install and configure drive
drive
is a Linux command line client for Google Drive. The easiest is to install it from a package.
After that:
Change into the directory on your computer that includes your whole files synced from Google Drive:
cd /home/user/example-dir/
Initialize drive
with access to your Google Drive. This will ask you to visit a URL and paste the auth code you get there, and save this in a config file in the current directory.
drive init
2. Comparing directories
I found that for large Google Drive folders (36 GiB of small files in my case), starting by comparing directories and fixing cases of missing directories was a good first step. (Also because drive
has no option to copy directories without the files inside between two Google Drive folders. Not a problem if you compare between local and remote files only.)
drive list -directories -recursive -no-prompt -sort name "source dir" > DirDiff.1-source.txt
drive list -directories -recursive -no-prompt -
sort name "dest dir" > DirDiff.2-dest.txt
vim -es +"%s/^\/source dir\///g" +"wq" DirDiff.1-source.txt
vim -es +"%s/^\/dest dir\///g" +"wq" DirDiff.2-dest.txt
The drive
command obtain lists of directories from Google Drive, and the vim
commands remove the differing base directories from each path so that comparison will work properly.
Now to list the directories that are only in the source tree:
comm -23 <(sort < DirDiff.1-source.txt) <(sort < DirDiff.2-dest.txt) > DirDiff.3-missing.txt
And to show the directories that are only in the destination tree:
comm -13 <(sort < DirDiff.1-source.txt) <(sort < DirDiff.2-dest.txt) > DirDiff.4-added.txt
About using comm
like this, see here.
3. Comparing files
This works very similar to comparing directory trees:
drive list -recursive -no-prompt -sort name "source dir" > 1-source-files.txt
drive list -recursive -no-prompt -sort name "dest dir" > 2-dest-files.txt
vim -es +"%s/^\/source dir\///g" +"wq" DirDiff.1-source.txt
vim -es +"%s/^\/dest dir\///g" +"wq" DirDiff.2-dest.txt
To show the files only in the source tree:
comm -23 <(sort < FileDiff.1-source.txt) <(sort < FileDiff.2-dest.txt) > FileDiff.3-missing.txt
To show the files only in the destination tree:
comm -13 <(sort < FileDiff.1-source.txt) <(sort < FileDiff.2-dest.txt) > FileDiff.4-added.txt
Best Answer
At this time it's not possible to use Google Drive as file hosting that maintains a folder structure.
This was a supported feature but it was retired few years ago.
Related