Archive for the 'Safari' Category

2017/04/21 Safariの最前面のウィンドウで表示している内容をMacJournalの選択中のjournalに新規エントリを作成して入れ

Safariの最前面のウィンドウで表示しているページのテキストとタイトルで、MacJournalの選択中のJournalに新規エントリを作成するAppleScriptです。

mjournal1.png

さまざまなデータ処理を行うさいのコーパス(例文)を集めるために作成したものです。本来は指定URLをリストで保持しておいて、そこから順次Webページを表示して複数のページを一気に処理するAppleScriptを作ったときに「ついで」に作成。

SafariからWebサイトのテキストを取得するのは、なかなか大変です。

何が大変かといえば、「取得そのもの」ではなく、「取得した内容」が本当に文字化けしていないかどうか、チェックする必要があるということです。とくに、古いWebサイトだと文字コードの指定が不十分で、自動判別できないケースもあります

とりあえず、その処理は省略して(すでに書いてあるので)、MacJournalの中にWebサイトから取得した本文を入れてみることにしました。

すべて自動で連続して作成したときには問題はなかったのですが、「現在表示中のWebサイトの内容を現在選択中のMacJournalのジャーナルに新規エントリに作成」とかいう、1回実行するだけのScriptを走らせてみたところ、予想外の挙動がありました。

選択中のジャーナル(フォルダみたいなもの)の中に新規エントリ(記事)を作成すると、そのエントリへのオブジェクト参照が返ってくることが期待できます。ところが、MacJournalで実行したところ、なぜか以前に作成したエントリに内容が上書きされてしまいました。

おそらく、内部処理のバグだと思うのですが、本来であればID(固有値)が返ってくるべきところでindex(順番で数えた数)が返ってきてしまっている様子。エントリの新規作成時の返り値をそのまま使うとだまされるわけです。

そこで、新規作成エントリが選択中される(selected entry)ことを利用し、その選択中のエントリに対してタイトルと本文を設定することで、新規作成エントリを指定しないで対処しました。

何も考えずに単にObjective-Cの解釈と書き換えを行うだけのAppleScriptObjCのプログラムよりも、出来の悪いGUIアプリケーションを相手に対策を考えることのほうがプログラミングっぽい感じがします。

AppleScript名:Safariの最前面のウィンドウで表示している内容をMacJournalの選択中のjournalに新規エントリを作成して入れる
– Created 2017-04-21 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
–http://piyocast.com/as/archives/4598

–現在選択中のJournalを取得
tell application "MacJournal"
  tell document 1
    set curJournal to selected journal
  end tell
end tell

set titleRes to getPageTitleOfFrontmostWindow() of me
if titleRes = false then return

set textRes to getPageTextOfFrontmostWindow() of me
if textRes = false then return

tell application "MacJournal"
  tell curJournal
    set jRes to make new journal entry –ここで新規作成したentryへの参照を取得するが、どうも固定のIDではなくindexが返ってくるもよう
  end tell
  
  
tell selected entry
    set name to titleRes
    
set plain text content to textRes
  end tell
end tell

on getPageTextOfFrontmostWindow()
  tell application "Safari"
    if (count every window) = 0 then return false
    
tell window 1
      set aProp to properties
    end tell
    
set aDoc to document of aProp
    
set aText to text of aDoc
  end tell
  
return aText
end getPageTextOfFrontmostWindow

on getPageTitleOfFrontmostWindow()
  tell application "Safari"
    if (count every window) = 0 then return false
    
tell window 1
      set aProp to properties
    end tell
    
set aDoc to document of aProp
    
set aText to name of aDoc
  end tell
  
return aText
end getPageTitleOfFrontmostWindow

★Click Here to Open This Script 

2016/09/21 macOS Sierraがついにリリース!

……と、気合をいれるほどの差がないmacOS Sierra(10.12)が登場しました。β版から使っていたので、リリース版の内容もほぼ変わらず、「驚きがないのが驚き」とでも言いたくなるような内容です。

AppleScriptの処理系のバージョンは2.5のまま変更はありません。スクリプトエディタについては、2.9でOS X 10.11の2.8.1から比べると微妙にバージョンアップしています。

sierra1.jpg

このため、useコマンドとOSバージョンの対応は、

 OS X 10.9:AppleScript version “2.3″
 OS X 10.10:AppleScript version “2.4″
 OS X 10.11:AppleScript version “2.5″
 OS X 10.12:AppleScript version “2.5″

となります。

スクリプトエディタが2.9になったからといって、

 ・Cocoaオブジェクトのログ表示
 ・Frontend Processでの強制実行

などが盛り込まれるといったことはありません。ほぼ、2.8から差がない状態です。公式のRelease NotesはまだAppleのWebサイトに掲載されていないので、詳細については不明です。

tabbarjpg.png
▲Sierraの新機能により、スクリプトエディタのウィンドウをタブでまとめられるようになりました

Script Templateに入っているテンプレートに「廃止になったApertureのテンプレが入ったままなのはいかがなものか?」と意見しておきましたが、リリース版でもそのままですね。

WWDC2016での発表において、いろいろ「なくなる」と言われていたものが、実はそのまま残っているという「穏便なアップデート」に変わったように見えます。「見えます」というのは、自分のテスト環境では使えているものの、それがすべてのユーザー環境で同様かどうかは確信が持てないからです。

