Archive for 8月, 2015

2015/08/31 ASOCでspotlight検索するじっけん

Cocoaの機能を用いてspotlightによる検索を行うAppleScriptの実験的な実装です。

オリジナルは、Appleのオンラインドキュメント「File Metadata Search Programming Guide」にあった、「Listing 2-1 Static Spotlight search implementation」です。これをAppleScriptObjCに(少しアレンジを加えつつ)翻訳したものです。

Script Editor上でCommand-Control-RによるForeground実行する必要があります。プログラムリスト中におけるログ内容はASObjC Explorer 4で表示させたもので、同様の内容を確認したい場合にはASObjC Explorer 4が必要です。

海外のユーザーから「どうやって表示してんの、それ?(Cocoa Objectのログ)」と、問い合わせがあって「通常のScript Editorでは表示できないよ」と回答。意外と知られていないようで、、、(もったいないので、ここで宣伝しておくことにしました)。

ASObjC Explorer 4のログ表示は、AppleScriptのプログラムの間にログ表示用のコードを挟んでいるとのことなので、必ずしも実際のオブジェクトとイコールの内容が表示されているわけではありませんが、実際の内容をつかみやすいものになっています。この機能を持つAppleScript系のエディタは、目下のところASObjC Explorer 4だけです。

Objective-CのプログラムをさらっとAppleScriptObjCのプログラムに書き換えできるのは、ASObjC ExplorerのCocoaオブジェクトログ機能があればこそです。ログを出しつつ属性値を確認できるため、おおいに役立っています。逆に、Cocoaオブジェクトログ機能がないと、全く歯が立ちません(AppleがShaneのプログラムを買い取って、標準のScript Editorに機能をマージすればいいのに、、、)。

AppleScript名:ASOCでspotlight検索するじっけん
– Created 2015-08-31 by Takaaki Naganoya
– 2015 Piyomaru Software

use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

property searchRes : {}

set searchRes to {} –initialize
initiateSearch(“kMDItemContentTypeTree == ’public.image’”)

–Waiting for the result
repeat while searchRes = {} –Inifinity loop, danger!!
  delay 0.1
end repeat

set anObj to searchRes’s firstObject() –Pick up the first one for test
set anAttrList to anObj’s attributes() –”mdls” attributes
–>  (NSArray) {”kMDItemContentTypeTree”, “kMDItemContentType”, “kMDItemPhysicalSize”, …}

set aFileName to anObj’s valueForKey:“kMDItemDisplayName”
–>  (NSString) ” 1 - 95.7.16.jpg” — example

on initiateSearch(aQueryStrings)
  
  
set aSearch to current application’s NSMetadataQuery’s alloc()’s init()
  
–>  (NSMetadataQuery)
  
  
current application’s NSNotificationCenter’s defaultCenter()’s addObserver:(me) selector:“queryDidUpdate:” |name|:(current application’s NSMetadataQueryDidUpdateNotification) object:aSearch
  
current application’s NSNotificationCenter’s defaultCenter()’s addObserver:(me) selector:“initalGatherComplete:” |name|:(current application’s NSMetadataQueryDidFinishGatheringNotification) object:aSearch
  
  
  
set aPredicate to current application’s NSPredicate’s predicateWithFormat:aQueryStrings
  
–> (NSComparisonPredicate) kMDItemContentTypeTree == “public.image”
  
aSearch’s setPredicate:aPredicate
  
  
  
set aScope to current application’s NSArray’s arrayWithObjects:{current application’s NSMetadataQueryUserHomeScope, current application’s NSMetadataQueryUbiquitousDocumentsScope}
  
