Archive for the 'OSAScriptView' Category

2017/10/18 macOS 10.12から10.13のマシンを呼び出してAppleScriptをリモート実行

リモートAppleEventsを使ってmacOS 10.12上で編集中のScriptを10.13側で実行して結果を表示するScriptです。

リモートAppleEventsは、OSのバージョンが違っていても複数のMacを連携させたシステムを組めるので、知っている人は少ないとしても有用な機構です。ちょっと前のOSでないと動かない周辺機器(FAXとかドキュメントスキャナとか)を最新のOS環境から利用できたりもします(直接ドライブするのではなく、結果だけもらってきたり、入力があったことを通知したり)。

同一のLAN内で、固定のIPアドレスを振って運用しています。

figs.png

macOS 10.13側

macOS 10.13のMac側の「システム環境設定」の「共有」で、

share_resized.png

リモートAppleEventsをオンにします。AppleScriptをリモートで受信して実行するアプレット「RemoteAgent」を作成して起動しっぱなしの設定にして(アプレットとして保存するときに「ハンドラの実行後に終了しない」のオプションをオンに設定)保存し、起動したままにしておきます。アプレットの名称にはとくに意味とか必然性はありません。たまたま、そういう名前で書いたのでそうなってるだけです。

AppleScript名:RemoteAgent
– Created 2017-10-18 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “OSAKit”
use framework “AppKit”
–http://piyocast.com/as/archives/4906

on run
  
end run

on testMe(aParam)
  return aParam
end testMe

on getVers()
  set vers to (do shell script “defaults read /System/Library/CoreServices/SystemVersion ProductUserVisibleVersion”)
  
set build to (do shell script “defaults read /System/Library/CoreServices/SystemVersion ProductBuildVersion”)
  
return {vers, build}
end getVers

on execASstring(aString)
  
  
set aRect to current application’s NSMakeRect(0, 0, 500, 200)
  
  
–Make AppleScript Controller & Script Editor View
  
set osaCon to current application’s OSAScriptController’s alloc()’s init()
  
set osaView to current application’s OSAScriptView’s alloc()’s initWithFrame:aRect
  
  
–Make Result View
  
set resView to current application’s NSTextView’s alloc()’s initWithFrame:aRect
  
resView’s setRichText:true
  
resView’s useAllLigatures:true
  
  
–Connect OSAScriptController to Editor View & Result View
  
osaCon’s setScriptView:osaView
  
osaCon’s setResultView:resView
  
  
–Set AppleScript Source to Editor View & Execute it
  
set aSource to current application’s NSString’s stringWithString:aString
  
osaView’s setString:aSource
  
osaCon’s runScript:(missing value)
  
  
–Get AppleScript’s Result as string
  
set aRes to resView’s |string|() as string
  
  
return aRes
end execASstring

–指定AppleScriptファイルのソースコードを取得する(実行専用Scriptからは取得できない)
– Original Created 2014-02-23 Shane Stanley
on getASsourceFor(anAlias as {alias, string})
  set anHFSpath to anAlias as string
  
set aURL to current application’s |NSURL|’s fileURLWithPath:(POSIX path of anHFSpath)
  
set theScript to current application’s OSAScript’s alloc()’s initWithContentsOfURL:aURL |error|:(missing value)
  
return theScript’s source() as text
end getASsourceFor

★Click Here to Open This Script 

macOS 10.12側

macOS 10.12側で呼び出し用のScriptを書いてScript Menuに登録しておきます。Script中のUser名とパスワードはmacOS 10.13側のものを書いておきます。ここではmacOS 10.13側のIPアドレスを直接記述していますが「MBP11.local」のようなBonjour名称でももちろんOKです。

ここにユーザー名とパスワードを書かないと毎回ダイアログが出てユーザー名、パスワード、キーチェーンに保存するかなど聞かれますが、結局保存されなくて毎回聞かれるので、直接コード中に書いておくか、別途キーチェーンに保存して実行時に読み出してもいいでしょう。