最たるものが、「システム環境設定」の「セキュリティとプライバシー」>「一般」における「ダウンロードしたアプリケーションの実行許可:」設定で、自分のテスト環境では「すべてのアプリケーションを許可」がイネーブルになっています。あっれえ?(^ー^;;

sierra3.jpg

これが、「開発アカウントを持っているため」なのか、「すべての環境がそうなっている」のか、テスト環境が1つだけなのでなんとも言えません。

あと、AppleScript Studioで作成したメモリー管理方式がGC=ONのアプリケーションも、問題なく起動できています。AdobeのCS6アプリケーションについても、とくに問題なく起動できているという話を聞きます

AFPも廃止になると聞いていたのに、β版のかなり早い段階で復活していました。この分でいくと、HFSも廃止になっているのかいないのか、、、、

sierra2.jpg

そのあたり、WWDC2016正誤表みたいな感じでまとまっていないと、アップデートしていいんだかよくないんだかわかりません。

一方で、iWorkアプリケーション群は久しぶりに大幅なアップデートが行われ、これはβ版のSierraでは評価できなかった内容なので、期待が持てます。iWorkアプリケーションも無償化されたので、もはやOSの一部といっても過言ではありません。

また、Safariがバージョン10になり(これは、OS X 10.11向けにもアップデータが登場)、このあたり……WebコンテンツをGUI Scripting経由で操作しているような処理がそのまま通るのか(WebViewへのオブジェクト階層がOSアップデートのたびにコロコロ変わるので)、確認が必要です。

ひとことに「Safari 10」といっても、OS X 10.10.x、OS X 10.11.x、macOS 10.12.xで、WebViewへのオブジェクト階層やら、実際に見えるWebView内のオブジェクト構成が微妙に違いそう(実際、同じSafari 9.1.xでも10.10.xと10.11.xでは違う)なので、気になるところです。

さらに、Safari 10では「開発」メニュー項目に、

safari10.jpeg

と「リモートオートメーションを許可」なる項目が新設され、これが何を指しているのかさっぱりわかりません(ヘルプにも載ってないし)。 Selenium Web DriverによるWebコンテンツのテストの自動化のための機能のもよう。 → 次期「Safari 10.0」で新しく追加される機能まとめ

あとは、とても期待していた音声認識でAppleScriptワークフローを呼び出す機能ですが、GMの段階で動きがおかしくなっていたので、リリース版もそうなっていると思います。このあたりは、実際に使い物になるまでしばらくアップデートを経過しないとダメだと見ています。

→ Siriをオフにしたら使える感じがします(確認済み)。どっちみち、Sierra+音声コントロールはAirPodsが発売になるまで(自分的には)完全体な環境ではないので、しばし待つつもりです。

comapplefolderactionssetup.jpg

フォルダアクション設定の場所が変わりました。スクリプトメニューに入っていたものが、 /System/Library/CoreServices/Applications/フォルダアクション設定 に。

Automatorのド派手なバグ(ヘルプメニューから飛ぶ先のURLが間違っている、など)を報告して、これは直っていることを確認しました。ただ、OS X 10.11でも同様のバグがあって、前からこの調子だったもよう、、、、

2016/07/16 as item?

US Appleが主催しているML「AppleScript-Users」において、珍しいものを見つけました。MLの内容についてはつねに分類・評価・分析を行い、分類については自動で仕分けを行うロボットScriptが稼働しています。

そこまでやっても、有用な情報は人間の目で見て判別する必要があるわけですが……なにげないやりとりの中に強い違和感が。

list1.png

こう書いて、思い通りにSafariの各Windowのタイトルが文字列で帰ってこないよ的な、初心者レベルな質問がありました。これについては、

list2.png

のように、contents ofで実際の内容を取得してから、nameをとってくるのが「定石」です。

ところが、

list3.png

のように、「as item」といった書き方ができるようで。これはcontents ofと同じ挙動を行う書き方のようです。こんな書き方ができるとは思ってもみませんでした。このケースでは「as text item」も通ります(同じ実行結果に)。

list4.png

実行速度を計測してみたところ、誤差範囲内でとくに速度は変わりません。

2016/05/18 Security Update 2016-003でOS X 10.10.5もSafari 9.1.1に

昨日のOS X 10.11.5アップデートに引き続き、OS X 10.10.5にもSecurity Updateがリリースされました。

Safariのバージョンも同様にv9.1.1となり、「開発」メニューの「Apple EventsからのJavaScriptを許可」が新設され、デフォルト設定でのAppleScriptからのdo javascriptコマンドの実行が抑止されるようになりました。

AppleScriptからのコントロールを行う場合には、あらかじめこの「Apple EventsからのJavaScriptを許可」にチェックを入れておく必要があります。

2016/05/17 OS X 10.11.5+Safari 9.1.1、新たなAS制限機能が増える

本日、OS X 10.11.5が正式リリースされました。OS X 10.11, El Capitanの最終リリースということになるのでしょう。OS X 10.12がWWDCで発表になり(多分)、2016年10月ごろにリリースになるというのが通例のスケジュールです。

OS X 10.11.5およびSafari 9.1.1では、AppleScript的には大きな変化を経験することになります。

4ac2e0d2-5af0-4a5c-88e6-7811e4b4fe71.jpg

いままで野放図にSafariをdo javascript命令でこづきまわしていましたが、この機能がデフォルトではオフになります。

fb082ac7-6e16-482b-a542-1147a9d548b1.jpg

Safariの「環境設定」>「詳細」で「メニューバーに”開発”メニューを表示」コマンドを実行して「開発」メニューを表示させ、「開発」メニューの「Apple EventsからのJavaScriptを許可」を実行してはじめてdo javascript命令が有効になります。

# 1回実行すれば、その状態が維持されます

このため、Safariでdo javascript命令を使って処理を行う場合には、無難なコマンドを最初に実行してエラーが発生しないかどうかを確認し、エラー発生時には「Apple EventsからのJavaScriptを許可」を実行してもらうようにダイアログを出して実行終了するよう、処理を追加すべきでしょう。

2016/03/13 AppleScriptからWebアプリを操作する場合に用いるWebブラウザは?

Mac系の会合で質問がありました。

「AppleScriptから、Webブラウザに表示されているボタンなどを操作してさまざまなWebアプリを操作できることはわかったが、その際にWebブラウザは何を使うべきなのか?」

script_webbrowser.png

とりあえずの最低条件は、「AppleScript用語辞書を備えているWebブラウザ」ということです。WindowやDocumentをopenしたりcloseでき、その中のTabなどにアクセスでき、URLを設定したり取得したり、ページ内のソースを取得できたりというひととおりの操作ができることが条件です。

sleipnir.png
Sleipnir 4.5.1にはAppleScript用語辞書が入っているものの、実装を間違っているらしくScript Editorでオープンすると真っ白な用語辞書が表示される(直接飲み会でF社の方に報告済み、、、なんですけど、、、、)

FireFoxにもAppleScript用語辞書が入ってはいるものの、肝心の「do javascript」命令がないので、「これで何をしろと??」という状態です。Vivaldiも同様に「do javascript」命令がないので、こうした用途には使えません。

次に、「GUI Scriptingで操作するのに問題がないこと」という条件がつきます。 Webコンテンツを操作するには、JavaScript経由でアクセスしたり、GUI Scriptingでアクセスしたりします。これで脱落するものはありません。だいたいは大丈夫です。

そして、「Webブラウザ独自のアプリストアなどの仕組みによって、予期しないダイアログ表示などが行われないこと」「アップデート通知でいきなり終了したりしないこと」というあたりで、Google Chromeが怪しくなってきます。

結局、こうした用途にOS X標準装備のSafari以外のWebブラウザを使うこと自体がリスキーなので、Safariを使ってくださいという話になります。User AgentでSafari以外のものを使うことがリスキー(銀行のサイトへのアクセスなどで不安が、、、)なので、かさねがさねSafari以外のものを使うことが考えられません。

最近では、Mac miniなどをAppleScript実行専用のロボットとして設定すると、まっさらな状態のOS X環境では、知らないうちに勝手にiTunesを起動されて困ります。iTunes Helperなどのアプリケーションのプロセスはみられませんが、勘弁してほしいところです。

2016/02/28 Safariの履歴を読んでトップ10をテキストで出力する

SafariのHistory.plistを読み込んで、アクセス回数のトップ10をテキスト出力するAppleScriptです。

Safari 9.1+OS X 10.11環境を前提としています。plistの内容については、Safariのバージョンごとに変更が加わってもおかしくないので、メジャーバージョンアップ時には動作確認する必要があることでしょう。

他のアプリケーションの.plistファイルにアクセスするのはかなり野蛮な処理ですが(Sandbox環境では許可されない)、場合によっては有用なこともあるでしょう。

ちなみに、Scriptの実行例はサブマシン(MacBook Air 2011)で実行したものです。

AppleScript名:Safariの履歴を読んでトップ10をテキストで出力する
– Created 2016-02-27 by Takaaki Naganoya
– Piyomaru Software 2016
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set libPath to (POSIX path of (path to library folder from user domain)) & “Safari/History.plist”
set aRec to retDictFromPlist(libPath) of me
set bRecList to aRec’s valueForKeyPath:“WebHistoryDates”

set bArray to sortRecListByLabel(bRecList, “visitCount”, false) of me
set outStr to “”
set aCount to 0

repeat with i from 0 to 100
  set anItem to (bArray’s objectAtIndex:i)
  
  
set aURL to (anItem’s valueForKeyPath:“”) as string
  
set aTitle to (anItem’s valueForKeyPath:“title”) as string
  
set aDispTItle to (anItem’s valueForKeyPath:“displayTitle”) as string
  
set aVisitCount to (anItem’s valueForKeyPath:“visitCount”) as string
  
set redirectURLs to (anItem’s valueForKeyPath:“redirectURLs”) as list
  
set lastVisitedDate to (anItem’s valueForKeyPath:“lastVisitedDate”) as string
  
  
if aURL does not start with “http://piyocast.com” then –自分のところのサイト関連を除外
    set aStr to ((aCount + 1) as string) & “:(” & (aVisitCount as string) & “)” & aTitle & return
    
set outStr to outStr & aStr
    
    
set aCount to aCount + 1
    
if aCount = 10 then exit repeat
    
  end if
  
  
end repeat

return outStr

(*
–>  ”1:(7657)radiko.jp
2:(608)Apple
3:(416)ソフトバンクWi-Fiスポット
4:(156)公式Apple Store(日本)- iPad Air、MacBook Pro、ほかにもたくさん
5:(125)Yahoo! JAPAN
6:(108)Mac整備済製品 - Apple Store (Japan)
7:(54)Apple-Style \”アップルなBlogをリンク\”
8:(44)PC Watch
9:(31)Facebook
10:(28)アップル - Mac Pro

*)

–Read plist
on retDictFromPlist(aPath as text)
  set thePath to current application’s NSString’s stringWithString:aPath
  
set thePath to thePath’s stringByExpandingTildeInPath()
  
set theDict to current application’s NSDictionary’s dictionaryWithContentsOfFile:thePath
  
return theDict
end retDictFromPlist

–リストに入れたレコードを、指定の属性ラベルの値でソート
on sortRecListByLabel(aRecList, aLabelStr, ascendF)
  set aArray to current application’s NSArray’s arrayWithArray:aRecList
  
set sortDesc to current application’s NSSortDescriptor’s alloc()’s initWithKey:aLabelStr ascending:ascendF
  
set sortDescArray to current application’s NSArray’s arrayWithObjects:sortDesc
  
set sortedArray to aArray’s sortedArrayUsingDescriptors:sortDescArray
  
return sortedArray
end sortRecListByLabel

★Click Here to Open This Script 

2015/11/11 Safariでアクセス中のページが設定しているCookieの値を求める

Safariでアクセス中のページ(最前面のページ)で設定しているCookieの値を求めるAppleScriptです。

Safariの各種コントロールを日々行っていますが、Cookieの値を見て処理を分岐できると便利そうなケースがあったため、一応調べてみました。結局、そのページでは有用な情報はCookieから取得することはできなかったのですが、いつかどこかで有用な用途があるのでは? と考え掲載しておきます。

Cookieの値をURLデコードするように変更しました。

AppleScript名:Safariでアクセス中のページが設定しているCookie値を求める
– Created 2015-11-11by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
tell application "Safari"
  set dCount to count every document
  
if dCount = 0 then return
  
  
tell front document
    set aRes to do JavaScript "document.cookie"
  end tell
end tell
set bRes to retURLdecodedStrings(aRes) of me

set cookieList to parseByDelim(bRes, ";") of me
return cookieList

on parseByDelim(aData, aDelim)
  set aStr to current application’s NSString’s stringWithString:aData
  
set aDelimStr to current application’s NSString’s stringWithString:aDelim
  
set delimArray to aStr’s componentsSeparatedByString:aDelimStr
  
set aList to delimArray as list
  
return aList
end parseByDelim

on retURLencodedStrings(aText)
  set aStr to current application’s NSString’s stringWithString:aText
  
set encodedStr to aStr’s stringByAddingPercentEncodingWithAllowedCharacters:(current application’s NSCharacterSet’s alphanumericCharacterSet())
  
return encodedStr as text
end retURLencodedStrings

on retURLdecodedStrings(aURLencodedStr)
  set aStr to current application’s NSString’s stringWithString:aURLencodedStr
  
set aDecoded to aStr’s stringByRemovingPercentEncoding()
  
return aDecoded as text
end retURLdecodedStrings

★Click Here to Open This Script 

2015/11/09 Safariと同じUser Agent文字列を組み立てる

Cocoaの機能を用いて、SafariのUser Agent名が返す文字列と同じものを生成するAppleScriptです。

さまざまな用途のために、AppleScriptでカスタムWebブラウザを作ることがあります。その際に、Safariと同じUser Agent名をWebサーバー側に返すことができるとメリットがあります。正確にいえば、Safariのフリをしてブラウズを行うことで、さまざまなトラブルを回避できます。

取得にあたっては、Safariを起動してSafariからUser Agent名を取るのではなく、WebKitが返すUser Agent情報に(未起動状態の)SafariのバージョンやビルドNo.をつないで生成しています。ビルドNo.についてはメジャーNo.の下3桁だけが出力されており、少々不思議なところですが、実物のSafariと合うように調整しています。

一応本ルーチンが正常に文字列を生成できているかのテストのために、SafariからUser Agent名を取得して比較を行い、同一の文字列が生成できていることを確認しています(実際に使うときには削除)。

AppleScript名:SafariのUser Agent文字を組み立てる
– Created 2015-11-09 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “Webkit”

set aRes to getSafariUserAgentString() of me
–>  ”Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/601.3.6 (KHTML, like Gecko) Version/9.0.2 Safari/601.3.6″

–ほんまもんのSafariからUser Agentを取得してテスト
tell application “Safari”
  tell document 1
    set dRes to do JavaScript “navigator.userAgent”
    
–>  ”Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/601.3.6 (KHTML, like Gecko) Version/9.0.2 Safari/601.3.6″
  end tell
end tell

return (aRes = dRes)
–>  true

–Safariと同じUser Agentの文字列を取得する
on getSafariUserAgentString()
  set aBundle to current application’s NSBundle’s bundleWithIdentifier:“com.apple.Safari”
  
set aVer to (aBundle’s infoDictionary()’s objectForKey:“CFBundleShortVersionString”) as text
  
–>  ”9.0.2″
  
  
set aBuildNo to (aBundle’s infoDictionary()’s objectForKey:“CFBundleVersion”) as text
  
–>  ”11601.3.6″
  
set {v1, v2, v3} to parseVersionNumber(aBuildNo) of me
  
set aV1 to current application’s NSString’s stringWithString:v1
  
set bV1 to aV1’s substringFromIndex:2 –3 characters from tail –?????
  
–> “601″
  
  
set bStr to retStrFromArrayWithDelimiter({bV1, v2, v3}, “.”) of me
  
  
set aWebView to current application’s WebView’s alloc()’s init()
  
set aRes to (aWebView’s stringByEvaluatingJavaScriptFromString:“navigator.userAgent”) as text
  
–>  ”Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/601.3.6 (KHTML, like Gecko)”
  
  
return (aRes & ” Version/” & aVer & ” Safari/” & bStr)
  
end getSafariUserAgentString

–バージョン番号文字列からメジャーバージョンを取り出し数値として返す
on parseVersionNumber(a)
  set aStr to current application’s NSString’s stringWithString:a
  
set aRes to (aStr’s componentsSeparatedByString:“.”)
  
set bRes to aRes’s allObjects()
  
return bRes as list
end parseVersionNumber

–リストを指定デリミタをはさんでテキスト化
on retStrFromArrayWithDelimiter(aList, aDelim)
  set anArray to current application’s NSArray’s arrayWithArray:aList
  
set aRes to anArray’s componentsJoinedByString:aDelim
  
return aRes as text
end retStrFromArrayWithDelimiter

★Click Here to Open This Script 

2015/09/20 iPhoneから自宅/会社のMac上のAppleScriptを呼び出すEntangler

以前、Otto’s Antennaという名前で紹介したアプリケーションがバージョンアップして、「Entangler」という名前になっていました。

ちょうど、奥方様の実家のFAXの動作確認をする必要があったので、MacにFAXモデムをつないで、指定の電話番号にFAX出力するAppleScriptを書いて、iPhone上のEntanglerから呼び出してみました。

EntanglerというアプリケーションのMac版をMacにインストールし、iOS版をiPhoneにインストールして、iOS側からMac側の機能を呼び出すというのが、基本的な運用スタイルです(AppleWatch版もあるとは知りませんでした)。

前バージョンであるOtto’s Antennaよりもデザインがよくなって、iOSデバイスから操作してからの反応が速くなっていました。EntanglerはAppleScriptのほかにもAutomatorアクションやshell scriptなども実行できるそうです(AppleScriptしかテストしていないですけれども)。

Scriptを実行するMacはSleepせずに、ネットワーク(LAN/WiFi)に接続した状態にしておく必要があります。

print1.png
▲MacBook ProにUSRoboticsのUSB FAX Modem(OS X 10.10.5でも使える)をつなぎ、Sleepしないようにしてスタンバイ

print2.png
▲FAX送信元の電話番号に「ps-ax」と設定(最初に入っていた状態そのまま)

print3.png
▲Mac上のEntanglerにFAX送信するAppleScriptを登録

AppleScript名:print_a_fax
– Created 2015-09-20 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”

property aPrinter : “USB Modem”
property targFaxNum : “03-XXXX-XXXX”

tell application “Safari”
  tell front document
    set aPrintSetting to {copies:1, starting page:1, ending page:9999, target printer:aPrinter, fax number:targFaxNum}
    
print with properties aPrintSetting without print dialog
  end tell
end tell

★Click Here to Open This Script 

print4.jpg
▲iPhone上のEntanglerを起動して、「print_a_fax」Scriptを実行

img_3127_resized.png
▲FAX受信中(「ps-ax」と通知が出ている)

63db476c-a6a1-4a82-8650-c79152570edd_resized.png
▲FAX受信中…

ptint0.png
▲Scriptの実行が終了すると、Macの通知センターに通知が表示される

bb1fb10f-5f86-43ed-bd72-fed8ec168e61_resized.png
▲確認のためにFAXで印刷したYahoo!のトップページ。印刷が途切れているのは、本来A4用紙が必要なところに無理やり別のサイズ(たぶんB5)の紙を突っ込んだため

2015/08/07 ASOCでSafariのダウンロードフォルダを取得する

Shaneから、Cocoaの機能を用いてSafariのダウンロードフォルダを求めるAppleScriptです。

やっていることは、Pure AppleScript版とほとんど同じなので、比較するとひじょうに参考になります。

AppleScript名:ASOCでSafariのダウンロードフォルダを取得する
– Created 2015-08-07 by Shane Stanley
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set aRes to getSafariDownloadFolder()
–>  file “Macintosh HD:Users:me:Downloads”

on getSafariDownloadFolder()
  set theID to id of application “Safari” –> “com.apple.Safari”
  
set storedDefaults to (current application’s NSUserDefaults’s standardUserDefaults()’s persistentDomainForName:theID)
  
set downloadFolder to storedDefaults’s valueForKeyPath:“DownloadsPath.stringByExpandingTildeInPath”
  
return downloadFolder as «class furl»
end getSafariDownloadFolder

★Click Here to Open This Script 

2015/07/18 指定のURLのYouTubeのムービーをOffLiberty経由でローカルにダウンロード v2

指定のURLのYouTube上のムービーをOffLiberty経由でダウンロードするAppleScriptのバージョンアップ版です。

yyyeyoyycyaye-2015-07-18-172834.png

先日のScriptを部品として呼び出し、複数のURLのムービーを連続してダウンロードするように処理を行ってみたところ、いくつかのムービーでビデオではなくオーディオのファイルがダウンロードされておりました。

OffLivertyサイト側が対策したのか、あるいは複数回リクエストすると挙動が変わるのか、普通にリクエストしただけではオーディオファイルのリンクが帰ってくるようになっていました。

OffLivertyのサイトがデータ処理結果を返すパターンには、まだ自分が遭遇していないようなケースもあるかもしれないので、「以前は動いていたが、最近動かなくなった」といった報告を求めたいところです(GUI Scriptingを有効にする設定をしていなかったとか、そもそもOS X 10.10を使っていないというケース以外で、、、)。

ret_audio.png

そこで、オーディオだけ帰ってきたとおぼしき場合には、「I want video file」のボタンをクリックして作業を継続させるようにしてみました。これで、テキストから与えた複数のYouTube上のビデオファイルをローカルに順次ダウンロードできるようになりました。

AppleScript名:指定のURLのYouTubeのムービーをOffLiberty経由でローカルにダウンロード v2
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

–ダウンロードしたいYouTubeのムービーのURL
set aURL to “https://www.youtube.com/watch?t=261&v=k95yIQn2Sdg”
set aRes to downloadYoutubeMovieViaOffLiberty(aURL) of me
–> true (OK) / false (NG)

–指定のURLのYouTubeのムービーをOffLiverty経由でローカルにダウンロード(2015/7/18 Version)
on downloadYoutubeMovieViaOffLiberty(aURL)
  
  
set groupList to {6, 3} –Click Link Group in OffLiberty Page
  
  
–OffLibertyの呼び出しブックマークレット
  
set jsText to “var title = window.location.href;
  if (title.indexOf(’http://offliberty.com’) == 0) { (function(){ location.href=’http://offliberty.com/#bookmarklet’; })(); }
  else { (function(){ window.open(’http://offliberty.com/#’+encodeURIComponent(location.href)); })(); }”

  
  
tell application “Safari”
    close every document
  end tell
  
  
  
tell application “Safari”
    make new document with properties {URL:aURL}
    
delay 1
    
do JavaScript jsText in document 1
    
activate
  end tell
  
  
tell current application
    delay 10
  end tell
  
  
–delay後に実行しないとHTML Viewへの参照が取得できなかった(要注意ポイント)
  
set aHTMLView to retSafariHTMLViewReference() of me
  
  
tell application “Safari”
    activate
  end tell
  
  
  
set hitF to false
  
  
repeat with aCount from 1 to 1000
    
    
tell current application
      delay 5
    end tell
    
    
set aTitle to “”
    
repeat with ii in groupList
      
      
set jj to contents of ii
      
      
tell application “System Events”
        tell aHTMLView
          
          
tell group jj –1回変換したものはサイト側でキャッシュしているようなのでループ(6–>3)で対応
            tell UI element 1
              try
                set aTitle to title
              end try
            end tell
          end tell
          
          
if (jj = 3 and aTitle = “Right-click here and ’Save link as…’”) then
            –オーディオファイルをダウンロードさせようとして、ビデオを直接ダウンロードさせない場合の対応
            
tell group 4
              click button 1 –”I want video file”ボタンをクリック
              
              
tell current application
                delay 5
              end tell
              
            end tell
          else if jj = 6 and aTitle = “Right-click here and ’Save link as…’” then
            set hitF to true
            
tell group jj
              tell UI element 1
                click –Download by clicking link
                
                
tell current application
                  delay 5
                end tell
                
                
return hitF
              end tell
            end tell
            
          end if
          
        end tell
      end tell
      
    end repeat
    
  end repeat
  
  
return hitF
  
end downloadYoutubeMovieViaOffLiberty

–SafariのWebViewへのGUI Scripting的な参照を取得する
on retSafariHTMLViewReference()
  
  
set aRes to detectSafariWindow1Status() of me
  
if aRes = false then return false
  
  
tell application “Safari”
    set aVer to version
  end tell
  
  
set majorVer to retMajorVersionNumber(aVer as string) of me
  
  
if majorVer 9 then
    set aRes to getRefOverSafari9() of me
  else
    set aRes to getRefUnderSafari8() of me
  end if
  
  
return aRes
  
end retSafariHTMLViewReference

–Safari 9 Betaに対応
on getRefOverSafari9()
  tell application “System Events”
    tell process “Safari”
      tell window 1
        return UI element 1 of scroll area 1 of group 1 of group 1 of tab group 1
      end tell
    end tell
  end tell
end getRefOverSafari9

–Safari 8に対応
on getRefUnderSafari8()
  tell application “System Events”
    tell process “Safari”
      
      
set wList to every window
      
set wLen to length of wList
      
if wLen = 0 then return false
      
      
tell window 1
        repeat with i from 1 to 10 –Usually from 1 to 5
          try
            tell group i
              tell UI element 1 of scroll area 1 of group 1 of group 1
                set aProp to role
                
if aProp = “AXWebArea” then
                  return (UI element 1 of scroll area 1 of group 1 of group 1 of group i of window 1 of process “Safari” of application “System Events”)
                end if
              end tell
            end tell
          end try
          
        end repeat
      end tell
      
    end tell
  end tell
end getRefUnderSafari8

–Safariでオープン中のURLのローディング完了を待つ
on page_loaded(timeout_value)
  tell current application
    delay 1
  end tell
  
  
repeat with i from 1 to the timeout_value
    tell application “Safari”
      if (do JavaScript “document.readyState” in document 1) is “complete” then
        return true
      else if i is the timeout_value then
        return false
      else
        tell current application
          delay 1
        end tell
      end if
    end tell
  end repeat
  
return false
end page_loaded

–バージョン番号文字列からメジャーバージョンを取り出し数値として返す
on retMajorVersionNumber(a)
  
  
set aStr to current application’s NSString’s stringWithString:a
  
–> “10.0.1″ (NSString)
  
  
set aRes to (aStr’s componentsSeparatedByString:“.”)
  
–> {”10″,”0″,”1″} (NSArray)
  
  
set bRes to aRes’s firstObject()
  
–> “10″ (NSString)
  
  
set cRes to bRes’s integerValue()
  
–> 10
  
  
return cRes as integer
  
end retMajorVersionNumber

–Window 1が通常のWebページを表示しているかどうか判定
on detectSafariWindow1Status()
  
  
–最前面のWindowの表示状態を取得して「処理対象外」のケースを検出する
  
tell application “Safari”
    –Windowの枚数をかぞえる
    
set wCount to count every window
    
if wCount = 0 then return false –Windowなしの場合には処理対象外
    
    
tell window 1
      set aProp to properties
    end tell
    
  end tell
  
  
  
try
    –Window 1に該当するdocumentを取得する
    
set aDoc to document of aProp
    
    
tell application “Safari”
      tell aDoc
        set bProp to properties
      end tell
    end tell
    
  on error
    –エラーが発生するのは通常ページ「ではない」ものを表示しているため、と判断
    
return false –Displaying pages of iCloud connected devices
    
  end try
  
  
  
tell application “Safari”
    set aURL to (URL of bProp)
  end tell
  
  
  
–「お気に入り」か「Pages of iCloud connected devices」表示中なら
  
if aURL = “favorites://” or aURL = missing value then
    return false
  end if
  
  
  
return true
  
end detectSafariWindow1Status

★Click Here to Open This Script 

2015/07/16 指定のURLのYouTubeのムービーをOffLiberty経由でローカルにダウンロード

指定のURLのYouTube上のムービーをOffLiberty経由でダウンロードするAppleScriptです。

ab58f773-fd6d-4e02-8054-c54031f24d91.jpg

a6f92604-4a92-4a35-8bc6-4773ae596f1e.jpg

4d180b9b-786f-4195-a4e8-55968aa7aded.jpg

GUI Scriptingを使用しているため、システム環境設定の「セキュリティとプライバシー」>「アクセシビリティ」で実行するプログラム(たぶんScript Editor)にあらかじめ実行許可を与えておく必要があります。

アーケードゲーム「戦場の絆」のリプレイムービー(5分ぐらい)をローカルにダウンロードする目的で作成したので、それよりも長い時間のものについては修正する必要があるかもしれません。

dl_movie.png

また、OffLibertyのサービスが止まったら動作できません。OffLibertyのサイトの応答時間が著しく伸びたような場合にも想定どおりには処理できません。トラブルへの対応を行うために「サイト自体の応答がなかったらエラーにする」「所定の応答待ち時間を超えたらエラーにする」処理が必要になることでしょう。

OffLibertyのサイトにBookmarkletが置いてあったので、これを解析してローカルからSafariのdo javascriptコマンドで実行できるように書き換えてみました。

BookmarkletのJavaScriptはたいした処理を行っていないので、処理内容をAppleScriptに完全に書き換えてしまうことも可能です。

AppleScript名:指定のURLのYouTubeのムービーをOffLiberty経由でローカルにダウンロード.scpt
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

–ダウンロードしたいYouTubeのムービーのURL
set aURL to “https://www.youtube.com/watch?v=OPF2f8HRrmQ&feature=youtu.be”
set aRes to downloadYoutubeMovieViaOffLiberty(aURL) of me
–> true (OK) / false (NG)

–指定のURLのYouTubeのムービーをOffLiverty経由でローカルにダウンロード
on downloadYoutubeMovieViaOffLiberty(aURL)
  
  
set groupList to {6, 3} –Click Link Group in OffLiberty Page
  
  
–OffLibertyの呼び出しブックマークレット
  
set jsText to “var title = window.location.href;
  if (title.indexOf(’http://offliberty.com’) == 0) { (function(){ location.href=’http://offliberty.com/#bookmarklet’; })(); }
  else { (function(){ window.open(’http://offliberty.com/#’+encodeURIComponent(location.href)); })(); }”

  
  
tell application “Safari”
    close every document
  end tell
  
  
  
tell application “Safari”
    make new document with properties {URL:aURL}
    
delay 1
    
do JavaScript jsText in document 1
    
activate
  end tell
  
  
tell current application
    delay 10
  end tell
  
  
–delay後に実行しないとHTML Viewへの参照が取得できなかった(要注意ポイント)
  
set aHTMLView to retSafariHTMLViewReference() of me
  
  
tell application “Safari”
    activate
  end tell
  
  
  
set hitF to false
  
  
repeat with aCount from 1 to 600
    
    
tell current application
      delay 2
    end tell
    
    
set aTitle to “”
    
repeat with ii in groupList
      
      
set jj to contents of ii
      
      
tell application “System Events”
        tell aHTMLView
          tell group jj –1回変換したものはサイト側でキャッシュしているようなのでループ(6–>3)で対応
            
            
tell UI element 1
              try
                set aTitle to title
              end try
              
              
if aTitle = “Right-click here and ’Save link as…’” then
                set hitF to true
                
click –Download by clicking link
                
return hitF
              end if
            end tell
          end tell
        end tell
      end tell
      
    end repeat
    
  end repeat
  
  
return hitF
  
end downloadYoutubeMovieViaOffLiberty

–SafariのWebViewへのGUI Scripting的な参照を取得する
on retSafariHTMLViewReference()
  
  
set aRes to detectSafariWindow1Status() of me
  
if aRes = false then return false
  
  
tell application “Safari”
    set aVer to version
  end tell
  
  
set majorVer to retMajorVersionNumber(aVer as string) of me
  
  
if majorVer 9 then
    set aRes to getRefOverSafari9() of me
  else
    set aRes to getRefUnderSafari8() of me
  end if
  
  
return aRes
  
end retSafariHTMLViewReference

–Safari 9 Betaに対応
on getRefOverSafari9()
  tell application “System Events”
    tell process “Safari”
      tell window 1
        return UI element 1 of scroll area 1 of group 1 of group 1 of tab group 1
      end tell
    end tell
  end tell
end getRefOverSafari9

–Safari 8に対応
on getRefUnderSafari8()
  tell application “System Events”
    tell process “Safari”
      
      
set wList to every window
      
set wLen to length of wList
      
if wLen = 0 then return false
      
      
tell window 1
        repeat with i from 1 to 10 –Usually from 1 to 5
          try
            tell group i
              tell UI element 1 of scroll area 1 of group 1 of group 1
                set aProp to role
                
if aProp = “AXWebArea” then
                  return (UI element 1 of scroll area 1 of group 1 of group 1 of group i of window 1 of process “Safari” of application “System Events”)
                end if
              end tell
            end tell
          end try
          
        end repeat
      end tell
      
    end tell
  end tell
end getRefUnderSafari8

–Safariでオープン中のURLのローディング完了を待つ
on page_loaded(timeout_value)
  tell current application
    delay 1
  end tell
  
  
repeat with i from 1 to the timeout_value
    tell application “Safari”
      if (do JavaScript “document.readyState” in document 1) is “complete” then
        return true
      else if i is the timeout_value then
        return false
      else
        tell current application
          delay 1
        end tell
      end if
    end tell
  end repeat
  
return false
end page_loaded

–バージョン番号文字列からメジャーバージョンを取り出し数値として返す
on retMajorVersionNumber(a)
  
  
set aStr to current application’s NSString’s stringWithString:a
  
–> “10.0.1″ (NSString)
  
  
set aRes to (aStr’s componentsSeparatedByString:“.”)
  
–> {”10″,”0″,”1″} (NSArray)
  
  
set bRes to aRes’s firstObject()
  
–> “10″ (NSString)
  
  
set cRes to bRes’s integerValue()
  
–> 10
  
  
return cRes as integer
  
end retMajorVersionNumber

–Window 1が通常のWebページを表示しているかどうか判定
on detectSafariWindow1Status()
  
  
–最前面のWindowの表示状態を取得して「処理対象外」のケースを検出する
  
tell application “Safari”
    –Windowの枚数をかぞえる
    
set wCount to count every window
    
if wCount = 0 then return false –Windowなしの場合には処理対象外
    
    
tell window 1
      set aProp to properties
    end tell
    
  end tell
  
  
  
try
    –Window 1に該当するdocumentを取得する
    
set aDoc to document of aProp
    
    
tell application “Safari”
      tell aDoc
        set bProp to properties
      end tell
    end tell
    
  on error
    –エラーが発生するのは通常ページ「ではない」ものを表示しているため、と判断
    
return false –Displaying pages of iCloud connected devices
    
  end try
  
  
  
tell application “Safari”
    set aURL to (URL of bProp)
  end tell
  
  
  
–「お気に入り」か「Pages of iCloud connected devices」表示中なら
  
if aURL = “favorites://” or aURL = missing value then
    return false
  end if
  
  
  
return true
  
end detectSafariWindow1Status

★Click Here to Open This Script 

2015/07/02 SafariのWebViewへのGUI Scripting的な参照を取得する v2

Safariに表示中のWebコンテンツをGUI Scriptingでコントロールする場合に必要となる、WebView部品へのGUI Scripting的な参照を取得するAppleScriptの、Safari v9 Beta対応版です。

Safariを強引に動かすAppleScriptのプログラムは多々あり(銀行口座へのログインから、オンライン通販サイトのデータダウンロード、戦場の絆の会員サイトからの搭乗履歴の取得などなど)、たいへんに差し迫った必要性があり新バージョンのSafariに対応させたものです。ただし、Safari v9自体がまだBeta段階のものなので今後変更になる可能性もあります。

以前のSafariは、お世辞にも綺麗なオブジェクト階層になっていませんでした。ローカライズも一般のCocoaアプリとはほど遠い状態でした。

新しいバージョンでは、より一般的なOS Xのアプリケーションのように(GUI Scriptingで)見えるようになりました。これに合わせています。

AppleScript名:SafariのWebViewへのGUI Scripting的な参照を取得する v2
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set aRes to retSafariHTMLViewReference()
–> UI element 1 of scroll area 1 of group 1 of group 1 of tab group 1 of window "戦場の絆" of application process "Safari" of application "System Events"

–SafariのWebViewへのGUI Scripting的な参照を取得する
on retSafariHTMLViewReference()
  tell application "Safari"
    set aVer to version
  end tell
  
  
set majorVer to retMajorVersionNumber(aVer as string) of me
  
  
if majorVer 9 then
    set aRes to getRefOverSafari9() of me
  else
    set aRes to getRefUnderSafari8() of me
  end if
  
  
return aRes
  
end retSafariHTMLViewReference

–Safari 9 Betaに対応
on getRefOverSafari9()
  tell application "System Events"
    tell process "Safari"
      tell window 1
        return UI element 1 of scroll area 1 of group 1 of group 1 of tab group 1
      end tell
    end tell
  end tell
end getRefOverSafari9

–Safari 8に対応
on getRefUnderSafari8()
  tell application "System Events"
    tell process "Safari"
      
      
set wList to every window
      
set wLen to length of wList
      
if wLen = 0 then return false
      
      
tell window 1
        repeat with i from 1 to 10 –Usually from 1 to 5
          try
            tell group i
              tell UI element 1 of scroll area 1 of group 1 of group 1
                set aProp to role
                
if aProp = "AXWebArea" then
                  return (UI element 1 of scroll area 1 of group 1 of group 1 of group i of window 1 of process "Safari" of application "System Events")
                end if
              end tell
            end tell
          end try
          
        end repeat
      end tell
      
    end tell
  end tell
end getRefUnderSafari8

–Safariでオープン中のURLのローディング完了を待つ
on page_loaded(timeout_value)
  tell current application
    delay 1
  end tell
  
  
repeat with i from 1 to the timeout_value
    tell application "Safari"
      if (do JavaScript "document.readyState" in document 1) is "complete" then
        return true
      else if i is the timeout_value then
        return false
      else
        tell current application
          delay 1
        end tell
      end if
    end tell
  end repeat
  
return false
end page_loaded

–バージョン番号文字列からメジャーバージョンを取り出し数値として返す
on retMajorVersionNumber(a)
  
  
set aStr to current application’s NSString’s stringWithString:a
  
–> "10.0.1" (NSString)
  
  
set aRes to (aStr’s componentsSeparatedByString:".")
  
–> {"10","0","1"} (NSArray)
  
  
set bRes to aRes’s firstObject()
  
–> "10" (NSString)
  
  
set cRes to bRes’s integerValue()
  
–> 10
  
  
return cRes as integer
  
end retMajorVersionNumber

★Click Here to Open This Script 

2015/05/30 Radikoで選局v6

SafariでRadiko.jpをオープンして現在の地域で選局可能なラジオ局の一覧を取得し、一覧から選択したあとに、指定したラジオ局をオープンするAppleScriptです。

自作のAppleScriptObjCのアプリケーション「radiRec」(あくまで個人用)に組み込んで、指定時刻に指定ラジオ局の番組を録音するために作成したものです。

Safariアプリケーション内のWebViewへの参照がいろいろ変わるので、そうした動的な変動を吸収するための機構を追加しました。

GUI Scripting経由でSafariにアクセスしているので、システム環境設定からあらかじめ「アクセシビリティ」から「補助装置にアクセスできるようにする」にチェックを入れておくか、Script実行時にパスワードを入力すると設定を変更します。

radiko41.png

OS X 10.10.3+Safari 8.0.7、場所は東京都内で動作確認してあります(他のエリアではチェックしていません)。

AppleScript名:Radikoで選局v6
–WevViewへの参照を動的に取得するように変更
–OS X 10.10.3(本当は4だけど), Safari 8.0.7, Radiko.jpがプレミアム会員サービスを開始した状態に対応

property waitSec : 10 –Safariのページローディングを待つ時間(秒)

–GUI Scriptingの確認
repeat 3 times
  tell application “System Events”
    set aRes to UI elements enabled
  end tell
  
  
if aRes = false then
    display dialog “GUI Scriptingをオンにしてください。” buttons {“OK”} default button 1
    
tell application “System Events”
      activate
      
set UI elements enabled to true
    end tell
  end if
end repeat
if aRes = false then return

set aList to getRadioStationList() of me
–> {”TBSラジオ”, “文化放送”, “ニッポン放送”, “ラジオNIKKEI第1″, “ラジオNIKKEI第2″, “InterFM”, “TOKYO FM”, “J-WAVE”, “ラジオ日本”, “bayfm78″, “NACK5″, “FMヨコハマ”, “放送大学”}

tell current application
  activate
  
set aRes to choose from list aList
end tell

set aaRes to first item of aRes

selectRadioStation(aaRes) of me –選曲

–SafariでRadikoの選局を行う
on selectRadioStation(aStation)
  activate application “Safari”
  
  
tell application “Safari”
    close every document
    
    
tell document 1
      tell current tab
        open location “http://radiko.jp”
      end tell
    end tell
  end tell
  
  
delay waitSec
  
  
tell application “System Events”
    tell process “Safari”
      
      
set webView to retSafariHTMLViewReference() of me
      
tell webView
        tell list 2
          –ログイン/プレミアム会員登録の箇所が増えたのでlist2に
          
set gList to every group
          
          
set uList to {}
          
          
repeat with i in gList
            tell i
              tell group 1 –ここ、1階層増えた
                set a to UI element 1
                
set statName to title of a
                
set the end of uList to statName
                
if statName = aStation then
                  
                  
click a
                  
                end if
              end tell
            end tell
          end repeat
          
        end tell
        
      end tell
    end tell
  end tell
  
end selectRadioStation

–SafariでRadikoのラジオ局一覧を取得する
on getRadioStationList()
  activate application “Safari”
  
  
tell application “Safari”
    close every document
    
    
tell document 1
      tell current tab
        open location “http://radiko.jp”
      end tell
    end tell
  end tell
  
  
delay waitSec
  
  
tell application “System Events”
    tell process “Safari”
      set webView to retSafariHTMLViewReference() of me
      
tell webView
        
        
tell list 2
          –ログイン/プレミアム会員登録の箇所が増えたのでlist2に
          
set gList to every group
          
          
set uList to {}
          
          
repeat with i in gList
            tell i
              tell group 1 –ここ、1階層増えた
                set a to UI element 1
                
set statName to title of a
                
set the end of uList to statName
              end tell
            end tell
          end repeat
          
          
return uList
          
        end tell
      end tell
      
    end tell
  end tell
  
end getRadioStationList

–SafariのWebViewへのGUI Scripting的な参照を取得する
on retSafariHTMLViewReference()
  tell application “System Events”
    tell process “Safari”
      
      
set wList to every window
      
set wLen to length of wList
      
if wLen = 0 then return false
      
      
tell window 1
        repeat with i from 1 to 10 –Usually from 1 to 5
          try
            tell group i
              tell UI element 1 of scroll area 1 of group 1 of group 1
                set aProp to role
                
if aProp = “AXWebArea” then
                  return (UI element 1 of scroll area 1 of group 1 of group 1 of group i of window 1 of process “Safari” of application “System Events”)
                end if
              end tell
            end tell
          end try
          
        end repeat
      end tell
      
    end tell
  end tell
end retSafariHTMLViewReference

★Click Here to Open This Script 

2015/03/06 ワイルドカードでSafariのダウンロードフォルダ中のファイルを抽出

This AppleScript gets pattern-matched file names in Safari’s Download folder.

Safariのダウンロードフォルダ中のファイルから、与えられたパターンに該当するファイル名のリストを取得するAppleScriptです。

(2015/8/10更新)チルダ付きのパスをechoコマンドで展開していたので、ASOC版のルーチンに差し替えました。

AppleScript名:ワイルドカードでSafariのダウンロードフォルダ中のファイルを抽出 v2
– Created 2015-03-06 by Takaaki Naganoya
– Created 2015-08-10 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

–Get Safari Download Folder Path
set downloadFolder to POSIX path of getSafariDownloadFolder()

–Make Filtering Predicates with WIldcard
set matchPattern to current application’s NSString’s stringWithString:“*.zip” –can use “*” , “?”
set aPredicate to current application’s NSPredicate’s predicateWithFormat_(“SELF like %@”, matchPattern)

–Get every file name in Safari Download Folder
set aFM to current application’s NSFileManager’s defaultManager()
set aConArray to aFM’s contentsOfDirectoryAtPath:downloadFolder |error|:(missing value)

–Filtering with Predicates
set aResArray to aConArray’s filteredArrayUsingPredicate:aPredicate
set aResList to aResArray as list
–>  {”33_fusagamepad_0.3.zip”, “expressmaci.zip”, “filer6.6.zip”, “Glyphs2.1.1-768.zip”, “LinCastor.zip”, “recordpadmaci.zip”, “TessOCR-1.08.zip”, “wavepadmaci.zip”}

–Safariのダウンロードフォルダーを取得する–Updated
on getSafariDownloadFolder()
  set theID to id of application “Safari” –> “com.apple.Safari”
  
set storedDefaults to (current application’s NSUserDefaults’s standardUserDefaults()’s persistentDomainForName:theID)
  
set downloadFolder to storedDefaults’s valueForKeyPath:“DownloadsPath.stringByExpandingTildeInPath”
  
return downloadFolder as «class furl»
end getSafariDownloadFolder

★Click Here to Open This Script 

2015/03/04 Safariでオープン中のURLをリロードする

This AppleScript reloads frontmost Safari window.

本AppleScriptはSafariの最前面のウィンドウをリロード(再読み込み)するものです。

AppleScript名:Safariでオープン中のURLをリロードする
tell application "Safari"
  if (count every document) > 0 then
    do JavaScript "location.reload();" in front document
  end if
end tell

★Click Here to Open This Script 

2014/12/20 SafariのWebViewのGUI Scripting的な参照を取得する

SafariのWebViewのGUI Scriptingからのオブジェクト参照を取得するAppleScriptです。

Safariで表示したWebコンテンツを操作する方法はいくつかあり、

(1)GUI Scripting経由で操作

(2)JavaScript(not JXA)経由で(do javascriptで)操作

だいたい、この両方を組み合わせて実行することになります。

safari_view_menu.png

ただし(1)は、Safariの各種要素(お気に入りバー、サイドバー、タブバー、ステータスバー)の表示状態によって参照要素番号が変わるため、これらの部品の表示・非表示に左右されないように対応しておく必要があります。

こうした柔軟な処理を行うためのサンプルです。ただし、Safariのメジャーバージョンが上がったような場合まではカバーしていません。GUI Scriptingの宿命で、バージョンが上がったら手直しせずに動くことは期待できません。

特定GUI部品以下のすべてのGUI部品を取得する処理(entire contents)もできなくはないのですが、安定性がいまひとつなのと、実行時間が読めないのと、グループ化されている部品には無意味なのと、動的にメニューを生成しているアプリなどでは危ないので避けています。

AppleScript名:SafariのWebViewのGUI Scripting的な参照を取得する
– Created 2014-12-20 by Takaaki Naganoya
– 2014 Piyomaru Software

set aRes to retSafariHTMLViewReference() of me
if aRes = false then return

tell aRes
  properties
end tell
–> {minimum value:missing value, orientation:missing value, position:{0, 85}, class:UI element, role description:”HTML コンテンツ”, accessibility description:”AS Hole(AppleScriptの穴) By Piyomaru Software”, focused:false, title:”", size:{900, -25413}, value:”", help:”", enabled:true, maximum value:missing value, role:”AXWebArea”, entire contents:{}, subrole:missing value, selected:false, name:missing value, description:”AS Hole(AppleScriptの穴) By Piyomaru Software”}

–SafariのWebViewへのGUI Scripting的な参照を取得する
on retSafariHTMLViewReference()
  tell application “System Events”
    tell process “Safari”
      
      
set wList to every window
      
set wLen to length of wList
      
if wLen = 0 then return false
      
      
tell window 1
        repeat with i from 1 to 10 –Usually from 1 to 5
          try
            tell group i
              tell UI element 1 of scroll area 1 of group 1 of group 1
                set aProp to role
                
if aProp = “AXWebArea” then
                  return (UI element 1 of scroll area 1 of group 1 of group 1 of group i of window 1 of process “Safari” of application “System Events”)
                end if
              end tell
            end tell
          end try
          
        end repeat
      end tell
      
    end tell
  end tell
end retSafariHTMLViewReference

★Click Here to Open This Script 

2014/04/07 Radikoで選局 v4

SafariでRadiko.jpをオープンして現在の地域で選局可能なラジオ局の一覧を取得し、一覧から選択したあとに、指定したラジオ局をオープンするAppleScriptです。

自作のAppleScriptObjCのアプリケーション「radiRec」(あくまで個人用)に組み込んで、指定時刻に指定ラジオ局の番組を録音するために作成したものです。

Radiko.jpのプレミアム会員サービス(エリアフリー聴取)がはじまり、Webサイトの構成も若干変更されたため、ラジオ局のリスト作成および選択用のプログラムも変更が必要になりました。

GUI Scripting経由でSafariにアクセスしているので、システム環境設定からあらかじめ「アクセシビリティ」から「補助装置にアクセスできるようにする」にチェックを入れておくか、Script実行時にパスワードを入力すると設定を変更します。

radiko41.png

OS X 10.9.2+Safari 7.0.3、場所は東京都内で動作確認してあります(他のエリアではチェックしていません)。

スクリプト名:Radikoで選局 v4
–東京エリアのRadikoのステーションリストを取得、指定のステーションを選局
–OS X 10.9.2(本当は3だけど), Safari 7.0.3, Radiko.jpがプレミアム会員サービスを開始した状態に対応

property waitSec : 10 –Safariのページローディングを待つ時間(秒)

–GUI Scriptingの確認
repeat 3 times
  tell application “System Events”
    set aRes to UI elements enabled
  end tell
  
  
if aRes = false then
    display dialog “GUI Scriptingをオンにしてください。” buttons {“OK”} default button 1
    
tell application “System Events”
      activate
      
set UI elements enabled to true
    end tell
  end if
end repeat
if aRes = false then return

set aList to getRadioStationList() of me
–> {”TBSラジオ”, “文化放送”, “ニッポン放送”, “ラジオNIKKEI第1″, “ラジオNIKKEI第2″, “InterFM”, “TOKYO FM”, “J-WAVE”, “ラジオ日本”, “bayfm78″, “NACK5″, “FMヨコハマ”, “放送大学”}

tell current application
  activate
  
set aRes to choose from list aList
end tell

set aaRes to first item of aRes

selectRadioStation(aaRes) of me –選曲

–SafariでRadikoの選局を行う
on selectRadioStation(aStation)
  activate application “Safari”
  
  
tell application “Safari”
    close every document
    
    
tell document 1
      tell current tab
        open location “http://radiko.jp”
      end tell
    end tell
  end tell
  
  
delay waitSec
  
  
tell application “System Events”
    tell process “Safari”
      tell window 1
        –おきにいりバーの表示/非表示に対応
        
set countGroup to count every group
        
        
tell group countGroup
          tell group 1
            tell group 1
              tell scroll area 1 –Scrollエリア
                tell UI element 1 –HTMLコンテンツ
                  tell list 2
                    –ログイン/プレミアム会員登録の箇所が増えたのでlist2に
                    
set gList to every group
                    
                    
set uList to {}
                    
                    
repeat with i in gList
                      tell i
                        tell group 1 –ここ、1階層増えた
                          set a to UI element 1
                          
set statName to title of a
                          
set the end of uList to statName
                          
if statName = aStation then
                            
                            
click a
                            
                          end if
                        end tell
                      end tell
                    end repeat
                    
                  end tell
                end tell
              end tell
            end tell
          end tell
        end tell
      end tell
    end tell
  end tell
  
end selectRadioStation

–SafariでRadikoのラジオ局一覧を取得する
on getRadioStationList()
  activate application “Safari”
  
  
tell application “Safari”
    close every document
    
    
tell document 1
      tell current tab
        open location “http://radiko.jp”
      end tell
    end tell
  end tell
  
  
delay waitSec
  
  
tell application “System Events”
    tell process “Safari”
      tell window 1
        –おきにいりバーの表示/非表示に対応
        
set countGroup to count every group
        
        
tell group countGroup
          tell group 1
            tell group 1
              tell scroll area 1 –Scrollエリア
                tell UI element 1 –HTMLコンテンツ
                  tell list 2
                    –ログイン/プレミアム会員登録の箇所が増えたのでlist2に
                    
set gList to every group
                    
                    
set uList to {}
                    
                    
repeat with i in gList
                      tell i
                        tell group 1 –ここ、1階層増えた
                          set a to UI element 1
                          
set statName to title of a
                          
set the end of uList to statName
                        end tell
                      end tell
                    end repeat
                    
                    
return uList
                    
                  end tell
                end tell
              end tell
            end tell
          end tell
        end tell
      end tell
    end tell
  end tell
  
end getRadioStationList

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2013/09/14 Radikoで選局 v3

SafariでRadiko.jpをオープンして現在の地域で選局可能なラジオ局の一覧を取得し、一覧から選択したあとに、指定したラジオ局をオープンするAppleScriptです。

半年に一度ぐらい、コントロール対策なのか、あまり意味のなさそうなWeb改修が行われ、それに対応したものです。ほかには、番組表のローディング時に行うアニメーション表現が増えたので、時間待ちの値を増やしています。

# サイトの微変更ではなく、Safariからの見え方が変わったということかもしれません。少なくとも、10.8上では従来のプログラムではコントロールできていませんでした

GUI Scripting経由でSafariにアクセスしているので、システム環境設定からあらかじめ「アクセシビリティ」から「補助装置にアクセスできるようにする」にチェックを入れておくか、Script実行時にパスワードを入力すると設定を変更します。

自作のAppleScriptObjCのアプリケーション「radiRec」に組み込んで動作を確認しました。AppleScriptObjCのプロジェクトに入れても問題ありません。

OS X 10.8.5+Safari 6.1、場所は東京都内で動作確認してあります(他のエリアではチェックしていません)。

スクリプト名:Radikoで選局 v3
property waitSec : 10 –Safariのページローディングを待つ時間(秒)

–GUI Scriptingの確認
repeat 3 times
  tell application “System Events”
    set aRes to UI elements enabled
  end tell
  
  
if aRes = false then
    display dialog “GUI Scriptingをオンにしてください。” buttons {“OK”} default button 1
    
tell application “System Events”
      activate
      
set UI elements enabled to true
    end tell
  end if
end repeat
if aRes = false then return

set aList to getRadioStationList() of me
–> {”TBSラジオ”, “文化放送”, “ニッポン放送”, “ラジオNIKKEI第1″, “ラジオNIKKEI第2″, “InterFM”, “TOKYO FM”, “J-WAVE”, “ラジオ日本”, “bayfm78″, “NACK5″, “FMヨコハマ”, “放送大学”}

tell current application
  activate
  
set aRes to choose from list aList
end tell

set aaRes to first item of aRes

selectRadioStation(aaRes) of me –選曲

–SafariでRadikoの選局を行う
on selectRadioStation(aStation)
  activate application “Safari”
  
  
tell application “Safari”
    close every document
    
    
tell document 1
      tell current tab
        open location “http://radiko.jp”
      end tell
    end tell
  end tell
  
  
delay waitSec
  
  
tell application “System Events”
    tell process “Safari”
      tell list 1 of UI element 1 of scroll area 1 of group 1 of group 1 of group 2 of window 1
        set gList to every group
        
        
set uList to {}
        
        
repeat with i in gList
          tell i
            tell group 1 –ここ、1階層増えた
              set a to UI element 1
              
set statName to title of a
              
set the end of uList to statName
              
if statName = aStation then
                
                
click a
                
              end if
            end tell
          end tell
        end repeat
        
      end tell
    end tell
  end tell
  
end selectRadioStation

–SafariでRadikoのラジオ局一覧を取得する
on getRadioStationList()
  activate application “Safari”
  
  
tell application “Safari”
    close every document
    
    
tell document 1
      tell current tab
        open location “http://radiko.jp”
      end tell
    end tell
  end tell
  
  
delay waitSec
  
  
tell application “System Events”
    tell process “Safari”
      tell list 1 of UI element 1 of scroll area 1 of group 1 of group 1 of group 2 of window 1
        set gList to every group
        
        
set uList to {}
        
        
repeat with i in gList
          tell i
            tell group 1 –ここ、1階層増えた
              set a to UI element 1
              
set statName to title of a
              
set the end of uList to statName
            end tell
          end tell
        end repeat
        
      end tell
    end tell
  end tell
  
  
return uList
  
end getRadioStationList

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2013/07/12 Safariでオープン中のURLを指定のWindowsのWebブラウザでオープン

Mac上のParallelsの上で動く、Windowsに対してイベントをAppleScriptから(Parallels経由で)投げて、Mac上のSafariで現在オープン中のURLをWindows 8.1Beta上のInternet Explorer 11で開いてみました。

調査したところ「Safariでオープン中のURLをIEでオープンする機能」はParallels Desktop 8(以下、Parallels)の標準機能で持っているらしいのですが、画面上で確認したかぎりでは見つけられませんでした。本Scriptでは、指定すればWindows上のChromeだろうがFireFoxだろうが対応できるので、標準機能よりも高度な処理に発展できます。

Paralles上でWindows 8.1Betaを起動した状態。この状態だと、

para10.png

ユーザーのホームディレクトリに「Applications(Parallels)」というフォルダが存在しており、

para7.png

さらに、その中に各ゲストOSのフォルダが存在。ここにWindows 8.1Betaのフォルダも存在しています。

この中に、各Windowsアプリケーションにイベントを転送するプロキシーアプリケーションが存在しています。もちろん、IE11も。

para11.png

ただし、ここで「Modern Internet Explorer」というWindows StoreアプリのIEも存在しており、これにイベントを投げてもWindows 8.1側でWebブラウザ表示にならない(タイル表示からInternet Explorerを選択すれば、オープンさせた内容を確認することは可能)ので、実用性がいまひとつでした。とっととWeb表示に切り替わってほしいので、Internet Explorerを指定しておきたいところです。

では、Finderに「Windows 8.1 Beta Applications」内の「Internet Explorer」ファイルを取得させればよいわけですが、ここにトンだ落とし穴が。

Finder上でこの「Internet Explorer」アプリの情報を調べてみると……

para12.png

Mac OS Xのローカライズドファイルネームの仕組みを使って、名前の指定を行っていることが分ります。その関係かどうか分りませんが、このディレクトリでAppleScriptからファイル名の収集を行うのにやたらと時間がかかります(MacBook Pro Retinaなのに、SSD上のデータなのに)。

この「Internet Explorer」の情報(Bundle ID)については、AppleScriptの初回実行時のみ取得するようにして、2回目以降はpropertyにキャッシュした内容を利用することにしました(処理速度向上のため)。こういう時間がかかる割に毎回同じ内容が返ってくるような処理結果はキャッシュしておくにかぎります。そういうのを毎回演算するのは、時間の無駄です。エラーが発生した場合にかぎって、再計算すればいいでしょう。

そして、「Internet Explorer」のBundle IDを取得して、open locationのイベントを投げます。すると、Parallelsを経由してWindows 8.1BetaのInternet Explorerにイベントが伝達され、Safariでオープン中のURLがWindows側に表示されます。

para8.png

このScriptを発展させて、指定URLを各バージョンのWindowsの各Webブラウザで一気に表示させるようなAppleScriptに仕上げると、かなり使い勝手がいいでしょう。仮想マシンはメモリーの許す限りいくつでも起動できるので、Windows XPとWindows 7とWinodws 8/8.1の仮想マシンを起動しておき、すべての対象OSのすべてのWebブラウザに一気にイベントを投げるという寸法です。

ただ、RAMが8GBの環境ではいささかつらく、最低でも16GBぐらいはほしいところです。

スクリプト名:Safariでオープン中のURLをWin 8.1のIEでオープンする
property aBundle : “” –バンドルID計算キャッシュ

–Safariの最前面のウィンドウからURLを取得
tell application “Safari”
  set dCount to count every document
  
if dCount = 0 then return
  
  
tell document 1
    set aURL to URL
  end tell
  
  
if aURL = “bookmarks://” then return
  
if aURL = “topsites://” then return
  
end tell

–Windows XPのPowerPointアプリのプロキシーアプリを探す
set homePath to path to home folder from user domain
set homePathStr to homePath as string
set homeParallelsApps to homePathStr & “Applications (Parallels):”
set winXPappPath to homeParallelsApps & “Windows 8.1 Beta Applications:” –このあたり、ユーザーごとにフォルダ名が違うかも

if aBundle = “” then
  tell application “Finder”
    tell folder winXPappPath
      set fList to (every file whose name of it contains “Internet Explorer”) as alias list –ここで、不気味なほど時間がかかる
    end tell
  end tell
  
  
if fList = {} then
    display dialog “Windows 8.1のIEが見つかりません”
    
return
  end if
  
set aPPTapp to contents of first item of fList
  
  
set infoF to info for aPPTapp
  
set aBundle to bundle identifier of infoF
end if

–Windows上のWeb BrowserでURLをオープン
tell application id aBundle
  open location aURL
end tell

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2013/04/05 SafariでRadiko選局を行う 10.6.8+5.1.8版

SafariでRadikoの選局を行うAppleScriptのMac OS X 10.6.8+Safari 5.1.8向けに改修を行ったものです。

OS X 10.8上でSafari 6.0.3を相手にラジオ局選択をできるようにはなったのですが、肝心の自宅ラジオ録音用マシン(Mac mini)はMac OS X 10.6.8で動いているので、ターゲット機に合わせて書き換える必要が出てきました。

仕方なく、UI Browser(のお試し版)を10.6.8のマシンにインストールして、Safari上のWebコンテンツのUIを調べつつ、オブジェクト階層の書き換えを行いました。また、非力なCoreDuo 1.6GHzのマシンに合わせて待ち時間を修正しました。

ちなみに、OS X 10.7.5上ではSafari 6.0.3が動いておりOS X 10.8用のAppleScriptがそのまま動きます。

スクリプト名:SafariでRadiko選局を行う 10.6.8+5.1.8版
–Mac OS X 10.6.8+Safari 5.1.8

property waitSec : 10 –Safariのページローディングを待つ時間(秒)

–GUI Scriptingの確認
repeat 3 times
  tell application “System Events”
    set aRes to UI elements enabled
  end tell
  
  
if aRes = false then
    display dialog “GUI Scriptingをオンにしてください。” buttons {“OK”} default button 1
    
tell application “System Events”
      activate
      
set UI elements enabled to true
    end tell
  end if
end repeat
if aRes = false then return

set aList to getRadioStationList_1068() of me
–> {”TBSラジオ”, “文化放送”, “ニッポン放送”, “ラジオNIKKEI第1″, “ラジオNIKKEI第2″, “InterFM”, “TOKYO FM”, “J-WAVE”, “ラジオ日本”, “bayfm78″, “NACK5″, “FMヨコハマ”, “放送大学”}

tell current application
  activate
  
set aRes to choose from list aList
end tell

set aaRes to first item of aRes

selectRadioStation_1068(aaRes) of me –選局

–SafariでRadikoの選局を行う
on selectRadioStation_1068(aStation)
  activate application “Safari”
  
  
tell application “Safari”
    close every document
    
    
tell document 1
      tell current tab
        open location “http://radiko.jp”
      end tell
    end tell
  end tell
  
  
delay waitSec
  
  
tell application “System Events”
    tell process “Safari”
      tell list 1 of UI element 1 of scroll area 1 of group 1 of group 1 of group 3 of window 1
        set gList to every group
        
        
set uList to {}
        
        
repeat with i in gList
          set j to contents of i
          
tell j
            set a to first item of (every UI element)
            
set statName to title of a
            
            
if statName = aStation then
              tell UI element aStation
                click
                
exit repeat
              end tell
            end if
          end tell
        end repeat
        
      end tell
    end tell
  end tell
  
end selectRadioStation_1068

–SafariでRadikoのラジオ局一覧を取得する
on getRadioStationList_1068()
  activate application “Safari”
  
  
tell application “Safari”
    close every document
    
    
tell document 1
      tell current tab
        open location “http://radiko.jp”
      end tell
    end tell
  end tell
  
  
delay waitSec
  
  
tell application “System Events”
    tell process “Safari”
      tell list 1 of UI element 1 of scroll area 1 of group 1 of group 1 of group 3 of window 1
        set gList to every group
        
        
set uList to {}
        
        
repeat with i in gList
          tell i
            set a to first item of (every UI element)
            
set statName to title of a
            
set the end of uList to statName
          end tell
        end repeat
        
      end tell
    end tell
  end tell
  
  
return uList
  
end getRadioStationList_1068

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2013/04/01 SafariでRadikoの選局を行う v2

SafariでRadiko.jpをオープンして現在の地域で選局可能なラジオ局の一覧を取得し、一覧から選択したあとに、指定したラジオ局をオープンするAppleScriptです。

radi1.png

GUI Scripting経由でSafariにアクセスしているので、システム環境設定からあらかじめ「アクセシビリティ」から「補助装置にアクセスできるようにする」にチェックを入れておくか、Script実行時にパスワードを入力すると設定を変更します。

自作のAppleScriptObjCのアプリケーション「radiRec」に組み込んで動作を確認しました。AppleScriptObjCのプロジェクトに入れても問題ありません。

radirec.png

OS X 10.8.3+Safari 6.0.3、場所は東京都内で動作確認してあります(他のエリアではチェックしていません)。

スクリプト名:SafariでRadikoの選局を行う v2
property waitSec : 5 –Safariのページローディングを待つ時間(秒)

–GUI Scriptingの確認
repeat 3 times
  tell application “System Events”
    set aRes to UI elements enabled
  end tell
  
  
if aRes = false then
    display dialog “GUI Scriptingをオンにしてください。” buttons {“OK”} default button 1
    
tell application “System Events”
      activate
      
set UI elements enabled to true
    end tell
  end if
end repeat
if aRes = false then return

set aList to getRadioStationList() of me
–> {”TBSラジオ”, “文化放送”, “ニッポン放送”, “ラジオNIKKEI第1″, “ラジオNIKKEI第2″, “InterFM”, “TOKYO FM”, “J-WAVE”, “ラジオ日本”, “bayfm78″, “NACK5″, “FMヨコハマ”, “放送大学”}

tell current application
  activate
  
set aRes to choose from list aList
end tell

set aaRes to first item of aRes

selectRadioStation(aaRes) of me –選曲

–SafariでRadikoの選局を行う
on selectRadioStation(aStation)
  activate application “Safari”
  
  
tell application “Safari”
    close every document
    
    
tell document 1
      tell current tab
        open location “http://radiko.jp”
      end tell
    end tell
  end tell
  
  
delay waitSec
  
  
tell application “System Events”
    tell process “Safari”
      tell list 1 of UI element 1 of scroll area 1 of group 1 of group 1 of group 2 of window 1
        set gList to every group
        
        
set uList to {}
        
        
repeat with i in gList
          tell i
            set a to first item of (every UI element)
            
set statName to title of a
            
set the end of uList to statName
            
if statName = aStation then
              
              
click a
              
            end if
          end tell
        end repeat
        
      end tell
    end tell
  end tell
  
end selectRadioStation

–SafariでRadikoのラジオ局一覧を取得する
on getRadioStationList()
  activate application “Safari”
  
  
tell application “Safari”
    close every document
    
    
tell document 1
      tell current tab
        open location “http://radiko.jp”
      end tell
    end tell
  end tell
  
  
delay waitSec
  
  
tell application “System Events”
    tell process “Safari”
      tell list 1 of UI element 1 of scroll area 1 of group 1 of group 1 of group 2 of window 1
        set gList to every group
        
        
set uList to {}
        
        
repeat with i in gList
          tell i
            set a to first item of (every UI element)
            
set statName to title of a
            
set the end of uList to statName
          end tell
        end repeat
        
      end tell
    end tell
  end tell
  
  
return uList
  
end getRadioStationList

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2013/03/10 Safariで指定User Agentで指定URLをオープン

Safariで指定ユーザーエージェント名で、指定のURLをオープンするAppleScriptです。

Safari 6.0.3+OS X 10.8.2で動作確認を行っています。GUI Scriptingを用いているので、あらかじめシステム環境設定の「アクセシビリティ」で「補助装置にアクセスできるようにする」のチェックを入れておいてください。

# GUI側からコントロールしているので、OSおよびSafariのバージョンに依存しています

最初に、ダミーURLをオープンしてから、ユーザーエージェント名を指定して、ターゲットURLをオープンすることになります。

いきなりターゲットのURLをデフォルト設定のままオープンしてしまうと、クッキーなどがデフォルトのブラウザ(Safari)に合わせて書き換えられる可能性があるので、こういう順序で処理させてみました。

スクリプト名:Safariで指定User Agentで指定URLをオープン
–Safari v6.0.3で指定可能なUser Agentの一覧(「その他」で具体的に指定することも可能
set uaList to {“Safari 6.0.3 ― Mac”, “Safari 5.1.7 ― Windows”, “Safari iOS 5.1 ― iPhone”, “Safari iOS 5.1 ― iPod touch”, “Safari iOS 5.1 ― iPad”, “Internet Explorer 9.0″, “Internet Explorer 8.0″, “Internet Explorer 7.0″, “Google Chrome 19.0 ― Mac”, “Google Chrome 19.0 ― Windows”, “Firefox 11.0 ― Mac”, “Firefox 11.0 ― Windows”, “Opera 11.62 ― Mac”, “Opera 11.62 ― Windows”}

–ためしに、リストからUser Agentを選択(普通、こんなかったるい処理はしませんが、動作テスト用)
set aRes to choose from list uaList with prompt “ユーザーエージェントを選択”
if aRes = false then return

set anUserAgent to contents of first item of aRes

set aURL to “http://piyocast.com/as” –オープン対象のURL
set bRes to openAurlBySpecifiedUserAgent(anUserAgent, aURL) of me
–> true(オープンできたとき)
–>false(オープンできなかったとき)

–指定User Agentで指定URLをオープン
on openAurlBySpecifiedUserAgent(aUAstr, aURL)
  
  
–最初にURLをオープンしておいて、あとでURLを変更する
  
set dummyURL to “http://www.google.co.jp” –どこか、適当なページ。ターゲットのURL以外ならどこでもいい? 
  
tell application “Safari”
    try
      make new document with properties {URL:dummyURL}
    on error
      return false
    end try
  end tell
  
  
activate application “Safari”
  
  
tell application “System Events”
    tell process “Safari”
      
      
–指定メニュー項目をクリック
      
repeat 10 times
        try
          click menu item aUAstr of menu 1 of menu item 2 of menu 1 of menu bar item 8 of menu bar 1
        on error
          return false
        end try
        
        
–本当に設定できたかどうか確認
        
set aRes to selected of menu item aUAstr of menu 1 of menu item 2 of menu 1 of menu bar item 8 of menu bar 1
        
if aRes is not equal to false then
          return false
        else
          exit repeat
        end if
        
        
delay 1
        
      end repeat
    end tell
  end tell
  
  
–ひらいておいたウィンドウで指定URLをオープンする
  
tell application “Safari”
    try
      tell document 1
        set URL to aURL
      end tell
    on error
      return false
    end try
  end tell
  
  
return true
  
end openAurlBySpecifiedUserAgent

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2013/03/10 Safariで指定可能なユーザーエージェントのリストを返す

Safariでプリセットで選択可能なユーザーエージェントを取得するAppleScriptです。OS X 10.8.2+Safari 6.0.3上で動作確認しています。

GUI Scriptingを用いているので、あらかじめシステム環境設定の「アクセシビリティ」で「補助装置にアクセスできるようにする」のチェックを入れておいてください。

safari0.png

Safariの「環境設定」>「詳細」で、「メニューバーに”開発”メニューを表示」の項目のチェックをオンにしておくと、メニューバーに「開発」の項目が表示されるようになります(Macユーザーの一般常識)。

この「開発」メニューの「ユーザーエージェント」の下に、Safariがあらかじめ用意しているユーザーエージェントの選択メニューが表示されます。この項目を適宜選択すると、指定ユーザーエージェント名でWebサーバーにアクセスするようになります。

safari1.png

この、Safariがメニューから指定可能なユーザーエージェントの一覧を取得します。

safari2.png

Safariではプリセットのユーザーエージェント名以外にも、「その他」から適宜指定可能なので、別にプリセットのユーザーエージェント名にこだわる必要はありません。

スクリプト名:Safariで指定可能なユーザーエージェントのリストを返す

–Safariでメニューから指定可能なUser Agentのリストを取得する
set uaList to retEnableUserAgentFromSafari() of me
–> {”Safari 6.0.3 ― Mac”, “Safari 5.1.7 ― Windows”, “Safari iOS 5.1 ― iPhone”, “Safari iOS 5.1 ― iPod touch”, “Safari iOS 5.1 ― iPad”, “Internet Explorer 9.0″, “Internet Explorer 8.0″, “Internet Explorer 7.0″, “Google Chrome 19.0 ― Mac”, “Google Chrome 19.0 ― Windows”, “Firefox 11.0 ― Mac”, “Firefox 11.0 ― Windows”, “Opera 11.62 ― Mac”, “Opera 11.62 ― Windows”}

–Safariで指定可能なユーザーエージェントのリストを返す
on retEnableUserAgentFromSafari()
  
  
–除外リスト(This list is for Japanese environment. This depends on each localized menu item string)
  
set exList to {“デフォルト(自動選択)”, “その他…”}
  
  
–activate application “Safari”
  
tell application “System Events”
    tell process “Safari”
      
      
–開発メニューのイネーブルチェック
      
tell menu bar 1
        set tList to title of every menu bar item
      end tell
      
      
if “開発” is not in tList then –(This String is for Japanese environment. This depends on each localized menu item string)
        display dialog “開発メニューがオンになっていません” buttons {“OK”} default button 1 with icon 1
        
return
      end if
      
      
–「開発」>「ユーザーエージェント」
      
tell menu 1 of menu item 2 of menu 1 of menu bar item 8 of menu bar 1
        set t2List to title of every menu item whose title is not “” –セパレーター以外のメニュー項目を取得
      end tell
      
    end tell
  end tell
  
  
set t3List to {}
  
repeat with i in t2List
    set j to contents of i
    
if j is not in exList then
      set the end of t3List to j
    end if
  end repeat
  
  
return t3List
  
end retEnableUserAgentFromSafari

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2013/02/28 Safariでさくらインターネットのサーバーホスティング管理画面にログインしてディスク使用量を取得する

Safariでさくらインターネットのサーバーホスティングの管理画面にログインして、ディスク使用量を取得して、計算を行い、計算内容をダイアログに表示するAppleScriptです。Safari 6.0.3+OS X 10.8.2で動作検証しています。

Webコンテンツに対してDOMアクセス……だけでなく、GUI Scripting経由でもコントロールしています(面倒だったので)。そのため、実行前にシステム環境設定の「アクセシビリティ」で「補助装置にアクセスできるようにする」にチェックを入れておく必要があります。

sakura1.png

この管理画面をオープンして、プログラム中にユーザー名とパスワード(適宜、ご自分の契約しているアカウントの情報を設定してください)を書いておいて(このあたり、池袋の喫茶店で奥方様と待ち合わせをしている間に書いたのでいいかげん。実際には、パスワードを入力させるようにして、キーチェーンから設定情報を取得するようにすべき)実行すると、管理画面にログインしてディスク使用量を取得して計算してクリップボードに計算データを転送したのち、計算式をダイアログ表示します。

昔作ったページのローディング待ちサブルーチンを引っ張り出してきましたが、いまひとつ期待したとおりに動いていない感じがします。そのため、ページローディング待ちをdelay文で時間待ちしてごまかしている状態で、インターネット接続回線の太さを考慮してdelayの数値を増減させてください。ちなみに、掲載リストは有線LANでつないでいる場合の(自分の)設定値です。

sakura2.png

いったん管理画面にログインしたのちに本Scriptを実行すると、一定時間はログイン動作が継続されていますので、何の因果かこのScriptを連続操作するような場合には明示的に「ログアウト」の操作を行ってください。

スクリプト名:Safariで管理画面にログインしてディスク使用量を取得する
set aUsername to “username” –ユーザー名(ドメイン名)
set aPassword to “password” —パスワード

–さくらインターネットのインターネットサーバコントロールパネルのログイン画面
set serverAdminURL to “https://secure.sakura.ad.jp/rscontrol/ms/”

tell application “Safari”
  activate
  
close every window
  
  
open location serverAdminURL
  
  
  
–ページのローディングを待つ
  
delay 2 –適当に変更してください
  
  
set pRes to page_loaded(30) of me
  
if pRes = false then
    display dialog “ページローディングエラー” buttons {“OK”} default button 1
    
return
  end if
  
  
do JavaScript “document.forms[0].elements[’domain’].value=’” & aUsername & “‘” in document 1
  
do JavaScript “document.forms[0].elements[’password’].value=’” & aPassword & “‘” in document 1
  
end tell

–送信ボタンを押してログイン
set cRes to clickSend() of me
if cRes = false then
  display dialog “ページローディングエラー” buttons {“OK”} default button 1
  
return
end if

delay 2 –適当に変更してください

set pRes to page_loaded(30) of me
if pRes = false then
  display dialog “ページローディングエラー” buttons {“OK”} default button 1
  
return
end if

activate application “Safari”
tell application “System Events”
  tell process “Safari”
    –GUI Scripting経由で管理画面の所定の情報を取得する(使用ディスク容量)
    
set a to value of static text 1 of group 8 of UI element 1 of scroll area 1 of group 1 of group 1 of group 2 of window 1 –Web/Mail
    
set b to value of static text 1 of group 10 of UI element 1 of scroll area 1 of group 1 of group 1 of group 2 of window 1 –Database
  end tell
end tell

–ここから下、作っておいた「クリップボードに入っている複数行の数字を足してクリップボードに転送」Scriptをほぼ使い回し

set aList to {a, b}
set outList to {}

repeat with i in aList
  set outItem to “”
  
  
set j to contents of i
  
  
set outItem to retNumChar(j) of me
  
  
if outItem is not equal to “” then
    set the end of outList to outItem
  end if
  
end repeat

if outList = {} then
  display dialog “何も計算する内容はありません” buttons {“OK”} default button 1
  
return
end if

set aSum to 0
repeat with i in outList
  set aSum to aSum + i
end repeat

set dispStr to retArrowText(outList, “ + ”) of me & ” = “ & (aSum as string)
set the clipboard to (aSum as string)

tell application “Safari”
  display dialog dispStr buttons {“OK”} default button 1
end tell

–リストを任意のデリミタ付きでテキストに
on retArrowText(aList, aDelim)
  set aText to “”
  
set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to aDelim
  
set aText to aList as text
  
set AppleScript’s text item delimiters to curDelim
  
return aText
end retArrowText

on retNumChar(testText)
  –AN文字列
  
set ankChar to {“0″, “1″, “2″, “3″, “4″, “5″, “6″, “7″, “8″, “9″, “.”}
  
  
set _testChar to characters of (testText as Unicode text)
  
set outStr to “”
  
  
ignoring case
    repeat with i in _testChar
      set j to contents of i
      
if j is in ankChar then
        set outStr to outStr & j
      end if
    end repeat
  end ignoring
  
  
return outStr
end retNumChar

on getTitleOfURL(aURL)
  tell application “Safari”
    if not (exists document 1) then
      make new document at the beginning of documents
    end if
    
set the URL of the front document to aURL –ローカルあるいはインターネット上のURL
    
    
page_loaded(10) of me
    
set a to do JavaScript “document.title” in document 1
    
return a
  end tell
end getTitleOfURL

on page_loaded(timeout_value)
  delay 2
  
repeat with i from 1 to the timeout_value
    tell application “Safari”
      if (do JavaScript “document.readyState” in document 1) is “complete” then
        return true
      else if i is the timeout_value then
        return false
      else
        delay 1
      end if
    end tell
  end repeat
  
return false
end page_loaded

–フォームの送信ボタンを押す
on clickSend()
  activate application “Safari”
  
tell application “System Events”
    tell process “Safari”
      try
        click button 1 of UI element 1 of row 3 of table 1 of UI element 1 of scroll area 1 of group 1 of group 1 of group 2 of window 1
        
return true
      on error
        return false
      end try
    end tell
  end tell
end clickSend

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2012/11/13 Safari 6で指定のURLをオープンする

Safari 6でAppleScript用語辞書そのものには変更されていなかったものの、新規Windowで指定URLをオープンするやりかたが変更されていたので、まとめてみました。

従来は新規Windowを作るようにしていましたが、v6からは新規documentを作るやり方に変える必要があります。よりシンプルに書けるようになったということで。

Radikoの各ラジオ局のURLを指定してSafariにオープンさせる処理を毎週していたところ、途中(Safari v6.02あたり?)で変わったことに気付きました。

スクリプト名:Safari 6で指定のURLをオープンする
set aURL to “http://piyocast.com/as”
openURLbySafari(aURL) of me

on openURLbySafari(aURL)
  tell application “Safari”
    make new document with properties {URL:aURL}
  end tell
end openURLbySafari

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2012/04/21 Safariの最前面のWindowの内容を1枚もののPDFにレンダリングしてデスクトップへ

Safariでオープン中の最前面のWindowの内容をデスクトップにPDF出力するAppleScriptです。

Web関係の仕事をすると、地味に必要になってくる「指定ページを1枚ものの画像にまとめた」PDF。Keynoteの書類などに貼り付けてページ遷移の説明を行ったりするのは、よくある話です。

Safariの最前面のWindowでオープン中のURLを取得し、CLI Webレンダラー「Wkpdf」でPDFにレンダリング出力します。

safario.png

その際に、ファイル名は日付をもとに生成。1枚ものの「長いPDF」として出力するためにWkpdfのレンダリングオプションを指定してページネーションを抑止したり、背景画像の表示をイネーブルにしたりと、見所はそのぐらいで、あとはたいしたことのないあっさりとした処理ばかりです。

Script Menuに入れて使うと便利です。ただ、使用頻度は人によって個人差がありそうなので、実用性がきわめて高い便利なScriptの割には忘れ去られそうな可能性も(自分でも、作っていたことを忘れていました)。

Wkpdf自体のインストールについては、Terminalからコマンドを叩いて行っておく必要がありますが、たいして難しくないので大丈夫でしょう。

スクリプト名:最前面のWindowの内容を1枚もののPDFにレンダリングしてデスクトップへ
tell application “Safari”
  set wCount to count every window
  
if wCount < 1 then
    display dialog “Windowが存在しません” buttons {“OK”} default button 1
    
return
  end if
  
  
tell window 1
    set aInfo to properties
  end tell
  
  
set aDoc to document of aInfo
  
  
tell aDoc
    set aURL to URL
  end tell
  
end tell

set aFileName to “webOut” & (do shell script “date +%Y%m%d%H%M%S”)
renderURLtoPDF(aURL, aFileName) of me

on renderURLtoPDF(aURL, aFileName)
  set s1Text to “cd ~/Desktop && “
  
set outPath to POSIX path of (path to desktop) & aFileName & “.pdf”
  
  
set s2Text to “wkpdf –source “ & aURL & ” –paginate false –print-background –output “ & outPath
  
  
set sAll to s1Text & s2Text
  
do shell script sAll
end renderURLtoPDF

(*
–指定URLの内容をレンダリングしてPDFに書き出す
on renderURLtoPDF(aURL, aFileName)
  set dDir to POSIX path of (path to desktop from user domain)
  set outFile to dDir & aFileName & “.pdf”
  try
    do shell script “cd /usr/local/bin && /usr/local/bin/coral -f PDF -o ” & quoted form of outFile & ” ” & aURL & ” &”
  on error
    return false
  end try
  –return outFile
end renderURLtoPDF
*)

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2012/04/21 iPhoto, iTunes, Safariアップデートについて

iPhoto 9.2.3、iTunes 10.6.1、Safari 5.1.5の各アップデートが提供されていますが、これらのアプリケーションのAppleScript用語辞書に変更はありません。

2012/03/27 Safari 5.1.5でAppleScript用語辞書に変更なし

本日ソフトウェア・アップデートから配布されたSafari 5.1.5のAppleScript用語辞書を確認したところ、とくに前バージョンとの差異は検出されませんでした。

………………………………Safari 5.1.5で「www.apple.co.jp」を表示させると、ちゃんと「www.apple.com/jp」にリダイレクトされるようですが……目の錯覚でしょうか。それとも、サーバーの転送設定が修正されたのでしょうか。