Acquiring the Google Drive folder my google script is located - google-drive-api

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.

Related

apps-script - Create new google doc in existing folder

I am creating a google doc from apps script as follows:
var newDoc = DocumentApp.create(docName);
I want this new document to be created in an existing folder in my drive. I tried the following way:
var dir = DriveApp.getFolderById("folder-id");
dir.addFile(newDoc);
But I get the error as:
ReferenceError: "DocsList" is not defined.
Is there any way to create a new document in my existing folder or move my file to an existing folder via apps script? Any help will be appreciated.
Folder.addFile() requires that you pass it a File, but DocumentApp.create() returns a Document. What you need to do is use newDoc.getId() to get its unique identifier, and then use it in DriveApp.getFileById() to properly move the file.
var newDoc = DocumentApp.create(docName); // Create a Document
var docFile = DriveApp.getFileById(newDoc.getId()); // Get Document as File
var dir = DriveApp.getFolderById("folder-id"); // Get the folder
dir.addFile(docFile); // Add the file to the folder
DriveApp.getRootFolder().removeFile(docFile); // Optionally remove the file from root
Please also note that Google Drive files can exist in multiple folders. So if you only want the file to be listed in the "folder-id" folder, then you'll need to remove it from the root folder where it was created by default.

Script - DriveApp.getFilesByName - get latest version?

As title suggests
Got a script that's fetching a CSV from a specific G-Drive folder, which is currently filtering by a specific file name.
Is it possible to just say 'get the latest file' from that folder instead of searching by the specific name?
Asking because multiple copies of the same file will be uploaded into the same folder (file name is content.csv, copies will either replace that file, or no doubt be uploaded as content(1).csv etc). So, therefore, assumed just trying to 'get the latest file' would be the best way?
Script:
function importCSVFromGoogleDrive() {
var fSource = DriveApp.getFolderById('xxxxxxxxxxxxx'); // folder where files are saved
var file = DriveApp.getFilesByName("content.csv").next(); // currently searching by file name
var csvData = Utilities.parseCsv(file.getBlob().getDataAsString()); csvData.splice(299,csvData.length-300);
var sheet = SpreadsheetApp.getActiveSheet();
sheet.getRange(1, 1, csvData.length, csvData[0].length).setValues(csvData);
}
You can order the files by date so you can list the recently uploaded files, and when you hit an already downloaded file you just stop whole process.
https://developers.google.com/drive/api/v3/reference/files/list#orderBy
Try this:
function getLatest(){
var optionalArgs = {
orderBy:"modifiedDate",
q:"title='TITLE'"
};
var files = Drive.Files.list(optionalArgs).items;
Logger.log(files);
}
This will use the Advanced Services API to search for the files and order them by date. To use this code you'll need to enable Google Advanced Services, which allows you to use the APIs directly. You should also look at the File Resource to know what properties are available. Lastly, files holds an array of the files returned by the list.

Google Apps Script returning all files in Drive, rather than files in a folder

I have a folder in Google Drive, where there are some files. I want to retrieve all of these file information, and that's all I want. There are many other files in other folders, but I don't need them. However, my following code is showing all files' names. How can I limit the result only to the files in the specified folder?
//Folder ID
var myFolderId = "XXXXXXXXXXXXXXXXXXXXXXXXX";
var files = DriveApp.getFolderById(myFolderId).getFiles();
while(files.hasNext())
{
var file = files.next();
Logger.log(file.getName());
}
For now, there are only 4 files in this folder, but the log shows the entire file names in my Google Drive. I don't know what I am doing wrong, because I am specifying the folder with ID. How come it is returning every file in Google Drive?
Answer:
Your code already works great!
Further information:
Google Apps Script doesn't allow the running of global code as specific functions need to be declared and run, at least, not in the same was as locally-run code. The global variables are static and can not be changed in the runtime.
Things you can do:
As Cooper mentioned in their comment - all you need to do is put your code in a function, call the function and you're set. The code works great:
function functionName(){
var myFolderId = "XXXXXXXXXXXXXXXXXXXXXXXXX";
var files = DriveApp.getFolderById(myFolderId).getFiles();
while(files.hasNext())
{
var file = files.next();
Logger.log(file.getName());
}
}
As a side-note: if you really want to use a global scope (or at least. use an emulation of it), the PropertiesService is available to you, though you'd still have to set them in a function and run a function to retrieve them:
function setVars(){
PropertiesService.getScriptProperties().setProperty('myFolderId', 'XXXXXXXXXXXXXXXXXXXXXXXXX');
}
function listFiles(){
var files = DriveApp.getFolderById(PropertiesService.getScriptProperties().getProperty('myFolderId')).getFiles();
//continue this code
}

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'

Google script Create new sheet file and move it to a specific folder Then copy the contents and 2 tabs from the active sheet to the newly created file

Welcome: I will not go into the code at the beginning, but I would like to ask a few questions. To learn the logic of operation.
Question 1:
When I create a new file using the function
var newFile = SpreadsheetApp.create("Name new sheets")
var newFileId = newFile.getId()
A new file is always saved to the root directory of the google disk?
Question 2
If I always write root directory of the google disk.The only way to move a newly created file is to use
var TARGE_FOLDER_ID = "asdFHd4hasdasn6nJMGLSQt8das331"
DriveApp.getFileById(newFileId).makeCopy("Name new sheets",TARGE_FOLDER_ID);
And after copying the removal from the main google drive folder?
When I create a new file using the function
Yes SpreadsheetApp.create("Name new sheets") puts files in the root directory you will have to move them
If I always write root directory of the google disk.The only way to move a newly created file is to use
Yes something like this Move file
var folder=DriveApp.getFoldersByName(folderName).next();//gets first folder with the given foldername
var file=SpreadsheetApp.create(fileName);
var copyFile=DriveApp.getFileById(file.getId());
folder.addFile(copyFile);
DriveApp.getRootFolder().removeFile(copyFile);