–> (NSArray) {{”kMDQueryScopeHome”, “NSMetadataQueryUbiquitousDocumentsScope”}
  
aSearch’s setSearchScopes:aScope
  
  
  
set sortKeys to current application’s NSSortDescriptor’s sortDescriptorWithKey:“kMDItemDisplayName” ascending:true
  
aSearch’s setSortDescriptors:(current application’s NSArray’s arrayWithObject:sortKeys)
  
  
  
aSearch’s startQuery()
  
end initiateSearch

on queryDidUpdate:sender
  log sender
  
–> (NSConcreteNotification) NSConcreteNotification 0×7fa618450820 {name = NSMetadataQueryDidFinishGatheringNotification; object = }
end queryDidUpdate:

on initalGatherComplete:sender
  log sender
  
–> (NSConcreteNotification) NSConcreteNotification 0×7fa618450820 {name = NSMetadataQueryDidFinishGatheringNotification; object = }
  
  
set anObject to sender’s object
  
anObject’s stopQuery()
  
  
set aRes to anObject’s resultCount()
  
–>  173352 –different in each environment. Just a test
  
  
set my searchRes to anObject’s results()
  
–>  (NSArray) {(NSMetadataItem) , (NSMetadataItem) , ……
  
  
current application’s NSNotificationCenter’s defaultCenter()’s removeObserver:me |name|:(current application’s NSMetadataQueryDidUpdateNotification) object:anObject
  
current application’s NSNotificationCenter’s defaultCenter()’s removeObserver:me |name|:(current application’s NSMetadataQueryDidFinishGatheringNotification) object:anObject
  
  
set anObject to missing value –really needed?
  
end initalGatherComplete:

★Click Here to Open This Script 

2015/08/28 ASOCでプロセス関連のじっけん

CocoaのNSProcessInfoを叩いて、CPUコア(スレッド数)の取得を行うついでにいろいろ情報を取得してみました。

CPUのスレッド数については、Terminal上で「sysctl -n hw.ncpu」などと実行すると取得できますが、CocoaのAPIを呼び出して取得する方法を調べてみました。スピードが速いとか超豪華なデータが返ってくるとかいうことは一切なく、ただスレッド数(仮想コア数)がわかるだけです。

AppleScript名:ASOCでプロセス関連のじっけん
– Created 2015-08-28 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set aCount to (current application’s NSProcessInfo’s processInfo()’s processorCount()) as integer –CPU’s Thread number
–>  8 –4 core, 8 thread machine (MacBook Pro Retina 2012)

set aInfo to current application’s NSProcessInfo’s processInfo()
–>  (NSProcessInfo)

aInfo’s hostName()
–>  (NSString) “mbpretina.local”

aInfo’s operatingSystemVersionString()
–>  (NSString) “バージョン 10.10.5(ビルド 14F27)”

–ASOC上で実行できない(T_T)
aInfo’s operatingSystemVersion()
–> can’t bridge argument of type {_NSOperatingSystemVersion=qqq}.

★Click Here to Open This Script 

OS X 10.11上でOSのバージョン取得を行ってみたところ、期待どおりの結果が得られました。

AppleScript名:10.11でOSバージョンを取得
– Created 2015-08-28 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set aInfo to current application’s NSProcessInfo’s processInfo()

–OS X 10.11上では結果を正しく返す
aInfo’s operatingSystemVersion()
–> {majorVersion:10, minorVersion:11, patchVersion:0}

★Click Here to Open This Script 

2015/08/28 ASOCでNSFont,NSFontManagerのじっけん

AppleScriptでNSFontやNSFontManagerを操作して情報を取得する実験です。

このあたり、Cocoaを呼べるからものすごい処理ができるぞ(TTSの音声検索なんかはわりとすごい)、とかいうことはなくて・・・普通にPure AppleScriptでFontBook.appを操作する方が有意義な感じがします。

Photoshop書類のテキストレイヤーからフォント情報を取り出してまとめて出力するAppleScriptを組んだときには、FontBookを用いてフォント情報の付け合わせを行いましたが・・・ここであえてNSFontやNSFontManagerを呼び出してみたところで、イレギュラーなフォントについてはまともに名前などの情報を返してこないケースもありますし、Photoshopのテキストレイヤー上に複数のフォントを指定してしまうとScript側からは正しく取得できないので困ります。

AppleScript名:ASOCでNSFontのじっけん
– Created 2015-08-27 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”

set aFont to current application’s NSFont’s fontWithName:“HiraKakuStd-W8″ |size|:16
–>  (NSFont) “HiraKakuStd-W8 16.00 pt. P [] (0×600001457340) fobj=0×6180001f2800, spc=5.33″

aFont’s displayName()
–>  (NSString) “ヒラギノ角ゴ Std W8″

aFont’s familyName()
–>  (NSString) “Hiragino Kaku Gothic Std”

aFont’s fontName()
–>  (NSString) “HiraKakuStd-W8″

aFont’s coveredCharacterSet()
–>  (__NSCFCharacterSet) <__nscfcharacterset : 0x6000004472c0>

aFont’s fontDescriptor()
(*)
–>  (NSCTFontDescriptor) NSCTFontDescriptor <0×61800009cb60> = {
NSFontNameAttribute = “HiraKakuStd-W8″;
NSFontSizeAttribute = 16;
}
*)

aFont’s mostCompatibleStringEncoding()
–>  2.147483649E+9 –???

aFont’s renderingMode()
–>  1
(*
typedef enum NSFontRenderingMode : NSUInteger {
NSFontDefaultRenderingMode = 0,
NSFontAntialiasedRenderingMode = 1,
NSFontIntegerAdvancementsRenderingMode = 2,
NSFontAntialiasedIntegerAdvancementsRenderingMode = 3
} NSFontRenderingMode;
*)

aFont’s printerFont()
–>  (NSFont) “HiraKakuStd-W8 16.00 pt. P [] (0×600001457340) fobj=0×6180001f2800, spc=5.33″

aFont’s screenFont()
–>  (NSFont) “HiraKakuStd-W8 16.00 pt. S [] (0×600001457340) fobj=0×6180001f2800, spc=5.00″

aFont’s numberOfGlyphs()
–>  9354

★Click Here to Open This Script 

AppleScript名:ASOCでNSFontManagerのじっけん
– Created 2015-08-27 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”

set aFontMan to current application’s NSFontManager’s sharedFontManager()’s availableFontFamilies()
–>  (NSArray) {​​​​​”01FLOPDESIGN”, ​​​​​”A-OTF Shin Go Pr6N”, ​​​​​”A-OTF Shin Go Pro”, ​​​​​”Abadi MT Condensed Extra Bold”, ​​​​​”Abadi MT Condensed Light”, ​​​​​”AGENDAJinmeiGyoshotaiL1″, ​​​​​”AGENDAJinmeiSeikaishotaiL1″, ​​​​​”Akubin”,….}

set aFontMan to current application’s NSFontManager’s sharedFontManager()’s availableMembersOfFontFamily:“MS Mincho”
–>  (NSArray) {​​​​​{​​​​​​​”MS-Mincho”, ​​​​​​​”Regular”, ​​​​​​​1, ​​​​​​​0​​​​​}​​​}

set aFontMan to current application’s NSFontManager’s sharedFontManager()’s availableMembersOfFontFamily:“Times”
–>  (NSArray) {​​​​​{​​​​​​​”Times-Roman”, ​​​​​​​”Regular”, ​​​​​​​1, ​​​​​​​0​​​​​}, ​​​​​{​​​​​​​”Times-Italic”, ​​​​​​​”Italic”, ​​​​​​​1, ​​​​​​​1​​​​​}, ​​​​​{​​​​​​​”Times-Bold”, ​​​​​​​”Bold”, ​​​​​​​1, ​​​​​​​2​​​​​}, ​​​​​{​​​​​​​”Times-BoldItalic”, ​​​​​​​”Bold Italic”, ​​​​​​​1, ​​​​​​​3​​​​​}​​​}

set aFontMan to current application’s NSFontManager’s sharedFontManager()’s localizedNameForFamily:“Osaka” face:“Regular-Mono”
–>  (NSString) “レギュラー−等幅”

★Click Here to Open This Script 

2015/08/27 NSTimeZoneのじっけん

NSTimeZoneについてのひととおりの(タイムゾーンの変更以外)メソッドを呼び出してテストしてみました。

AppleScript名:NSTimeZoneの実験
– Created 2015-08-27 by Takaaki Naganoya
– Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set aTZ to current application’s NSTimeZone’s localTimeZone()
–>  (__NSLocalTimeZone) Local Time Zone (Asia/Tokyo (JST) offset 32400)

set aTZstr to aTZ’s |name|()
–>  (NSString) “Asia/Tokyo”

set aSecFromGMT to aTZ’s secondsFromGMT()
–>  32400

set a1Str to aTZ’s abbreviation()
–>  (NSString) “JST”

set a2Str to aTZ’s |description|()
–>  (NSString) “Local Time Zone (Asia/Tokyo (JST) offset 32400)”

set a3F to aTZ’s isDaylightSavingTime()
–>  false

set a4Num to aTZ’s daylightSavingTimeOffset()
–>  0.0

set a5Num to aTZ’s nextDaylightSavingTimeTransition()
–>  missing value

set bTZ to current application’s NSTimeZone’s systemTimeZone()
–>  (__NSTimeZone) Asia/Tokyo (JST) offset 32400

set cTZ to current application’s NSTimeZone’s timeZoneWithAbbreviation:“JST”
–>  (__NSTimeZone) Asia/Tokyo (JST) offset 32400

set dTZ to current application’s NSTimeZone’s timeZoneWithName:“Asia/Tokyo”
–>  (__NSTimeZone) Asia/Tokyo (JST) offset 32400

set aDat to current application’s NSTimeZone’s defaultTimeZone()’s |data|()
–>  (NSData) <545a6966 00000000 00000000 00000000 00000000 00000003 00000003 00000000 00000009 00000003 0000000d c3553b70 d73e1e90 d7ec1680 d8f91690 d9cbf880 db071d10 dbabda80 dce6ff10 dd8bbc80 02010201 02010201 0200007e 90000000 008ca001 0500007e 9000094a 43535400 4a445400 4a535400 00000000 0000>
set eTZ to (current application’s NSTimeZone’s timeZoneWithName:“Japan” |data|:aDat)’s |description|()
–>  (NSString) “Japan (JST) offset 32400″

set fTZ to current application’s NSTimeZone’s timeZoneForSecondsFromGMT:32400
–>  (__NSTimeZone) GMT+0900 (GMT+9) offset 32400

set gTZ to current application’s NSTimeZone’s alloc()’s initWithName:“JST”
–>  (__NSTimeZone) JST (JST) offset 32400

set hTZ to current application’s NSTimeZone’s alloc()’s initWithName:“JST” |data|:aDat
–>  (__NSTimeZone) JST (JST) offset 32400

set aVerStr to current application’s NSTimeZone’s timeZoneDataVersion()
–>  (NSString) “2015f”

set iTZ to current application’s NSTimeZone’s localTimeZone()
–>  (__NSLocalTimeZone) Local Time Zone (Asia/Tokyo (JST) offset 32400)

set jTZ to current application’s NSTimeZone’s defaultTimeZone()
–>  (__NSTimeZone) Asia/Tokyo (JST) offset 32400

set kTZ to current application’s NSTimeZone’s systemTimeZone()
–>  (__NSTimeZone) Asia/Tokyo (JST) offset 32400

set aDic to current application’s NSTimeZone’s abbreviationDictionary()
–>  (NSDictionary) {​​​​​EDT:”America/New_York”, ​​​​​GMT:”GMT”, ​​​​​AST:”America/Halifax”, ​​​​​IRST:”Asia/Tehran”, ​​​​​ICT:”Asia/Bangkok”, ​​​​​PET:”America/Lima”, ​​​​​KST:”Asia/Seoul”, ​​​​​PST:”America/Los_Angeles”, ​​​​​CDT:”America/Chicago”, ​​​​​EEST:”Europe/Istanbul”, ​​​​​NZDT:”Pacific/Auckland”, ​​​​​WEST:”Europe/Lisbon”, ​​​​​EAT:”Africa/Addis_Ababa”, ​​​​​HKT:”Asia/Hong_Kong”, ​​​​​IST:”Asia/Calcutta”, ​​​​​MDT:”America/Denver”, ​​​​​NZST:”Pacific/Auckland”, ​​​​​WIT:”Asia/Jakarta”, ​​​​​ADT:”America/Halifax”, ​​​​​BST:”Europe/London”, ​​​​​ART:”America/Argentina/Buenos_Aires”, ​​​​​CAT:”Africa/Harare”, ​​​​​GST:”Asia/Dubai”, ​​​​​PDT:”America/Los_Angeles”, ​​​​​SGT:”Asia/Singapore”, ​​​​​COT:”America/Bogota”, ​​​​​PKT:”Asia/Karachi”, ​​​​​EET:”Europe/Istanbul”, ​​​​​UTC:”UTC”, ​​​​​WAT:”Africa/Lagos”, ​​​​​EST:”America/New_York”, ​​​​​JST:”Asia/Tokyo”, ​​​​​CLST:”America/Santiago”, ​​​​​CET:”Europe/Paris”, ​​​​​BDT:”Asia/Dhaka”, ​​​​​MSK:”Europe/Moscow”, ​​​​​AKDT:”America/Juneau”, ​​​​​CLT:”America/Santiago”, ​​​​​AKST:”America/Juneau”, ​​​​​BRST:”America/Sao_Paulo”, ​​​​​BRT:”America/Sao_Paulo”, ​​​​​CEST:”Europe/Paris”, ​​​​​CST:”America/Chicago”, ​​​​​HST:”Pacific/Honolulu”, ​​​​​MSD:”Europe/Moscow”, ​​​​​MST:”America/Denver”, ​​​​​PHT:”Asia/Manila”, ​​​​​WET:”Europe/Lisbon”​​​}

set bDic to current application’s NSTimeZone’s knownTimeZoneNames()
–>  (NSArray) {​​​​​”Africa/Abidjan”, ​​​​​”Africa/Accra”, ​​​​​”Africa/Addis_Ababa”​​​​​….​​​}

★Click Here to Open This Script 

2015/08/27 100%クラッシュするNSCalendarの操作

AppleScriptObjCでNSCalendarをテストしだしたところ、実行するScript Editorが100%クラッシュする記述に遭遇。OS X 10.10.5でも、OS X 10.11 Betaでもクラッシュします(バグレポートずみ)。

# OS X 10.10.x/10.11.xでこれを実行してクラッシュしない環境があったら、逆におしえていただきたいです(2台でともに100%クラッシュ)

MacScriptersのBBSでもクラッシュの話が(ずいぶん前から)出ており、有名な話のようです。

*** CAUTION: THIS SCRIPT CAUSE CRASH ***

AppleScript名:ASOCでNSCalendarのじっけん(100%クラッシュ)
– Created 2015-08-27 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set aCal to current application’s NSCalendar’s alloc()’s initWithCalendarIdentifier:(current application’s NSGregorianCalendar)

★Click Here to Open This Script 

Shane Stanleyから「こう書くとクラッシュを避けられるよ」というのを教えてもらいました。本当に重要ですよね、落とし穴がどこにあいているかの情報は、、、

AppleScript名:クラッシュしないNSCalendarのじっけん
– Created 2015-08-28 by Shane Stanley
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set aCal to current application’s NSCalendar’s calendarWithIdentifier:(current application’s NSGregorianCalendar)
–>  (_NSCopyOnWriteCalendarWrapper) <_nscopyonwritecalendarwrapper : 0x610000239e20>

★Click Here to Open This Script 

2015/08/27 ASOCでNSLocaleのじっけん

CocoaのNSLocale関連のメソッドなどを調べてみました。

AppleScript名:ASOCでNSLocaleのじっけん
– Created 2015-08-26 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set aLocale to current application’s NSLocale’s currentLocale()
–>  (__NSCFLocale) <__nscflocale : 0x6000000f6b00>

aLocale’s localeIdentifier()
–>  (NSString) “ja_JP”

set bLocale to current application’s NSLocale’s systemLocale()
–>  (__NSCFLocale) <__nscflocale : 0x6180000f9100>

bLocale’s localeIdentifier()
–>  (NSString) “”

set cLocale to current application’s NSLocale’s alloc()’s initWithLocaleIdentifier:“en_US”
–>  (__NSCFLocale) <__nscflocale : 0x6000010f5680>

cLocale’s localeIdentifier()
–>  (NSString) “en_US”

set anArray to current application’s NSLocale’s availableLocaleIdentifiers()
–>  (NSArray) {​​​​​”eu”, ​​​​​”hr_BA”, ​​​​​”en_CM”, ​​​​​”rw_RW”, ….., ​​​​​”ja_JP”….”uk_UA”​​​}

set bArray to current application’s NSLocale’s ISOCountryCodes()
–>  (NSArray) {​​​​​”AD”, ​​​​​”AE”, ​​​​​”AF”, ​​​​​”AG”,….. ​​​​​”JP”…. ​​​​​”ZW”​​​}

set cArray to current application’s NSLocale’s ISOCurrencyCodes()
–>  (NSArray) {​​​​​”ADP”, ​​​​​”AED”, ​​​​​”AFA”, ​​​​​….”JPY”….. ​​​​​”ZWD”​​​}

set dArray to current application’s NSLocale’s ISOLanguageCodes()
–>  (NSArray) {​​​​​”aa”, ​​​​​”ab”, ​​​​​”ace”, ​​​​​”ach”,…. ​​​​​”jpr”,….​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​”zza”​​​}

set eArray to current application’s NSLocale’s commonISOCurrencyCodes()
–>  (NSArray) {​​​​​”AED”, ​​​​​”AFN”, ​​​​​”ALL”, …​​​​​”JPY”….​​​​​”ZMW”​​​}

set aStr to current application’s NSLocale’s canonicalLocaleIdentifierFromString:“ja_JP”
–>  (NSString) “ja_JP”

set aObj to current application’s NSLocale’s componentsFromLocaleIdentifier:“ja_JP”
–>  (NSDictionary) {​​​​​kCFLocaleLanguageCodeKey:”ja”, ​​​​​kCFLocaleCountryCodeKey:”JP”​​​}

set bObj to current application’s NSLocale’s localeIdentifierFromComponents:aObj
–>  (NSString) “ja_JP”

set bStr to current application’s NSLocale’s canonicalLanguageIdentifierFromString:“ja_JP”
–>  (NSString) “ja-JP”

set cStr to current application’s NSLocale’s localeIdentifierFromWindowsLocaleCode:17
–>  (NSString) “ja”

set dStr to current application’s NSLocale’s windowsLocaleCodeFromLocaleIdentifier:“ja_JP”
–>  1041

set fArray to current application’s NSLocale’s preferredLanguages()
–>  (NSArray) {​​​​​”ja”, ​​​​​”en-US”, ​​​​​”en-GB”, ​​​​​”fr”, ​​​​​”en”​​​}

set aNum to current application’s NSLocale’s characterDirectionForLanguage:“ja_JP”
–> 1 –Left to Right
set bNum to current application’s NSLocale’s characterDirectionForLanguage:“ar”
–>  2 –Right to Left

set cNum to current application’s NSLocale’s lineDirectionForLanguage:“ja_JP”
–>  3 –Up to Down
set dNum to current application’s NSLocale’s lineDirectionForLanguage:“ar”
–>  3 –Up to Down

★Click Here to Open This Script 

2015/08/26 ASOCでHostの情報を取得する

CocoaのNSHost関連のメソッドなどを調べてみました。

AppleScript名:ASOCでHostの情報を取得する
– Created 2015-08-26 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set aHost to current application’s NSHost’s currentHost()

aHost’s localizedName()
–>  (NSString) “MBPretina”

aHost’s |name|()
–>  (NSString) “mbpretina.local”

aHost’s address()
–>  (NSString) “xxxx::xxxx:xxxx:xxxx:xxxx%en0″

aHost’s addresses()
–>  (NSArray) {​​​​​”xxxx::xxxx:xxxx:xxxx:xxxx%en0″, ​​​​​”192.168.0.10″, ​​​​​”xxxx::xxxx:xxxx:xxxx:xxxx%awdl0″, ​​​​​”xxxx::xxxx:xxxx:xxxx:xxxx%utun0″, ​​​​​”xxxx:xxxx:xxx:xxxx:xxxx:xxxx:xxxx:xxxx”, ​​​​​”xxxx::xxxx:xxxx:xxxx:xxx%utun1″, ​​​​​”xxxx::xxxx:xxxx:xxxx:xxxx%utun2″, ​​​​​”::1″, ​​​​​”127.0.0.1″, ​​​​​”xxxx::1%lo0″​​​}

set bHost to current application’s NSHost’s hostWithName:“mba13.local”
–>  (NSHost) (null) (() ())

bHost’s address()
–>  (NSString) “192.168.0.23″

set cHost to current application’s NSHost’s hostWithAddress:“192.168.0.23″
cHost’s |name|()
–>  missing value –Why ???????

bHost’s isEqualToHost:cHost
–>  true –OK

★Click Here to Open This Script 

2015/08/26 ASOCで性別と言語コードを指定してTTS voiceを取得 v2

Cocoaの機能を用いて、Text To Speechの音声から性別と言語を指定して、TTS Voice名称をリストで返すAppleScriptです。最初のバージョンに対して、「Premium」voiceに限定しないvoice名取得ルーチン「getAllVoiceNameWithFiltering」を追加しています。ほかに、機能的な差異はありません。

前バージョンに対し、Shane StanleyからNSPredicateの指定について、

set aStr to current application’s NSString’s stringWithString:(”VoiceLocaleIdentifier == ‘” & voiceLang & “‘ and  VoiceGender == ‘” & voiceGender & “‘ and VoiceIdentifier ENDSWITH[c] ‘premium’”)
set aPredicate to current application’s NSPredicate’s predicateWithFormat:aStr

って、書いてあるけど引数をNSPredicateの指定文字列から分離したほうがクォートで囲む囲まないで悩まなくていいから、分離しといたほうがいいよ(意訳)という指摘があって・・・実際、NSPredicate以外のコードはすぐに書けたものの・・・クォートの指定でけっこう試行錯誤して悩んでいたので、まったくその通り(^ー^;;;;

set aPredicate to current application’s NSPredicate’s predicateWithFormat_(”VoiceLocaleIdentifier == %@ and VoiceGender == %@ and VoiceIdentifier ENDSWITH[c] %@”, voiceLang, voiceGender, “premium”)

とか(ここで「predicateWithFormat_」とアンダースコアで書かないと構文確認をパスできないところにASOCの闇と、Shaneの試行錯誤を感じます、、、)、

set aPredicate to current application’s NSPredicate’s predicateWithFormat:”VoiceLocaleIdentifier == %@ and VoiceGender == %@ and VoiceIdentifier ENDSWITH[c] %@” argumentArray:{voiceLang, voiceGender, “premium”}

みたいに書いたほうがシンプルでいいよ的な話で、まさにそのとおり。で、いろいろ書き換えておきました。

各TTS Voiceについては、性別、言語、国などのほかに「年齢」というパラメータも持っているのですが、年齢を条件にして綿密に絞り込む・・・というほどには、TTS Voiceの数が多くないので、年齢は考慮していません。

これ(↑)を掲載するまでに、「クリップボードの内容をスタイル付きテキストで取得する方法」について調べ、調べきれなかったので、do shell script使いまくりの昔作ったAppleScriptでHTMLに書き出した、というオチもありました。Cocoaのクリップボード関連、普段使わないうえに、いざ真剣に調べだしてもあんまりまとまったまともでわかりやすい情報がなくて困りものです。

AppleScript名:ASOCで性別と言語コードを指定してTTS voiceを取得 v2
– Created 2015-08-25 by Takaaki Naganoya
– Modified 2015-08-26 by Shane Stanley, Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
use BridgePlus : script “BridgePlus”

load framework

set v1Res to getPremiumVoiceNameWithFiltering(“VoiceGenderMale”, “ja_JP”)
–>  {​​​​​”Otoya”​​​}

set v2Res to getPremiumVoiceNameWithFiltering(“VoiceGenderFemale”, “en_US”)
–>  {​​​​​”Allison”, ​​​​​”Ava”, ​​​​​”Jill”, ​​​​​”Samantha”​​​}

set v3Res to getAllVoiceNameWithFiltering(“VoiceGenderFemale”, “en_US”)
–>  {​​​​​”Agnes”, ​​​​​”Allison”, ​​​​​”Ava”, ​​​​​”Jill”, ​​​​​”Kathy”, ​​​​​”Princess”, ​​​​​”Samantha”, ​​​​​”Vicki”, ​​​​​”Victoria”​​​}

–Premium Voices Only
on getPremiumVoiceNameWithFiltering(voiceGender, voiceLang)
  –Make Blank Array
  
set outArray to current application’s NSMutableArray’s arrayWithObject:{}
  
  
–Make Installed Voice List
  
set aList to current application’s NSSpeechSynthesizer’s availableVoices()
  
set bList to aList as list
  
  
repeat with i in bList
    set j to contents of i
    
set aDIc to (current application’s NSSpeechSynthesizer’s attributesForVoice:j)
    (
outArray’s addObject:aDIc)
  end repeat
  
  
–Filter Voice
  
set aPredicate to current application’s NSPredicate’s predicateWithFormat_(“VoiceLocaleIdentifier == %@ and VoiceGender == %@ and VoiceIdentifier ENDSWITH[c] %@”, voiceLang, voiceGender, “premium”)
  
set filteredArray to outArray’s filteredArrayUsingPredicate:aPredicate
  
set aReList to (filteredArray’s valueForKey:“VoiceName”) as list
  
  
return aReList
  
end getPremiumVoiceNameWithFiltering

–All Voices
on getAllVoiceNameWithFiltering(voiceGender, voiceLang)
  –Make Blank Array
  
set outArray to current application’s NSMutableArray’s arrayWithObject:{}
  
  
–Make Installed Voice List
  
set aList to current application’s NSSpeechSynthesizer’s availableVoices()
  
set bList to aList as list
  
  
repeat with i in bList
    set j to contents of i
    
set aDIc to (current application’s NSSpeechSynthesizer’s attributesForVoice:j)
    (
outArray’s addObject:aDIc)
  end repeat
  
  
–Filter Voice
  
set aPredicate to current application’s NSPredicate’s predicateWithFormat_(“VoiceLocaleIdentifier == %@ and VoiceGender == %@”, voiceLang, voiceGender)
  
  
set filteredArray to outArray’s filteredArrayUsingPredicate:aPredicate
  
set aReList to (filteredArray’s valueForKey:“VoiceName”) as list
  
  
return aReList
  
end getAllVoiceNameWithFiltering

on getLaunguageCodeFromTTSVoices()
  
  
–Make Blank Array
  
set outArray to current application’s NSMutableArray’s arrayWithObject:{}
  
  
–Make Installed Voice List
  
set aList to current application’s NSSpeechSynthesizer’s availableVoices()
  
set bList to aList as list
  
  
repeat with i in bList
    set j to contents of i
    
set aDict to (current application’s NSSpeechSynthesizer’s attributesForVoice:j)
    (
outArray’s addObject:aDict)
  end repeat
  
  
set aResArray to (outArray’s valueForKey:“VoiceLocaleIdentifier”)
  
  
set aSet to current application’s NSMutableSet’s setWithArray:aResArray
  
set aResList to aSet’s allObjects()
  
  
set bResList to BridgePlus’s listByDeletingBlanksIn:aResList –Remove Blank Items
  
  
return bResList
  
end getLaunguageCodeFromTTSVoices

★Click Here to Open This Script 

2015/08/25 ASOCで性別と言語コードを指定して高音質voiceを取得

Cocoaの機能を用いて、Text To Speechの音声から性別と言語を指定して、高音質のVoice名称をリストで返すAppleScriptです。

voice1.png
▲システム環境設定「音声入力と読み上げ」>「テキスト読み上げ」

voice2.png
▲OSにインストールされているVoiceリスト

男性:VoiceGenderMale
女性:VoiceGenderFemale

で性別を指定して高音質のvoice名称を取得します。

アメリカ英語(en_US)で男性の音声をどれでもいいから指定したいが、どの音声が入っているかは特定できないしデフォルトで指定されているかどうかもわからない、といった場合にある程度の見当をつけるために作ったものです。

TTS Voiceで使用可能な言語コード一覧については、「ASOCで全voiceから言語コードを抽出」のプログラムで取得できるようにしておきました。

AppleScript名:ASOCで性別と言語コードを指定して高音質voiceを取得
– Created 2015-08-25 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”

set v1Res to getPremiumVoiceNameWithFiltering(“VoiceGenderMale”, “ja_JP”)
–>  {​​​​​”Otoya”​​​}

set v2Res to getPremiumVoiceNameWithFiltering(“VoiceGenderFemale”, “en_US”)
–>  {​​​​​”Allison”, ​​​​​”Ava”, ​​​​​”Jill”, ​​​​​”Samantha”​​​}

set v3Res to getPremiumVoiceNameWithFiltering(“VoiceGenderMale”, “en_GB”)
–> {”Daniel”}

–Premium Voices Only
on getPremiumVoiceNameWithFiltering(voiceGender, voiceLang)
  –Make Blank Array
  
set outArray to current application’s NSMutableArray’s arrayWithObject:{}
  
  
–Make Installed Voice List
  
set aList to current application’s NSSpeechSynthesizer’s availableVoices()
  
set bList to aList as list
  
  
repeat with i in bList
    set j to contents of i
    
set aDIc to (current application’s NSSpeechSynthesizer’s attributesForVoice:j)
    (
outArray’s addObject:aDIc)
  end repeat
  
  
–Filter Voice
  
set aStr to current application’s NSString’s stringWithString:(“VoiceLocaleIdentifier == ’” & voiceLang & “’ and VoiceGender == ’” & voiceGender & “’ and VoiceIdentifier ENDSWITH[c] ’premium’”)
  
set aPredicate to current application’s NSPredicate’s predicateWithFormat:aStr
  
set filteredArray to outArray’s filteredArrayUsingPredicate:aPredicate
  
set aReList to (filteredArray’s valueForKey:“VoiceNameRoot”) as list
  
  
return aReList
  
end getPremiumVoiceNameWithFiltering

★Click Here to Open This Script 

AppleScript名:ASOCで全voiceから言語コードを抽出
– Created 2015-08-25 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
use BridgePlus : script “BridgePlus”

load framework

set cRes to getLaunguageCodeFromTTSVoices()
–>  {​​​​​”fr_FR”, ​​​​​”zh_TW”, ​​​​​”it_IT”, ​​​​​”en_ZA”, ​​​​​”es_AR”, ​​​​​”ko_KR”, ​​​​​”ro_RO”, ​​​​​”en_IN”, ​​​​​”fr_CA”, ​​​​​”hi_IN”, ​​​​​”da_DK”, ​​​​​”en-scotland”, ​​​​​”pt_BR”, ​​​​​”zh_CN”, ​​​​​”sv_SE”, ​​​​​”es_ES”, ​​​​​”hu_HU”, ​​​​​”ar_SA”, ​​​​​”en_GB”, ​​​​​”ja_JP”, ​​​​​”fi_FI”, ​​​​​”zh_HK”, ​​​​​”tr_TR”, ​​​​​”nb_NO”, ​​​​​”pl_PL”, ​​​​​”id_ID”, ​​​​​”cs_CZ”, ​​​​​”el_GR”, ​​​​​”he_IL”, ​​​​​”ru_RU”, ​​​​​”de_DE”, ​​​​​”en_AU”, ​​​​​”nl_BE”, ​​​​​”pt_PT”, ​​​​​”th_TH”, ​​​​​”sk_SK”, ​​​​​”en_US”, ​​​​​”en_IE”, ​​​​​”nl_NL”, ​​​​​”es_MX”​​​}

on getLaunguageCodeFromTTSVoices()
  
  
–Make Blank Array
  
set outArray to current application’s NSMutableArray’s arrayWithObject:{}
  
  
–Make Installed Voice List
  
set aList to current application’s NSSpeechSynthesizer’s availableVoices()
  
set bList to aList as list
  
  
repeat with i in bList
    set j to contents of i
    
set aDIc to (current application’s NSSpeechSynthesizer’s attributesForVoice:j)
    (
outArray’s addObject:aDIc)
  end repeat
  
  
set aResArray to (outArray’s valueForKey:“VoiceLocaleIdentifier”)
  
  
set aSet to current application’s NSMutableSet’s setWithArray:aResArray
  
set aResList to aSet’s allObjects()
  
  
set bResList to BridgePlus’s listByDeletingBlanksIn:aResList –Remove Blank Items
  
  
return bResList
  
end getLaunguageCodeFromTTSVoices

★Click Here to Open This Script 

2015/08/25 MacのHardware UUIDを取得する

Macのハードウェアを一意に特定する、Hardware UUIDを取得するAppleScript(shellを呼んでいるだけ)です。

uuid1.png
▲Appleメニューの「このMacについて」を実行。このWindowの下部にあるボタン「システムレポート…」をクリックすると…

uuid2.png
▲「ハードウェアの概要:」で「ハードウェアUUID」が表示されます

アプリケーションの中に入れて呼ぶ可能性については想定していませんが、ツール的にメニューから呼び出して使うことは考えています。たとえば、自分が参加している(知り合いの作者が行っている)ソフトウェアのβテスト時に、ソフトウェアの作者に伝えるような用途です。

shell呼び出しをなくす方向でいろいろ調べてはみたのですが、ASOCで扱えないCFStringなどの機能を用いているサンプルコードしか見当たりませんでした。残念!

AppleScript名:MacのHardware UUIDを取得する
– Created 2015-08-25 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions

set sText to “/usr/sbin/ioreg -rd1 -c IOPlatformExpertDevice | /usr/bin/awk ’/IOPlatformUUID/ { print $3; }’”
set aRes to do shell script sText
–>  ”\”XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\”"

★Click Here to Open This Script 

2015/08/24 ASOCでPDFを印刷するテスト

Cocoaの機能を用いてPDFをAppleScriptだけでアプリケーションに依存しないで印刷するscriptです。

pdfprint1.png
▲Script Editor上でCommand-Control-「R」でforeground実行すると、PDFを選択し、印刷ダイアログを表示します(Window非表示)

pdfprint2.png
▲プリンタも選択可能

AppleScript名:ASOCでPDFを印刷するテスト
– Created 2015-08-24 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “Quartz”
use framework “AppKit”

–Check If this script runs in foreground
if not (current application’s NSThread’s isMainThread()) as boolean then
  display alert “This script must be run from the main thread (Command-Control-R in Script Editor).” buttons {“Cancel”} as critical
  
error number -128
end if

–Choose a PDF to print
set aDoc to POSIX path of (choose file of type {“com.adobe.pdf”})
set aDocPath to current application’s NSString’s stringWithString:aDoc
set aPDF to current application’s PDFDocument’s alloc()’s initWithURL:(current application’s |NSURL|’s fileURLWithPath:aDocPath)

–Make PDFView
set aPDFView to current application’s PDFView’s alloc()’s init()
aPDFView’s setDocument:aPDF
aPDFView’s setAutoScales:true
aPDFView’s setDisplaysPageBreaks:false

–Make Window
set aWin to current application’s NSWindow’s alloc()’s init()
aWin’s setContentSize:(aPDFView’s frame()’s |size|())
aWin’s setContentView:aPDFView
aWin’s |center|()

–Print PDF
set sharedPrintInfo to current application’s NSPrintInfo’s sharedPrintInfo()
aPDFView’s printWithInfo:sharedPrintInfo autoRotate:true

★Click Here to Open This Script 

2015/08/22 NSDataDetectorを用いてテキストから各種データを抽出

NSDataDetectorを用いて、本来は自然言語のテキスト(メールの本文とかスケジュールとか)から指定の属性の情報を抽出するAppleScriptです。

前バージョンよりも情報抽出部を短く記述できるという指摘がShaneからあったため、その点を書き換えて動作確認したものです。内容自体は前バージョンと変わりありません。

NSDataDetectorのサンプルで、すべての属性データを指定しているものが存在せず、ひととおり調べてテストするのにはそれなりに時間がかかりました(T_T)

AppleScript名:ASOCで各種文字列からdate objectを抽出 v2
– Created 2015-08-21 by Shane Stanley
– Modified 2015-08-22 by Shane Stanley
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use script “BridgePlus”

set theString to “Sunny September 4
Fri., September 1
Fri. Sept. 2
Fri Sep 3
Sep. 4
Sept. 9
9/8
9/7/15
09/06/2015
9/5/2015
2015/9/5
2015年9月5日
2015年9月5日(土)
2015.9.5


set theDates to ASify from (my getDatesIn:theString)
–>  {​​​​​date “2015年9月4日金曜日 12:00:00″, ​​​​​date “2015年9月1日火曜日 12:00:00″, ​​​​​date “2015年9月2日水曜日 12:00:00″, ​​​​​date “2015年9月3日木曜日 12:00:00″, ​​​​​date “2015年9月4日金曜日 12:00:00″, ​​​​​date “2015年9月9日水曜日 12:00:00″, ​​​​​date “2009年7月15日水曜日 12:00:00″, ​​​​​date “2015年9月6日日曜日 12:00:00″, ​​​​​date “2015年9月5日土曜日 12:00:00″, ​​​​​date “2015年9月5日土曜日 12:00:00″, ​​​​​date “2015年9月5日土曜日 12:00:00″, ​​​​​date “2015年9月5日土曜日 12:00:00″​​​}

on getDatesIn:aString
  set anNSString to current application’s NSString’s stringWithString:aString
  
  set {theDetector, theError} to current application’s NSDataDetector’s dataDetectorWithTypes:(current application’s NSTextCheckingTypeDate) |error|:(reference)
  
  set theMatches to theDetector’s matchesInString:anNSString options:0 range:{0, anNSString’s |length|()}
  
set theResults to theMatches’s valueForKey:“date”
  
  return theResults as list
end getDatesIn:

★Click Here to Open This Script 

AppleScript名:ASOCで各種文字列から電話番号を抽出 v2
– Created 2015-08-21 by Shane Stanley
– Modified 2015-08-21 by Takaaki Naganoya
– Modified 2015-08-22 by Shane Stanley
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set theString to “長野谷隆昌
(Takaaki Naganoya)
maro@piyocast.com
http://piyocast.com/as
2015年8月21日〜23日
080-1111-2222
東京都練馬区中村橋1-2-3

set theDates to (extractPhoneNumberFromNaturalText(theString))
–>  {​​​​​”080-1111-2222″​​​}

on extractPhoneNumberFromNaturalText(aString)
  set anNSString to current application’s NSString’s stringWithString:aString
  
  
set {theDetector, theError} to current application’s NSDataDetector’s dataDetectorWithTypes:(current application’s NSTextCheckingTypePhoneNumber) |error|:(reference)
  
  
set theMatches to theDetector’s matchesInString:anNSString options:0 range:{0, anNSString’s |length|()}
  
set theResults to theMatches’s valueForKey:“phoneNumber”
  
  
return theResults as list
end extractPhoneNumberFromNaturalText

★Click Here to Open This Script 

AppleScript名:ASOCで各種文字列から住所を抽出 v2
– Created 2015-08-21 by Shane Stanley
– Modified 2015-08-21 by Takaaki Naganoya
– Modified 2015-08-22 by Shane Stanley
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set theString to “長野谷隆昌
(Takaaki Naganoya)
maro@piyocast.com
http://piyocast.com/as
2015年8月21日〜23日
東京都練馬区中村橋1-2-3

set theDates to (extractAddressFromNaturalText(theString))
–>  {{State:”東京都”, Street:”中村橋1-2-3″, City:”練馬区”}}

on extractAddressFromNaturalText(aString)
  set anNSString to current application’s NSString’s stringWithString:aString
  
  
set {theDetector, theError} to current application’s NSDataDetector’s dataDetectorWithTypes:(current application’s NSTextCheckingTypeAddress) |error|:(reference)
  
  
set theMatches to theDetector’s matchesInString:anNSString options:0 range:{0, anNSString’s |length|()}
  
set theResults to theMatches’s valueForKey:“addressComponents”
  
  
return theResults as list
end extractAddressFromNaturalText

★Click Here to Open This Script 

AppleScript名:ASOCで各種文字列からリンクURLを抽出 v2
– Created 2015-08-21 by Shane Stanley
– Modified 2015-08-21 by Takaaki Naganoya
– Modified 2015-08-22 by Shane Stanley
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set theString to "長野谷隆昌
(Takaaki Naganoya)
maro@piyocast.com
http://piyocast.com/as
2015年8月21日〜23日
080-1111-2222
東京都練馬区中村橋1-2-3
"

set theDates to (extractLinksFromNaturalText(theString))
–>  {​​​​​(NSURL) mailto:maro@piyocast.com, ​​​​​(NSURL) http://piyocast.com/as​​​}

on extractLinksFromNaturalText(aString)
  set anNSString to current application’s NSString’s stringWithString:aString
  
  
set {theDetector, theError} to current application’s NSDataDetector’s dataDetectorWithTypes:(current application’s NSTextCheckingTypeLink) |error|:(reference)
  
  
set theMatches to theDetector’s matchesInString:anNSString options:0 range:{0, anNSString’s |length|()}
  
set theResults to theMatches’s valueForKey:"URL"
  
  
return theResults as list
end extractLinksFromNaturalText

★Click Here to Open This Script 

AppleScript名:ASOCで各種文字列からフライト情報を抽出 v2
– Created 2015-08-21 by Shane Stanley
– Modified 2015-08-21 by Takaaki Naganoya
– Modified 2015-08-22 by Shane Stanley
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set theString to “UA460 SFO to YVR [Flight] 6/12/2013 United Airlines(UA) #460 dep SFO 7:57pm PDT arr YVR 10:14pm PDT; Ticket #0162360127882, Ticket #0162360127883; conf #K5XBXY; Note:, Seats:—/30A , Seats:—/30B

set theDates to (extractTransitInfoFromNaturalText(theString))
–>  {​​​​​{​​​​​​​Flight:”460″​​​​​}​​​}

on extractTransitInfoFromNaturalText(aString)
  set anNSString to current application’s NSString’s stringWithString:aString
  
  
set {theDetector, theError} to current application’s NSDataDetector’s dataDetectorWithTypes:(current application’s NSTextCheckingTypeTransitInformation) |error|:(reference)
  
  
set theMatches to theDetector’s matchesInString:anNSString options:0 range:{0, anNSString’s |length|()}
  
set theResults to theMatches’s valueForKey:“components”
  
  
return theResults as list
end extractTransitInfoFromNaturalText

★Click Here to Open This Script 

2015/08/22 ASOCで各種文字列からdate objectに変換 ほかNSDataDetectorの活用

Shane StanleyのShane StanleyによるScript Library「BridgePlus」の機能を用いた各種「日付っぽい文字列」をdate objectに変換するAppleScriptです。

US Appleが主催しているMailing List「AS Users ML」にて、少々ラフな記述を行った日付文字をdate objectに変換できないのはおかしいとかバグじゃないかとか、荒れ気味の議論が起こった際に、Shaneがリーサルウェポン級の破壊力を持つScriptを投稿。

なんと、NSDataDetectorを用いて、本来は自然言語のテキスト(メールの本文とかスケジュールとか)から日付関連の情報を抽出するところを、「荒れた記法の日付情報」を変換するのに利用。こういうやり方があるかと、いたく感心しました(^ー^)。

AppleScript名:ASOCで各種文字列からdate objectに変換
– Created 2015-08-21 by Shane Stanley
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use script “BridgePlus”

set theString to “Sunny September 4
Fri., September 1
Fri. Sept. 2
Fri Sep 3
Sep. 4
Sept. 9
9/8
9/7/15
09/06/2015
9/5/2015
2015/9/5
2015年9月5日
2015年9月5日(土)
2015.9.5

set theDates to ASify from (my getDatesIn:theString)
–>  {​​​​​date “2015年9月4日金曜日 12:00:00″, ​​​​​date “2015年9月1日火曜日 12:00:00″, ​​​​​date “2015年9月2日水曜日 12:00:00″, ​​​​​date “2015年9月3日木曜日 12:00:00″, ​​​​​date “2015年9月4日金曜日 12:00:00″, ​​​​​date “2015年9月9日水曜日 12:00:00″, ​​​​​date “2009年7月15日水曜日 12:00:00″, ​​​​​date “2015年9月6日日曜日 12:00:00″, ​​​​​date “2015年9月5日土曜日 12:00:00″, ​​​​​date “2015年9月5日土曜日 12:00:00″, ​​​​​date “2015年9月5日土曜日 12:00:00″, ​​​​​date “2015年9月5日土曜日 12:00:00″​​​}

on getDatesIn:aString
  set anNSString to current application’s NSString’s stringWithString:aString
  
  
set {theDetector, theError} to current application’s NSDataDetector’s dataDetectorWithTypes:(current application’s NSTextCheckingTypeDate) |error|:(reference)
  
  
set theMatches to theDetector’s matchesInString:anNSString options:0 range:{0, anNSString’s |length|()}
  
set theDates to current application’s NSMutableArray’s array()
  
  
repeat with i from 1 to theMatches’s |count|()
    set thisMatch to (theMatches’s objectAtIndex:(i - 1))
    (
theDates’s addObject:(thisMatch’s |date|()))
  end repeat
  
  
return theDates
end getDatesIn:

★Click Here to Open This Script 

NSDataDetectorで指定できる抽出データのタイプは、

 【日付】 NSTextCheckingTypeDate
 【電話番号】 NSTextCheckingTypePhoneNumber
 【住所】 NSTextCheckingTypeAddress
 【リンクURL】 NSTextCheckingTypeLink
 【フライト情報】 NSTextCheckingTypeTransitInformation

となっており、それぞれテキストからの抽出が可能とあります。そこで、date以外も実際にためしてみました。

AppleScript名:ASOCで各種文字列から電話番号を抽出
– Created 2015-08-21 by Shane Stanley
– Modified 2015-08-21 by Takaaki Naganoya
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set theString to “長野谷隆昌
(Takaaki Naganoya)
maro@piyocast.com
http://piyocast.com/as
2015年8月21日〜23日
080-1111-2222
東京都練馬区中村橋1-2-3

set theDates to (extractPhoneNumberFromNaturalText(theString))
–>  {​​​​​”080-1111-2222″​​​}

on extractPhoneNumberFromNaturalText(aString)
  set anNSString to current application’s NSString’s stringWithString:aString
  
  
set {theDetector, theError} to current application’s NSDataDetector’s dataDetectorWithTypes:(current application’s NSTextCheckingTypePhoneNumber) |error|:(reference)
  
  
set theMatches to theDetector’s matchesInString:anNSString options:0 range:{0, anNSString’s |length|()}
  
set theResults to current application’s NSMutableArray’s array()
  
  
repeat with i from 1 to theMatches’s |count|()
    set thisMatch to (theMatches’s objectAtIndex:(i - 1))
    (
theResults’s addObject:(thisMatch’s phoneNumber()))
  end repeat
  
  
return theResults as list
end extractPhoneNumberFromNaturalText

★Click Here to Open This Script 

AppleScript名:ASOCで各種文字列から住所を抽出
– Created 2015-08-21 by Shane Stanley
– Modified 2015-08-21 by Takaaki Naganoya
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set theString to “長野谷隆昌
(Takaaki Naganoya)
maro@piyocast.com
http://piyocast.com/as
2015年8月21日〜23日
東京都練馬区中村橋1-2-3

set theDates to (extractAddressFromNaturalText(theString))
–>  {{State:”東京都”, Street:”中村橋1-2-3″, City:”練馬区”}}

on extractAddressFromNaturalText(aString)
  set anNSString to current application’s NSString’s stringWithString:aString
  
  
set {theDetector, theError} to current application’s NSDataDetector’s dataDetectorWithTypes:(current application’s NSTextCheckingTypeAddress) |error|:(reference)
  
  
set theMatches to theDetector’s matchesInString:anNSString options:0 range:{0, anNSString’s |length|()}
  
set theResults to current application’s NSMutableArray’s array()
  
  
repeat with i from 1 to theMatches’s |count|()
    set thisMatch to (theMatches’s objectAtIndex:(i - 1))
    (
theResults’s addObject:(thisMatch’s addressComponents()))
  end repeat
  
  
return theResults as list
end extractAddressFromNaturalText

★Click Here to Open This Script 

AppleScript名:ASOCで各種文字列からリンクURLを抽出
– Created 2015-08-21 by Shane Stanley
– Modified 2015-08-21 by Takaaki Naganoya
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set theString to “長野谷隆昌
(Takaaki Naganoya)
maro@piyocast.com
http://piyocast.com/as
2015年8月21日〜23日
080-1111-2222
東京都練馬区中村橋1-2-3

set theDates to (extractLinksFromNaturalText(theString))
–>  {​​​​​(NSURL) mailto:maro@piyocast.com, ​​​​​(NSURL) http://piyocast.com/as​​​}

on extractLinksFromNaturalText(aString)
  set anNSString to current application’s NSString’s stringWithString:aString
  
  
set {theDetector, theError} to current application’s NSDataDetector’s dataDetectorWithTypes:(current application’s NSTextCheckingTypeLink) |error|:(reference)
  
  
set theMatches to theDetector’s matchesInString:anNSString options:0 range:{0, anNSString’s |length|()}
  
set theResults to current application’s NSMutableArray’s array()
  
  
repeat with i from 1 to theMatches’s |count|()
    set thisMatch to (theMatches’s objectAtIndex:(i - 1))
    (
theResults’s addObject:(thisMatch’s |URL|()))
  end repeat
  
  
return theResults as list
end extractLinksFromNaturalText

★Click Here to Open This Script 

AppleScript名:ASOCで各種文字列からフライト情報を抽出
– Created 2015-08-21 by Shane Stanley
– Modified 2015-08-21 by Takaaki Naganoya
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set theString to “UA460 SFO to YVR [Flight] 6/12/2013 United Airlines(UA) #460 dep SFO 7:57pm PDT arr YVR 10:14pm PDT; Ticket #0162360127882, Ticket #0162360127883; conf #K5XBXY; Note:, Seats:—/30A , Seats:—/30B

set theDates to (extractTransitInfoFromNaturalText(theString))
–>  {​​​​​{​​​​​​​Flight:”460″​​​​​}​​​}

on extractTransitInfoFromNaturalText(aString)
  set anNSString to current application’s NSString’s stringWithString:aString
  
  
set {theDetector, theError} to current application’s NSDataDetector’s dataDetectorWithTypes:(current application’s NSTextCheckingTypeTransitInformation) |error|:(reference)
  
  
set theMatches to theDetector’s matchesInString:anNSString options:0 range:{0, anNSString’s |length|()}
  
set theResults to current application’s NSMutableArray’s array()
  
  
repeat with i from 1 to theMatches’s |count|()
    set thisMatch to (theMatches’s objectAtIndex:(i - 1))
    (
theResults’s addObject:(thisMatch’s components()))
  end repeat
  
  
return theResults as list
end extractTransitInfoFromNaturalText

★Click Here to Open This Script 

2015/08/21 El Capitanの各Apple純正ツールのAppleScript用語辞書の変更度合い

なるべくOS X 10.10.5で粘ろうと思っていたのですが、そろそろ潮時かと思い、β版をサブマシンにインストールしました。

US AppleのMailing Listで示されたガイドラインで、「El Capitan上で動作するコードなどについて議論するのはOK。ただし、El Capitan上で撮ったスクリーンショットを掲載してはいけない」というものがあり、ぼちぼち調べて判明したことを載せていこうかと思います。

# OS X 10.11上で動作確認を行ったScriptについては、「10.11 savvy」のタグを追加しています

まずは、まっさきに行うのがAppleScript用語辞書がどの程度変更されたかという調査。

これまで、「AS Dictionary」でAppleScript用語辞書をHTMLに書き出して、HTML同士で比較してきました(そのための書き出し&比較Scriptも書いた)が・・・最近、AppleScript用語辞書(sdefファイル)の分割(include文みたいなもので、外部のsdefを参照する)があちらこちらで行われており(Office 2016とか)、これにAS Dictionaryが対応できていないためsdef同士で(手作業で)比較するようにしました。

elcapitan1.png
※This image was captured on OS X 10.10.5.

El Capitanの辞書とYosemiteの辞書で比較して、明確に変化が認められたものを赤、変化していないものを青、びみょーに変化しているものを黄色でラベルづけしました。

特筆すべきは、変化したもの(赤)ではなく、「変化しなかったもの(青)」です。つまり、OSおよびアプリケーションに機能が追加されても、AppleScript用語辞書にはそれが反映されていない(AppleScriptから直接は叩けない、呼び出せない)ことを意味します。

それはFinderです。タブ(tab)が追加されようがタグ(tag)が追加されようが、用語辞書ではサポートされていません。自分はタブもタグも使っていないので関係なく、タグ(tag)についてはCocoaの機能でいじくれるので問題はないですが、タブ(tab)を操作できないのはちょっとどうかと思います。

# タブ(tab)の位置付けが既存のオブジェクト階層と合わないのかも

その一方で、OS X 10.9あたりから本腰を入れて整備されだしたのが、System Eventsのファイル操作関連の用語。10.11でもずいぶん真剣に実装している様子が伺われます。まるで、Finderがない環境(製品)でも出てくるかのごとく、真剣に取り組んでいる印象を受けます。

たとえばの話ですが、タブレット型のMac(か、噂されているようなOS Xが動くiPad)が出てきたら、そういう環境に近くなることも予想されます。

Script Editorの用語辞書は、sdefに改行が入っていないため比較しづらく、変更があるようなんですが・・・それが多いかどうかはわかりません(多くはないはず)。

久しぶりにDatabase Eventsに変更が加わりましたが、これ使ってる人がどのぐらいいるんでしょう。最近はAppleScriptObjCでCocoaの機能が盛大に使えるので、Database Eventsで何かをしようとはまったく思えません。

Photosは、10.11上のものが正式仕様(本番)で、これが正念場。これでダメなら本当に(担当者が)ダメなんでしょう。

Calendarが微妙に頑張っている印象。Messagesは、何かの機能が減っていました。まだリリース版ではないため、今秋までに(たぶん10月末)何か変更が加わるかもしれません。

2015/08/20 ASOCでdate pickerによる日付選択

Shane StanleyのScript Library「BridgePlus」の機能を用いた日付/時刻選択インタフェース「date picker」による日付/時刻選択を行うAppleScriptです。実行には、あらかじめBridgePlusをインストールしておく必要があります。

datepicker1.png
▲ASObjC Explorer 4での実行画面

datepicker2.png
▲Script Editorでの実行画面(Control-Command-R)

そうそう、こういうのが(OS標準で)欲しかったんですよね〜。あと、開始日と終了日の選択とか、休日を選択できないようにできるといいかも。

AppleScript名:ASOCでdate pickerによる日付選択
– Created 2015-08-20 by Shane Stanley
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
use script “BridgePlus” – for pre-10.11 compatibility

if not (current application’s NSThread’s isMainThread()) as boolean then
  display alert “This script must be run from the main thread.” buttons {“Cancel”} as critical
  
error number -128
end if

– create a view
set theView to current application’s NSView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, 100, 200))

– create date picker
set datePicker to current application’s NSDatePicker’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, 100, 100))

