Foltia with AppleScript

Foltia animelockerのトラブルシューティング

常駐型アプレット M-loop_pubの作製

監視プログラムの概要

アップルスクリプトの常駐型アプレットをつかって一定間隔で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}

    --FailSafefalseならチェックなし所定時間経過したら進む。

    --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をクリックします

M-loop_pubのログがterminalでTail -f で表示され、リアルタイムにログがアップデートされるでしょう。 この設定だと50秒おきにテストログ、LogOnConsole({cmt:"Main Loop test", open_:false}) of me が表示される事になります。

まとめ

今回はメインの骨組みだけのループスクリプトを作りました。 以降はこのMainLoop内にモジュールを追加してゆく感じですね。