When adding a file to a folder, how to make it not default save in Google Drive? - google-apps-script

In my script I have template docs in the main drive, but when the copy is created and populated with my excel data, I want it to be saved in a folder in drive. I have the script do that, but it has one copy of the file in the Main Google Drive, and the other in the folder I want it in. If I delete one of the copies, it deletes both.
Is there any way I can have it save automatically in the specified folder without also being in the main drive folder?

Folders in Google drive are not exactly like forders in a computer : having the file in your 'root' folder and in another folder doesn't mean there are 2 files, but rather 1 and only file with 2 labels... that's why you can't delete one without deleting the other !
The solution is simply to play with these labels in the script, here is how it works : (I commented each step to make it clear.)
function othertest(){
folder=DocsList.createFolder("MyFolder"); // or getFolderById or whatever other way to get your target folder
var file=DocsList.createFile('File2', 'Empty');// just an empty file for test but this would be your file copy that you want to "move"
file.addToFolder(folder);// put it in the folder
file.removeFromFolder(DocsList.getRootFolder());// and remove from the root
}
The other possible solution is to create the file directly in the target folder since the folder object supports the createFile method. (Not sure though that you can do it in your specific use case)
here is an example, you can see that the file is not in the root folder.
function createFileinFoldertest() {
var folder = DocsList.getFolder('test')
folder.createFile('Empty test fileName','nothing in there')
}

Related

Google App script: Overwrite existing csv file. Not create a copy using createFile

Hi I've got this Google App script that needs to overwrite a file.
At the moment it creates a copy.
Is there a line or two that can check if it exists,then delete?
Or is there an alternative to createFile that overwrites?
DriveApp.getFolderById(fold).createFile(file.getName()+'-'+sheet+'.csv', csv);
Many thanks for looking!
Filenames are not unique on Google Drive - the uniqueness of files is determined by their ID. Whereas on a regular file system, creating a file with a similar filename would erase the old file, in this case you are creating a new unique file every time.
As far as I know, the easiest way would the be to move the existing file to the trash. You can keep you existing script but add to it. Assuming your file will always exist, this should work:
const folder = DriveApp.getFolderById(fold);
folder.getFilesByName(file.getName()+'-'+sheet+'.csv').next().setTrashed(true);
folder.createFile(file.getName()+'-'+sheet+'.csv', csv);
If you are unsure that a file with that name will exist, or if there might be multiple files with that name, you will have to iterate through all them:
const folder = DriveApp.getFolderById(fold);
const files = folder.getFilesByName(file.getName()+'-'+sheet+'.csv');
while(files.hasNext()){
let f = files.next();
f.setTrashed(true);
}
folder.createFile(file.getName()+'-'+sheet+'.csv', csv);
I haven't tested this code, but it should be pretty close to what you need.
Edit
Contrary to what I said, the method DriveApp.File.setContent(content) can overwrite the content of a file. The above solution still works and avoids potential data loss.

Can copy file, can't add it Google script

In a Google script, I have a folder object (testFolder) and a file object (testFile). I have these two lines of code:
testFolder.addFile(testFile);
testFile.makeCopy('this is a copy', testFolder);
The second line correctly copies the file into the folder.
The first line seems to do nothing. I'm expecting it to add a reference to the file and place it in the folder.
I obviously have the correct objects and I am the owner of the file and the folder, so any other ideas?
Thanks
You can make a copy create new file in Google Drive. But one cannot simply move a file into a folder. You have to make a copy into the desired folder and then remove the old file. Or you have to directly create the file in the desired folder location.
What is your code for getting the 'testFile' and 'testFolder' objects? Are you referencing them by ID or by name? If you have multiple folders of the same name in your Google Drive, this could be causing the issue. Here's the script that worked for me
var file = DriveApp.getFileById('YOUR_FILE_ID');
var folder1 = DriveApp.getFolderById("YOUR_FOLDER1_ID");
var folder2 = DriveApp.getFolderById("YOUR_FOLDER2_ID");
file.makeCopy('another copy', folder1);
folder1.addFile(file);

I want to find some files that includes some keyword and copy it to other folder

I want to find files that includes some keyword and copy it to other folder.
So I need two features.
Find files by keyword and list it at "file" type value.
copy the file to different directory.
But Google drive supports same folder name so I don't know how to targeting folder by name. And I want copy the file only if there is not file has same name. Because I'll run this script every 5 minutes and if I don't set about that, there are many same name files to target directory.
How can I do this?
AFAIK, the only supported methods that you can use to get files in Class DriveApp are:
getFileById(id)
getFiles()
getFilesByName(name)
getFilesByType(mimeType)
Then, to make a copy to other folder, you can use the following methods that are given in Class File
makeCopy(destination)
makeCopy(name, destination)
Lastly, the suggested solutions given in this SO post might also help.

Embedding folders in a Google File Cabinet and including files in the folders

Refering to the link and the section 'Embedding folders in a File Cabinet' I've used this script to control and update a file cabinet in my google sites page. However, it only works on the root folder and doesn't add files that are in the sub folders. Please could you help me understand how you pick this up and also control the file cabinet so that it displays this easily?
This is the current appscript code:
function showFolderInSite() {
//var files = DocsList.getFolder("xxxxxxx").getFiles(); commented out this line as using getfolderbyID.
var files = DocsList.getFolderById('xxxxxxxxxxxxx').getFiles();
var page = SitesApp.getPageByUrl('https://sites.google.com/x/xxxxxxxx/xxxxx/xxxxxxxxx');
var attachments = page.getAttachments();
for (i in attachments) {
attachments[i].deleteAttachment();
}
for (i in files) {
page.addWebAttachment(files[i].getName(), '', files[i].getUrl());
}
}
I just tried to attach a picture but apparently I need some reputation points to post images.. how do I get those?! this is the link to it incase it does work <> In the meantime the picture shows the folders have been added but there are no files when you expand them.
Edit 5/8/14: No replies yet (hope someone can help soon). Some ideas of mine... Do I need to track what is a file and what is a folder and then assume that when the array is populated what comes through after a folder will be what is found in that folder. One problem with that is how do you differentiate a folder in a sub folder.
var files = DocsList.getFolderById('xxxxxxxxxxxxx').getFiles();
This row returns all the files of the first level in the folder. It does not retrieve any subfolders or their files. This is the same for DriveApp note that Docslist is deprecated
So getfiles() from DriveApp:
Gets a collection of all files that are children of the current
folder.
This means that you need to recursively fetch all the subfolders and their files. Also note that folders are also files in Google Drive, they only have a different mime type, application/vnd.google-apps.file
Your current script fetches the files, including the folders of the current folder, and creates links to those files and folders. It does not upload those files into the file cabinet, only refers to them. If that is the goal, you only need to recurse into the subfolders. Here you also need to note that file cabinets only go one level deep, you will not be able to create a similar structure using the file cabinet if the folders are more than one level deep.

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.