– set style: choices are NSTextFieldAndStepperDatePickerStyle, NSClockAndCalendarDatePickerStyle, or NSTextFieldDatePickerStyle
datePicker’s setDatePickerStyle:(current application’s NSClockAndCalendarDatePickerStyle)

– set elements: choices include NSHourMinuteDatePickerElementFlag, NSHourMinuteSecondDatePickerElementFlag, NSTimeZoneDatePickerElementFlag, NSYearMonthDatePickerElementFlag, and NSEraDatePickerElementFlag
datePicker’s setDatePickerElements:((current application’s NSYearMonthDayDatePickerElementFlag) + (current application’s NSHourMinuteSecondDatePickerElementFlag as integer))

– set initial date
datePicker’s setDateValue:(current application’s NSDate’s |date|())

– get the size it needs
set theSize to datePicker’s fittingSize()

–resize the picker and view accordingly
theView’s setFrameSize:theSize
datePicker’s setFrameSize:theSize

– add the picker to the view
theView’s setSubviews:{datePicker}

– create an alert
set theAlert to current application’s NSAlert’s alloc()’s init()

– set up alert
tell theAlert
  its setMessageText:“Pick a date”
  
its setInformativeText:“Any date”
  
its addButtonWithTitle:“OK”
  
its addButtonWithTitle:“Cancel”
  
