Posted at

Google Driveでディレクトリごとまるっとコピーしてやるぜ!

More than 3 years have passed since last update.


きっかけ

Advent Calendarで何を書こうか迷っていた時に、こんなツイートを見たわけです。

https://twitter.com/sinmetal/status/544314381379452929


Google Driveには、ディレクトリのコピーがメニューにない

Google Driveでディレクトリで右クリックしてみました。

マイドライブ_-_Google_ドライブ.png

ファイルを右クリックすると「コピーを作成」がある。

chugoku-gtug_-_Google_ドライブ.png


Google Apps Scriptで実現するしかなさそう

ということで、作ってみました。


コード.gs

function myFunction() {

var folders = DriveApp.getFoldersByName("コピーサンプルデータ");
var dest = DriveApp.createFolder("コピーサンプルデータのコピー");
while(folders.hasNext()) {
var folder = folders.next();
folderCopy(folder, dest);
}
}

function folderCopy(folder, dest) {
// var folders = DriveApp.getFolders();
var folders = folder.getFolders();
var files = folder.getFiles();

while(files.hasNext()) {
var file = files.next();
// file.makeCopy(dest);とすると、****のコピーというファイル名になるので…。
file.makeCopy(file.getName(), dest);
}

while(folders.hasNext()) {
var subFolder = folders.next();
var folderName = subFolder.getName();
var copyFolder = dest.createFolder(folderName);
folderCopy(subFolder, copyFolder);
}
}



承認が必要なので

Driveへのアクセスの承認をして下さい。

許可のリクエスト.png


解説


DriveAppにはフォルダのコピーAPIがない。

DriveAppにはフォルダのコピーを作るというAPIがないので、同じ名前でフォルダを作ってやらないといけません。

ということで、フォルダを階層を維持したまま別の所にコピーするのを実現するには、フォルダを探索する再帰呼び出しをしてやります。


DriveApp.getFolders()/Folder.getFolders()はフォルダしか取得できない。

当然ですが、getFolders()を呼び出してもファイルは取得されないので、フォルダの探索と同時にファイルの探索File.getFiles()を呼び出して、ファイルのコピーを作っています。


File.makeCopy(dest)にすると、****のコピーというファイル名になるので…。

FileにはmakeCopy()というAPIがありますが、名前を指定しないものを呼び出すと"****のコピー"というファイル名になってしまいます。(その方が都合が良い場合もありますが)コピーを作る時は、同じファイル名で作ると思いますから、File.makeCopy(name, dest)の方を呼び出してファイル名が変わらないように制御します。


ただし、弱点が

コピーを作る先がルートフォルダになる。これは、destの指定がまずいだけですが、DriveApp.createFolder()を使うと、ルートディレクトリにFolderを作ってしまうので、パスを指定してFolderを作る方法があればもう少し便利になるかもしれない。


結論

今年は「早すぎる男」になれませんでした…。


Disclaimer


  • この記事は個人的なものです。私の雇用者とは全く関係はありません。(一応つけておきます)