change default saving location in "make a copy" of a Google Doc - google-apps-script

Im sure you know the option, that, if you click on a link of a GOogle Doc, you can adjust the link with
/copy, and each time you open the document, you have the option to click on "Make a copy" and
a copy of the original file (Doc, sheet...) gets created and saved on "My drive" per default.
My question now is, can I somehow change this default path, where the files gets saved?
Like, can i say, save it per default in Google Drive folder xy, or can I even say, that
he shall ask in which of my Drive folder, the copy shall get saved?
Thanks for any hint

Try using makeCopy(name, destination).
makeCopy(name, destination)
Creates a copy of the file in the destination directory and names it with the name provided.
function myFunction() {
var files = DriveApp.getFilesByName('Sample Document');
while (files.hasNext()) {
var file = files.next();
var copyFolder = DriveApp.getFolderById('FOLDERID')
file.makeCopy('Sample Document Copy',copyFolder)
}
}
Note:
The folder must be selected using folderID not byName( based on experience and the tutorial example)
Valuable Sources:
Developer Guide
tutorial - How to use the makeCopy(name, destination) function (This is very useful!)
Hope it helps.

Related

Trying to copy files I do not own from a shared drive to personal drive

I am an educator and have content I created and co-created on a school google drive. I am leaving the school and trying to take a copy of the lessons I created and co-created. The school drive has files where I am the owner and not the owner in a main folder with subfolders. Our tech person said to try the code below, but I am getting an error and no further support from my school.
I have tried sharing files within the google drive application and then have gotten as far as trying to use the code below by inputting my folder names, but it give me an error on line 22 of the code. I don't know what to do other than open each individual file and manually save it. I only have access to the shared drive until July 26. PLEASE HELP!
function duplicate() {
var sourceFolder = "5-8 Shared Humanities";
var targetFolder = "Copy of humanities curriculum from FSMN";
var source = DriveApp.getFoldersByName(sourceFolder);
var target = DriveApp.createFolder(targetFolder);
if (source.hasNext()) {
copyFolder(source.next(), target);
}
}
function copyFolder(source, target) {
var folders = source.getFolders();
var files = source.getFiles();
while(files.hasNext()) {
var file = files.next();
file.makeCopy(file.getName(), target);
}
while(folders.hasNext()) {
var subFolder = folders.next();
var folderName = subFolder.getName();
var targetFolder = target.createFolder(folderName);
copyFolder(subFolder, targetFolder);
}
}
I expected the code to copy the file structure and all files from all owners from the shared drive to the new personal drive I created. It seems like I am still running into file permissions issues for files I do not own. I am getting the following error:
Access denied: DriveApp. (line 22, file "Code")
I tried your script on stuff that was shared with me, both with modification permission and just read-only, and it worked fine.
That error is usually about drive apps being disabled (which prevents scripts too). See link
But since, it works for the files you own, I'm guessing that those you don't are either in 'read-only' or 'comment' mode. As is it wouldn't prevent you from making a copy, but when sharing the owner can check a box to disable print, download and copy options for commenters and readers.
So I think your only solution is to ask the owner to uncheck that box :/
To copy the files into your personal storage than do the following:
Make a shortcut of the folder in your personal drive.
Create a new Google Colaboratory notebook.
Mount your drive using following code:
from google.colab import drive
drive.mount("/content/drive")
Next, Enter Command:
!cp -rp '/content/drive/JAVA_ANDROID/*' '/content/drive/My Drive'
Where,
JAVA_ANDROID is name of the shortcut of the folder, put the name of the folder you desire to copy and append /* to copy all files at that location.
Next is path of the folder where copied files are to be saved, which is /content/drive/My Drive in this case.
Edit: I have noticed that in some cases adding /* doesn't work. So if it doesn't work the above specified way. Just don't append * to the shortcut name and try. So in this case the above command would be:
!cp -rp '/content/drive/JAVA_ANDROID/' '/content/drive/My Drive'

Acquiring the Google Drive folder my google script is located

With the help of a nice article (https://www.labnol.org/internet/google-drive-tree/21198/), I just setup my first google script in Google Drive.
Quick Question:
How may I get a running script /myFolder1/music/myFirstScript.gs, to determine it's running in /myFolder1/music?
This didn't work. I got the Url but nothing in the log file showed the correct answer.
var files = DriveApp.searchFiles('title contains "GoogleTreeAgenda5"');
while (files.hasNext()) {
var file = files.next();
Logger.log(file.getName());
Logger.log(file.getUrl());
Logger.log(file.getDownloadUrl());
Logger.log(file.getDescription());
Logger.log(file.getOwner());
Logger.log(file.getParents());
Logger.log(file.getParents()[0].getName());
Logger.log("------------------------------");
}
Longer Behind The Scenes Reason:
The file will be modified a bit so that each month I will create a new tree structure off the root with agenda topics and the script will create an html file from the directory tree which is based on topic. Basically it will be an outline creator based on the current location of the script file. So Let's say this month it's in: /myFolder1/music (so in other words it's /myFolder1/music/myFirstScript.gs. The script needs to determine that folder is /myFolder1/music so that I can have it print the tree structure starting from the folder it's located in to an html file..
In the example application provided by the site I noted above, there are 2 options to print the tree from the google script:
1) Tree starting from the root folder
var parentFolder = DriveApp.getRootFolder();
2) Starting from a particular folder (but I can't figure out and will need "Folder_Name" to be determined dynamically from the location where the .gs file is located)
var parent = DriveApp.getFoldersByName("FOLDER_NAME").next();
I've used getScriptId() this will:
Gets the script project's unique id.
This id is also the unique id in the Google Drive. Then from there, create a recurring getParents() until you reach the root folder.
Here is the complete code:
function myFunction() {
var scriptID = ScriptApp.getScriptId();
// Logger.log(scriptID)
// Log the name of every parent folder
var driveFile = DriveApp.getFileById(scriptID);
var parentFolder = driveFile.getParents();
while (parentFolder.hasNext()) {
var folder = parentFolder.next();
Logger.log(folder.getName());
}
}
NOTE:
There is no real or concrete path since a file can have multiple parents. It is also stated here in this related SO post.
Hope this helps.

Spreadsheet creation - Permissions, file location and remove file

I have an Adwords script that creates a new spreadsheet by using the command below:
var ssNew = SpreadsheetApp.create("Name document");
Is it possible to create this file in a specific folder of my Google Drive?
If so; the file will have the default access (view, edit, comment) permissions as the folder has, right?
If not; is it possible to give the created file a permission as in "Everyone in [company] can edit this file"?
Furthermore, is it possible to set some sort of expiration date for the file?
I'm planning on running the script daily and old files will no longer be relevant.
I can build some sort of check to find the old file, delete it and then run the script again, but if there is some sort of expiration function that would save me quite some code.
Thanks!
It is apparently not possible to create Spreadsheets within folders.
You'll have to use something like this:
function createNewSpreadsheetinFolder(){
var ssNew = SpreadsheetApp.create("Name document");
var targetFolder = DriveApp.getFolderById("0B1TY_1aqz3fpWktMa25LbVkzQTQ");
var ssnewFile = DriveApp.getFileById(ssNew.getId());
var ssFinal = ssnewFile.makeCopy("Name document", targetFolder);
ssnewFile.setTrashed(true);
try {ssFinal.addViewers(targetFolder.getViewers())} catch(e){};
try {ssFinal.addEditors(targetFolder.getEditors())} catch(e){};
}

How do I copy & move a file to a folder in Google Apps Script?

Is there a way to copy and rename a file and move that copy to a particular folder without having a second copy in the root folder? I have used combinations of copy, rename, move in different order, but each time, I still end up with a copy of the renamed file the root drive. Is this by default? It is annoying to say the least.
In the new version of google apps script all you need to acheive your task is the following:
file.makeCopy("new name", folder);
EDIT : I had a look at your original question (before edit) and from there I understood the confusion you made about how files and folders work in Google Drive.
When you make a copy of a file you get a new file in the root folder, when you add this new file to another folder you have to consider that as sticking a label on this file without creating any new copy of it.
You can actually see the file in both the root and the other folder but it is the very same file with 2 different labels! (and you did notice that since you tried to delete it and saw it was deleted in both places)
The only thing you have to do to get the new file in its folder and not shown in the root it to remove the "root label".
That's how Google drive works. And when you think about it and compare to a local hard disk storage it gets logical : when you move a file from one folder to another on the same logical drive you don't move data (ie the bytes on the disk) but simply tell the disk operating system that this file is somewhere else on the map.
So consider Google Drive as a (very) large disk unit with billions on files that you can't move but on which you can stick as many labels as you want ;-) (the most important label being your Google account ID !)
And to play with these labels in the case you describe just try this simple function :
function copyAndMove(file,folder){
var newfile=file.makeCopy('copy of '+file.getName());// here you can define the copy name the way you want...
newfile.addToFolder(folder);// add the copy to the folder
newfile.removeFromFolder(DocsList.getRootFolder());// and remove it from your root folder
}
to test it just use the 2 required parameters : the file object anf the folder object that you can get from many different methods, see the DocsList documentation for details on how to get it if you need to but I guess you already know that ;-)
Yeah, it is a bit odd that Google does not provide a move method. But, considering how drive works and that a file can belong to multiple folders, it makes some sense that you have write your own moves. Here is a simple move function I wrote:
// Moves a file to a new folder by removing all current
// parent folders and then adding the new one.
function moveFileTo(fileObj, folderObj) {
// Attempt the move only if folderObj has a value.
// Otherwise, the file will be left without a folder.
// (Lost files can be found in the "All items" area.)
if (folderObj) {
var folders = fileObj.getParents();
for (var i = 0; i < folders.length; i++) {
fileObj.removeFromFolder(folders[i]);
}
fileObj.addToFolder(folderObj);
return true;
}
return false;
}
Basically, use it like this:
var file = DocsList.getFileById(fileID);
var folder = DocsList.getFolder('Some folder name');
// Make a backup copy.
var file2 = file.makeCopy('BACKUP ' + Utilities.formatDate(new Date(), Session.getTimeZone(), 'yyyy-MM-dd') + '.' + file.getName());
// Move the backup file.
if (moveFileTo(file2, folder)) {
...
I should note that this simple function is exactly that... simple. It assumes you are okay with whacking all parent folders -- owned or shared. This can have unexpected consequences with shared files in various shared folders of various users if you are not careful. It does not appear, however, to remove parent folders that are not shared with the user of this script -- which is good. Anyhow, one obvious alternative to control things better would be to specify the "from" folder as well as the "to" folder.

How do I set the sharing options for files in Google Drive

I want to change the sharing 'visibility' of currently stored documents from 'anyone with the link may view' to 'private'. This is distinct from removing named viewers and editors.
Unfortunately, the GAS has a very limited support of the documents visibibility. There is no functionality to change this option for the DocsList.File and DocumentApp.Document classes. The Spreadsheet class has the setAnonymousAccess method using which is possible to set if a spreadsheet is public.
Please open a new feature request on the issue tracker if this feature is important for you.
There is an easy way to get what you want using a method that has already been mentioned in this post
You can set the sharing / visibility parameters of any document by moving it to a shared folder. If you remove it from the shared folder then it is no long shared and that is what you wanted to do didn't you ?
So all you need to do is not to use individual sharing parameters on files but rather use the folder structure to share your files.
As a reminder, the code could be something like this to add to the folder :
function sharebyFolder(){
var file = DocsList.getFileById('docId');
var folder = DocsList.getFolderById('shared folder Id');
file.addToFolder(folder)
}
and to remove it :
function UnsharebyFolder(){
var file = DocsList.getFileById('docId');
var folder = DocsList.getFolderById('shared folder Id');
file.removeFromFolder(folder)
}
The old docs API offers a good solution:
https://developers.google.com/google-apps/documents-list/#removing_sharing_permissions