監視プログラムの概要
アップルスクリプトの常駐型アプレットをつかって一定間隔でFoltiaサーバーへ接続して状況を確認し、必要な対応をしてゆくというプログラムになります。
on idle
on reopen
on open of theFileをつかってループを回します。
idleでの戻り値は数字になりますが、その秒数後に再び実行するというものになります。 戻り値が60なら60秒ごとに実行と言う感じですね。基本的にあんまり頻繁にアクセスするのもいやなので50秒ごとにアクセスするように設定しています。
アプレット型のアップルスクリプトは動作させたとき最初の一回目にほかのアプリ(ターミナルとか、サファリとか)へのアクセスを許可しなくてはなりません。 まあこれもシステムから聞かれますので、オーケーしてください。
このアプレット型のアップルスクリプトは編集するたびにこの他アプリのコントロールをしてよいか聞かれるので面倒ということもあって、私は基本的に外部の別ファイルにメインのスクリプトを記載してそれをアプリケーション型アップルスクリプトから実行時に毎回読み込みにいくように設定してます。 設定場所をDropbox内に設定しています。
M-loop_pubのテスト
property gP : {loopPerSec:50, pswd:""}
on idle {}
set f to load script file ( ( (path to home folder from user domain) as string) & "Dropbox:Scripts:M-loop_pub.scpt") as alias
set gP to MainLoop(gP) of f
return gP's loopPerSec
end idle
on reopen
set f to load script file ( ( (path to home folder from user domain) as string) & "Dropbox:Scripts:M-loop_pub.scpt") as alias
set q to MainReOpen(gP) of f
return q's loopPerSec
end reopen
on open of theFile
set f to load script file ( ( (path to home folder from user domain) as string) & "Dropbox:Scripts:M-loop_pub.scpt") as alias
set null_ to MainDrop(theFile) of f
return gP's loopPerSec
end open
on MainDrop(theFile) --Manually_HandBrakeCLI(q)
end MainDrop
on MainReOpen(q)
set q to q & {foltia:"foltia", JPVolume:"JP-file-style"}
set a to (display dialog "選択" buttons {"続行", "停止する", "プログラムを実行テストする"} default button "続行" giving up after 5)'s button returned
if a is "" or a is "続行" then
else if a is "停止する" then
continue quit
else if a is "プログラムを実行テストする" then
set MenuList to {"qファイルを表示", "ローカルログ表示", "戻る"}
set TG to choose from list MenuList with prompt "どのプログラムを実行しますか?"
if TG is false then set TG to {"戻る"}
if TG is {"qファイルを表示"} then
LogOnConsole({cmt:{pswd:""} & q, open_:true}) of me
else if TG is {"ローカルログ表示"} then
term({ActionList:{"", "$Here", "Tail -f " & quoted form of ( ( (path to documents folder from user domain) as string)'s POSIX path & "M-loop_pub.log"), ""}, closeWindow:false}) of me
else if TG is {"戻る"} then
end if
set q to {loopPerSec:1} & q
end if
return q
end MainReOpen
on MainLoop(q)
set q to {status:"good", erro:false, loopPerSec:50} & q
LogOnConsole({cmt:"Main Loop test", open_:false}) of me
return q
end MainLoop
##########################################
(*以下はとりあえず M-loop_pubに記載してますが、後でサブのscriptファイルに記載し直します*)
on term(q) --termは基本的に返値なし
set q to {error_:""} & q & {tab_:"", ActionList:{}, wSec:10, ti:0.1, FailSafe:true, WaitBusy:false, closeWindow:true}
--FailSafeはfalseならチェックなし所定時間経過したら進む。
--Prompt1, Action1, Prompt2, Action2 の順番で処理し、空白が出現した段階で停止する。
--"$Here"ならproHere, "$There"ならProThereを入れる
set ProHere to "@*~"
set ProThere to "@*~"
if (do shell script "Echo " & (system info)'s system version & "|sed -e 's/\\(^[0-9]*.[0-9]*\\)[^0-9].*/\\1/g'") ≤ 10.13 then set ProHere to "~*\\$"
set max to round ( (length of q's ActionList) / 2)
--偶数個ないと最後は実行されない。
--tell application "Terminal" to close every window
repeat with i from 1 to max
if q's tab_ is "" then
tell application "Terminal" to set q's tab_ to do script item (i * 2 - 1) of q's ActionList
else
tell application "Terminal" to do script (item (i * 2 - 1) of q's ActionList) in q's tab_
end if
delay q's ti
set wPrompt to item (i * 2) of q's ActionList
if wPrompt is "$Here" or wPrompt is "$local" or wPrompt is "$client" then set wPrompt to ProHere
if wPrompt is "$There" or wPrompt is "$remote" or wPrompt is "$server" then set wPrompt to ProThere
set q to WaitPrompt({tab_:q's tab_, wPrompt:wPrompt} & q) of me & q
if q's FailSafe then return {error_:"ActionList:" & item (i * 2) of q's ActionList & "が返却されない"} & q
end repeat
if q's closeWindow then tell application "Terminal" to close window 1
return q
end term
on WaitPrompt(q)
set q to q & {tab_:"", wSec:10, FailSafe:true, wPrompt:"", ti:0.1, SerchFullText:false, WaitBusy:true, LastLine:""}
if q's tab_ is "" then tell application "Terminal" to set q's tab_ to tab 1 of window 1
if q's wPrompt is "" then
delay q's ti
return {FailSafe:false} & q
end if
tell application "Terminal" to tell q's tab_
if q's WaitBusy then
repeat while busy is true
delay q's ti
end repeat
end if
if q's wPrompt is "" then return q
set a to ""
repeat q's wSec times
set history_ to history as string
set Len to 1
try
set Len to (length of history_) - 1000
end try
if Len < 1 then set Len to 1
set history_ to text Len thru end of history_
if q's SerchFullText then
set a to do shell script "echo " & quoted form of (history as string) & "|grep -v '^$'|tr -d '^\\r'|tr \\\\r \\\\n|grep '" & q's wPrompt & "'||true"
else
try
set a to do shell script "echo " & quoted form of (history_) & "|grep -v '^$'|tr -d '^\\r'|tr \\\\r \\\\n|tail -n 2|grep -B 1 '" & q's wPrompt & "'||true"
end try
end if
if a is not "" then
set q's FailSafe to false
exit repeat
end if
delay 1
end repeat
end tell
return {LastLine:a} & q
end WaitPrompt
on LogOnConsoleR(q)
return (LogOnConsole(q) of me)'s FinalComment
end LogOnConsoleR
on LogOnConsole(q)
tell application "Finder"
set XL to ( (path to me)'s name extension as string)'s length
set NL to ( (path to me)'s name as string)'s length
set Filename_ to text 1 thru (NL - XL - 1) of ( (path to me)'s name as string)
set path_ to ( (path to documents folder from user domain) as string)
end tell
set q to q & {TimeFormat_:"+%Y-%m-%d %H:%M:%S"} & {cmt:"", CleanUpPastLog_:false, Filename_:Filename_, error_:"", path_:path_, open_:true}
set time_ to ""
set comment_ to ""
try
set time_ to do shell script "date " & (q's TimeFormat_)'s quoted form
set comment_ to time_ & " | "
end try
set a to q's cmt
try
a as string
set comment_ to comment_ & q's cmt
on error error_message
set comment_ to comment_ & error_message & "\\n"
end try
set q to {FinalComment:comment_} & q
set log_ to q's path_ & q's Filename_ & ".log"
do shell script "touch " & quoted form of (log_'s POSIX path)
set arrow to " >"
if not q's CleanUpPastLog_ then set arrow to arrow & ">"
do shell script "echo " & quoted form of comment_ & arrow & " " & quoted form of (POSIX path of log_ as Unicode text)
set log_alias to log_ as alias
try
if q's open_ then
tell application "Terminal"
if (every window whose name contains "tail -f ") is {} then do script "tail -f " & quoted form of (log_'s POSIX path)
end tell
end if
end try
return q
end LogOnConsole
まずはこのサンプルを使って見てください。 これをアップルスクリプトエディターにコピーしてコンパイル後に M-loop_pub.scptというファイル名で、~/Dropbox/Scripts というフォルダを作って入れておきましょう。 M-loop_pub.scptはスクリプトの読み込みソースでも有りますし、終了後に停止しないタイプのアプリケーション(アプレット)型に保存すると、起動や各種インターフェースのスイッチになるようにデザインしています。
後々各種モジュールを追加して行く形で機能を追加していきましょう。 またAppleScriptはプログラムで使うサブルーティンの事をハンドラという名前で呼ぶのでその名前で呼称してゆきます。
常駐型アプレットM-loop_pubの作成
アップルスクリプトを初めて触る方もおられると思うので、常駐型アプレットの作り方を説明しておきます。
1,メニューバーから書き出すを選択
メニューバーのファイルから書き出すを選択します
2,ファイルフォーマットをアプリケーションにします
ファイルフォーマットのプルダウンメニューをアプリケーションにセット
3,オプションでハンドラの実行後に終了しないをON
4,デスクトップ上のM-loop_pub.appをダブルクリックで起動します
ダブルクリックで起動してみましょう
5,起動後アクセス権の許可ダイアローグが出るので許可をクリック
6,起動した状態でもう一度M-loop_pub.appをクリックして、出てきたダイアローグからプログラムを実行テストするをクリック
起動した状態でもう一度アプリケーションをクリックすると、ダイアローグが出てきます。 プログラムを実行テストするをクリックすると、プログラム選択画面が出てくるのでローカルログを表示を選択して見ましょう。
7,ローカルログの表示を実行してみましょう。選択してOKをクリックします
まとめ
今回はメインの骨組みだけのループスクリプトを作りました。 以降はこのMainLoop内にモジュールを追加してゆく感じですね。