AppleScript名:2フォルダ間の内容比較 |
— Created 2015-12-22 by Takaaki Naganoya — 2015 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set aFol to (choose folder with prompt "Select Folder A") set bFol to (choose folder with prompt "Select Folder B") set aPath to POSIX path of aFol set bPath to POSIX path of bFol set aFM to current application’s NSFileManager’s defaultManager() set aRes to (aFM’s contentsEqualAtPath:aPath andPath:bPath) as boolean |
月: 2018年3月
2ファイルの内容比較(Binary)
AppleScript名:2ファイルの内容比較(Binary) |
— Created 2016-03-22 by Takaaki Naganoya — 2016 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set aPOSIX to POSIX path of (choose file with prompt "Select File A") set bPOSIX to POSIX path of (choose file with prompt "Select File B") set aDat to current application’s NSMutableData’s dataWithContentsOfFile:aPOSIX set bDat to current application’s NSMutableData’s dataWithContentsOfFile:bPOSIX set aRes to (aDat’s isEqualToData:bDat) as boolean |
2ファイルの内容比較(UTF-8 String)
AppleScript名:2ファイルの内容比較(UTF-8 String) |
— Created 2016-03-22 by Takaaki Naganoya — 2016 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set aPOSIX to POSIX path of (choose file with prompt "Select Text File A") set bPOSIX to POSIX path of (choose file with prompt "Select Text File B") set aStr to current application’s NSString’s stringWithContentsOfFile:aPOSIX encoding:(current application’s NSUTF8StringEncoding) |error|:(missing value) set bStr to current application’s NSString’s stringWithContentsOfFile:bPOSIX encoding:(current application’s NSUTF8StringEncoding) |error|:(missing value) set aRes to (aStr’s isEqualToString:bStr) as boolean |
テキストのパーセント表記を数値に変換する
AppleScript名:テキストのパーセント表記を数値に変換する |
— Created 2018-03-18 by Takaaki Naganoya — 2018 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set aStr to current application’s NSString’s stringWithString:"80%" set aNum to aStr’s intValue() –> 80 set bNum to aStr’s doubleValue() –> 80.0 |
URLとrecordからパラメータつきURLを生成する v3
指定のURLに対して、recordで指定したパラメータつきURLを生成するAppleScriptです。
REST APIを呼び出すときに使っているため、登場頻度がきわめて高いサブルーチンです。OLD Style AppleScriptの機能の範囲内で書くこともできますが、Cocoaの機能を用いたほうが圧倒的に手軽に書ける好例といえます。
AppleScript名:URLとrecordからパラメータつきURLを生成する v3 |
— Created 2016-04-19 by Takaaki Naganoya — Modified 2016-11-12 by Takaaki Naganoya — 2016 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" property NSURLQueryItem : a reference to current application’s NSURLQueryItem property NSMutableDictionary : a reference to current application’s NSMutableDictionary property NSURLComponents : a reference to current application’s NSURLComponents set aBaseURL to "https://slack.com/api/auth.test" set aRec to {token:"aaaa", channel:"ぴよまるソフトウェア"} set aRes to retURLwithParams(aBaseURL, aRec) of me –> "https://slack.com/api/auth.test?token=aaaa&channel=%E3%81%B4%E3%82%88%E3%81%BE%E3%82%8B%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2" on retURLwithParams(aBaseURL as string, aRec as record) set aDic to NSMutableDictionary’s dictionaryWithDictionary:aRec set aKeyList to (aDic’s allKeys()) as list set aValList to (aDic’s allValues()) as list set aLen to length of aKeyList set bLen to length of aValList if aLen is not equal to bLen then return false set qList to {} repeat with i from 1 to aLen set aName to (contents of item i of aKeyList) as string set aVal to (contents of item i of aValList) as string set the end of qList to (NSURLQueryItem’s queryItemWithName:aName value:aVal) end repeat set aComp to NSURLComponents’s alloc()’s initWithString:aBaseURL aComp’s setQueryItems:qList set aURL to (aComp’s |URL|()’s absoluteString()) as text return aURL end retURLwithParams |
USBゲームコントローラーの情報を取得する
MacにUSB接続しているゲームコントローラーの情報を取得するAppleScriptです。
あくまでUSB接続しているコントローラーに限られ、同時にBluetooth接続のゲームコントローラー(PlayStation 3用のDual Shock3)があっても無視されるようです。
AppleScript名:USBゲームコントローラーの情報を取得する |
— Created 2017-03-21 18:47:15 +0900 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "GameController" set aController to current application’s GCController’s controllers() –> (NSArray) {(_GCController) <GCController 0x6080004a2580 vendorName=’USB Game Device’ deviceHash=0xbe8dba5719e63307>} set aCon to aController’s firstObject() if aCon = missing value then return set aGameCon to aCon’s gamepad() –> (_GCMFiGamepadControllerProfile) <_GCMFiGamepadControllerProfile: 0x6000000df870> set aExGameCon to aCon’s extendedGamepad() –> missing value set aMicGameCon to aCon’s microGamepad() –> (_GCMFiGamepadControllerProfile) <_GCMFiGamepadControllerProfile: 0x6000000df870> set aMotion to aCon’s motion() –> missing value set aVendor to aCon’s vendorName() as string –> "USB Game Device" set anAttached to aCon’s isAttachedToDevice() –> false |
Bluetoothデバイスのバッテリー残量を取得 v3
Bluetooth経由でMacに接続しているデバイスのうち、バッテリー残量を取得できるものの情報を取得するAppleScriptです。
# as anythingの解釈違いから「as list of string or string」と展開される部分をmacOS 10.13以降のOSでは誤解されなくなったので、v4として追記してあります
現在Bluetooth経由で接続中のデバイス名一覧を取得し、各名称のデバイスのバッテリー残量情報をSystem Profiler経由で取得します。
ただし、バッテリー残量を取得できているのはApple純正のキーボードとマウスだけで、同じく純正品といってもペアリングしているiPhoneのバッテリー残量は取得できませんし、Bluetoothメニューにバッテリー残量が表示されるAirPodsもこの方法では取得できていません。
サードパーティのデバイス(PlayStation 3のゲームコントローラー)についても確認しましたが、メニューにも残量は出ていませんし、同様に本AppleScriptでもバッテリー残量は取得できません。
あと、プログラムはもっと短くできるような気がとてもします。
AppleScript名:Bluetoothデバイスのバッテリー残量を取得 v3 |
— Created 2018-03-18 by Takaaki Naganoya — 2018 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "IOBluetooth" property NSArray : a reference to current application’s NSArray property NSString : a reference to current application’s NSString property NSPredicate : a reference to current application’s NSPredicate property NSMutableArray : a reference to current application’s NSMutableArray property NSMutableDictionary : a reference to current application’s NSMutableDictionary property NSPropertyListFormat : a reference to current application’s NSPropertyListFormat property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding property NSPropertyListImmutable : a reference to current application’s NSPropertyListImmutable property NSPropertyListSerialization : a reference to current application’s NSPropertyListSerialization set devList to getBTBatteryLifeByNameList() of me return devList –> {{devName:"Takaaki Naganoya のマウス", battPercentage:79}, {devName:"Takaaki Naganoya のキーボード #1", battPercentage:93}} on getBTBatteryLifeByNameList() –Get name of connected devices set aDevNameList to getBTPeripheralsConnected() of me –Get System Profiler information set sRes to do shell script "/usr/sbin/system_profiler SPBluetoothDataType -detailLevel full -xml" set aSource to (readPlistFromStr(sRes) of me) as list set aaList to contents of first item of aSource –Filter System Profiler output set outList to {} set aList to _items of aaList repeat with aDevName in aDevNameList set aName to contents of aDevName repeat with i in aList set aDict to (NSMutableDictionary’s dictionaryWithDictionary:(contents of i)) set aKeyPath to "device_title." & aName set aVal to (aDict’s valueForKeyPath:aKeyPath) as list of string or string set tmpOut to filterDevListByName(aVal) of me as list of string or string if (tmpOut ≠ missing value) and (tmpOut ≠ "") then set the end of outList to {devName:aName, battPercentage:retIntNumFromPercentageString(tmpOut) of me} exit repeat end if end repeat end repeat return outList end getBTBatteryLifeByNameList on retIntNumFromPercentageString(aStr) set aStr to current application’s NSString’s stringWithString:aStr set aNum to aStr’s intValue() return aNum end retIntNumFromPercentageString on filterDevListByName(aVal) set outList to {} repeat with ii in aVal set jj to contents of ii if jj is not equal to missing value then set tmpRec to (current application’s NSDictionary’s dictionaryWithDictionary:jj) set tmpRes to (tmpRec’s valueForKeyPath:"device_batteryPercent") if tmpRes ≠ missing value then return (tmpRes as list of string or string) end if end if end repeat return "" end filterDevListByName –Bluetooth経由で接続されているデバイス名をリストで返す on getBTPeripheralsConnected() set pRes to getBluetoothPowerState() of me if pRes = false then return false set dArray to current application’s IOBluetoothDevice’s pairedDevices() set aRes to my filterRecListByLabel1(dArray, "mIONotification != 0") set dNames to (aRes’s mName) as list return dNames end getBTPeripheralsConnected –stringのplistを読み込んでRecordに on readPlistFromStr(theString) set aSource to NSString’s stringWithString:theString set pListData to aSource’s dataUsingEncoding:(NSUTF8StringEncoding) set aPlist to NSPropertyListSerialization’s propertyListFromData:pListData mutabilityOption:(NSPropertyListImmutable) |format|:(NSPropertyListFormat) errorDescription:(missing value) return aPlist end readPlistFromStr –リストに入れたレコードを、指定の属性ラベルの値で抽出 on filterRecListByLabel(aRecList as list, aPredicate as string) set aArray to NSArray’s arrayWithArray:aRecList set aPredicate to NSPredicate’s predicateWithFormat:aPredicate set filteredArray to aArray’s filteredArrayUsingPredicate:aPredicate set bList to filteredArray as list return bList end filterRecListByLabel –リストに入れたレコードを、指定の属性ラベルの値で抽出 on filterRecListByLabel1(aRecList, aPredicate as string) set aArray to current application’s NSArray’s arrayWithArray:aRecList set aPredicate to current application’s NSPredicate’s predicateWithFormat:aPredicate set filteredArray to aArray’s filteredArrayUsingPredicate:aPredicate return filteredArray end filterRecListByLabel1 –Mac本体のBluetoothのパワー状態を取得 on getBluetoothPowerState() set aCon to current application’s IOBluetoothHostController’s alloc()’s init() set pRes to (aCon’s powerState()) as boolean end getBluetoothPowerState |
「as anything」の部分がmacOS 10.13より前のバージョンでは「as list of string or string」と解釈されてしまいますが、macOS 10.14以降のスクリプトエディタでは「as anyhing」、Script Debuggerでは「as any」と解釈されるため(用語がそれぞれ整備されたため)、「as anything」で書き換えておきました。
「as anything」については、言語仕様の重箱の隅のさらに隅をつついている状態なので、「as {list, string, missing value}」などと、想定できるデータ型を列挙しておいたほうが安全です。でも、このany型のcastはCocoa ObjectからAppleScript Objectの型指定しない変換ができて便利なので、言語仕様上ないと不便です。
AppleScript名:Bluetoothデバイスのバッテリー残量を取得 v4.scpt |
— Created 2018-03-18 by Takaaki Naganoya — 2018 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "IOBluetooth" property NSArray : a reference to current application’s NSArray property NSString : a reference to current application’s NSString property NSPredicate : a reference to current application’s NSPredicate property NSMutableArray : a reference to current application’s NSMutableArray property NSMutableDictionary : a reference to current application’s NSMutableDictionary property NSPropertyListFormat : a reference to current application’s NSPropertyListFormat property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding property NSPropertyListImmutable : a reference to current application’s NSPropertyListImmutable property NSPropertyListSerialization : a reference to current application’s NSPropertyListSerialization set devList to getBTBatteryLifeByNameList() of me return devList –> {{devName:"Takaaki Naganoya のマウス", battPercentage:79}, {devName:"Takaaki Naganoya のキーボード #1", battPercentage:93}} on getBTBatteryLifeByNameList() –Get name of connected devices set aDevNameList to getBTPeripheralsConnected() of me –Get System Profiler information set sRes to do shell script "/usr/sbin/system_profiler SPBluetoothDataType -detailLevel full -xml" set aSource to (readPlistFromStr(sRes) of me) as list set aaList to contents of first item of aSource –Filter System Profiler output set outList to {} set aList to _items of aaList repeat with aDevName in aDevNameList set aName to contents of aDevName repeat with i in aList set aDict to (NSMutableDictionary’s dictionaryWithDictionary:(contents of i)) set aKeyPath to "device_title." & aName set aVal to (aDict’s valueForKeyPath:aKeyPath) as anything set tmpOut to filterDevListByName(aVal) of me as anything if (tmpOut ≠ missing value) and (tmpOut ≠ "") then set the end of outList to {devName:aName, battPercentage:retIntNumFromPercentageString(tmpOut) of me} exit repeat end if end repeat end repeat return outList end getBTBatteryLifeByNameList on retIntNumFromPercentageString(aStr) set aStr to current application’s NSString’s stringWithString:aStr set aNum to aStr’s intValue() return aNum end retIntNumFromPercentageString on filterDevListByName(aVal) set outList to {} repeat with ii in aVal set jj to contents of ii if jj is not equal to missing value then set tmpRec to (current application’s NSDictionary’s dictionaryWithDictionary:jj) set tmpRes to (tmpRec’s valueForKeyPath:"device_batteryPercent") if tmpRes ≠ missing value then return (tmpRes as anything) end if end if end repeat return "" end filterDevListByName –Bluetooth経由で接続されているデバイス名をリストで返す on getBTPeripheralsConnected() set pRes to getBluetoothPowerState() of me if pRes = false then return false set dArray to current application’s IOBluetoothDevice’s pairedDevices() set aRes to my filterRecListByLabel1(dArray, "mIONotification != 0") set dNames to (aRes’s mName) as list return dNames end getBTPeripheralsConnected –stringのplistを読み込んでRecordに on readPlistFromStr(theString) set aSource to NSString’s stringWithString:theString set pListData to aSource’s dataUsingEncoding:(NSUTF8StringEncoding) set aPlist to NSPropertyListSerialization’s propertyListFromData:pListData mutabilityOption:(NSPropertyListImmutable) format:(NSPropertyListFormat) errorDescription:(missing value) return aPlist end readPlistFromStr –リストに入れたレコードを、指定の属性ラベルの値で抽出 on filterRecListByLabel(aRecList as list, aPredicate as string) set aArray to NSArray’s arrayWithArray:aRecList set aPredicate to NSPredicate’s predicateWithFormat:aPredicate set filteredArray to aArray’s filteredArrayUsingPredicate:aPredicate set bList to filteredArray as list return bList end filterRecListByLabel –リストに入れたレコードを、指定の属性ラベルの値で抽出 on filterRecListByLabel1(aRecList, aPredicate as string) set aArray to current application’s NSArray’s arrayWithArray:aRecList set aPredicate to current application’s NSPredicate’s predicateWithFormat:aPredicate set filteredArray to aArray’s filteredArrayUsingPredicate:aPredicate return filteredArray end filterRecListByLabel1 –Mac本体のBluetoothのパワー状態を取得 on getBluetoothPowerState() set aCon to current application’s IOBluetoothHostController’s alloc()’s init() set pRes to (aCon’s powerState()) as boolean end getBluetoothPowerState |
(GET)駅すぱあとAPIで平均待ち時間「バスのみ探索」
ヴァル研究所が提供している、公共交通機関の乗り換え検索アプリケーション「駅すぱあと」のREST APIを呼び出して、バス路線の検索を行うAppleScriptです。
(「47都道府県鉄道路線図」より引用)
掲載の本Scriptをためしてみる場合には、かならずご自分で「駅すぱあとWebサービス スタンダードプラン」90日間無料試用コードを取得してScript末尾にあるハンドラに記入してから実行してください。そのまま実行するとエラーになります。
駅コードで発停留所、着停留所をIDで指定して経路検索を行います。本サンプルでは、関東バスの「中村橋」から、「阿佐ヶ谷駅」までの経路を検索しています。時間については平均待ち時間を適用しているとのこと。
AppleScript名:(GET)駅すぱあとAPIで平均待ち時間バスのみ探索 |
— Created 2018-03-16 by Takaaki Naganoya — 2018 Piyomaru Software use AppleScript version "2.5" –macOS 10.11 or later use scripting additions use framework "Foundation" –http://docs.ekispert.com/v1/api/search/course/bus.html set aURL to "https://api.ekispert.jp/v1/json/search/course/bus" set apiKey to retAccessToken() of me set aRec to {|key|:apiKey, |from|:"45848", |to|:"45507"} –関東バス 「中村橋駅」発、「阿佐ヶ谷」着 set reqURLStr to retURLwithParams(aURL, aRec) of me set aRes to callRestGETAPIAndParseResults(reqURLStr) of me set aRESCode to (responseCode of aRes) as integer if aRESCode is not equal to 200 then return false set aRESHeader to responseHeader of aRes set aRESTres to json of aRes as list of string or string –GET methodのREST APIを呼ぶ on callRestGETAPIAndParseResults(aURL) set aRequest to current application’s NSMutableURLRequest’s requestWithURL:(current application’s |NSURL|’s URLWithString:aURL) aRequest’s setHTTPMethod:"GET" aRequest’s setValue:"gzip" forHTTPHeaderField:"Content-Encoding" set aRes to current application’s NSURLConnection’s sendSynchronousRequest:aRequest returningResponse:(reference) |error|:(missing value) set resList to aRes as list set bRes to contents of (first item of resList) set resStr to current application’s NSString’s alloc()’s initWithData:bRes encoding:(current application’s NSUTF8StringEncoding) set jsonString to current application’s NSString’s stringWithString:resStr set jsonData to jsonString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding) set aJsonDict to current application’s NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value) –Get Response Code & Header set dRes to contents of second item of resList if dRes is not equal to missing value then set resCode to (dRes’s statusCode()) as number set resHeaders to (dRes’s allHeaderFields()) as record else set resCode to 0 set resHeaders to {} end if return {json:aJsonDict, responseCode:resCode, responseHeader:resHeaders} end callRestGETAPIAndParseResults on retURLwithParams(aBaseURL, aRec) set aDic to current application’s NSMutableDictionary’s dictionaryWithDictionary:aRec set aKeyList to (aDic’s allKeys()) as list set aValList to (aDic’s allValues()) as list set aLen to length of aKeyList set qList to {} repeat with i from 1 to aLen set aName to contents of item i of aKeyList set aVal to contents of item i of aValList set the end of qList to (current application’s NSURLQueryItem’s queryItemWithName:aName value:aVal) end repeat set aComp to current application’s NSURLComponents’s alloc()’s initWithString:aBaseURL aComp’s setQueryItems:qList set aURL to (aComp’s |URL|()’s absoluteString()) as text return aURL end retURLwithParams on retAccessToken() return "xxxx_XXxxXXXxxXX" –API Key end retAccessToken |
(GET)駅すぱあとAPIで経路簡易探索(駅名称指定)
ヴァル研究所が提供している、公共交通機関の乗り換え検索アプリケーション「駅すぱあと」のREST APIを呼び出して、駅名から経路検索を行うAppleScriptです。
(「47都道府県鉄道路線図」より引用)
掲載の本Scriptをためしてみる場合には、かならずご自分で「駅すぱあとWebサービス スタンダードプラン」90日間無料試用コードを取得してScript末尾にあるハンドラに記入してから実行してください。そのまま実行するとエラーになります。
駅コードで発駅、経由駅、着駅を指定して経路検索を行います。本サンプルでは、西武池袋線の中村橋駅から、池袋駅を経由して、京急線の羽田空港国内線ターミナル駅までの経路を検索しています。
AppleScript名:(GET)駅すぱあとAPIで経路簡易探索(駅名称指定) |
— Created 2018-03-16 by Takaaki Naganoya — 2018 Piyomaru Software use AppleScript version "2.5" –macOS 10.11 or later use scripting additions use framework "Foundation" –http://docs.ekispert.com/v1/api/search/course.html set aURL to "https://api.ekispert.jp/v1/json/search/course" set apiKey to retAccessToken() of me set aRec to {|key|:apiKey, |from|:"中村橋", |to|:"池袋", via:"羽田空港国内線ターミナル"} –中村橋駅 発、池袋経由、羽田空港国内線ターミナル 着 set reqURLStr to retURLwithParams(aURL, aRec) of me set aRes to callRestGETAPIAndParseResults(reqURLStr) of me set aRESCode to (responseCode of aRes) as integer if aRESCode is not equal to 200 then return false set aRESHeader to responseHeader of aRes set aRESTres to json of aRes as list of string or string –GET methodのREST APIを呼ぶ on callRestGETAPIAndParseResults(aURL) set aRequest to current application’s NSMutableURLRequest’s requestWithURL:(current application’s |NSURL|’s URLWithString:aURL) aRequest’s setHTTPMethod:"GET" aRequest’s setValue:"gzip" forHTTPHeaderField:"Content-Encoding" set aRes to current application’s NSURLConnection’s sendSynchronousRequest:aRequest returningResponse:(reference) |error|:(missing value) set resList to aRes as list set bRes to contents of (first item of resList) set resStr to current application’s NSString’s alloc()’s initWithData:bRes encoding:(current application’s NSUTF8StringEncoding) set jsonString to current application’s NSString’s stringWithString:resStr set jsonData to jsonString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding) set aJsonDict to current application’s NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value) –Get Response Code & Header set dRes to contents of second item of resList if dRes is not equal to missing value then set resCode to (dRes’s statusCode()) as number set resHeaders to (dRes’s allHeaderFields()) as record else set resCode to 0 set resHeaders to {} end if return {json:aJsonDict, responseCode:resCode, responseHeader:resHeaders} end callRestGETAPIAndParseResults on retURLwithParams(aBaseURL, aRec) set aDic to current application’s NSMutableDictionary’s dictionaryWithDictionary:aRec set aKeyList to (aDic’s allKeys()) as list set aValList to (aDic’s allValues()) as list set aLen to length of aKeyList set qList to {} repeat with i from 1 to aLen set aName to contents of item i of aKeyList set aVal to contents of item i of aValList set the end of qList to (current application’s NSURLQueryItem’s queryItemWithName:aName value:aVal) end repeat set aComp to current application’s NSURLComponents’s alloc()’s initWithString:aBaseURL aComp’s setQueryItems:qList set aURL to (aComp’s |URL|()’s absoluteString()) as text return aURL end retURLwithParams on retAccessToken() return "xxxx_XXxxXXXxxXX" –API Key end retAccessToken |
(GET)駅すぱあとAPIでデータバージョンを取得
ヴァル研究所が提供している、公共交通機関の乗り換え検索アプリケーション「駅すぱあと」のREST APIを呼び出して、データのバージョンを求めるAppleScriptです。
本Scriptをためしてみる場合には、かならずご自分で「駅すぱあとWebサービス スタンダードプラン」の試用コードを取得してScript末尾にあるハンドラに記入してから実行してください。そのまま実行するとエラーになります。
AppleScript名:(GET)駅すぱあとAPIでデータバージョンを取得 |
— Created 2018-03-16 by Takaaki Naganoya — 2018 Piyomaru Software use AppleScript version "2.5" –macOS 10.11 or later use scripting additions use framework "Foundation" set aURL to "https://api.ekispert.jp/v1/json/dataversion" set apiKey to retAccessToken() of me set aRec to {|key|:apiKey} set reqURLStr to retURLwithParams(aURL, aRec) of me set aRes to callRestGETAPIAndParseResults(reqURLStr) of me set aRESCode to (responseCode of aRes) as integer if aRESCode is not equal to 200 then return false set aRESHeader to responseHeader of aRes set aRESTres to json of aRes as list of string or string (* {ResultSet:{engineVersion:"201803_04a", Version:{{createType:"Edition", create:"20180304", caption:"知識ベース"}, {createType:"Edition", create:"20180304", caption:"鉄道時刻表"}, {createType:"Date", caption:"JR", createComment:"Now", create:"20180317"}, {createType:"Date", caption:"私鉄", createComment:"Now", create:"20180312"}, {createType:"Edition", caption:"航空時刻表", rangeTo:"20180531", rangeFrom:"20180201", rangeCaption:"有効期間", create:"20180401"}, {createType:"Edition", create:"20180401", caption:"高速・連絡・深夜急行バス"}, {createType:"Edition", create:"20180401", caption:"船"}, {createType:"Date", caption:"得トクきっぷデータ", createComment:"Now", create:"20180201"}, {createType:"HideDay", caption:"住所データ", createComment:"Now", create:"20170101"}}, Copyrights:{companyId:"2", text:"交承 平成25年68号 JRデータの内容は、株式会社交通新聞社発行の「JR時刻表」2018年3月号に基づいています。 この時刻データを無断で転載・複写し、又は紙媒体、電磁媒体その他いかなる媒体に加工することも禁じます。 JRバスデータの内容は、株式会社交通新聞社作成のデータ平成30年3月分に基づいています。この時刻データを無断転載・複写や電磁媒体等に加工することを禁じます。 名鉄バスの情報は、名鉄バス株式会社作成のデータに基づいています。ただし一部のバス停ポール情報は株式会社ヴァル研究所が自らの責任により加工したものです。 ほか、一部の内容は株式会社ヴァル研究所が自らの責任により加工したものです。 on callRestGETAPIAndParseResults(aURL) set aRequest to current application’s NSMutableURLRequest’s requestWithURL:(current application’s |NSURL|’s URLWithString:aURL) aRequest’s setHTTPMethod:"GET" aRequest’s setValue:"gzip" forHTTPHeaderField:"Content-Encoding" set aRes to current application’s NSURLConnection’s sendSynchronousRequest:aRequest returningResponse:(reference) |error|:(missing value) set resList to aRes as list set bRes to contents of (first item of resList) set resStr to current application’s NSString’s alloc()’s initWithData:bRes encoding:(current application’s NSUTF8StringEncoding) set jsonString to current application’s NSString’s stringWithString:resStr set jsonData to jsonString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding) set aJsonDict to current application’s NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value) –Get Response Code & Header set dRes to contents of second item of resList if dRes is not equal to missing value then set resCode to (dRes’s statusCode()) as number set resHeaders to (dRes’s allHeaderFields()) as record else set resCode to 0 set resHeaders to {} end if return {json:aJsonDict, responseCode:resCode, responseHeader:resHeaders} end callRestGETAPIAndParseResults on retURLwithParams(aBaseURL, aRec) set aDic to current application’s NSMutableDictionary’s dictionaryWithDictionary:aRec set aKeyList to (aDic’s allKeys()) as list set aValList to (aDic’s allValues()) as list set aLen to length of aKeyList set qList to {} repeat with i from 1 to aLen set aName to contents of item i of aKeyList set aVal to contents of item i of aValList set the end of qList to (current application’s NSURLQueryItem’s queryItemWithName:aName value:aVal) end repeat set aComp to current application’s NSURLComponents’s alloc()’s initWithString:aBaseURL aComp’s setQueryItems:qList set aURL to (aComp’s |URL|()’s absoluteString()) as text return aURL end retURLwithParams on retAccessToken() return "xxxx_XXxxXXXxxXX" –API Key end retAccessToken |
(GET)駅すぱあとAPIで経路検索
ヴァル研究所が提供している、公共交通機関の乗り換え検索アプリケーション「駅すぱあと」のREST APIを呼び出して、経路検索を行うAppleScriptです。
(「47都道府県鉄道路線図」より引用)
掲載の本Scriptをためしてみる場合には、かならずご自分で「駅すぱあとWebサービス スタンダードプラン」90日間無料試用コードを取得してScript末尾にあるハンドラに記入してから実行してください。そのまま実行するとエラーになります。
駅コードで発駅、経由駅、着駅を指定して経路検索を行います。本サンプルでは、西武池袋線の中村橋駅から、池袋駅を経由して、京急線の羽田空港国内線ターミナル駅までの経路を検索しています。
駅すぱあとAPIのドキュメントを読んだかぎりでは、
①駅コード(ユニークなコード)で検索
②駅名称で検索
③緯度経度情報で検索
④住所情報を検索
⑤地区データで検索
といった検索が可能なようです。まずは、一番重要な駅コードによる検索を調べてみた次第です。
AppleScript名:(GET)駅すぱあとAPIで経路検索 |
— Created 2018-03-16 by Takaaki Naganoya — 2018 Piyomaru Software use AppleScript version "2.5" –macOS 10.11 or later use scripting additions use framework "Foundation" set aURL to "https://api.ekispert.jp/v1/json/search/course/extreme" set apiKey to retAccessToken() of me set aRec to {|key|:apiKey, viaList:"22854:22513:22911"} –中村橋駅 発、池袋経由、羽田空港国内線ターミナル 着 set reqURLStr to retURLwithParams(aURL, aRec) of me set aRes to callRestGETAPIAndParseResults(reqURLStr) of me set aRESCode to (responseCode of aRes) as integer if aRESCode is not equal to 200 then return false set aRESHeader to responseHeader of aRes set aRESTres to json of aRes as list of string or string –GET methodのREST APIを呼ぶ on callRestGETAPIAndParseResults(aURL) set aRequest to current application’s NSMutableURLRequest’s requestWithURL:(current application’s |NSURL|’s URLWithString:aURL) aRequest’s setHTTPMethod:"GET" aRequest’s setValue:"gzip" forHTTPHeaderField:"Content-Encoding" set aRes to current application’s NSURLConnection’s sendSynchronousRequest:aRequest returningResponse:(reference) |error|:(missing value) set resList to aRes as list set bRes to contents of (first item of resList) set resStr to current application’s NSString’s alloc()’s initWithData:bRes encoding:(current application’s NSUTF8StringEncoding) set jsonString to current application’s NSString’s stringWithString:resStr set jsonData to jsonString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding) set aJsonDict to current application’s NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value) –Get Response Code & Header set dRes to contents of second item of resList if dRes is not equal to missing value then set resCode to (dRes’s statusCode()) as number set resHeaders to (dRes’s allHeaderFields()) as record else set resCode to 0 set resHeaders to {} end if return {json:aJsonDict, responseCode:resCode, responseHeader:resHeaders} end callRestGETAPIAndParseResults on retURLwithParams(aBaseURL, aRec) set aDic to current application’s NSMutableDictionary’s dictionaryWithDictionary:aRec set aKeyList to (aDic’s allKeys()) as list set aValList to (aDic’s allValues()) as list set aLen to length of aKeyList set qList to {} repeat with i from 1 to aLen set aName to contents of item i of aKeyList set aVal to contents of item i of aValList set the end of qList to (current application’s NSURLQueryItem’s queryItemWithName:aName value:aVal) end repeat set aComp to current application’s NSURLComponents’s alloc()’s initWithString:aBaseURL aComp’s setQueryItems:qList set aURL to (aComp’s |URL|()’s absoluteString()) as text return aURL end retURLwithParams on retAccessToken() return "xxxx_XXxxXXXxxXX" –API Key end retAccessToken |
(GET)駅すぱあとAPIで駅コード検索
ヴァル研究所が提供している、公共交通機関の乗り換え検索アプリケーション「駅すぱあと」のREST APIを呼び出して、駅名称から「駅すぱあと」内部で利用している駅コードを検索するAppleScriptです。
(「47都道府県鉄道路線図」より引用)
「駅すぱあと」はほぼ日本人なら(とくに首都圏に住んでいると)誰でも知っている、電車をはじめとする公共交通機関の乗り換え情報を検索するアプリケーションです。
本来、AppleScriptと相性の良い処理のはずなのですが、Mac版のアプリケーションが最近は提供されておらず、さらに昔のMac版のアプリケーションもAppleScriptに対応していなかったので、長らく接点がありませんでした。
そんな中、「駅すぱあと」のREST APIが試用できるようになっていることを知り、さっそくサインアップして「駅すぱあとWebサービス スタンダードプラン」90日試用コードを取得してみました。掲載の本Scriptをためしてみる場合には、かならずご自分で試用コードを取得してScript末尾にあるハンドラに記入してから実行してください。そのまま実行するとエラーになります。
ドキュメントもよく整備されており、首をひねるような仕様もなく、日本国内で提供されているREST APIとしては非常によく整理されているといえます。
本来はいきなり経路検索を行いたかったのですが、経路検索を行うのに、駅固有のユニークコードである「駅コード」を調べられないと困るので、まずは駅コードから駅名称を調べたり、駅名称から駅コードを調べるAppleScriptを書いてみました(羽田空港からの帰りのバスの中で)。
これで、MacのExcelやFileMaker Pro、Numbersといったアプリケーションの書類上に入れたデータから経路検索を行なってこれらのアプリケーションのデータに返すことができるようになったわけで、応用範囲はきわめて広いといえます。
AppleScript名:(GET)駅すぱあとAPIで駅コード検索 |
— Created 2018-03-16 by Takaaki Naganoya — 2018 Piyomaru Software use AppleScript version "2.5" –macOS 10.11 or later use scripting additions use framework "Foundation" set aURL to "https://api.ekispert.jp/v1/json/station/light" set apiKey to retAccessToken() of me set aRec to {|key|:apiKey, |name|:"羽田空港国内線ターミナル", type:"train"} set reqURLStr to retURLwithParams(aURL, aRec) of me set aRes to callRestGETAPIAndParseResults(reqURLStr) of me set aRESCode to (responseCode of aRes) as integer if aRESCode is not equal to 200 then return false set aRESHeader to responseHeader of aRes set aRESTres to (json of aRes) –NSDictionaryで返ってくる set staCode to (aRESTres’s valueForKeyPath:"ResultSet.Point.Station.code") as list of string or string –as anything –> 22854 –GET methodのREST APIを呼ぶ on callRestGETAPIAndParseResults(aURL) set aRequest to current application’s NSMutableURLRequest’s requestWithURL:(current application’s |NSURL|’s URLWithString:aURL) aRequest’s setHTTPMethod:"GET" aRequest’s setValue:"gzip" forHTTPHeaderField:"Content-Encoding" set aRes to current application’s NSURLConnection’s sendSynchronousRequest:aRequest returningResponse:(reference) |error|:(missing value) set resList to aRes as list set bRes to contents of (first item of resList) set resStr to current application’s NSString’s alloc()’s initWithData:bRes encoding:(current application’s NSUTF8StringEncoding) set jsonString to current application’s NSString’s stringWithString:resStr set jsonData to jsonString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding) set aJsonDict to current application’s NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value) –Get Response Code & Header set dRes to contents of second item of resList if dRes is not equal to missing value then set resCode to (dRes’s statusCode()) as number set resHeaders to (dRes’s allHeaderFields()) as record else set resCode to 0 set resHeaders to {} end if return {json:aJsonDict, responseCode:resCode, responseHeader:resHeaders} end callRestGETAPIAndParseResults on retURLwithParams(aBaseURL, aRec) set aDic to current application’s NSMutableDictionary’s dictionaryWithDictionary:aRec set aKeyList to (aDic’s allKeys()) as list set aValList to (aDic’s allValues()) as list set aLen to length of aKeyList set qList to {} repeat with i from 1 to aLen set aName to contents of item i of aKeyList set aVal to contents of item i of aValList set the end of qList to (current application’s NSURLQueryItem’s queryItemWithName:aName value:aVal) end repeat set aComp to current application’s NSURLComponents’s alloc()’s initWithString:aBaseURL aComp’s setQueryItems:qList set aURL to (aComp’s |URL|()’s absoluteString()) as text return aURL end retURLwithParams on retAccessToken() return "xxxx_XXxxXXXxxXX" –API Key end retAccessToken |
(GET)駅すぱあとAPIで駅コードから駅名称を取得
ヴァル研究所が提供している、公共交通機関の乗り換え検索アプリケーション「駅すぱあと」のREST APIを呼び出して、「駅すぱあと」内部で利用している駅コードから駅の名称を取得するAppleScriptです。
「駅すぱあと」はほぼ日本人なら(とくに首都圏に住んでいると)誰でも知っている、電車をはじめとする公共交通機関の乗り換え情報を検索するアプリケーションです。
(「47都道府県鉄道路線図」より引用)
本来、AppleScriptと相性の良い処理のはずなのですが、Mac版のアプリケーションが最近は提供されておらず、さらに昔のMac版のアプリケーションもAppleScriptに対応していなかったので、長らく接点がありませんでした。
そんな中、「駅すぱあと」のREST APIが試用できるようになっていることを知り、さっそくサインアップして「駅すぱあとWebサービス スタンダードプラン」90日試用コードを取得してみました。掲載の本Scriptをためしてみる場合には、かならずご自分で試用コードを取得してScript末尾にあるハンドラに記入してから実行してください。そのまま実行するとエラーになります。
「駅すぱあと」のREST APIはドキュメントもよく整備されており、首をひねるような仕様もなく、日本国内で提供されているREST APIとしては非常によく整理されているといえます。
本来はいきなり経路検索を行いたかったのですが、経路検索を行うのに、駅固有のユニークコードである「駅コード」を調べられないと困るので、まずは駅コードから駅名称を調べたり、駅名称から駅コードを調べるAppleScriptを書いてみました(羽田空港からの帰りのバスの中で)。
これで、MacのExcelやFileMaker Pro、Numbersといったアプリケーションの書類上に入れたデータから経路検索を行なってこれらのアプリケーションのデータに返すことができるようになったわけで、応用範囲はきわめて広いといえます。
駅すぱあとAPIのドキュメントについては、1点だけ「format」の説明(結果の取得フォーマットがjsonかXMLかを指定)の説明がわかりづらく、この説明だとformat=jsonといった指定を行なってしまうと思います。
AppleScript名:(GET)駅すぱあとAPIで駅コードから駅名称を取得 |
— Created 2018-03-16 by Takaaki Naganoya — 2018 Piyomaru Software use AppleScript version "2.5" –macOS 10.11 or later use scripting additions use framework "Foundation" set aURL to "https://api.ekispert.jp/v1/json/station" set apiKey to retAccessToken() of me set aRec to {|key|:apiKey, code:"25853"} set reqURLStr to retURLwithParams(aURL, aRec) of me set aRes to callRestGETAPIAndParseResults(reqURLStr) of me set aRESCode to (responseCode of aRes) as integer if aRESCode is not equal to 200 then return false set aRESHeader to responseHeader of aRes set aRESTres to (json of aRes) –NSDictionaryで返ってくる set staCode to aRESTres’s valueForKeyPath:"ResultSet.Point.Station.Name" –> "大阪" –GET methodのREST APIを呼ぶ on callRestGETAPIAndParseResults(aURL) set aRequest to current application’s NSMutableURLRequest’s requestWithURL:(current application’s |NSURL|’s URLWithString:aURL) aRequest’s setHTTPMethod:"GET" aRequest’s setValue:"gzip" forHTTPHeaderField:"Content-Encoding" set aRes to current application’s NSURLConnection’s sendSynchronousRequest:aRequest returningResponse:(reference) |error|:(missing value) set resList to aRes as list set bRes to contents of (first item of resList) set resStr to current application’s NSString’s alloc()’s initWithData:bRes encoding:(current application’s NSUTF8StringEncoding) set jsonString to current application’s NSString’s stringWithString:resStr set jsonData to jsonString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding) set aJsonDict to current application’s NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value) –Get Response Code & Header set dRes to contents of second item of resList if dRes is not equal to missing value then set resCode to (dRes’s statusCode()) as number set resHeaders to (dRes’s allHeaderFields()) as record else set resCode to 0 set resHeaders to {} end if return {json:aJsonDict, responseCode:resCode, responseHeader:resHeaders} end callRestGETAPIAndParseResults on retURLwithParams(aBaseURL, aRec) set aDic to current application’s NSMutableDictionary’s dictionaryWithDictionary:aRec set aKeyList to (aDic’s allKeys()) as list set aValList to (aDic’s allValues()) as list set aLen to length of aKeyList set qList to {} repeat with i from 1 to aLen set aName to contents of item i of aKeyList set aVal to contents of item i of aValList set the end of qList to (current application’s NSURLQueryItem’s queryItemWithName:aName value:aVal) end repeat set aComp to current application’s NSURLComponents’s alloc()’s initWithString:aBaseURL aComp’s setQueryItems:qList set aURL to (aComp’s |URL|()’s absoluteString()) as text return aURL end retURLwithParams on retAccessToken() return "xxxx_XXxxXXXxxXX" –API Key end retAccessToken |
NSSharingService経由でメールを新規作成(作成するだけ、送信しない)
NSSharingServiceを利用してメールを新規作成するAppleScriptです。
仕様上、新規作成するだけで送信は行いません。普通にMail.appをコントロールすればメールの送信は行えるので、単にNSSharingServiceのテストです。
AppleScript名:NSSharingService経由でメールを新規作成(作成するだけ、送信しない) |
— Created 2017-02-23 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "AppKit" set shareItems to {"てすとだよおおおん 2行目 3行目", "よろしくー1 よろしくー2", "Footer?"} set aService to current application’s NSSharingService’s sharingServiceNamed:(current application’s NSSharingServiceNameComposeEmail) aService’s setDelegate:me aService’s setRecipients:{"nobody@piyocast.com"} aService’s setSubject:"試験送信" aService’s performWithItems:shareItems |
指定名称のアプリケーションをフルスクリーン表示
指定名称のアプリケーションをフルスクリーン表示するAppleScriptです。
AppleScript自体とフルスクリーン表示の相性はよくありません。操作対象のGUIアプリケーションとスクリプトエディタ(Script Debuggerでも可)と最低でも2つのウィンドウがオープンしていることが望ましいので、Scriptを書いている最中でフルスクリーン表示というのはありえません。
ただ、運用段階でフルスクリーン表示をしたい、というニーズがないこともないので、やり方を調べておきました。
AppleScript名:指定名称のアプリをフルスクリーン表示 |
— Created 2015-07-29 by Takaaki Naganoya — 2015 Piyomaru Software use AppleScript version "2.4" use scripting additions set a to "Safari" set aRes to dispAppWithFullScreen(a) of me –指定名称のアプリケーション(起動中のもの)をフルスクリーン表示 on dispAppWithFullScreen(applicationName) set appName to returnExactNameOfAnApp(applicationName) if appName = false then return false –指定のアプリがなかった、あるいはアプリケーション名を間違って指定した set pID to id of application appName tell application appName reopen activate end tell tell application "System Events" tell (process 1 whose bundle identifier is pID) set b1List to every button of window 1 whose subrole is "AXFullScreenButton" –Full Screen set b2List to every button of window 1 whose subrole is "AXZoomButton" –Zoom if b1List = {} then set targB to first item of b2List –フルスクリーン表示機能を持たないアプリの場合 else set targB to first item of b1List –フルスクリーン表示機能を持つアプリの場合 end if click targB end tell end tell return true end dispAppWithFullScreen –Displayed Nameでアプリケーション名が与えられた場合に、正しい名称を返す on returnExactNameOfAnApp(aName) tell application "System Events" set ap1List to every process whose name is equal to aName if ap1List = {} then set ap1List to every process whose displayed name is equal to aName if ap1List = {} then return false end if set anApp to contents of first item of ap1List return name of anApp end tell end returnExactNameOfAnApp |
mouseClickを用いて指定座標をクリック
ネット上に転がっていたサンプルコードをかき集めて作ったmouseClick.frameworkを用いて指定座標のクリックを行うAppleScriptです。
# ご注意:マウスカーソルの移動やクリックを行うのは、本来のAppleScriptの処理ではありません
# ご注意:他のマシン上で同じ動作を再現することが(初心者には)難しいため、おすすめしません
強制的なマウスカーソル移動とクリック(プレスともいいますね)は、「仕方なくほかに方法がなくなった場合」の、アプリケーション操作の最終手段です。やらないに越したことはない「必要悪」ともいえます。Automatorの作業記録機能が「クリック座標を記録する」という仕組みで実装されているため、AutomatorからAppleScriptに移ってきたユーザーがその調子で組もうとしてドツボにハマる姿がたまに見られます。
step1: 対象のGUIアプリケーションがAppleScript対応であれば、AppleScript用語辞書を調べて、目的の機能が呼び出せるかを確認する
step2: 対象のGUIアプリケーションの特殊機能(Custom URL Protocolなど)で目的の機能が呼び出せないかを確認する(URL Protocolだと非同期実行なので、あまり当てにならないので役に立たないケース多し)
→ とくに、Maps.appではURL Protocol経由で、しかもCustom URL schemeでもなく、http://maps.apple.comで操作するようになっています
step3: step1,2で目的の機能が呼び出せないことがわかったら、GUI Scripting経由で(メニューやボタンを操作して)呼び出せないかを試す
step4: step3でもどうしても呼び出せない場合に、GUI Scriptingで座標を指定してクリックイベントを送るという操作をためす
step5: ごくまれに、step4でも操作できないアプリケーションがある。AdobeのCreativeアプリケーションはポップアップメニューの内容を毎回プログラムから再生成していたりして、これがGUI Scriptingでも操作できない事態を引き起こす。この段階でマウスの強制移動とクリックの使用が検討される
これまで、古い仕組みを使ってマウスカーソル移動とクリックを行なっていましたが、とうとうmacOS 10.13で動かなくなり(これはバグではなく仕方ない話。OS X 10.6あたりでDeprecatedになったので)、代替手段を探していました。
CGEventRef mousedown = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseDown, point, kCGMouseButtonLeft);
CGEventPost(kCGHIDEventTap, mousedown);
CGEventRef mouseup = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseUp, point, kCGMouseButtonLeft);
CGEventPost(kCGHIDEventTap, mouseup);
こんな感じでカーソル移動とクリックを行なっています。サンプルコードではCGPointでパラメータを受け渡していましたが、AppleScriptから呼びやすいようにNSPointで座標値を受け渡すよう書き換えてみました。
本Framework+AppleScript「mouseClickを用いて指定座標をクリック v2」はmacOS 10.13上で動きます。
–> mouseClick.framework (To ~/Library/Frameworks/)
後日談:
なぜか、CGPostMouseEventの機能はmacOS 10.14でふたたび使えるようになり、macOS 12上でも動作しています。deprecatedとは?
AppleScript名:mouseClickを用いて指定座標をクリック v2 |
— Created 2018-03-10 by Takaaki Naganoya — 2018 Piyomaru Software use AppleScript version "2.4" — Yosemite (10.10) or later use framework "Foundation" use framework "mouseClick" use scripting additions my clickAt(100, 10) on clickAt(newX, newY) set aPoint to current application’s NSMakePoint(newX, newY) current application’s ForceClick’s alloc()’s init()’s click:aPoint end clickAt |
AppleScript名:ASOCでマウスの強制移動とクリック(macOS 10.12まで) |
— Created 2015-10-04 by Takaaki Naganoya — 2015 Piyomaru Software use AppleScript version "2.4" –max version macOS 10.12 use scripting additions use framework "Foundation" use framework "ApplicationServices" use framework "Quartz" my clickAt(100, 10) on clickAt(newX, newY) set pt to current application’s CGPointZero set x of pt to newX set y of pt to newY current application’s CGPostMouseEvent(pt, 1, 1, 1) current application’s CGPostMouseEvent(pt, 1, 1, 0) end clickAt |
Mail.appで選択中のメールからMessage IDを取得する
MailCore2.frameworkを利用して、Mail.app上で選択中のメールのヘッダーからMessage IDを取得するAppleScriptです。
Mail.appから取得したヘッダーテキストから、MailCore2.frameworkでヘッダーオブジェクトを生成し、同フレームワークの機能を利用してMessage IDを取得します。1メールあたり0.03秒ぐらいで取得します。
ヘッダーのテキストを行単位でparseしてサーチしても全然いいのですが、メール関連は割と込み入った仕様がてんこ盛りなので、AppleScriptでもMailCore2をよく活用しています。
もはや、MailCore2がないとできない処理が多すぎて、これが使えないとけっこう泣きが入ります。
MailCore.framework(To ~/Library/Frameworks/)
AppleScript名:Mail.appで選択中のメールからMessage IDを取得する.scptd |
— – Created by: Takaaki Naganoya – Created on: 2018/03/12 — – Copyright © 2018 Piyomaru Software, All Rights Reserved — use AppleScript version "2.4" — Yosemite (10.10) or later use framework "Foundation" use scripting additions use framework "MailCore" –https://github.com/MailCore/mailcore2 tell application "Mail" set a to selection if a = {} then error "No Selection" set aa to first item of a set aSource to source of aa –メールのソースを取得 end tell set aStr to current application’s NSString’s stringWithString:aSource set aData to aStr’s dataUsingEncoding:(current application’s NSUTF8StringEncoding) set aHeader to current application’s MCOMessageHeader’s headerWithData:aData set aMessageID to (aHeader’s messageID()) as string –> "0A23983C-81B0-4E33-9C0B-B4A934A0E284@xxxxxx-xxx.xxx.xx" |
Enable Script Menu
メニューバー上にあるScript Menuを表示状態に設定変更するAppleScriptです。
Script Menuの表示・非表示はスクリプトエディタ内の環境設定で制御するようになっていますが、Script Menu自体はMenu Extraでスクリプトエディタとは独立して動作しているので、外部からオンにすることが可能です。
▲Default
▲実行後
AppleScript名:Enable System Wide Script Menu |
tell application "Finder" open (POSIX file "/System/Library/CoreServices/Menu Extras/Script Menu.menu") as alias end tell |
AppleScript名:Enable System Wide Script Menu (Shell) |
do shell script "open " & quoted form of "/System/Library/CoreServices/Menu Extras/Script Menu.menu" |
追記:macOS 10.14でOS標準装備のScript MenuがMenu Extraから単体のアプリケーションに変更になったので、Enableの方法も変更になりました。
AppleScript名:Enable System Wide Script Menu_10.14.scpt |
tell application "Finder" open (POSIX file "/System/Library/CoreServices/Script Menu.app") as alias end tell |
defaultsAppLibを呼び出してURLスキームに対応するアプリケーション情報を取得、設定
defaultappを呼び出して、指定のURLスキームに対応するdefault applicationを取得したり設定したりするAppleScriptです。
–> defaultAppLib (To ~/Library/Script Libraries/)
AppleScript名:defaultsAppLibを呼び出してURLスキームに対応するアプリケーション情報を取得、設定 |
use AppleScript version "2.4" use scripting additions use defautApLib : script "defaultAppLib" –https://github.com/Grayson/defaultapp –指定のURLスキームに対応するアプリケーションのパスを取得 set aRes to getDefaultAppForScheme("http") of defautApLib –> "/Applications/Safari.app" set bRes to getDefaultAppForScheme("ftp") of defautApLib –> "/Applications/Transmit.app" –指定のURLスキームに対応するアプリケーションを設定 set cRes to setDefaultAppForScheme("ftp", "Safari") of defautApLib –> true –指定のURLスキームに対応するアプリケーションのパスを取得(再確認) set dRes to getDefaultAppForScheme("ftp") of defautApLib –> "/Applications/Safari.app" |
shebangっぽい行から実行プログラムを取得してスクリプト言語の拡張子を取得
shebangを含む複数行のテキストからshebang(らしきもの)を検索して、実行プログラム名を取得し、実行するScript言語のファイルの拡張子を判定するAppleScriptです。
RTFで記述したシェルスクリプトやRubyのスクリプトのスケルトンに、色分けしたパラメータ部分のデータを差し替えてRubyやシェルスクリプトの実行ファイルを動的に書き出し、所定のスクリプト言語処理系で実行するAppleScriptを書いたときに用いたものです。
割と処理内容はヘロヘロでたいした固い処理は行なっていませんが、凶悪な処理を行うためのキーパーツです。
AppleScript名:shebangっぽい行から実行プログラムを取得してスクリプト言語の拡張子を取得 |
set aText to "#!/usr/bin/env python import re " set aLang to splitLangFromShebangStr(aText) of me if aLang = false then error "This data seems not a shebang" set aExt to detectScriptFileExtension(aLang) of me return {aLang, aExt} –> {"python", "py"} –shebangっぽい行から実行プログラム名を抽出 on splitLangFromShebangStr(aText) set aTmpList to paragraphs of aText repeat with i in aTmpList set j to contents of i if j starts with "#!" then set aWorkList to words of j set aLang to contents of last item of aWorkList return aLang end if end repeat return false end splitLangFromShebangStr on detectScriptFileExtension(aLang) ignoring case if aLang = "Ruby" then return "rb" else if aLang = "Python" then return "py" else if aLang = "perl" then return "pl" else if aLang = "sh" then return "sh" else return "" end if end ignoring end detectScriptFileExtension |