AppleScript名:macOS 10.13でリモート実行
– Created 2017-10-18 by Takaaki Naganoya
– 2017 Piyomaru Software
–http://piyocast.com/as/archives/4906
tell application “Script Editor”
  tell front document
    set aSource to contents
  end tell
end tell

tell application “RemoteAgent” of machine “eppc://user:password@192.168.0.7″
  set {vRes, bRes} to getVers()
  
set aRes to execASString(aSource)
end tell

set vText to “macOS “ & vRes & ” (Build:” & bRes & “) Result:”
display dialog vText default answer aRes

★Click Here to Open This Script 

macos10126_1.png

こんなAppleScriptをScript Editor上でオープンした状態で(複数Window表示時には最前面であること)、Scriptを実行。

macos10126_2.png

LANごしにリモートAppleEventを実行し、macOS 10.13上のアプレットで指定のAppleScriptを動的にコンパイルして実行。結果をmacOS 10.12のマシン側に返してきます。

macos10126_3.png

こんな感じで動作確認を行なっています。ただリモート実行するだけなら、もうちょっとシンプルに書けたような気もしますが、Cocoa系の機能を使ってリモートScript実行を行なってみたときの部品をそのまま流用しています。

LAN経由、とくにWiFi経由でのリモートAppleEventsは通信にコストがかかる(時間がかかる)ため、パラメータだけ与えてまとめて結果をもらうようにするべきです。VPN経由で遠隔地のMacの操作を行うような場合にも同様です。

2016/01/07 OSAScriptViewでAppleScriptをソース取得&コンパイルして書式付きでPDF出力

Cocoaの機能を用いて、指定のAppleScriptのソースを取得して、再度OSAScriptView上でコンパイル(構文確認)を行い、構文色分けを反映させたスタイルつきのPDFとして出力するAppleScriptです。

わかりにくいですが、AppleScriptの書類をPDF出力するAppleScriptです(正確に書けば書くほどわからなくなるのはなぜだろう)。デスクトップフォルダ上に元Scriptのファイル名でPDF出力します。

script1.png
▲出力対象のAppleScript書類

scriptpdf.png
▲上記書類をPDF出力したもの

PDF出力部分は、指定URLの内容を1枚モノのPDFに書き出すAppleScriptを書いた際に利用した記述そのままです。ページネーションは一切していないため、こういう用途ではページネーション指定をしてPDF出力したほうがよいかもしれません。

AppleScriptのパスだけ与えれば、あとはGUIアプリの機能は利用していないため、大量データの並列処理に適した構造になっています。

「なんでこんなもの作ったの?」と聞かれましたが、結局「これじゃない何か」を作ろうとして、その途中経過ができたものなので、本Scriptは本当に作りたいものの副産物です。

AppleScript名:OSAScriptViewでAppleScriptをソース取得&コンパイルして書式付きでPDF出力
– Created 2016-01-07 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “OSAKit”
use framework “AppKit”
use framework “Quartz”

set targX to 1024 –PDF Width
set targY to 2048 –PDF Height

–Select & Read AppleScript Source (Only Editable AppleScripts are available)
set aScriptAlias to (choose file with prompt “Choose AppleScript to convert to PDF” of type {“com.apple.applescript.script-bundle”, “com.apple.applescript.script”})

set srcStr to getASsourceFor(aScriptAlias) of me
if srcStr = missing value or srcStr = “” then
  –Error
  
display dialog “Error in reading script source….” buttons {“OK”} default button 1 with icon 1
  
return
end if

–Making PDF Out Path from source script file name
set outName to getFileNameFromAlias(aScriptAlias) of me
set outFol to POSIX path of (path to desktop)
set outPath to outFol & outName
set pathString to current application’s NSString’s stringWithString:outPath
set newPath to pathString’s stringByDeletingPathExtension()
set pdfOutPath to newPath’s stringByAppendingPathExtension:“pdf”

