« Aleph One JPをMacでプレイする | トップページ | JavaScript for Automation (JXA)でフォルダアクション »

2018年2月15日 (木)

JavaScript for Automation (JXA)で色々やってみる

故あって、普段よく使っている Apple Script を数件、JavaScript for Automation (JXA) に移植した。

その際、メモしておいたヒントなどをいくつかここに書き留めておく。

ある場所にある項目が存在するかどうか調べる

デスクトップ上に hogehoge.txt があるかどうかを調べ、あれば処理を加える。

var finder = Application('Finder')
finder.includeStandardAdditions = true
var chk_wfolder_exist = finder.exists(Path("/Users/xxxxx/Desktop/hogehoge.txt"))
if (chk_wfolder_exist == true) {
	//ここにコード
}


ファイル選択ダイアログボックスからファイルを開き、パスとして受け取る

var finder = Application('Finder')
finder.includeStandardAdditions = true
var item_1 = finder.chooseFile()
var item_1Path = item_1.toString()

item_1 は Path("/Users/xxxxx/foo/bar") 型のデータとして受け取る。そこからパスを得るには item_1.toString() と書く。


なお、ダイアログボックスではなく、Finder ウィンドウやデスクトップで選択されている項目から直接パスを得ることについては JXA では今のところ、簡単なやり方がないらしい。

var finder = Application('Finder')
finder.includeStandardAdditions = true
var s = new Array()
s = finder.selection()
for (var i of s) {
	i
}

上のコードで i は Path("/Users/xxxxx/foo/bar") 型とは違う複雑な形のデータとして受け取っているらしく、その内容は i.properties.get() で得られる。

その中に、url というプロパティーが存在するので、それを i.url.get() で得ることができるのだが、url は file:/// で始まっている上、日本語のフォルダ名やファイル名がエンコードされている。なので、

var finder = Application('Finder')
finder.includeStandardAdditions = true
var s = new Array()
s = finder.selection()
for (var i of s) {
	var iUrl = i.url.get()
	iUrl = iUrl.replace(/^file\:\/\//, "")
	iUrl = decodeURI(iUrl)
}
(表記の都合上、バックスラッシュが全角で表示されているが、実際には半角)

などと書けばよい。ただ、これではフォルダーへのパスがスラッシュで終わっているなどの問題があるため、これについてはどこかのサイトでもっとちゃんとパスを取得できるコードが公開されているので、そちらを参照。

なお、この型のデータの場合、ファイル名を得たいなら単に i.name.get() で得られる。

むしろ、Path("/Users/xxxxx/foo/bar") 型 の方が名前を得るのは手間がかかり、.toString() で得られたパスからスラッシュで区切られた一番最後のデータを得るという方法をとることになる。例えば

item_1_Name = item_1.toString().split("/").pop()

など。


他のスクリプトから呼び出す

下記のような形で呼び出す。sentData というデータを送っている。

var app = Application.currentApplication()
app.includeStandardAdditions = true
app.runScript('/Users/xxxxx/Library/Scripts/foobar.scpt', {withParameters:sentData})

呼び出される側のスクリプトは

var app = Application.currentApplication()
app.includeStandardAdditions = true
function run(sentData) {
	for (var i of sentData) {
		//ここにコード
	}
}

のような形になる。


« Aleph One JPをMacでプレイする | トップページ | JavaScript for Automation (JXA)でフォルダアクション »

コメント

コメントを書く

(ウェブ上には掲載しません)

« Aleph One JPをMacでプレイする | トップページ | JavaScript for Automation (JXA)でフォルダアクション »