指定のWebページ(URL)の最終更新日時(Last Modified Date)を取得するAppleScriptです。
AppleScriptそのものにWebの最終更新日時を取得する関数や機能はありません。はい、おしまい。
……というのでは、AppleScriptの本質がぜんぜん分かっていないね、ということになります。AppleScriptは「それができるアプリケーション」(など)に依頼を出すのが処理スタイルだからです。
まずは、Safariにコマンドを投げて実行するスタイル。
AppleScript名:Safariのdo javascriptコマンドで最終更新日時を取得 |
— Created 2018-08-17 by Takaaki Naganoya — 2018 Piyomaru Software tell application "Safari" tell front document set dRes to (do JavaScript "document.lastModified;") end tell end tell |
だいたいは、これで手を打つでしょう。ただし、最近のmacOSではセキュリティ強化のためにSafariのdo javascriptコマンドがデフォルトでは禁止されているので、Safariで「開発」メニューを表示させたあとに、「開発」メニューの「AppleEventからのJavaScriptを許可」「スマート検索フィールドからのJavaScriptを許可」を実行しておく必要があります(→ 書籍「AppleScript 10大最新技術」P-84)。
Mac AppStore上で配布/販売するアプリケーションの中で処理することを考えると、SafariをコントロールすることをInfo.plist内で宣言しておけばとくに問題はありません。
do javascriptコマンドの実行で一般的にはファイナルアンサーなのですが、なぜでしょう。リアルタイム日付が返ってくるパターンが多いです。
次は、shellのcurlコマンドを呼び出すスタイルです。指定URLのレスポンスヘッダーを出力させられるので、これを検索して出力します。ただ、YouTubeをはじめとするWebサイトでこの最終更新日を返してこないので、これでもダメな時はダメです。
AppleScript名:curlコマンドで最終更新日時を取得 |
— Created 2018-08-17 by Takaaki Naganoya — 2018 Piyomaru Software tell application "Safari" tell front document set aURL to URL end tell end tell try set uRes to (do shell script "curl -D – -s -o /dev/null " & aURL & " | grep Date:") on error return false end try |
これも現在日時を返してくるパターンが多いですね。また、噂レベルではあるものの「do shell scriptコマンドは極力使わないほうがいいよ」というお達しがScripter界隈で流れているので、将来的に何かがあるのかもしれません(昔の、ごくごく初期のMac OS XはBSDレイヤーというかBSDコマンド類が、OSインストール時にオプション扱いだったので、そういう未来はあるかもしれない)。
Mac AppStore上で配布/販売するアプリケーションの中で処理するのも、とくに問題はないのですが、今度はネットワーク接続することをあらかじめ宣言しておくのと、httpによる通信を行うことを宣言しておかないとネットワーク接続ができません。
最後の手段。Cocoaを呼び出して自前でWebのレスポンスヘッダーを取得するスタイル。
AppleScript名:Cocoaの機能で最終更新日時を取得 |
— Created 2018-08-17 by Takaaki Naganoya — 2018 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" property NSString : a reference to current application’s NSString property NSLocale : a reference to current application’s NSLocale property NSURLRequest : a reference to current application’s NSURLRequest property NSDateFormatter : a reference to current application’s NSDateFormatter property NSURLConnection : a reference to current application’s NSURLConnection property NSURLRequestUseProtocolCachePolicy : a reference to current application’s NSURLRequestUseProtocolCachePolicy tell application "Safari" tell front document set aURL to URL end tell end tell set aURL to (current application’s |NSURL|’s URLWithString:aURL) set {exRes, headerRes, aData} to checkURLResourceExistence(aURL, 3) of me set aDate to headerRes’s |date| as string set lastUpdateDate to dateFromStringWithDateFormat(aDate, "EEE, dd MMM yyyy HH:mm:ss zzz") of me return lastUpdateDate — 指定URLにファイル(画像など)が存在するかチェック –> {存在確認結果(boolean), レスポンスヘッダー(NSDictionary), データ(NSData)} on checkURLResourceExistence(aURL, timeOutSec as real) set aRequest to (NSURLRequest’s requestWithURL:aURL cachePolicy:(NSURLRequestUseProtocolCachePolicy) timeoutInterval:timeOutSec) set aRes to (NSURLConnection’s sendSynchronousRequest:aRequest returningResponse:(reference) |error|:(missing value)) set dRes to (first item of (aRes as list)) set bRes to (second item of (aRes as list)) if bRes is not equal to missing value then set hRes to (bRes’s allHeaderFields()) set aResCode to (bRes’s statusCode()) as integer else set hRes to {} set aResCode to -1 –error end if return {(aResCode = 200), hRes, dRes} end checkURLResourceExistence –指定形式の日付テキストをAppleScriptのdateオブジェクトに変換 on dateFromStringWithDateFormat(dateString, dateFormat) set dStr to NSString’s stringWithString:dateString set dateFormatStr to NSString’s stringWithString:dateFormat set aDateFormatter to NSDateFormatter’s alloc()’s init() aDateFormatter’s setDateFormat:dateFormatStr aDateFormatter’s setLocale:(NSLocale’s alloc()’s initWithLocaleIdentifier:"en_US_POSIX") set aDestDate to (aDateFormatter’s dateFromString:dStr) return aDestDate as date end dateFromStringWithDateFormat |
結果は3つとも変わりませんでした。Cocoa呼び出しするものも、作り置きしておいたサブルーチンを使いまわしただけなので、作るのに3分もかかっていません。
curlを呼び出すスタイル同様、Mac AppStore上で配布/販売するアプリケーションの中で処理するのもとくに問題はないのですが、httpによる通信を行うことを宣言しておかないとネットワーク接続ができません。
Safariでdo javascriptコマンドを実行するものは、最初にdo javascriptコマンドを実行する設定が必要。curlコマンドはまあそんなもんだろうかと。Cocoaの機能を呼び出す方法は、ここまでやってダメならあきらめがつくというところでしょうか。