its setAccessoryView:theView
end tell

– show alert in modal loop
set returnCode to theAlert’s runModal()
if returnCode = (current application’s NSAlertSecondButtonReturn) then error number -128

– retrieve date
set theDate to ASify from (datePicker’s dateValue()) – or simply coerce to date in 10.11

–>  date “2015年8月20日木曜日 19:43:58″

★Click Here to Open This Script 

2015/08/20 ASOCで動的にWindowを作成

Cocoaの機能を用いて動的にWindowを作成し、メッセージを表示したあとにWindowを消すAppleScriptです。

dispcustomwin.png

Mac OS X登場当時から、こうしたカスタムメッセージ表示用の部品の必要性がひろくscripterに認識されており、さまざまな実装が試されたなか・・・OS Xのnotification center(display notificationでAppleScriptからも表示可能)に集約されていったという歴史があります。

notification.png

オリジナルは、edama2さんの「Okaeri(シンプル版)」のコードで、そこから大幅に機能を簡略化し、当時のCocoa AppleScript Appletから、OS X 10.10上のAppleScriptObjC向けに書き換えたものです。

dispcustomwin2_resized.png

AppleScript側から汎用的にメッセージを表示させるサブルーチンに変更してみました。かなり手軽に使えます。ASOCはARC環境で動いているので、Windowオブジェクトを明示的にReleaseしてあげる必要はないはずですが・・・さて?

