Moving a file or folder with DriveApp - google-apps-script

Really, there is no way to move a file or folder using the DriveApp class?
From what I could gather on the docs and on the StackOverflow answered questions all proposed implementations seem to copy the file to another location and then delete the original file. That would result in at least two problems:
File/folder having a different folderId on the destination;
File/folder being duplicated and stored indefinitely on Google Vault by retention policy.
I must be doing something wrong. Why is there not a method to simply move the file/folder to another destination (as provided by the Drive Web UI)?
Thanks,

When it comes to moving files with DriveApp, you need to work from the Folder rather than the File.
Open the folder you want to move the file to and use the "addFile(file)" method to add the file to that folder, then open the folder you want to move the file from and use "removeFile(file)" to remove it.
This might seem a bit clunky but it's actually possible to have a file in more than one folder at a time on Drive. The folders are really just labels. When considering a file that is already in multiple folders, the meaning of "moving" it to a new folder is kind of ambiguous, it's really a matter of adding/removing it from folders.
Add:
https://developers.google.com/apps-script/reference/drive/folder#addfilechild
Remove:
https://developers.google.com/apps-script/reference/drive/folder#removeFile(File)

Stumbled across this post (two years & 6 months later) and just wanted to point out that its now possible to do this:
DriveApp.getFileById(myFileId).moveTo(DriveApp.getFolderById(myTargetFolderId));

Related

Flutter render downloaded html

I have an elearning APP in Flutter, which can render html files stored online. Now I want to download these files to assets, so they may be accessed offline. For this, I will download a zipped file with the entire html's folder and unzip it.
The problem is the html has many subfolders with it's own assets, which I would have to declare in the pubsp.yaml in order to access, but these downloadable htmls are constantly being added (every new course has new files).
I see a few ways to solve the problem:
Somehow declare access to subfolders in the pubsp.yaml.
As far as I know, this cannot be done.
Update the folder access for the installed APP dynamically.
As far as I know, this cannot be done.
Read the html file without unziping it.
I don't know if this is doable (I'm using webview_flutter_plus to render) and weather it would allow access to files in folders inside the zip without declaring them in the .yaml.
Pre-load empty folders inside assets that would mimic the html folder structure, declare them in the .yaml and then unzip and read the htmls from these folders. I would create some 100 of them in order to accomodate a large number of course downloads.
I believe this method would work, but it seems very cumbersome and inelegant.
So my questions are:
Would any of methods 1-3 work and if so how?
Would method 4 work?
Is it possible to reference folders in the .yaml file without them existing? It would make method 4 far easier.
Is there any other way to accomplish this? I cannot change the language, since the APP is months along, but plugins are fair game.
Thanks in advance!

How to create folders recursively in googledrive through api?

For example, I'm going to upload a file scenery.jpg to /images/2020/03/18/ directory, if I upload to OneDrive, the upload url going to be like this:
https://graph.microsoft.com/v1.0/me/drive/root:/images/2020/03/18/scenery.jpg
I don't have to know if the images folder, the 2020, 03 and 18 folder exists or not, OneDrive will auto create it recursively, acting like Object-based Storage.
But now, I'm going to upload it to GoogleDrive and GoogleDrive seems can't create folders recursively(as far as I know, see Create and populate folders), now I have 2 questions:
1、Is that I have to check if these folders exists one by one to make sure if I have to create these folders?
/images/
/images/2020/
/images/2020/03/
/images/2020/03/18/
2、If none of above folder exists, is that I have to create these four folders one by one(means request api four times)?
Anyone who did this before? I hope what I assume is wrong, because it's too complicated to do it in this way.
Unfortunately you are correct
Google handles file and folder hierarchy in a different way and indeed the only way create / list nested files and folders is to iterate recursively.
Also, if you want to know if a file / folder already exists with the method Files:get, you need to know the file / folder ID, rather than just the name. If you do not know the ID, than you need to list all files on your drive / (unless you specify a certain folder as the parent folder, e.g. '1234567' in parents with the query parameter q).
The same applies for creation. If you create a folder which you want to be a subfolder of a different parent folder - you also need to create the parent folder.
However, it is not as complicated as you may think.
Here is one of many available samples of how to list the contents of all subfolders and subfolders of subfolders dynamically - in your case you would just need to add the condition to create a certain folder if it is not contained in the list.
You would need to take some time to study the working principle of Drive API, however once you get an understanding it is not complicated.

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.

Drive SDK: locating files in directories

I am using the Google Drive SDK to implement cloud storage for my iOS app. One thing I'm unclear on from the docs is how to query for files deep in the Drive directory structure.
I can make a query like:
title = 'TheFileTitle' and '1234567' in parents
But how to I find the fileID '1234567'? I am creating a directory structure to store my data in the cloud but I only know the subdirectory's name. How do I get the fileID that is needed for this query?
I could query for that directory and look for the fileID in the metadata but that just raises the question again. That directory name may not be unique so I would have to know its parent's fileID to locate the correct one.
Any help clarifying this would be appreciated.
Drive offers very little in the way of folder tree navigation. This is for the very good reason that folders are simply labels attached to files, rather than a strict hierarchy. So for example a file can have two or more parent folders. Although I've never tried it (I'm frightened it would create a black hole and universe would end) it's possible to create a loop where folder-A has child folder-B has child folder-C has child folder-A. Please don't try this at home, kids.
So the answer to your question, is start by querying for all folders and follow their parent arrays to build up an in-memory hierarchy. Then use that to navigate to a given file.
I would also suggest that you ask yourself the question whether deeply nested folders is a good idea. The answer may well be 'yes', but you should at least consider alternatives. Remember, folders were an afterthought in Drive, so might not be all they seem.

In Google Drive SDK how do you copy a folder?

Very simple question. How can I copy a folder with the Google Drive API?
It looks like the file/copy API endpoint doesn't work with folders (though this limitation is not clearly indicated in the documentation).
Of course I could add a second parent to the file, but obviously that's not a solution as most of the time a folder copy is done to do something with it without modifying the original.
So how can I do that? Any idea?
'copy' wouldn't make much sense on a folder. The purpose of copy is to create a second file with the same media content as the first. Since a folder has no media content, 'copy' doesn't really apply.
To answer the question, we need to understand your use case a little. Take a *nix paradigm, "cp -R folder1 folder2" is recursively duplicating all of the files. If that is your use case, you'll need to manually recurse down the tree. If you want the same files to appear in two places, (ie. "ln -s folder1 folder2") then that is done by adding a second parent.
I've published a pypi package to copy a google drive folder. It basically implements the recursive behaviour described in the first answer
https://pypi.org/project/googledrive-cloner/