2015年1月17日土曜日

Google Apps Scriptのファイル/フォルダ操作(2)

同じパスのフォルダやファイルが複数存在可能なGoogleDriveで階層が深いフォルダを一発で指定したり、階層が深いフォルダを一回で作成するための関数を検討してみた。簡単な動作確認では思ったとおりに動作しているようだ。まったくオブジェクト志向ではないコードになってしまいました。
/**
* フォルダパスを指定してフォルダを生成する。
*
* @param {String} path フォルダパス
* @param {Folder} base ベースフォルダ(省略時はルート)
* @return {Folder} 生成したフォルダ。失敗時はnull。
*/
function createFolder(path,base)
{
if(typeof base === 'undefined'){
base = DriveApp.getRootFolder();
}
var splitpath = path.split("/");
if( splitpath[0] == "" ){
splitpath.splice(0,1);
}
if( splitpath[0] == "" ){
base = DriveApp.getRootFolder();
splitpath.splice(0,1);
}
var parent= new Array();
var child=new Array();
parent[0] = base;

for( var level=0; level < splitpath.length && splitpath[level]!=""; level++ ){
for( var i = 0; i<parent.length ; i++ ){
var folders = parent[i].getFoldersByName(splitpath[level]);
while( folders.hasNext() ){
child.push( folders.next() );
}
}
if( child.length == 0 ){
child[0] = parent[0].createFolder( splitpath[level] );
}
parent = [];
parent = [].concat(child);
child=[];
}
return parent[0];
}
/**
* フォルダパスを指定してフォルダを取得する。
*
* @param {String} path フォルダパス
* @param {Folder} base ベースフォルダ(省略時はルート)
* @return {Folder} ファイルパスを指定してファイルを取得する。失敗時はnull。
*/
function getFoldersByPathName(path,base)
{
if(typeof base === 'undefined'){
base = DriveApp.getRootFolder();
}
var splitpath = path.split("/");
if( splitpath[0] == "" ){
splitpath.splice(0,1);
}
if( splitpath[0] == "" ){
base = DriveApp.getRootFolder();
splitpath.splice(0,1);
}
var parent= new Array();
var child=new Array();
parent[0] = base;

for( var level=0; level < splitpath.length && splitpath[level]!=""; level++ ){
for( var i = 0; i<parent.length; i++ ){
var folders = parent[i].getFoldersByName(splitpath[level]);
while( folders.hasNext() ){
child.push( folders.next() );
}
}
if( child.length != 0 ){
parent = [];
parent = [].concat(child);
child=[];
}else{
return null;
}
}
return parent;
}

2015年1月12日月曜日

Google Apps Scriptのファイル/フォルダ操作(1)

GASでGoogle Driveのファイルにアクセスするときには少し癖がある。例えば、"ABC/DEF"フォルダにアクセスするために"DocsList.getFolder(path)"という関数が提供されており、"/"をセパレータとしてフォルダやファイルを指定することができる。
 var folder = DocsList.getFolder('ABC/DEF/GHI');
しかし、GASのReferenceによるとこの関数は"Deprecated. This function is deprecated and should not be used in new scripts."となっている。Deprecatedになった理由を考えてみるとGoogle Driveの癖のある仕様に行き着く。 Windows(DOS)やLinixなどではPATHでファイル/フォルダを識別しているが、Google Driveでは同じフォルダに同じ名前のファイルやフォルダを作成することができるため、PATHを指定しても一つのファイル/フォルダを特定できないのだ。 そのため以下の様な構成も可能なのであり、'ABC/DEF/GHI'と指定しても(1)〜(4)のどのフォルダなのか特定することができない。
ABC/
DEF/
GHI/ ・・・(1)
GHI/ ・・・(2)
DEF/
GHI/ ・・・(3)
GHI/ ・・・(4)
Google Driveで一つのファイルやフォルダを特定するのはIDであり、パスではないので注意が必要だ。例えば、スクリプトのログをひとつのファイルに保存し続けたい場合などは注意が必要だ。確実に同じファイルにアクセスするためには一度作成したファイルのIDを保存しておきそのIDを用いてアクセスしなければならない。
今後作成するスクリプトでログを残したくなることがあると思うので、まずはScript/Logフォルダにログファイルを保存する仕組みを考えていきたい。
 目標仕様としては
  • ログファイルIDをスクリプトのプロパティとして保存する。
  • 初回起動時などプロパティにログファイルIDが保存されていない時は指定されたパスに従いファイルを探す。
  • 指定されたパスのファイルが存在しなかった場合には新規ファイルを作成し、IDをプロパティに保存する。
  • 指定されたパスのファイルが存在しているときは最初に見つかったものを採用し、IDをプロパティに保存する。