–Compile AppleScript
set osaCon to current application’s OSAScriptController’s alloc()’s init()
set osaView to current application’s OSAScriptView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, targX, targY))
osaCon’s setScriptView:osaView
osaView’s setString:srcStr
osaCon’s compileScript:(missing value) –Compile(構文確認)

–Make Print into PDF
set aPrintInfo to current application’s NSPrintInfo’s sharedPrintInfo()
set newPrintOp to current application’s NSPrintOperation’s PDFOperationWithView:(osaView) insideRect:(current application’s NSMakeRect(0, 0, targX, targY)) toPath:pdfOutPath printInfo:aPrintInfo

set runPrint to newPrintOp’s runOperation()
return (runPrint as boolean)

–指定AppleScriptファイルのソースコードを取得する(実行専用Scriptからは取得できない)
– Original Created 2014-02-23 Shane Stanley
on getASsourceFor(anAlias as {alias, string})
  set anHFSpath to anAlias as string
  
set aURL to current application’s |NSURL|’s fileURLWithPath:(POSIX path of anHFSpath)
  
set theScript to current application’s OSAScript’s alloc()’s initWithContentsOfURL:aURL |error|:(missing value)
  
return theScript’s source() as text
end getASsourceFor

–指定のAliasからファイル名を取得する
on getFileNameFromAlias(anAlias)
  set aPath to POSIX path of anAlias
  
set pathString to current application’s NSString’s stringWithString:aPath
  
set newPath to pathString’s lastPathComponent()
  
return newPath as string
end getFileNameFromAlias

★Click Here to Open This Script 

2016/01/07 OSAScriptController+OSAScriptViewでAppleScriptを実行

Cocoaの機能を用いて、OSAScriptController+OSAScriptViewの組み合わせでAppleScriptのテキストを実行するAppleScriptです。

osascriptexe.png

AppleScriptの動的生成(テキストを組み立ててコンパイル(構文確認)してAppleScriptにして)+実行については、

 (1)AppleScriptのコマンドrun scriptで実行するもの
 (2)shellのosascriptコマンドで実行するもの
 (3)OSAScriptのinitWithSource: compileAndReturnError:メソッドで実行するもの

ぐらいが定番でしょうか。文法的に無茶なことを実現(recordの動的生成など)するために、昔から使われてきたブラックテクノロジー(セキュリティ的に穴になりそうな無茶な処理)です。

#  recordの動的生成については、OS X 10.10から通常のAppleScriptでもCocoaの機能が普通に呼び出せるようになったので、NSDictionaryを作成してrecord生成できます。正規表現なども普通に使えるようになったので、かつての「常識」が根底から変わってきています

で、なんでOSAScriptController+OSAScriptViewとかいう「自分流Script Editorを作る部品」を引っ張り出してきたかといえば、

 AppleScriptを直接PDF化したい(書式つきで)

ような場合に、OSAScriptViewからリッチテキストを取得して、RTF、HTML、PDFなどに変換するような処理ができると考えたからです。まっとうに考えれば、Script EditorをAppleScriptでコントロールして書き出すあたりになりますが、それだと並列処理できませんので。

並列処理実行できるように、このような部品を使ってみた次第です。

AppleScript名:OSAScriptViewでAppleScriptを実行
– Created 2016-01-07 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “OSAKit”
use framework “AppKit”

set srcStr to current application’s NSMutableString’s stringWithString:“display dialog \”OSAScript TEST\”"

set osaCon to current application’s OSAScriptController’s alloc()’s init()
–>  (OSAScriptController) <OSAScriptController: 0×7ff7240ae190>

set osaView to current application’s OSAScriptView’s alloc()’s init()

osaCon’s setScriptView:osaView
osaView’s setString:srcStr
–osaCon’s compileScript:(missing value)
osaCon’s runScript:(missing value)

–set aRT to osaView’s

★Click Here to Open This Script