# 連続して実行すると3回目に表示がおかしくなるのは、、、何か足りないかも、、、まだ油断できないレベルです

Shaneから「foreground/main threadから実行する必要があるよ」という指摘があり、ASObjC Explorer 4では問題なく連続して何回でも実行できることを確認。Script EditorだとCommand-Control-Rを実行して、表示がすぐに消えたりやっぱり3回目にScript Editorごとクラッシュしたりと不思議な現象が(ーー;;;

AppleScript名:ASOCで動的にWindowを作成
– Created 2012-06-13 by edama2
– Modified 2015-08-20 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”

if not (current application’s NSThread’s isMainThread()) as boolean then
  display alert “This script must be run from the main thread (Command-Control-R in Script Editor).” buttons {“Cancel”} as critical
  
error number -128
end if

set aWin to makeWinWithMessage(“Piyomaru Software”, “Custom Message From Takaaki Naganoya”)
tell current application
  delay 5
end tell
my closeWin:aWin

–ウィンドウを作成
on makeWinWithMessage(aTitle, aMes)
  
  
set aScreen to current application’s NSScreen’s mainScreen()
  
set aFrame to {{0, 0}, {800, 250}}
  
set aBacking to current application’s NSTitledWindowMask
  
set aDefer to current application’s NSBackingStoreBuffered
  
  
– Window
  
set aWin to current application’s NSWindow’s alloc()
  (
aWin’s initWithContentRect:aFrame styleMask:aBacking backing:aDefer defer:false screen:aScreen) –’s autorelease()
  
aWin’s setBackgroundColor:(current application’s NSColor’s whiteColor())
  
  
aWin’s setTitle:aTitle
  
aWin’s setDelegate:me
  
aWin’s setDisplaysWhenScreenProfileChanges:true
  
aWin’s setHasShadow:true
  
aWin’s setIgnoresMouseEvents:true
  
aWin’s setLevel:(current application’s NSNormalWindowLevel)
  
aWin’s setOpaque:false
  
aWin’s setReleasedWhenClosed:true
  
aWin’s |center|()
  
aWin’s makeKeyAndOrderFront:(me)
  
  
– Custom View
  
set aCustView to current application’s NSView’s alloc()
  
aCustView’s initWithFrame:aFrame
  
aCustView’s setNeedsDisplay:true
  
set {origin:{x:x, y:y}, |size|:{width:w, height:h}} to aCustView’s |bounds|()
  
aWin’s setContentView:aCustView
  
  
– Text View
  
set aTV2 to current application’s NSTextView’s alloc()
  
  
set titleHeight to 26
  
set y2 to h - titleHeight - (titleHeight / 6)
  
set y3 to h - titleHeight
  
set y3 to h - y3 - (y3 / 6)
  
  
aTV2’s initWithFrame:{{0, y3}, {w, y2}}
  
aTV2’s insertText:aMes
  
aTV2’s setAlignment:(current application’s NSCenterTextAlignment)
  
aTV2’s setDrawsBackground:false
  
aTV2’s setEditable:false
  
aTV2’s setFont:(current application’s NSFont’s fontWithName:“HiraMinPro-W3″ |size|:72)
  
aTV2’s setSelectable:false
  
aTV2’s setTextColor:(current application’s NSColor’s blackColor())
  
aCustView’s addSubview:aTV2
  
  
–aWin’s setBackgroundColor:(current application’s NSColor’s clearColor())
  
  
return aWin
  
end makeWinWithMessage

–ウィンドウを閉じる
on closeWin:aWindow
  delay 3
  
repeat with n from 10 to 1 by -1
    (aWindow’s setAlphaValue:n / 10)
    
delay 0.02
  end repeat
  
aWindow’s |close|()
end closeWin:

★Click Here to Open This Script 

2015/08/20 ASOCでスレッド処理?

Cocoaの機能を用いて、NSThreadによる並列処理のテストを行うAppleScriptです。

画像ファイルにCIFilterによるフィルタ処理を行ったのちにリサイズし、仕上げに再度CIFilterによるリサイズを行う・・・そういう処理を書いて、リサイズ前に画像にフィルタをかけるのにはそれなりに時間がかかったため、複数の画像ファイルを同時に並列で処理できるといいんじゃないか、というのがテストを行った趣旨です。

テストに用いたのがsyslogにコメントを残すという処理なので、このテスト用の処理自体があまりふさわしくないのかもしれないですが、期待していたよりも重い感じです。

とりあえず、100個(ぐらい)の画像のリサイズをシーケンシャルに順次処理する場合と、並列で(実行環境に存在するCPUのコア数を鑑みつつ並列数を決定)処理する場合とで、実際に速度を計測してみるとよいと思われます。

AppleScript名:ASOCでスレッド処理?
– Created 2015-08-20 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set aThread to current application’s NSThread’s alloc()’s initWithTarget:me selector:"_threadLoop:" object:(current application’s NSString’s stringWithString:"Apple")

set bThread to current application’s NSThread’s alloc()’s initWithTarget:me selector:"_threadLoop:" object:(current application’s NSString’s stringWithString:"Orange")

set aRes to current application’s NSThread’s isMultiThreaded()
–>  true

set bRes to current application’s NSThread’s currentThread()
–>  (NSThread) <NSThread: 0×600000068a00>{number = 1, name = main}

set a1Res to current application’s NSThread’s currentThread()’s threadDictionary()
–>  (NSDictionary) {NSAppleEventManagerHandlingStack:{}, NSDocumentsContinuingFileAccess:(NSSet) {}, OSADefaultComponentInstanceKey:(OSAComponentInstance) <OSAComponentInstance: 0×618000215970>, OSADefaultLanguageKey:(OSALanguage) <OSALanguage: 0×6180002159a0>, OSAAvailableLanguagesKey:{(OSALanguage) <OSALanguage: 0×618000215980>, (OSALanguage) <OSALanguage: 0×6180002159a0>, (OSALanguage) <OSALanguage: 0×600000217a80>}}

set cRes to current application’s NSThread’s callStackReturnAddresses()
–>  (NSArray) {140735481653180, 140735481652754, 140735559055105, 140735559057361, 4473123264, 4473263701, 4473142396, 4473141941, 4472935365, 4472916653, 140735705914913, 140735481264735, 4400422881, 4400227287, 140735611717816, 140735611717253, 140735611714364, 140735611713043, 140735453174803, 140735453224127, 140735482160121, 140735481878159, 140735481875416, 140735475504495, 140735475503850, 140735475503403, 140735666104491, 140735666101848, 140735666060019, 140735665521220, 140735553762761, 1}

set dRes to current application’s NSThread’s callStackSymbols()
–>  (NSArray) {"0 CoreFoundation 0×00007fff886427bc __invoking___ + 140", " …… (omit)

aThread’s setName:"Apple"
bThread’s setName:"Orange"

aThread’s |threadPriority|()
–> 0.5 –(0.0〜1.0)

set c1Res to aThread’s |name|()
–>  (NSString) "Apple"
set c2Res to bThread’s |name|()
–>  (NSString) "Orange"

aThread’s threadDictionary()
–>  (NSDictionary) {}

aThread’s stackSize()
–>  524288 –this depends on each machine’s memory configuration?

aThread’s isExecuting()
–>  false

aThread’s isFinished()
–>  false

aThread’s isCancelled()
–>  false

set noter1 to current application’s NSNotificationCenter’s defaultCenter()
noter1’s addObserver:me selector:"_threadWillExit:" |name|:(current application’s NSThreadWillExitNotification) object:aThread
noter1’s addObserver:me selector:"_threadWillExit:" |name|:(current application’s NSThreadWillExitNotification) object:bThread

aThread’s start()
bThread’s start()

–各Threadが実行するハンドラ
on _threadLoop:aInfo
  repeat 3 times
    set aText to aInfo as text
    
do shell script "logger -s " & quoted form of aText & " &"
    
set aNum to random number from 1 to 3
    
delay aNum
  end repeat
end _threadLoop:

–Threadが終了する際に呼ばれるハンドラ
on _threadWillExit:aNotification
  
  
set tmpRes to aNotification’s object’s |name|()
  
say ((tmpRes as text) & " finished.") using "Alex"
  
end _threadWillExit:

★Click Here to Open This Script 

2015/08/19 ASOCで選択した画像をリサイズ v3

Cocoaの機能を使って指定画像を指定サイズにリサイズ(縮小Only)するAppleScriptです。

CIFilterを使って、縮小前にぼかしフィルタを、縮小後にシャープネスフィルタをかけています。

いろいろテストしていたのですが、

  「フィルタ処理するたびに画像が右上にズレるのはなぜ??」

とちょっと悩んでいました・・・どうやら、当初指定していたぼかしフィルタ(Gaussian Blur)の仕様ではないかと考え、別のぼかしフィルタ(CIBoxBlur)に変更したところ、右上への移動問題が発生しなくなりました。

処理結果に癖があるのとフィルタすると処理時間もそれなりにかかるので、Photoshopを使わない処理のほうがよい・・・ともいいにくいものがあります(「餅は餅屋」という表現がぴったり、、、)。ただし、並列処理で大量の画像を処理するような場合にはこっちを使うことになるでしょう(たぶん)。

resized10.png
▲Resized by this AppleScript

resized21.png
▲Resized by other AppleScript using Photoshop

後日談:
指定のフォルダに入っている画像を順次リサイズするように記述してみたところ、1ファイル処理したときに数秒(1〜3秒?)待たされたのがウソのように高速に(^ー^;; 1.3〜6.4MBのPNGファイルを200個処理してみたところ、所要時間55.35秒。画像1枚あたり0.28秒(MacBook Pro Retina 2012)。なかなか高速です。

AppleScript名:ASOCで選択した画像をリサイズ v3
– Created 2015-08-19 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
use framework “QuartzCore”

set targW to 450 –Target Width (Pixel)

set aPath to POSIX path of (choose file of type {“public.image”})
set aURL to current application’s |NSURL|’s fileURLWithPath:aPath

–指定したURLから画像を読み込み
set aImage to current application’s NSImage’s alloc()’s initWithContentsOfURL:aURL

–出力ファイル名を組み立てる
set aStr to current application’s NSString’s stringWithString:aPath
set bStr to (aStr’s stringByDeletingPathExtension()) as text
set outPath to bStr & “_resized” & “.png” –pngで出力

–ぼかしフィルタ
set aDict to current application’s NSDictionary’s dictionaryWithObjects:{current application’s NSNumber’s numberWithFloat:(2.0 as real)} forKeys:{“inputRadius”}
set bImage to execFilterToNSImage(aImage, “CIBoxBlur”, aDict)

–リサイズ
set cImage to resizeNSImage(targW, bImage)

–シャープフィルタ
set bDict to current application’s NSDictionary’s dictionaryWithObjects:{current application’s NSNumber’s numberWithFloat:(1.0 as real)} forKeys:{“inputSharpness”}
set dImage to execFilterToNSImage(cImage, “CISharpenLuminance”, bDict)

–ファイル保存
set aRes to saveImageRepAtPathAsPNG(dImage, outPath)

–指定画像を指定の横幅に縦横比を維持したままリサイズ
on resizeNSImage(targW, aImage)
  
  
–とりあえずImageからサイズの情報を取得
  
set sizeInfo to |size|() of aImage
  
  
set wNum to (width of sizeInfo) as integer
  
set hNum to (height of sizeInfo) as integer
  
  
  
–ターゲット横サイズをもとに、縦横のターゲットサイズを計算
  
if wNum > targW then
    –横幅がターゲットサイズよりも大きかった場合
    
set newRatioW to targW / wNum
    
set newRatioH to (hNum * newRatioW)
    
    
set newW to (wNum * newRatioW) as integer
    
set newH to (hNum * newRatioW) as integer
  else
    –横幅がターゲットサイズよりも小さかった場合はオリジナルサイズでそのまま
    
set newW to wNum
    
set newH to hNum
  end if
  
  
  
set tmpSize to current application’s NSZeroSize
  
set tmpSize’s width to newW as real
  
set tmpSize’s height to newH as real
  
  
set resImg to current application’s NSImage’s alloc()’s initWithSize:tmpSize
  
  
resImg’s lockFocus()
  
  
set aTransform to current application’s NSAffineTransform’s transform()
  
aTransform’s scaleBy:(newRatioW as real)
  
aTransform’s concat()
  
aImage’s drawAtPoint:(current application’s NSZeroPoint) fromRect:(current application’s NSZeroRect) operation:(current application’s NSCompositeCopy) fraction:1.0
  
  
resImg’s unlockFocus()
  
  
return resImg
  
end resizeNSImage

–画像を指定パスにPNG形式で保存
on saveImageRepAtPathAsPNG(anImage, outPath)
  
  
–画像のRaw画像を作成
  
set imageRep to anImage’s TIFFRepresentation()
  
set aRawimg to current application’s NSBitmapImageRep’s imageRepWithData:imageRep
  
  
–書き出しファイルパス情報を作成
  
set pathString to current application’s NSString’s stringWithString:outPath
  
set newPath to pathString’s stringByExpandingTildeInPath()
  
  
–書き出し
  
set myNewImageData to (aRawimg’s representationUsingType:(current application’s NSPNGFileType) |properties|:(missing value))
  
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
  
  
return aRes –成功ならtrue、失敗ならfalseが返る
  
end saveImageRepAtPathAsPNG

–NSImageにCIFilterを実行して返す
on execFilterToNSImage(aNSImage, aFilterName, aParamDic)
  
  
–NSImageからCIImageを生成
  
set aTiff to aNSImage’s TIFFRepresentation()
  
set aBitmap to current application’s NSBitmapImageRep’s imageRepWithData:aTiff
  
set aCIImage to current application’s CIImage’s alloc()’s initWithBitmapImageRep:aBitmap
  
  
– CIFilter をフィルタの名前で生成してフィルタ実行
  
set aFilter to current application’s CIFilter’s filterWithName:aFilterName
  
aFilter’s setDefaults() –各フィルタのパラメータはデフォルト
  
aFilter’s setValuesForKeysWithDictionary:aParamDic
  
aFilter’s setValue:aCIImage forKey:“inputImage”
  
set aOutImage to aFilter’s valueForKey:“outputImage”
  
  
  
–フィルター結果のbitmapImageRepをNSImageに変換して返す
  
set aRep to current application’s NSBitmapImageRep’s alloc()’s initWithCIImage:aOutImage
  
set outImage to current application’s NSImage’s alloc()’s initWithSize:(aRep’s |size|())
  
outImage’s addRepresentation:aRep
  
  
return outImage –NSImage
  
end execFilterToNSImage

★Click Here to Open This Script 

2015/08/19 ASOCで選択した画像をリサイズ v2

Cocoaの機能を使って指定画像を指定サイズにリサイズ(縮小Only)するAppleScriptです。

汎用的に利用できるように、リサイズルーチンとファイル保存ルーチンを分離しました。NSImageによる値渡し(call by value)で処理を行っています。

resized1.png
▲Resized by this AppleScript

resized2.png
▲Resized by other AppleScript using Photoshop

resized7.png
▲Resized by other AppleScript using Cocoa CIFilter

AppleScript名:ASOCで選択した画像をリサイズ v2
– Created 2015-08-19 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”

set targW to 450 –Target Width (Pixel)

set aPath to POSIX path of (choose file of type {“public.image”})
set aURL to current application’s |NSURL|’s fileURLWithPath:aPath

–指定したURLから画像を読み込み
set aImage to current application’s NSImage’s alloc()’s initWithContentsOfURL:aURL

–出力ファイル名を組み立てる
set aStr to current application’s NSString’s stringWithString:aPath
set bStr to (aStr’s stringByDeletingPathExtension()) as text
set outPath to bStr & “_resized” & “.png” –pngで出力

–リサイズ
set bImage to resizeNSImage(targW, aImage)

–ファイル保存
set aRes to saveImageRepAtPathAsPNG(bImage, outPath)

–指定画像を指定の横幅に縦横比を維持したままリサイズ
on resizeNSImage(targW, aImage)
  
  
–とりあえずImageからサイズの情報を取得
  
set sizeInfo to |size|() of aImage
  
  
set wNum to (width of sizeInfo) as integer
  
set hNum to (height of sizeInfo) as integer
  
  
  
–ターゲット横サイズをもとに、縦横のターゲットサイズを計算
  
if wNum > targW then
    –横幅がターゲットサイズよりも大きかった場合
    
set newRatioW to targW / wNum
    
set newRatioH to (hNum * newRatioW)
    
    
set newW to (wNum * newRatioW) as integer
    
set newH to (hNum * newRatioW) as integer
  else
    –横幅がターゲットサイズよりも小さかった場合はオリジナルサイズでそのまま
    
set newW to wNum
    
set newH to hNum
  end if
  
  
  
set tmpSize to current application’s NSZeroSize
  
set tmpSize’s width to newW as real
  
set tmpSize’s height to newH as real
  
  
set resImg to current application’s NSImage’s alloc()’s initWithSize:tmpSize
  
  
resImg’s lockFocus()
  
  
set aTransform to current application’s NSAffineTransform’s transform()
  
aTransform’s scaleBy:(newRatioW as real)
  
aTransform’s concat()
  
aImage’s drawAtPoint:(current application’s NSZeroPoint) fromRect:(current application’s NSZeroRect) operation:(current application’s NSCompositeCopy) fraction:1.0
  
  
resImg’s unlockFocus()
  
  
return resImg
  
end resizeNSImage

–画像を指定パスにPNG形式で保存
on saveImageRepAtPathAsPNG(anImage, outPath)
  
  
–画像のRaw画像を作成
  
set imageRep to anImage’s TIFFRepresentation()
  
set aRawimg to current application’s NSBitmapImageRep’s imageRepWithData:imageRep
  
  
–書き出しファイルパス情報を作成
  
set pathString to current application’s NSString’s stringWithString:outPath
  
set newPath to pathString’s stringByExpandingTildeInPath()
  
  
–書き出し
  
set myNewImageData to (aRawimg’s representationUsingType:(current application’s NSPNGFileType) |properties|:(missing value))
  
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
  
  
return aRes –成功ならtrue、失敗ならfalseが返る
  
end saveImageRepAtPathAsPNG

★Click Here to Open This Script 

2015/08/19 ASOCで選択した画像をリサイズ

Cocoaの機能を使って指定画像を指定サイズにリサイズ(縮小Only)するAppleScriptです。

実験レベルの実装なんで、あんまり自由度は持たせていません。強制的にPNGで保存します。

resize0.png
▲Resized By This AppleScript

resize1.png
▲Resized By other AppleScript using Photoshop

仕上がりのクオリティーについては、Photoshopでさまざまなフィルタ処理を行いつつリサイズするScriptにくらべれば落ちますが、Cocoaのフィルタ処理を追加してみるとよいかもしれません。

resizedwithciimage2.png
▲その後、CoreImageでフィルタしつつリサイズするようにしたScriptの処理結果。パラメータの設定やフィルタの種類を選ぶ余地がありそうな、、、

AppleScript名:ASOCで選択した画像をリサイズ
– Created 2015-08-19 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”

set targW to 450 –Target Width (Pixel)
set aPath to POSIX path of (choose file of type {“public.image”})
set aRes to resizeImage(targW, aPath)

–指定画像を指定の横幅に縦横比を維持したままリサイズ
on resizeImage(targW, origimgPath)
  
  
–出力ファイル名を組み立てる
  
set aStr to current application’s NSString’s stringWithString:origimgPath
  
set bStr to (aStr’s stringByDeletingPathExtension()) as text
  
set cStr to (aStr’s pathExtension()) as text
  
set dStr to bStr & “_resized” & “.png” –pngで出力
  
  
–オリジナル画像のPOSIX pathをCocoaのNSURLに変換
  
set aURL to current application’s |NSURL|’s fileURLWithPath:origimgPath
  
  
–指定したURLから画像を読み込み
  
set aImage to current application’s NSImage’s alloc()’s initWithContentsOfURL:aURL
  
  
–とりあえずImageからサイズの情報を取得
  
set sizeInfo to |size|() of aImage
  
  
set wNum to (width of sizeInfo) as integer
  
set hNum to (height of sizeInfo) as integer
  
  
  
–ターゲット横サイズをもとに、縦横のターゲットサイズを計算
  
if wNum > targW then
    –横幅がターゲットサイズよりも大きかった場合
    
set newRatioW to targW / wNum
    
set newRatioH to (hNum * newRatioW)
    
    
set newW to (wNum * newRatioW) as integer
    
set newH to (hNum * newRatioW) as integer
  else
    –横幅がターゲットサイズよりも小さかった場合はオリジナルサイズでそのまま
    
set newW to wNum
    
set newH to hNum
  end if
  
  
  
set tmpSize to current application’s NSZeroSize
  
set tmpSize’s width to newW as real
  
set tmpSize’s height to newH as real
  
  
set resImg to current application’s NSImage’s alloc()’s initWithSize:tmpSize
  
  
resImg’s lockFocus()
  
  
set aTransform to current application’s NSAffineTransform’s transform()
  
aTransform’s scaleBy:(newRatioW as real)
  
aTransform’s concat()
  
aImage’s drawAtPoint:(current application’s NSZeroPoint) fromRect:(current application’s NSZeroRect) operation:(current application’s NSCompositeCopy) fraction:1.0
  
  
resImg’s unlockFocus()
  
  
set aRes to saveImageRepAtPathAsPNG(resImg, dStr)
  
return aRes
  
end resizeImage

–画像を指定パスにPNG形式で保存
on saveImageRepAtPathAsPNG(anImage, outPath)
  
  
–画像のRaw画像を作成
  
set imageRep to anImage’s TIFFRepresentation()
  
set aRawimg to current application’s NSBitmapImageRep’s imageRepWithData:imageRep
  
  
–書き出しファイルパス情報を作成
  
set pathString to current application’s NSString’s stringWithString:outPath
  
set newPath to pathString’s stringByExpandingTildeInPath()
  
  
–書き出し
  
set myNewImageData to (aRawimg’s representationUsingType:(current application’s NSPNGFileType) |properties|:(missing value))
  
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
  
  
return aRes –成功ならtrue、失敗ならfalseが返る
  
end saveImageRepAtPathAsPNG

★Click Here to Open This Script 

2015/08/18 ASOCで無線LANの各種情報を取得する v2

Cocoaの機能を用いて無線LANの各種情報を取得するAppleScriptです。Shane Stanleyから「こんなやり方もあるよ」と教えてもらったものです。

CoreWLANまわりをいろいろ探ってみたものの、どーもCFSTR(ASOCで扱えない)を作成できないと呼べない機能などに阻まれ、あんまり凝ったことはできなさそうです。

[Update] WiFiがオフになっている場合への対処、およびv1のテストコードを統合しました。基本的にv1を短く書いたもので、機能は同じです。

AppleScript名:ASOCで無線LANの各種情報を取得する v2.1
– Created 2015-08-18 by Shane Stanley
– Modified 2015-08-18 by Takaaki Naganoya
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “CoreWLAN”

set allNames to current application’s CWInterface’s interfaceNames()’s allObjects()
–>  (NSArray) {”en0″} –@MacBook Pro Retina 2012

set hitF to false
repeat with i from 1 to allNames’s |count|()
  set aInterface to (current application’s CWInterface’s interfaceWithName:(allNames’s objectAtIndex:(i - 1)))
  
if aInterface’s serviceActive() as boolean then
    set hitF to true
    
exit repeat
  end if
end repeat

if hitF = false then return false –ActiveなWLANがない場合(WiFiをオフにしている)にはfalseをリターン

set aChan to aInterface’s wlanChannel()
–> (CWChannel) [channelNumber=52(5GHz), channelWidth={40MHz(+1)}, DFS]

set chanNumber to aChan’s channelNumber()
–> 52
set chanBand to aChan’s channelBand() – 0 = unknown, 1 = 2GHz, 2 = 5GHz
–> 2
set chanWidth to aChan’s channelWidth() – 0 = unknown, 1 = 20MHz, 2 = 40MHz
–> 2
set aTransRate to aInterface’s transmitRate()
–>  162.0
set aPower to aInterface’s transmitPower()
–>  0

set aChannnels to aInterface’s supportedWLANChannels()
–>  (NSSet) {(CWChannel) [channelNumber=1(2GHz), channelWidth={20MHz}, active], (CWChannel) [channelNumber=2(2GHz), channelWidth={20MHz}, active], ……………(CWChannel) [channelNumber=64(5GHz), channelWidth={20MHz}, DFS], (CWChannel) [channelNumber=136(5GHz), channelWidth={20MHz}, DFS]}

set aSSIDdata to aInterface’s ssidData()
–>  (NSData) <45787472 xxxxxxxx xxxxxxxx xxxx>

set aSSID to aInterface’s ssid() as text
–>  ”Extreme net_5G”

set aActive to aInterface’s serviceActive()
–>  true

set aSecurity to aInterface’s security()
–>  4

set aRSSIval to aInterface’s rssiValue()
–>  -72

set aPower to aInterface’s powerOn()
–>  true

set aNoise to aInterface’s noiseMeasurement()
–>  -91

set aIFname to aInterface’s interfaceName() as text
–>  ”en0″

set aMode to aInterface’s interfaceMode()
–>  1

set aHWAddress to aInterface’s hardwareAddress() as text
–>  ”b8:xx:xx:xx:xx:xx”–MAC Address

set aCountry to aInterface’s countryCode() as text
–>  ”JP”

set aConfig to aInterface’s configuration()
–>  (CWConfiguration)

set aCacheRes to aInterface’s cachedScanResults()
–>  (NSSet) {(CWNetwork) ……………… [channelNumber=11(2GHz), channelWidth={20MHz}], ibss=0]}

set aBSSID to aInterface’s bssid() as text
–>  ”10:XX:XX:XX:XX:XX”

set aPhyMode to aInterface’s activePHYMode()
–>  4

★Click Here to Open This Script 

2015/08/18 ASOCで無線LANの各種情報を取得する

Cocoaの機能を用いて無線LANの各種情報を取得するAppleScriptです。CoreWLAN.frameworkの機能(CWInterface)を使っています。

実行結果をみると、 transmitPower() だけ不思議な(アクティブになっているのに0が返ってくる)感じです。

AppleScript名:ASOCで無線LANの各種情報を取得する
– Created 2015-08-18 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “CoreWLAN”

set dName to getWiFiDeviceName()
–> “en0″ –(example on MacBook Pro Retina 2012)

set aInterface to current application’s CWInterface’s alloc()’s initWithInterfaceName:dName
–>(CWInterface) [interfaceName=en0]

set aChan to aInterface’s wlanChannel()
–>  (CWChannel) [channelNumber=52(5GHz), channelWidth={40MHz(+1)}, DFS]

set aTransRate to aInterface’s transmitRate()
–>  162.0

set aPower to aInterface’s transmitPower()
–>  0

set aChannnels to aInterface’s supportedWLANChannels()
–>  (NSSet) {(CWChannel) [channelNumber=1(2GHz), channelWidth={20MHz}, active], (CWChannel) [channelNumber=2(2GHz), channelWidth={20MHz}, active], ……………(CWChannel) [channelNumber=64(5GHz), channelWidth={20MHz}, DFS], (CWChannel) [channelNumber=136(5GHz), channelWidth={20MHz}, DFS]}

set aSSIDdata to aInterface’s ssidData()
–>  (NSData) <45787472 xxxxxxxx xxxxxxxx xxxx>

set aSSID to aInterface’s ssid() as text
–>  ”Extreme net_5G”

set aActive to aInterface’s serviceActive()
–>  true

set aSecurity to aInterface’s security()
–>  4

set aRSSIval to aInterface’s rssiValue()
–>  -72

set aPower to aInterface’s powerOn()
–>  true

set aNoise to aInterface’s noiseMeasurement()
–>  -91

set aIFname to aInterface’s interfaceName() as text
–>  ”en0″

set aMode to aInterface’s interfaceMode()
–>  1

set aHWAddress to aInterface’s hardwareAddress() as text
–>  ”b8:xx:xx:xx:xx:xx”–MAC Address

set aCountry to aInterface’s countryCode() as text
–>  ”JP”

set aConfig to aInterface’s configuration()
–>  (CWConfiguration)

set aCacheRes to aInterface’s cachedScanResults()
–>  (NSSet) {(CWNetwork) ……………… [channelNumber=11(2GHz), channelWidth={20MHz}], ibss=0]}

set aBSSID to aInterface’s bssid() as text
–>  ”10:XX:XX:XX:XX:XX”

set aPhyMode to aInterface’s activePHYMode()
–>  4

–指定ハードウェアポートのデバイス名を取得する
on getWiFiDeviceName()
  set v2 to system attribute “sys2″ –> 4
  
if v2 6 then
    set hardWareName to “AirPort” –Under Mac OS X 10.6.8
    
set aMesStr to “Current AirPort Network: “
  else if v2 7 then
    set hardWareName to “Wi-Fi” –Mac OS X 10.7 or later
    
set aMesStr to “Current Wi-Fi Network: “
  else
    display dialog “error”
  end if
  
  
set dName to getHardwareDeviceName(hardWareName) of me
  
return dName
end getWiFiDeviceName

–指定ハードウェアポートのデバイス名を取得する
on getHardwareDeviceName(targName)
  set sRes to do shell script “/usr/sbin/networksetup -listallhardwareports”
  
log sRes
  
set sList to paragraphs of sRes
  
set s1List to items 2 thru -1 of sList
  
  
set s2List to {}
  
repeat with i in s1List
    set j to contents of i
    
if j is equal to “VLAN Configurations” then
      exit repeat
    end if
    
set the end of s2List to j
  end repeat
  
  
–ネットワークポート関連のレコードを作成
  
set s3List to {}
  
set aLen to length of s2List
  
repeat with i from 1 to aLen by 4
    set a1Item to contents of item i of s2List
    
set a1Item to repChar(a1Item, “Hardware Port: “, “”) of me
    
    
set a2Item to contents of item (i + 1) of s2List
    
set a2Item to repChar(a2Item, “Device: “, “”) of me
    
    
set a3Item to contents of item (i + 2) of s2List
    
set a3Item to repChar(a3Item, “Ethernet Address: “, “”) of me
    
    
set the end of s3List to {hardwarePort:a1Item, device:a2Item, ethernetAddress:a3Item}
  end repeat
  
  
repeat with i in s3List
    set j1 to hardwarePort of i
    
set j2 to device of i
    
if j1 is equal to targName then
      return j2
    end if
  end repeat
  
  
return “”
  
end getHardwareDeviceName

–文字置換ルーチン
on repChar(origText, targStr, repStr)
  set {txdl, AppleScript’s text item delimiters} to {AppleScript’s text item delimiters, targStr}
  
set temp to text items of origText
  
set AppleScript’s text item delimiters to repStr
  
set res to temp as text
  
set AppleScript’s text item delimiters to txdl
  
return res
end repChar

★Click Here to Open This Script 

2015/08/18 ASOCで与えられた画像ファイルがNSImageでハンドリング可能かを取得

Cocoaの機能を用いて、NSImageで取り扱いが可能な画像かどうかをチェックするAppleScript(chkNSImageAcceptableFormat)です。

以前に、sipsによる画像変換ルーチンをまとめたときに、処理可能なファイルタイプのチェックをあらかじめ拡張子の2D Listを作成しておき、

{{”jpeg”, “jpg”}, {”tiff”, “tif”}, {”png”}, {”gif”, “giff”}, {”jp2″}, {”pict”}, {”bmp”}, {”qtif”}, {”psd”}, {”sgi”}, {”tga”}, {”pdf”}}

これをループで回して画像タイプのチェックおよびファイル形式指定の修正(”jpg”と指定されても”jpeg”に修正)を行うなど、Pure AppleScriptらしいやりかたで処理していました。

これに対して、本ScriptではNSWorkspaceの機能を用いてファイルタイプ(UTI)を取得(拡張子による揺らぎを吸収)、NSImageが受付可能かどうかは imageTypes() でUTIの一覧を取得して、両者を存在確認することでNSImageで処理可能かどうかをチェックしている点が非常に参考になります。

ただし、sipsコマンドについてもNSImageについてもcom.apple.pict(PICTファイル)についてはCarbon(QuickDraw)が必要で32bitアプリ内でしか処理できないため、sipsそのものおよびScript Editor上で記述できるASOC(64bit環境が前提)でNSImageを利用した場合では処理できません。なんでPICTが処理できると返ってくるのか、逆に不思議です。

→ PICTからJPEGへの変換はこちら

AppleScript名:ASOCで与えられた画像ファイルがNSImageでハンドリング可能かを取得
– Created 2015-08-18 by Shane Stanley
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set oldPath to POSIX path of (choose file of type {“public.image”})
set aRes to convertPictureFileAt(oldPath, “JPEG”)

on convertPictureFileAt(aPath, targetFormatExt)
  set aRes to chkNSImageAcceptableFormat(aPath, targetFormatExt)
  
set bRes to chkIsThereNeedToConvert(aPath, targetFormatExt)
  
return {aRes, bRes}
  
  
–convert images
  
end convertPictureFileAt

–与えられた画像ファイルがNSImageでハンドリング可能かを取得
on chkNSImageAcceptableFormat(aPath as text, targetFormatExt as text)
  
  
– check if UTI of file is one NSImage can read
  
set theWorkspace to current application’s NSWorkspace’s sharedWorkspace()
  
set theType to theWorkspace’s typeOfFile:aPath |error|:(missing value) – returns UTI of file
  
–>  (NSString) “public.jpeg”
  
  
set supportedTypes to current application’s NSImage’s imageTypes() – returns supported UTIs
  
–>  (NSArray) {”com.adobe.pdf”, “com.apple.pict”, “com.adobe.encapsulated-postscript”, “public.jpeg”, “public.png”, “com.compuserve.gif”, “public.jpeg-2000″, “com.canon.tif-raw-image”, “com.adobe.raw-image”, “com.dxo.raw-image”, “com.canon.cr2-raw-image”, “com.leafamerica.raw-image”, “com.hasselblad.fff-raw-image”, “com.hasselblad.3fr-raw-image”, “com.nikon.raw-image”, “com.nikon.nrw-raw-image”, “com.pentax.raw-image”, “com.samsung.raw-image”, “com.sony.raw-image”, “com.sony.sr2-raw-image”, “com.sony.arw-raw-image”, “com.epson.raw-image”, “com.kodak.raw-image”, “public.tiff”, “com.apple.icns”, “com.canon.crw-raw-image”, “com.fuji.raw-image”, “com.panasonic.raw-image”, “com.panasonic.rw2-raw-image”, “com.leica.raw-image”, “com.leica.rwl-raw-image”, “com.konicaminolta.raw-image”, “com.olympus.sr-raw-image”, “com.olympus.or-raw-image”, “com.olympus.raw-image”, “com.adobe.photoshop-image”, “com.microsoft.ico”, “com.microsoft.bmp”, “com.microsoft.cur”, “com.truevision.tga-image”, “com.sgi.sgi-image”, “com.apple.macpaint-image”, “com.ilm.openexr-image”, “public.radiance”, “public.mpo-image”, “public.pbm”, “public.pvr”, “com.apple.rjpeg”, “com.apple.quicktime-image”, “com.kodak.flashpix-image”}
  
  
if (supportedTypes’s containsObject:theType) as boolean is false then
    return “File format is unsupported”
    
– check required type doesn’t already match
  else
    return true
  end if
  
end chkNSImageAcceptableFormat

–変換元の画像パスと変換対象の拡張子を与え、変換不要(同一ファイル”JPG”–> “JPEG”など)かをチェックする
on chkIsThereNeedToConvert(aPath as text, targetFormatExt as text)
  set theWorkspace to current application’s NSWorkspace’s sharedWorkspace()
  
set theType to theWorkspace’s typeOfFile:aPath |error|:(missing value) – returns UTI of file
  
if (theWorkspace’s filenameExtension:targetFormatExt isValidForType:theType) as boolean then
    return false –”No conversion needed”
  else
    return true
  end if
end chkIsThereNeedToConvert

★Click Here to Open This Script 

2015/08/15 ASOCでRTFの内容を読み取って指定文字を置換してファイルに保存する

Cocoaの機能を利用して、既存のRTF(リッチテキストフォーマット)の内容を読み取って、指定文字を置換するAppleScriptです。置換したあとのスタイル付きテキストをファイルに保存するところまでの処理を追加しました。

前バージョンを掲載したところ、(自分的には目的にかなう内容であったものの)Shaneからツッコミ。「ファイルに書かないと置換した内容の確認のしようがないじゃん(意訳)」という指摘により、保存処理を追加しました。

AppleScript名:ASOCでRTFの内容を読み取って指定文字を置換してファイルに保存する
– Created 2015-08-15 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

–Input
set aFile to POSIX path of (choose file of type {“public.rtf”})
set aFilePath to current application’s NSString’s stringWithString:aFile

–Output
set bFile to POSIX path of (choose file name with prompt “Choose replaced new RTF to save (with \”.rtf\” extension)”)
set bFilePath to current application’s NSString’s stringWithString:bFile

–Read RTF to NSData
set aData to current application’s NSData’s dataWithContentsOfFile:aFilePath options:0 |error|:(missing value)
set theStyledText to current application’s NSMutableAttributedString’s alloc()’s initWithData:aData options:(missing value) documentAttributes:(null) |error|:(missing value)
set astyledLength to theStyledText’s |string|()’s |length|()

–Replace Tag with String
theStyledText’s mutableString()’s replaceOccurrencesOfString:“<name>” withString:“長野谷” options:(current application’s NSCaseInsensitiveSearch) range:(current application’s NSMakeRange(0, astyledLength))

–Convert NSMutableStyledStrings to RTF
set bstyledLength to theStyledText’s |string|()’s |length|()
set bDict to current application’s NSDictionary’s dictionaryWithObject:“NSRTFTextDocumentType” forKey:(current application’s NSDocumentTypeDocumentAttribute)
–>  (NSDictionary) {​​​​​DocumentType:”NSRTFTextDocumentType”​​​}

set bRTF to theStyledText’s RTFFromRange:(current application’s NSMakeRange(0, bstyledLength)) documentAttributes:bDict

–Save to File
bRTF’s writeToFile:bFilePath atomically:true

★Click Here to Open This Script 

2015/08/14 ASOCでRTFの内容を読み取って指定文字を置換する

Cocoaの機能を利用して、既存のRTF(リッチテキストフォーマット)の内容を読み取って、指定文字を置換するAppleScriptです。

rtf1.png

こういう(↑)RTFを(OS X標準添付のTextEditなどで)作成したとして、本Scriptを実行すると、

rtf2.png

このようになります。RTFDの読み込みも実験しているのですが、こちらはなかなかうまくいきません。

AppleScript名:ASOCでRTFの内容を読み取って指定文字を置換する
– Created 2015-08-14 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set aFile to POSIX path of (choose file of type {“public.rtf”})
set aFilePath to current application’s NSString’s stringWithString:aFile

set aData to current application’s NSData’s dataWithContentsOfFile:aFilePath options:0 |error|:(missing value)
set theStyledText to current application’s NSMutableAttributedString’s alloc()’s initWithData:aData options:(missing value) documentAttributes:(null) |error|:(missing value)
set astyledLength to theStyledText’s |string|()’s |length|()

theStyledText’s mutableString()’s replaceOccurrencesOfString:“<name>” withString:“長野谷” options:(current application’s NSCaseInsensitiveSearch) range:(current application’s NSMakeRange(0, astyledLength))

★Click Here to Open This Script 

2015/08/14 ASOCでUUID文字列を取得する

Cocoaの機能を利用してUUID文字列を取得するAppleScriptです。

AppleScriptで各種処理を行う際にUUIDの取得を行うケースは割と多いので、do shell script(uuidgenコマンド)の呼び出しを行わなくて済むようにするため、ASOCベースのルーチンに差し替えられるとメリットがあることでしょう。

AppleScript名:ASOCでUUID文字列を取得する
– Created 2015-08-14 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set aUUID to current application’s NSUUID’s UUID()
–>  (__NSConcreteUUID) <__nsconcreteuuid 0x7f87d814d000> 6737A4CD-D509-42F5-BD0C-DB894127424D

set aStr to aUUID’s UUIDString()
–>  (NSString) “6737A4CD-D509-42F5-BD0C-DB894127424D”

set bStr to aStr as text
–> “6737A4CD-D509-42F5-BD0C-DB894127424D”

★Click Here to Open This Script 

2015/08/13 Automatorを使ってAppleScriptベースの「サービス」を記述

Automatorについては、最初のバージョンの段階で「検索キーワードに柔軟性がなさすぎ」(日本語のように同義語が多い言語では使いにくい)といったフィードバックをしたものの、とくに改善されずに今日にいたり・・・これを使うよりもScript Editorを起動したほうが手っ取り早いので、1年に一度起動するかしないか・・・といった利用頻度。

同じく、NeXTstepの時代から「これもうちょっとなんとかならないのかな?」と思い続けてきた「サービス」についても、ながらく「有用な用途」が見つけられず(中途半端にアプリを連携させるより、AppleScriptを書いてワークフローすべてを自動化するほうが便利なので)、サービスについてもほとんど使ったことがありませんでした。

オンラインの各種サービスとつないだり、LAN上の他のマシン(上で公開しているサービス)を認識して動的にメニュー表示させたら便利そうだなーと思っていたものの、基本的にはNeXT時代とさほど変わらぬ位置づけで今日にいたります。

たまたまAppleScriptでサービスを書くという話を見かけて、自分用にメモとして残しておきます。

auto1.png
Automatorを起動して、メニューから「ファイル」>「新規」を実行して「サービス」を選択。

auto2.png
とりあえず、Safari上で選択したテキストを受け付けるように設定

auto0.png
アクション「AppleScriptを実行」を選択して、いつもの調子でScriptを記述。useコマンドも使えるし、ASOCも書ける。script文で論理分割したAppleScriptも書けるし、呼び出すことも可能。これを「ASTEST」の名前で保存

auto3.png
Safari上でテキストを選択して・・・

auto4.png
Safariの「サービス」メニューからサービス「ASTEST」を実行

auto5.png
入力データ「input」とパラメータ「parameters」の内容をテキスト化してダイアログ表示してみたところ

inputの内容はリストに入れられたテキストだということが思い出せたので、そのように書けば大丈夫だとわかりました。ただ、たぶんサービスをAutomator上で書くことはほとんどないはず・・・

auto7.png

Safari上に表示された「戦場の絆」のリプレイIDを選択しておくと、リプレイムービーのURLに変換したり、リプレイムービーをダウンロードしたり、リプレイの再生を開始するAppleScriptを作成したので、こういうものを「サービス」に組み込んでおくと何か便利だろうかと思ったのですが、結局Script Menuから実行することになるでしょう、、、

なにげに、実行するScriptのソースコードがまるごと取得できることがわかったので、いろいろ高度な(込み入った)ことができそうな気がいたします。

2015/08/12 ASOCで少数点以下の数値の切り上げ、切り下げ v2

Cocoaの機能を用いて、少数点以下の数値の四捨五入を行うAppleScriptです。

NSNumberFormatterRoundHalfUpで四捨五入ができるのを見つけて、実際にためしてみました。

AppleScript名:ASOCで少数点以下の数値の切り上げ、切り下げ v2
– Created 2015-08-12 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set a to 10.511111
set a1Res to roundingAsTaughtInSchool(a, 1)
–>  10.5

set a2Res to roundingAsTaughtInSchool(a, 2)
–>  10.51

set b to 10.565111
set b1Res to roundingAsTaughtInSchool(b, 1)
–>  10.6

set b2Res to roundingAsTaughtInSchool(b, 2)
–>  10.57

on roundingAsTaughtInSchool(aNum, aDigit as integer)
  set a to aNum as real
  
set aFormatter to current application’s NSNumberFormatter’s alloc()’s init()
  
aFormatter’s setMaximumFractionDigits:aDigit
  
aFormatter’s setRoundingMode:(current application’s NSNumberFormatterRoundHalfUp)
  
set aStr to aFormatter’s stringFromNumber:(current application’s NSNumber’s numberWithFloat:a)
  
return (aStr as text) as real
end roundingAsTaughtInSchool

★Click Here to Open This Script 

2015/08/12 ASOCでScript Editorの構文色分け情報を設定ファイルから取り出す v2

Cocoaの機能を用いて、AppleScriptの構文色分け(色+フォント)情報が入っているplistから情報を取り出し、RGBの各8ビットの値のリストにまとめるAppleScriptです。

NSDeviceRGBColorからRGBの各値を取り出すテストを行ったものです。

AppleScript名:ASOCでScript Editorの構文色分け情報を設定ファイルから取り出す v2
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set AppleScriptFontFile to “~/Library/Preferences/com.apple.applescript.plist”
set aRec to retDictFromPlist(AppleScriptFontFile) of me

set asAttr to AppleScriptSourceAttributes of aRec
set colList to {}
set aMAX to 255 –or 65535 (AS Color は0〜65535 あまり意味はないが、、、)

repeat with i in asAttr
  set aCol to NSColor of i
  
–>  {{(NSDeviceRGBColor) NSDeviceRGBColorSpace 0.568627 0.156863 0.564706 1….}
  
set aColO to (current application’s NSUnarchiver’s unarchiveObjectWithData:aCol)
  
set the end of colList to retColListFromNSColor(aColO, aMAX)
end repeat
colList
–aMAX=255の場合
–> {{128, 0, 128}, {95, 94, 94}, {14, 62, 251}, {120, 52, 203}, {252, 42, 28}, {0, 0, 0}, {145, 82, 17}, {18, 18, 18}, {39, 201, 201}, {15, 62, 251}, {31, 182, 252}, {129, 58, 217}, {93, 54, 146}, {9, 55, 187}, {8, 55, 187}, {9, 55, 186}, {86, 55, 189}, {52, 32, 99}}

–aMax=65535の場合
–> {{32768, 0, 32768}, {24415, 24158, 24158}, {3598, 15934, 64507}, {30840, 13364, 52171}, {64764, 10794, 7196}, {0, 0, 0}, {37265, 21074, 4369}, {4721, 4721, 4721}, {10023, 51657, 51657}, {3855, 15934, 64507}, {7967, 46774, 64764}, {33153, 14906, 55769}, {23901, 13878, 37522}, {2313, 14135, 48059}, {2056, 14135, 48059}, {2313, 14135, 47802}, {22102, 14135, 48573}, {13364, 8224, 25443}}

–Read plist as record
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 as record
end retDictFromPlist

–NSColorからrgbの8bitの値を取り出す
on retColListFromNSColor(aCol, aMAX as integer)
  set aRed to round ((aCol’s redComponent()) * aMAX) rounding as taught in school
  
set aGreen to round ((aCol’s greenComponent()) * aMAX) rounding as taught in school
  
set aBlue to round ((aCol’s blueComponent()) * aMAX) rounding as taught in school
  
return {aRed, aGreen, aBlue}
end retColListFromNSColor

★Click Here to Open This Script 

2015/08/12 ASOCで少数点以下の数値の切り上げ、切り下げ

Cocoaの機能を用いて、少数点以下の数値の切り上げ、切り下げを行うAppleScriptです。

Pure AppleScriptでround命令ひとつで(正確にいえば、round aVal rounding as taught in schoolといった表現)四捨五入が行えるのに比べるとちょっと面倒な気がします。

AppleScript名:ASOCで少数点以下の数値の切り上げ、切り下げ
– Created 2015-08-12 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set a to 10.511111
set a1Res to roundingDown(a, 1)
–>  10.5

set a2Res to roundingDown(a, 2)
–>  10.51

set b to 10.565111
set b1Res to roundingUp(b, 1)
–>  10.6

set b2Res to roundingUp(b, 2)
–>  10.57

on roundingDown(aNum, aDigit as integer)
  set a to aNum as real
  
set aFormatter to current application’s NSNumberFormatter’s alloc()’s init()
  
aFormatter’s setMaximumFractionDigits:aDigit
  
aFormatter’s setRoundingMode:(current application’s NSNumberFormatterRoundDown)
  
set aStr to aFormatter’s stringFromNumber:(current application’s NSNumber’s numberWithFloat:a)
  
return (aStr as text) as real
end roundingDown

on roundingUp(aNum, aDigit as integer)
  set a to aNum as real
  
set aFormatter to current application’s NSNumberFormatter’s alloc()’s init()
  
aFormatter’s setMaximumFractionDigits:aDigit
  
aFormatter’s setRoundingMode:(current application’s NSNumberFormatterRoundUp)
  
set aStr to aFormatter’s stringFromNumber:(current application’s NSNumber’s numberWithFloat:a)
  
return (aStr as text) as real
end roundingUp

★Click Here to Open This Script