注意事項としては以下の構成で"Script/Log/yyyLog.TXT"を見つけることだ。
(1)のScriptフォルダに入り、(2)のLogフォルダに入り、"yyyLog.TXT"を検索し見つからなかった場合、(2)のフォルダに"yyyLog.TXT"を作っていはいけない。(1)フォルダ下の検索が完了したら(3)フォルダ、(4)フォルダと検索しyyyLog.TXTを見つけなければならない。
Script/ ・・・(1)
Log/ ・・・(2)
Script/ ・・・(3)
Log/ ・・・(4)
yyyLog.TXT

仕様として考えなければいけないこととしては"yyyLog.txt"が存在しない時にどこにファイルを作成するかだ。
案1:最初に見つかったフォルダに作成
Script/ ・・・(1)
Log/ ・・・(2)
yyyLog.TXT
Script/ ・・・(3)
Log/ ・・・(4)
案2:最後に見つかったフォルダに作成
Script/ ・・・(1)
Log/ ・・・(2)
Script/ ・・・(3)
Log/ ・・・(4)
yyyLog.TXT
実際には同じフォルダに同じ名前のファイル/フォルダを作成することはないのだが、しっかり考えて見ると面倒なことに気がついた、、、

2015年1月11日日曜日

Acer C720用ケース購入(Amazonベーシック ラップトップスリーブ 11.6インチ)

Chromebook(Acer C720)用のケースを購入した。当初は100円均一ショップでの購入を検討していたが、なかなか100円均一ショップに行く時間がなかった。Amazonで探してみたがいろいろ種類があり、どれも黒で同じに見えるので決めることができなかった。なんとなく目についたAmazonブランドのケース(Amazonベーシック ラップトップスリーブ 11.6インチ)を860円で購入した。
しっかりサイズを調べなかったため不安ではあったが、ピッタリ収まり、更にケースに入れた状態でも充電できるので安心した。当初検討していた100円からは随分高かった(8.5倍、750円高)がデザインも気に入ったので満足。


2015年1月5日月曜日

Chromebook(Acer C720) 購入

以前から興味があったChromebookを購入した。興味があったと言ってもどのメーカーからどのような機種が発売されているかなどは調べていなかったので、ヨドバシ・ドット・コムで適当に調べ、価格的にも安く、デザインも気に入ったAcer C720を32,180円で購入した。もしかしたらAmazonなどでもう少し安く買えるかもしれないが、調べないようにしている。
初回起動は時間がかかったが、起動完了後はGoogleのアカウントとパスワードを入力するだけですぐに使用できた。しかもパソコンで使用しているChromeブラウザのテーマやお気に入りなどが引き継がれておりすぐに使用できた。

DesktopパソコンにリモートデスクトップするのがChromebookを購入した目的の一つだったので、早々にChrome RDPをインストールして接続を試してみたが、つまらないくらい簡単に接続出来た。
後はWakeup-On-Lanのアプリケーションがあれば良いのだが、まだ見つかっていない。

iPhoneのテザリングも問題なく接続でき、L2TP/IPSecによるVPN接続も問題なく接続できた。リモートデスクトップ端末としては最適の選択肢だったと思う。