Archive for the 'システム情報取得(sys info)' Category

2015/04/23 Macのモデル名を返す

Macのモデル名を返すAppleScriptです。Mac Pro/Mac mini/iMac/MacBook Pro/MacBook Air/MacBook などのざっくりしたモデル名(マシン種別)です。

AppleScript名:Macのモデル名を返す
–By Christopher Stone <listmeister@thestoneforge.com>
–2011/09/15

set aModelName to getModelName()
–> "MacBook Pro"

on getModelName()
  # Keeping the hardware data record:
  
set hardwareData to do shell script "system_profiler SPHardwareDataType" without altering line endings
  
set cmd to "sed -nE ’/Model Name/p’ <<< " & quoted form of hardwareData & " | sed -E ’s/^ +//’"
  
set macModel to do shell script cmd
  
  
# One-liner:
  
set macModel to do shell script "system_profiler SPHardwareDataType | sed -nE ’/Model Name/p’| sed -E ’s/^ +//’"
  
  
return (text 13 thru -1 of macModel) –Skip "Model Name: " strings
  
end getModelName

★Click Here to Open This Script 

2015/04/02 CocoaでDisk Free Space (Bytes) を求める

Shane wrote me various methods to get free space in Cocoa way. NSByteCountFormatter seems very useful.

“usedSpaceLongString” is good because they take the user’s number formatting and language into account (Shane said).

ShaneがCocoaでDiskの空き容量を(Byte単位で)返すscriptを書いてくれました(Thanks!)。NSByteCountFormatterが非常に使い勝手がありそうです。

“usedSpaceLongString”は実行時のユーザー環境の数値フォーマット形式と言語設定を反映させるため有用です(Shane談)。

あれ??? このScript、使用率が%で返ってきているものをただ文字フォーマットしているだけかも、、、

AppleScript名:CocoaでDiskSpace(Bytes)を求める
– Created 2015-04-02 by Shane Stanley
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

usedSpace(“/”)
–>  4.5772857344E+10

usedSpace2(“/”)
–>  4.5772857344E+10

usedSpaceString(“/”)
–>  ”45.77 GB”

usedSpaceLongString(“/”)
–>  ”45.77 GB (45,772,857,344 bytes)”–English user environment
–>  ”45.77 GB (45,772,857,344 バイト)”–Japanese user environment

tell application “Finder”
  free space of startup disk
end tell
–>  4.5784592712E+10

on usedSpace(volumePath)
  set theNSURL to current application’s class “NSURL”’s fileURLWithPath:volumePath –considering “ASOC in Xcode”
  
set {theResult, theSize} to theNSURL’s getResourceValue:(reference) forKey:(current application’s NSURLVolumeAvailableCapacityKey) |error|:(missing value)
  
  
return theSize as real – integer may be too big for AS
end usedSpace

on usedSpace2(volumePath)
  set fileAttr to current application’s NSFileManager’s defaultManager()’s attributesOfFileSystemForPath:volumePath |error|:(missing value)
  
  
return (fileAttr’s objectForKey:(current application’s NSFileSystemFreeSize)) as real – integer may be too big for AS
end usedSpace2

on usedSpaceString(volumePath)
  set fileAttr to current application’s NSFileManager’s defaultManager()’s attributesOfFileSystemForPath:volumePath |error|:(missing value)
  
set fRes to fileAttr’s objectForKey:(current application’s NSFileSystemFreeSize)
  
  
–Formatting
  
set sizeString to current application’s NSByteCountFormatter’s stringFromByteCount:fRes countStyle:(current application’s NSByteCountFormatterCountStyleDecimal)
  
  
return sizeString as text
end usedSpaceString

on usedSpaceLongString(volumePath)
  set fileAttr to current application’s NSFileManager’s defaultManager()’s attributesOfFileSystemForPath:volumePath |error|:(missing value)
  
set fRes to fileAttr’s objectForKey:(current application’s NSFileSystemFreeSize)
  
  
–Formatting
  
set theFormatter to current application’s NSByteCountFormatter’s alloc()’s init()
  
theFormatter’s setCountStyle:(current application’s NSByteCountFormatterCountStyleDecimal)
  
theFormatter’s setIncludesActualByteCount:true
  
set sizeString to theFormatter’s stringFromByteCount:fRes
  
  
return sizeString as text
end usedSpaceLongString

★Click Here to Open This Script 

2015/02/08 起動中のプロセスの存在確認(ASOC)v2

Bundle IDで指定したアプリケーションプロセスが起動中かどうかを調べるAppleScriptです。

v1は「とりあえずこんなもんで動くだろー。でももっと短く書けそう」というものでしたが、やっぱり短く書けました。Shane Stanleyからチェックが入って(汗)、もっと短く書けるよ、とのこと。感謝です(^ー^)

AppleScript名:指定Bundle IDのプロセス存在確認(ASOC)v2
– Created 2015-02-08 by Shane Stanley
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “ASObjCExtras”
use framework “AppKit”

set aRes to chkAppProcesByBundleID(“com.adobe.Photoshop”)
–> true

set aRes to chkAppProcesByBundleID(“com.adobe.Photoshopoo!”)
–> false

on chkAppProcesByBundleID(aBundleID)
  set appArray to current application’s NSRunningApplication’s runningApplicationsWithBundleIdentifier:aBundleID
  
return (appArray’s |count|() > 0)
end chkAppProcesByBundleID

★Click Here to Open This Script 

2015/02/08 起動中のプロセスの存在確認

Bundle IDで指定したプロセスが起動しているかどうかを確認するAppleScriptです。

AppleScript的には、System Eventsを経由してプロセスの起動中確認を行います。

AppleScript名:指定Bundle IDのプロセス存在確認(AS)
use AppleScript version “2.4″
use scripting additions

set aRes to chkAppProcesByBundleID(“com.adobe.Photoshop”)
–> true

set aRes to chkAppProcesByBundleID(“com.adobe.Photoshopoo!”)
–> false

on chkAppProcesByBundleID(aBundleID as string)
  tell application “System Events”
    set a to every process whose bundle identifier is aBundleID
    
if length of a 1 then
      return true
    else
      return false
    end if
  end tell
end chkAppProcesByBundleID

★Click Here to Open This Script 

しかし、この方法ではもしもMac App Storeに申請するアプリケーションで、System Eventsへのアクセスが封じられたらおしまいです。一応、shell script経由でpsコマンドを実行するという手段もありますが・・・

そこで、ASOCでCocoaの機能を用いてプロセスの存在確認を行ってみました。もうちょっと短く書けそうな気配もするのですが、とりあえず。

AppleScript名:指定Bundle IDのプロセス存在確認(ASOC)
– Created 2015-02-08 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “ASObjCExtras”
use framework “AppKit”

set aRes to chkAppProcesByBundleID(“com.adobe.Photoshop”)
–> true

set aRes to chkAppProcesByBundleID(“com.adobe.Photoshopoo!”)
–> false

on chkAppProcesByBundleID(aBundleID as string)
  set appArray to current application’s NSWorkspace’s sharedWorkspace’s runningApplications()
  
set appList to appArray’s ASify() as list
  
  
repeat with i in appList
    set anID to (i’s bundleIdentifier()) as string
    
if anID = aBundleID then
      return true
    end if
  end repeat
  
  
return false
end chkAppProcesByBundleID

★Click Here to Open This Script 

2015/02/08 指定アプリケーションの存在確認

Bundle IDで指定したアプリケーションの存在確認を行うAppleScriptです。

古くから(Classic Mac OSの時代から)、AppleScriptにはFinder経由でアプリケーションの存在確認を行う手段が用意されてきました。いまはBunde IDで、Classic Mac OS時代にはcreator codeで存在確認を行ってきましたが、同様にFinderに対して問い合わせを行っていました。

AppleScript名:指定アプリケーションの存在確認(AS)
use AppleScript version “2.4″
use scripting additions

set aRes to chkAppIsInstalled(“com.adobe.photoshop”)
–> true

on chkAppIsInstalled(aBundleID as string)
  try
    tell application “Finder”
      set a to application file id “com.adobe.photoshop”
    end tell
    
return true
  on error
    return false
  end try
end chkAppIsInstalled

★Click Here to Open This Script 

そのため、一般的にはFinderで確認する方法で問題はないのですが、もしもMac AppStoreに申請を行うASOCのアプリケーションでFinder経由の確認を行っていた場合に、唐突に「この方法ではダメ」と言われかねません。

そこで、Cocoaの機能を利用して確認を行う方法について調査しておきました。速度面でとくに通常のASにくらべて有利ということはありませんが、SandBox内での実行が制限されづらいだろうということで書いておきました。

実際、有名なところではログイン時に自動起動されるStartup ItemsにAppleScript経由で登録する方法を採用すると、Mac App Store申請時にリジェクトされるという制限が知られています。

AppleScript名:指定アプリケーションの存在確認(ASOC)
– Created 2014-12-23 by Takaaki Naganoya
– 2014 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”

set aRes to chkAppIsInstalled(“com.adobe.photoshop”)
–>  true

on chkAppIsInstalled(aBundleID as string)
  set aRes to current application’s NSWorkspace’s sharedWorkspace()’s URLForApplicationWithBundleIdentifier:aBundleID
  
set bRes to (aRes is not equal to missing value)
  
return bRes
end chkAppIsInstalled

★Click Here to Open This Script 

2015/02/02 カレンダー.app(旧称iCal)で選択中のイベントの情報を取得

海外のBlogで、カレンダー.app(Calendar.app)の画面上で選択中のイベントの情報を取得するAppleScriptが公開されていました。

→ Reference selected Calendar events in AppleScript

カレンダー.appのAppleScript用語辞書にはselectionとかselected eventなどの予約語が用意されておらず、そのうえ「リマインダー.app」とイベントが共有されており区別できないなど、Apple純正アプリとしてはかなり「残念な出来」になっている筆頭残念アプリケーションです。

同Blogによれば、AppleScript用語辞書にselectionなどのプロパティは存在しないのに、設定ファイル”com.apple.ical.plist”には「SelectedEvents」のエントリが存在しているので、それをdefaults readコマンドで読み取って、parseして、sqlite3経由でsqlを発行して該当するイベントの情報を取得するのだとか。

・・・ここまでしないと取得できないことを嘆くべきか、存在しない機能を実現した努力を讃えるべきなのか、そもそも最初からselectionの機能があるべきという主張をすべきなのか、なかなか悩ましいところです。

カレンダー.app上でイベントを選択して同AppleScriptを実行してみたところ、どうも「選択中のイベントを取得できる」ときと「できない」ときがあります。ソース中にもそのように書いてあり、いろいろ試行錯誤してみたところ・・・

数行追加したら、バッチリ取れるようになりました。ただ、フィードバックするにも同Blogはコメント読んでないようで・・・修正版を掲載しておきます。オリジナルのScriptでは、取得した「選択中のイベント」の発生15分前にアラームを鳴らすようにしてありましたが、変更されるのがいやだったのでコメントアウトしてあります。

AppleScript名:カレンダー.app上で選択中のイベントを取得する
–https://www.johneday.com/1086/reference-selected-calendar-events-applescript
– Title: Reference selected Calendar events in AppleScript
– Created 2015-02-02 by @johneday on Twitter
– Modified 2015-02-02 by Takaaki Naganoya

use AppleScript version "2.4"
use scripting additions

——————————
– ABOUT
——————————
– Written and tested in Yosemite, Calendar Version 8.0
– The plist may take several seconds to update after a new event has been selected.
– Only the first instance of a recurring event will be referenced.

——————————-
– Modify by Takaaki Naganoya
——————————
tell application "Calendar"
  if running = false then return
  
activate
end tell
do shell script "sync"

——————————-
– MAIN CODE
——————————
set defaultsReply to (do shell script "defaults read com.apple.ical SelectedEvents")
set selectedEvents to parseDefaults(defaultsReply)

if selectedEvents = {} then
  display notification "Please try again" with title "No Calendar Event Selected"
  
return
end if

set eventReferenceList to {}
repeat with sEvent in selectedEvents
  set {eventID, calendarID} to sqlQuery(sEvent)
  
tell application "Calendar"
    set eventReference to event id eventID of calendar id calendarID
    
– INSERT YOUR CODE TO PROCESS EACH EVENT
    
    – Example of "Alert 15 minutes before start"
    
–my addDisplayAlarm(eventReference, -15)
    
    – OR BUILD A LIST OF EVENTS
    
set end of eventReferenceList to eventReference
  end tell
end repeat
return eventReferenceList

——————————
– HANDLERS
——————————
on parseDefaults(resultText)
  set localUIDs to {}
  
set {TID, text item delimiters} to {text item delimiters, quote}
  
set resultItems to text items of resultText
  
set text item delimiters to TID
  
repeat with i from 1 to (count resultItems)
    if i mod 2 = 0 then set end of localUIDs to resultItems’s item i
  end repeat
  
return localUIDs
end parseDefaults

on sqlQuery(localUID)
  local dateString, localUID
  
if localUID contains "/" then
    set {TID, text item delimiters} to {text item delimiters, "/"}
    
set {dateString, localUID} to text items of localUID
    
set text item delimiters to TID
  end if
  
  set sqlText to "
SELECT DISTINCT zcalendaritem.zshareduid AS eventID
, znode.zuid as calID
FROM zcalendaritem
JOIN znode
ON znode.z_pk = zcalendaritem.zcalendar
AND zcalendaritem.zlocaluid = ’" & localUID & "’
;"
  
  set sqlPath to POSIX path of (path to library folder from user domain) & "Calendars/Calendar Cache"
  
set {TID, text item delimiters} to {text item delimiters, "|"}
  
set {eID, cID} to text items of (do shell script "echo " & quoted form of sqlText & " | sqlite3 " & quoted form of sqlPath)
  
set text item delimiters to TID
  
return {eID, cID}
end sqlQuery

on addDisplayAlarm(myEvent, triggerInterval)
  tell application "Calendar"
    tell myEvent
      if not (exists (display alarms whose trigger interval = triggerInterval)) then
        set myAlarm to make new display alarm at end of display alarms with properties {trigger interval:triggerInterval}
      end if
    end tell
  end tell
end addDisplayAlarm

★Click Here to Open This Script 

2015/01/22 指定したアプリケーションの各lproj内の各stringsファイルのパス一覧を取得する

指定したアプリケーションの各言語のlprojフォルダ内にある、各stringsファイルへのパスを取得するAppleScriptです。

各アプリのローカライズ情報を取り出すプログラムはいろいろと試してはいるものの、作り方とかローカライズ方法が全然違うアプリケーションが紛れていることがあり、イレギュラーを除去すべきなのかも(Apple純正でもSafariあたりは全然違うし)。

AppleScript名:指定したアプリケーションの各lproj内の各stringsファイルのパス一覧を取得する
– Created 2015-01-22 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "ASObjCExtras"

set apPath1 to (path to applications folder) –dialog’s default directory
set anAlias to choose file of type "com.apple.application-bundle" default location apPath1 with prompt "ローカライズ情報を取得するアプリケーションを選択"
set aRes to getStringsPathWithinEachLanguageInApp(anAlias)
–> {{langStr:"English", stringsPath:{"/Applications/mi.app/Contents/Resources/English.lproj/Localizable.strings"}}, {langStr:"Japanese", stringsPath:{"/Applications/mi.app/Contents/Resources/Japanese.lproj/Localizable.strings"}}}

–指定したアプリケーションの各lproj内の各stringsファイルのパス一覧を取得する
on getStringsPathWithinEachLanguageInApp(anAlias)
  –アプリケーションのローカリゼーションを取得する(言語の重複を許容)
  
set locList to getSpecifiedAppFilesLocalizationListWithDuplication(anAlias) of me
  
  
set lprojList to {}
  
  
repeat with ii in locList
    
    
set jj to contents of ii
    
    
set appPath to POSIX path of anAlias
    
set appBundle to (current application’s NSBundle’s bundleWithPath:appPath)
    
set resPath to ((appBundle’s pathForResource:jj ofType:"lproj") as string) & "/"
    
    
if resPath is not equal to missing value then
      
      
set aLangBundle to (current application’s NSBundle’s bundleWithPath:resPath)
      
if aLangBundle is not equal to missing value then
        
        
set stringsList to (aLangBundle’s pathsForResourcesOfType:"strings" inDirectory:"") as list
        
        
if stringsList is not equal to {} then
          set the end of lprojList to {langStr:jj, stringsPath:stringsList}
        end if
        
      end if
    end if
    
  end repeat
  
  
return lprojList
  
end getStringsPathWithinEachLanguageInApp

–指定アプリケーションファイルの、指定Localeにおけるローカライズ言語リストを求める。重複を許容
on getSpecifiedAppFilesLocalizationListWithDuplication(anAppAlias as alias)
  
  
set aURL to (current application’s SMSFord’s URLFrom:anAppAlias)
  
set aBundle to current application’s NSBundle’s bundleWithURL:aURL
  
  
set theNSLocale to current application’s NSLocale’s localeWithLocaleIdentifier:"en" –Output Locale Name in English (en)
  
  
–Get Localization Info
  
set locList to aBundle’s localizations()
  
–> {"de", "English", "fr", "French", "German", "ja", "Japanese"}
  
  
return locList as list
  
end getSpecifiedAppFilesLocalizationListWithDuplication

★Click Here to Open This Script 

2015/01/22 言語と地域の「優先する言語」を取得する(ASOC)

「システム環境設定」の「言語と地域」で、「優先する言語:」に指定されている言語リストを取得するAppleScriptです。

本当は、OS上で用意している言語(35言語)のリストが欲しかったのですが、とりあえず。

international.png

AppleScript名:言語と地域の「優先する言語」を取得する(ASOC)
– Created 2015-01-22 by Takaaki Naganoya
– 2015 Piyomaru Software
– Technical Q&A QA1391
– How can I determine the order of the languages set by the user in the Language tab of the International preference pane?
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set defaultsO to current application’s NSUserDefaults’s standardUserDefaults()
set globalDomain to defaultsO’s persistentDomainForName:"NSGlobalDomain"
set langArray to (globalDomain’s objectForKey:"AppleLanguages") as list
–>  {​​​​​"ja", ​​​​​"en-US", ​​​​​"en-GB", ​​​​​"fr", ​​​​​"en"​​​}

★Click Here to Open This Script 

2015/01/13 Display情報の取得

NSScreenの情報にアクセスして、各ディスプレイの詳細情報を取得するAppleScriptです。

img_0866.png

非Retina DisplayはResolutionが{width:72.0, height:72.0}、MacBook Pro Retina 2012のRetina Displayは{width:144.0, height:144.0}と返ってきます。

screens0.png

ただ、結果を見直してみると・・・RetinaではないDisplayでも{width:144.0, height:144.0}と返ってくるケースがあり、実際にScreen CaptureをそのDisplay上で行うとRetina解像度のキャプチャ画像が取得されたりして、ソフトウェア的なResolutionのことを指しているのではないかとも思われます。

moni12.png

その割に、同一構成でMacBook Pro Retina本体をLid Closed Mode運用させると(本体を閉じると)、Resolutionで軒並み{width:72.0, height:72.0}が返ってくるあたりが悩ましいです。

ここでは、「OSが返してくる値がこうなっている」という事実のみ書いておきます。ご覧の通り、とくにScript側で数値に手心を加えているわけではありません。

moni3.png

上記のように、同一の表示&同一のDisplay上でのScreen Capture画像を比較した場合に、Retina Displayを含むモニター群の場合の画面キャプチャと、含まない場合の画面キャプチャでは解像度が異なっていました。仮想画面自体が、Retina Modeと非Retina Modeの切り替えを行うのかもしれません。

なお、本ScriptはCocoa経由でデスクトップピクチャを調査しようとして作成した副産物です(でも、AppleScript経由で調べたほうが圧倒的に楽、、、、)。

AppleScript名:display情報の取得
– Created 2015-01-13 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “ASObjCExtras”
use framework “AppKit”

–Retina Displayを含む構成のとき
set dInfoList to retScreenInfos()
–>  {{screenSize:{{width:1920.0, height:1200.0}}, screenResol:{{width:144.0, height:144.0}}, screenIsScreen:true, screenNumber:”69501832″, screenColorSpace:”NSCalibratedRGBColorSpace”, screenColDepth:”8″}, {screenSize:{{width:1920.0, height:1200.0}}, screenResol:{{width:144.0, height:144.0}}, screenIsScreen:true, screenNumber:”69513475″, screenColorSpace:”NSCalibratedRGBColorSpace”, screenColDepth:”8″}, {screenSize:{{width:1920.0, height:1200.0}}, screenResol:{{width:144.0, height:144.0}}, screenIsScreen:true, screenNumber:”69731202″, screenColorSpace:”NSCalibratedRGBColorSpace”, screenColDepth:”8″}, {screenSize:{{width:1920.0, height:1080.0}}, screenResol:{{width:72.0, height:72.0}}, screenIsScreen:true, screenNumber:”458586661″, screenColorSpace:”NSCalibratedRGBColorSpace”, screenColDepth:”8″}}

–Retina Displayを含まない構成のとき(MacBook Pro Retina本体のLid Closed Mode時)
set dInfoList to retScreenInfos()
–>  {{screenSize:{{width:1920.0, height:1200.0}}, screenResol:{{width:72.0, height:72.0}}, screenIsScreen:true, screenNumber:”69501832″, screenColorSpace:”NSCalibratedRGBColorSpace”, screenColDepth:”8″}, {screenSize:{{width:1920.0, height:1200.0}}, screenResol:{{width:72.0, height:72.0}}, screenIsScreen:true, screenNumber:”69513475″, screenColorSpace:”NSCalibratedRGBColorSpace”, screenColDepth:”8″}, {screenSize:{{width:1920.0, height:1080.0}}, screenResol:{{width:72.0, height:72.0}}, screenIsScreen:true, screenNumber:”458586661″, screenColorSpace:”NSCalibratedRGBColorSpace”, screenColDepth:”8″}}

on retScreenInfos()
  set sList to (current application’s NSScreen’s screens()) as list
  
  
set dList to {}
  
repeat with i in sList
    set a to i’s deviceDescription()
    
set aSize to a’s NSDeviceSize as list
    
set aResol to a’s NSDeviceResolution as list
    
set aScrn to a’s NSDeviceIsScreen as boolean
    
set aNum to a’s NSScreenNumber as string
    
set aColSpc to a’s NSDeviceColorSpaceName as string
    
set aColDepth to a’s NSDeviceBitsPerSample as string
    
set the end of dList to {screenSize:aSize, screenResol:aResol, screenIsScreen:aScrn, screenNumber:aNum, screenColorSpace:aColSpc, screenColDepth:aColDepth}
  end repeat
  
  
return dList
  
end retScreenInfos

★Click Here to Open This Script 

2014/12/25 アプリケーションごとのローカライズ言語数を求める

/Applicationsフォルダ以下の全アプリケーションのローカライズ言語数を求めて多い順にソートして返すAppleScriptです。

便利な部品ができてきたので、本来の用途以外に転用するのも簡単になってきました。

ただ、こういう「調査活動」以外にこの処理が生きるかどうかは未知数です、、、

OS X自体のローカライズ言語数=35ということが見て取れますが(ただし、対応言語は幾つかのレベルに分けられており、ユーザー数によって対応度が違うはず)、それ以上のローカライズ言語を持っているアプリケーションの存在が気になります。

AppleScript名:アプリケーションごとのローカライズ言語数を求める
– Created 2014-12-25 by Takaaki Naganoya

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

–/Applications以下のアプリケーションのパスをすべて求める
set apPath1 to (path to applications folder) as string
set aList to getFileListWithSpotLight(“kMDItemContentType”, “com.apple.application-bundle”, apPath1) of me

–各アプリケーションのローカリゼーション情報を取得(重複情報はカウントしつつ保持)
set aaList to {}

repeat with i in aList
  set j to contents of i
  
  
–アプリケーションのローカリゼーションを取得する(重複言語の除去ずみ)
  
set locList to getSpecifiedAppFilesLocalizationList(j) of me
  
  
tell application “System Events”
    set aName to name of j
  end tell
  
  
set the end of aaList to {aName, length of locList}
  
end repeat

–Sort Result (Many->Little)
set sortIndexes to {1} –Key Item id: begin from 0
set sortOrders to {false} –Descending Sort Order
set sortTypes to {“compare:”}
set rList to (current application’s SMSFord’s subarraysIn:aaList sortedByIndexes:sortIndexes ascending:sortOrders sortTypes:sortTypes |error|:(missing value)) as list

return rList
–> {{”VLC.app”, 93}, {”Creative Cloud.app”, 61}, {”Adobe Application Manager.app”, 61}, {”Google Drive.app”, 53}, {”Google Chrome.app”, 53}, {”Uninstall Product.app”, 43}, {”Uninstall Product.app”, 43}, {”Google Earth.app”, 42}, {”VueScan.app”, 40}, {”Evernote.app”, 40}, {”Adobe Muse CC 2014.app”, 37}, {”iTunes.app”, 35}, {”Digital Color Meter.app”, 35}, {”Image Capture.app”, 35}, {”Grab.app”, 35}, {”Game Center.app”, 35}, {”iBooks.app”, 35}, {”Boot Camp Assistant.app”, 35}, {”Bluetooth File Exchange.app”, 35}, {”System Information.app”, 35}, {”Safari.app”, 35}, {”Terminal.app”, 35}, {”Contacts.app”, 35}, {”Preview.app”, 35}, {”App Store.app”, 35}, {”Automator.app”, 35}, ……

–指定アプリケーションファイルの、指定Localeにおけるローカライズ言語リストを求める。重複を排除
on getSpecifiedAppFilesLocalizationList(anAppAlias as alias)
  
  
set aURL to (current application’s SMSFord’s URLFrom:anAppAlias)
  
set aBundle to current application’s NSBundle’s bundleWithURL:aURL
  
  
set theNSLocale to current application’s NSLocale’s localeWithLocaleIdentifier:“en” –Output Locale Name in English (en)
  
  
–Get Localization Info
  
set locList to aBundle’s localizations()
  
–> {”de”, “English”, “fr”, “French”, “German”, “ja”, “Japanese”}
  
set theEnumerator to locList’s objectEnumerator()
  
  
set theSet to current application’s NSMutableSet’s |set|()
  
  
repeat
    set aValue to theEnumerator’s nextObject()
    
if aValue is missing value then exit repeat
    
    
set theName to (theNSLocale’s displayNameForKey:(current application’s NSLocaleIdentifier) value:aValue)
    
    
if theName is missing value then
      –”English”や”French”などは、missing valueが返ってくるので、”English”や”French”などをそのまま追加
      
theSet’s addObject:aValue
    else
      –”de”や”fr”などは、”German”や”French”が返ってくるので、それを追加
      
theSet’s addObject:theName
    end if
  end repeat
  
  
–NSCountedSetをNSMutableArrayに変換
  
set theArray to current application’s NSMutableArray’s array()
  
set theEnumerator to theSet’s objectEnumerator()
  
  
–NSMutableArrayから順次取り出して、NSArrayに出力
  
repeat
    set aValue to theEnumerator’s nextObject()
    
if aValue is missing value then exit repeat
    
theArray’s addObject:aValue
  end repeat
  
  
return theArray as list
  
end getSpecifiedAppFilesLocalizationList

–指定階層下で、指定メタデータが指定パラメータであるファイルを取得(alias list)
on getFileListWithSpotLight(aMetaDataItem as string, aParam as string, startDir as {alias, string})
  set sDirText to quoted form of POSIX path of startDir
  
set shellText to “/usr/bin/mdfind ’” & aMetaDataItem & ” == \”" & aParam & “\”’ -onlyin “ & sDirText
  
try
    set aRes to do shell script shellText
  on error
    return {}
  end try
  
set pList to paragraphs of aRes
  
set aList to {}
  
repeat with i in pList
    set aPath to POSIX file i
    
set aPath to aPath as alias
    
set the end of aList to aPath
  end repeat
  
return aList
end getFileListWithSpotLight

★Click Here to Open This Script 

2014/12/25 アプリケーションのローカライズ分布を取得する v5

/Applicationsフォルダ内に入っているアプリケーションのローカライズ言語の度数分布を取得するAppleScriptのバージョンアップ版です。

1つのアプリケーションが複数の重複するローカライズ情報を持っているケース({”de”, “English”, “fr”, “French”, “German”, “ja”, “Japanese”})があり、1つのアプリケーションから情報を取得する段階で重複を除去するルーチンを作成。重複を排除して({”German”, “English”, “French”,”Japanese”})のように整理して取得するように変更しました。

また、/Applicationsフォルダの直下のアプリケーションのファイルしか取得していなかったので、mdfindで/Applicationsフォルダ以下すべてのアプリケーションを取得するように変更。

また、言語名ではなく出現頻度でソートするように変更しました。

途中で、mdfindでアプリケーションのファイルを抽出する処理を試していたら、サブフォルダ内のアプリケーションが出てこないという問題があり・・・開発マシンのSSD内のspotlightの検索辞書が壊れていたようで、再生成したら正常に動作するようになりました。mdfindの処理の落とし穴です。

マイナー言語(失礼!)をこまかくフォローしているのはGoogleアプリかと思っていたら、VLCでした。OSがサポートしていない言語用のローカライズを行っても意味はないのですが、ムービーの字幕表示などの関係でしょうか?

AppleScript名:アプリケーションのローカライズ分布を取得する v5
– Created 2014-12-23 by Takaaki Naganoya
– Changed 2014-12-24 by Shane Stanley
– Changed 2014-12-25 by Takaaki Naganoya

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

–mdfindで指定フォルダ以下にあるすべてのアプリケーションファイルを取得
set apPath1 to (path to applications folder) as string
set apList to getFileListWithSpotLight(“kMDItemContentType”, “com.apple.application-bundle”, apPath1) of me

set theCountedSet to current application’s NSCountedSet’s |set|()

–各アプリケーションのローカリゼーション情報を取得する
repeat with i in apList
  set j to contents of i
  
  
–指定アプリケーションのローカライズ言語を取得。重複を除去
  
set locList to getSpecifiedAppFilesLocalizationList(j) of me
  
–> {”de”, “English”, “fr”, “French”, “German”, “ja”, “Japanese”}
  
—-> {”German”, “English”, “French”,”Japanese”}
  
  
set locArray to (current application’s SMSFord’s Cocoaify:locList)
  
  
set theEnumerator to locArray’s objectEnumerator()
  
repeat
    set aValue to theEnumerator’s nextObject()
    
if aValue is missing value then exit repeat
    
    (
theCountedSet’s addObject:aValue)
  end repeat
end repeat

–NSCountedSetをNSMutableArrayに変換
set theArray to current application’s NSMutableArray’s array()
set theEnumerator to theCountedSet’s objectEnumerator()

–NSMutableArrayから順次取り出して、NSArrayに対してDictionaryを追加
repeat
  set aValue to theEnumerator’s nextObject()
  
if aValue is missing value then exit repeat
  
theArray’s addObject:(current application’s NSDictionary’s dictionaryWithObjects:{aValue, (theCountedSet’s countForObject:aValue)} forKeys:{“theName”, “numberOfTimes”})
end repeat

–出現回数(numberOfTimes)で降順ソート
set theDesc to current application’s NSSortDescriptor’s sortDescriptorWithKey:“numberOfTimes” ascending:false
theArray’s sortUsingDescriptors:{theDesc}

return theArray as list

–> {{theName:”English”, numberOfTimes:733}, {theName:”Japanese”, numberOfTimes:404}, {theName:”French”, numberOfTimes:266}, {theName:”German”, numberOfTimes:265}, {theName:”Italian”, numberOfTimes:219}, {theName:”Spanish”, numberOfTimes:203}, {theName:”Dutch”, numberOfTimes:165}, {theName:”Chinese (China)”, numberOfTimes:149}, {theName:”Swedish”, numberOfTimes:133}, {theName:”Korean”, numberOfTimes:131}, {theName:”Russian”, numberOfTimes:129}, {theName:”Chinese (Taiwan)”, numberOfTimes:127}, {theName:”Portuguese”, numberOfTimes:124}, {theName:”Polish”, numberOfTimes:118}, {theName:”Danish”, numberOfTimes:117}, {theName:”Finnish”, numberOfTimes:110}, {theName:”Norwegian”, numberOfTimes:100}, {theName:”Czech”, numberOfTimes:92}, {theName:”Turkish”, numberOfTimes:90}, {theName:”Hungarian”, numberOfTimes:87}, {theName:”Greek”, numberOfTimes:76}, {theName:”Ukrainian”, numberOfTimes:75}, {theName:”Romanian”, numberOfTimes:74}, {theName:”Portuguese (Portugal)”, numberOfTimes:70}, {theName:”Slovak”, numberOfTimes:69}, {theName:”Catalan”, numberOfTimes:63}, {theName:”Croatian”, numberOfTimes:63}, {theName:”Arabic”, numberOfTimes:61}, {theName:”Thai”, numberOfTimes:61}, {theName:”Hebrew”, numberOfTimes:60}, {theName:”Indonesian”, numberOfTimes:58}, {theName:”Vietnamese”, numberOfTimes:57}, {theName:”Malay”, numberOfTimes:56}, {theName:”Spanish (Mexico)”, numberOfTimes:49}, {theName:”Base”, numberOfTimes:46}, {theName:”Portuguese (Brazil)”, numberOfTimes:22}, {theName:”Norwegian Bokmål”, numberOfTimes:21}, {theName:”Chinese (Simplified)”, numberOfTimes:19}, {theName:”Chinese”, numberOfTimes:14}, {theName:”English (United Kingdom)”, numberOfTimes:12}, {theName:”Bulgarian”, numberOfTimes:12}, {theName:”Chinese (Traditional)”, numberOfTimes:11}, {theName:”Latvian”, numberOfTimes:10}, {theName:”Lithuanian”, numberOfTimes:9}, {theName:”Slovenian”, numberOfTimes:9}, {theName:”Japanese (Japan)”, numberOfTimes:9}, {theName:”Czech (Czech Republic)”, numberOfTimes:9}, {theName:”Estonian”, numberOfTimes:8}, {theName:”Ukrainian (Ukraine)”, numberOfTimes:8}, {theName:”Spanish (Spain)”, numberOfTimes:7}, {theName:”Turkish (Turkey)”, numberOfTimes:7}, {theName:”Hungarian (Hungary)”, numberOfTimes:6}, {theName:”Danish (Denmark)”, numberOfTimes:6}, {theName:”Russian (Russia)”, numberOfTimes:6}, {theName:”French (XM)”, numberOfTimes:6}, {theName:”Swedish (Sweden)”, numberOfTimes:6}, {theName:”Serbian”, numberOfTimes:6}, {theName:”Norwegian Bokmål (Norway)”, numberOfTimes:6}, {theName:”Dutch (Netherlands)”, numberOfTimes:6}, {theName:”Persian”, numberOfTimes:5}, {theName:”Korean (South Korea)”, numberOfTimes:5}, {theName:”Finnish (Finland)”, numberOfTimes:5}, {theName:”Italian (Italy)”, numberOfTimes:5}, {theName:”German (Germany)”, numberOfTimes:5}, {theName:”French (Canada)”, numberOfTimes:5}, {theName:”French (France)”, numberOfTimes:5}, {theName:”Polish (Poland)”, numberOfTimes:5}, {theName:”Hindi”, numberOfTimes:5}, {theName:”English (United States)”, numberOfTimes:5}, {theName:”Hebrew (Israel)”, numberOfTimes:4}, {theName:”Arabic (United Arab Emirates)”, numberOfTimes:4}, {theName:”Spanish (Latin America)”, numberOfTimes:4}, {theName:”Romanian (Romania)”, numberOfTimes:4}, {theName:”Spanish (Namibia)”, numberOfTimes:4}, {theName:”Filipino”, numberOfTimes:4}, {theName:”Spanish (Laos)”, numberOfTimes:4}, {theName:”empty”, numberOfTimes:4}, {theName:”Greek (Greece)”, numberOfTimes:4}, {theName:”Telugu”, numberOfTimes:3}, {theName:”Malayalam”, numberOfTimes:3}, {theName:”Icelandic”, numberOfTimes:3}, {theName:”Kannada”, numberOfTimes:3}, {theName:”Galician”, numberOfTimes:3}, {theName:”Bengali”, numberOfTimes:3}, {theName:”Gujarati”, numberOfTimes:3}, {theName:”Marathi”, numberOfTimes:3}, {theName:”Tamil”, numberOfTimes:3}, {theName:”Belarusian”, numberOfTimes:3}, {theName:”Albanian”, numberOfTimes:2}, {theName:”Mongolian”, numberOfTimes:2}, {theName:”French (Morocco)”, numberOfTimes:2}, {theName:”Georgian”, numberOfTimes:2}, {theName:”Sinhala”, numberOfTimes:2}, {theName:”jp”, numberOfTimes:2}, {theName:”ua”, numberOfTimes:2}, {theName:”Amharic”, numberOfTimes:2}, {theName:”English (United Arab Emirates)”, numberOfTimes:2}, {theName:”Finnish (FL)”, numberOfTimes:2}, {theName:”Catalan (Spain)”, numberOfTimes:2}, {theName:”Basque”, numberOfTimes:2}, {theName:”English (Israel)”, numberOfTimes:2}, {theName:”Norwegian (NB)”, numberOfTimes:2}, {theName:”Oriya”, numberOfTimes:1}, {theName:”Punjabi”, numberOfTimes:1}, {theName:”Serbo-Croatian”, numberOfTimes:1}, {theName:”Walloon”, numberOfTimes:1}, {theName:”Corsican”, numberOfTimes:1}, {theName:”Sorani Kurdish”, numberOfTimes:1}, {theName:”Chinese (Hong Kong SAR China)”, numberOfTimes:1}, {theName:”Breton”, numberOfTimes:1}, {theName:”Cornish”, numberOfTimes:1}, {theName:”Chiga”, numberOfTimes:1}, {theName:”Aragonese”, numberOfTimes:1}, {theName:”Macedonian”, numberOfTimes:1}, {theName:”Japan”, numberOfTimes:1}, {theName:”Bosnian”, numberOfTimes:1}, {theName:”Ganda”, numberOfTimes:1}, {theName:”Tetum”, numberOfTimes:1}, {theName:”Welsh”, numberOfTimes:1}, {theName:”Armenian”, numberOfTimes:1}, {theName:”Kyrgyz”, numberOfTimes:1}, {theName:”Scottish Gaelic”, numberOfTimes:1}, {theName:”Afrikaans”, numberOfTimes:1}, {theName:”Zulu”, numberOfTimes:1}, {theName:”Swahili”, numberOfTimes:1}, {theName:”Burmese”, numberOfTimes:1}, {theName:”Chinese (Traditional, Taiwan)”, numberOfTimes:1}, {theName:”ct”, numberOfTimes:1}, {theName:”Tagalog”, numberOfTimes:1}, {theName:”Kazakh”, numberOfTimes:1}, {theName:”Bengali (India)”, numberOfTimes:1}, {theName:”Pashto”, numberOfTimes:1}, {theName:”Nepali”, numberOfTimes:1}, {theName:”Acoli”, numberOfTimes:1}, {theName:”Friulian”, numberOfTimes:1}, {theName:”Norwegian Nynorsk”, numberOfTimes:1}, {theName:”Asturian”, numberOfTimes:1}, {theName:”Thai (Thailand)”, numberOfTimes:1}, {theName:”Khmer”, numberOfTimes:1}, {theName:”Irish”, numberOfTimes:1}, {theName:”American”, numberOfTimes:1}, {theName:”Fulah”, numberOfTimes:1}, {theName:”Chinese (Traditional, Hong Kong SAR China)”, numberOfTimes:1}, {theName:”Occitan”, numberOfTimes:1}, {theName:”Interlingua”, numberOfTimes:1}, {theName:”Uzbek”, numberOfTimes:1}, {theName:”Azerbaijani”, numberOfTimes:1}}

–指定アプリケーションファイルの、指定Localeにおけるローカライズ言語リストを求める。重複を排除
on getSpecifiedAppFilesLocalizationList(anAppAlias as alias)
  
  
set aURL to (current application’s SMSFord’s URLFrom:anAppAlias)
  
set aBundle to current application’s NSBundle’s bundleWithURL:aURL
  
  
set theNSLocale to current application’s NSLocale’s localeWithLocaleIdentifier:“en” –Output Locale Name in English (en)
  
  
–Get Localization Info
  
set locList to aBundle’s localizations()
  
–> {”de”, “English”, “fr”, “French”, “German”, “ja”, “Japanese”}
  
set theEnumerator to locList’s objectEnumerator()
  
  
set theSet to current application’s NSMutableSet’s |set|()
  
  
repeat
    set aValue to theEnumerator’s nextObject()
    
if aValue is missing value then exit repeat
    
    
set theName to (theNSLocale’s displayNameForKey:(current application’s NSLocaleIdentifier) value:aValue)
    
    
if theName is missing value then
      –”English”や”French”などは、missing valueが返ってくるので、”English”や”French”などをそのまま追加
      
theSet’s addObject:aValue
    else
      –”de”や”fr”などは、”German”や”French”が返ってくるので、それを追加
      
theSet’s addObject:theName
    end if
  end repeat
  
  
–NSCountedSetをNSMutableArrayに変換
  
set theArray to current application’s NSMutableArray’s array()
  
set theEnumerator to theSet’s objectEnumerator()
  
  
–NSMutableArrayから順次取り出して、NSArrayに対してDictionaryを追加
  
repeat
    set aValue to theEnumerator’s nextObject()
    
if aValue is missing value then exit repeat
    
theArray’s addObject:aValue
  end repeat
  
  
return theArray as list
  
end getSpecifiedAppFilesLocalizationList

–指定階層下で、指定メタデータが指定パラメータであるファイルを取得(alias list)
on getFileListWithSpotLight(aMetaDataItem as string, aParam as string, startDir as {alias, string})
  set sDirText to quoted form of POSIX path of startDir
  
set shellText to “/usr/bin/mdfind ’” & aMetaDataItem & ” == \”" & aParam & “\”’ -onlyin “ & sDirText
  
try
    set aRes to do shell script shellText
  on error
    return {}
  end try
  
set pList to paragraphs of aRes
  
set aList to {}
  
repeat with i in pList
    set aPath to POSIX file i
    
set aPath to aPath as alias
    
set the end of aList to aPath
  end repeat
  
return aList
end getFileListWithSpotLight

★Click Here to Open This Script 

2014/12/24 アプリケーションのローカライズ分布を取得する v4

/Applicationsフォルダ内に入っているアプリケーションのローカライズ言語の度数分布を取得するAppleScriptのバージョンアップ版です。

Shane Stanleyからのクリスマスプレゼントともいえるもので、実に処理内容がクールです。いや、これはいい。

v3で言語表記の「ゆらぎ」をカバーしようとしましたが、このv4はOSのサービスを用いて、”jp”や”fr”といった短縮表記からフルネームの”Japanese”や”French”といった名称を展開し、そのうえで重複を排除しています。

AppleScript名:アプリケーションのローカライズ分布を取得する v4
– v1 Created 2014-12-24 By Takaaki Naganoya
– v2 Changed 2014-12-24 by Shane Stanley
– v3 Changed 2014-12-24 by Takaaki Naganoya
– v4 Changed 2014-12-24 by Shane Stanley

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

set apPath to (path to applications folder) as string

tell application “Finder”
  tell folder apPath
    set aList to (every application file) as alias list
  end tell
end tell

set theCountedSet to current application’s NSCountedSet’s |set|()
set theNSLocale to current application’s NSLocale’s localeWithLocaleIdentifier:“en” –Output Locale Name in English (en)
–set theNSLocale to current application’s NSLocale’s currentLocale() –Output Locale Name in current Locale Language (ex. Japanese)

repeat with i in aList
  set j to contents of i
  
set aURL to (current application’s SMSFord’s URLFrom:j)
  
set aBundle to (current application’s NSBundle’s bundleWithURL:aURL)
  
  
–アプリケーションのローカリゼーションを取得する
  
set locList to aBundle’s localizations()
  
set theEnumerator to locList’s objectEnumerator()
  
repeat
    set aValue to theEnumerator’s nextObject()
    
if aValue is missing value then exit repeat
    
set theName to (theNSLocale’s displayNameForKey:(current application’s NSLocaleIdentifier) value:aValue)
    
if theName is missing value then
      (theCountedSet’s addObject:aValue)
    else
      (theCountedSet’s addObject:theName)
    end if
  end repeat
  
  
log {“theCountedSet”, theCountedSet} –ASObjC Explorer 4だとCocoaのObjectも読める形式でログ出力可能
  
end repeat

–NSCountedSetをNSMutableDictionaryに変換してからASのrecordに変換
set theArray to current application’s NSMutableArray’s array()
set theEnumerator to theCountedSet’s objectEnumerator()
repeat
  set aValue to theEnumerator’s nextObject()
  
if aValue is missing value then exit repeat
  
theArray’s addObject:(current application’s NSDictionary’s dictionaryWithObjects:{aValue, (theCountedSet’s countForObject:aValue)} forKeys:{“theName”, “numberOfTimes”})
end repeat
set theDesc to current application’s NSSortDescriptor’s sortDescriptorWithKey:“theName” ascending:true
theArray’s sortUsingDescriptors:{theDesc}

return theArray as list
–> {{theName:”Acoli”, numberOfTimes:1}, {theName:”Afrikaans”, numberOfTimes:1}, {theName:”Albanian”, numberOfTimes:1}, {theName:”American”, numberOfTimes:1}, {theName:”Amharic”, numberOfTimes:2}, {theName:”Arabic”, numberOfTimes:36}, {theName:”Aragonese”, numberOfTimes:1}, {theName:”Armenian”, numberOfTimes:1}, {theName:”Asturian”, numberOfTimes:1}, {theName:”Azerbaijani”, numberOfTimes:1}, {theName:”Base”, numberOfTimes:30}, {theName:”Basque”, numberOfTimes:2}, {theName:”Belarusian”, numberOfTimes:2}, {theName:”Bengali”, numberOfTimes:3}, {theName:”Bengali (India)”, numberOfTimes:1}, {theName:”Bosnian”, numberOfTimes:1}, {theName:”Breton”, numberOfTimes:1}, {theName:”Bulgarian”, numberOfTimes:8}, {theName:”Burmese”, numberOfTimes:1}, {theName:”Catalan”, numberOfTimes:39}, {theName:”Chiga”, numberOfTimes:1}, {theName:”Chinese”, numberOfTimes:8}, {theName:”Chinese (China)”, numberOfTimes:69}, {theName:”Chinese (Hong Kong SAR China)”, numberOfTimes:1}, {theName:”Chinese (Simplified)”, numberOfTimes:14}, {theName:”Chinese (Taiwan)”, numberOfTimes:64}, {theName:”Chinese (Traditional)”, numberOfTimes:8}, {theName:”Chinese (Traditional, Hong Kong SAR China)”, numberOfTimes:1}, {theName:”Cornish”, numberOfTimes:1}, {theName:”Corsican”, numberOfTimes:1}, {theName:”Croatian”, numberOfTimes:40}, {theName:”Czech”, numberOfTimes:48}, {theName:”Danish”, numberOfTimes:62}, {theName:”Danish (Denmark)”, numberOfTimes:1}, {theName:”Dutch”, numberOfTimes:77}, {theName:”Dutch (Netherlands)”, numberOfTimes:1}, {theName:”English”, numberOfTimes:307}, {theName:”English (United Kingdom)”, numberOfTimes:7}, {theName:”English (United States)”, numberOfTimes:1}, {theName:”Estonian”, numberOfTimes:6}, {theName:”Filipino”, numberOfTimes:4}, {theName:”Finnish”, numberOfTimes:56}, {theName:”French”, numberOfTimes:130}, {theName:”Friulian”, numberOfTimes:1}, {theName:”Fulah”, numberOfTimes:1}, {theName:”Galician”, numberOfTimes:2}, {theName:”Ganda”, numberOfTimes:1}, {theName:”Georgian”, numberOfTimes:2}, {theName:”German”, numberOfTimes:135}, {theName:”Greek”, numberOfTimes:43}, {theName:”Gujarati”, numberOfTimes:3}, {theName:”Hebrew”, numberOfTimes:36}, {theName:”Hindi”, numberOfTimes:5}, {theName:”Hungarian”, numberOfTimes:44}, {theName:”Icelandic”, numberOfTimes:3}, {theName:”Indonesian”, numberOfTimes:38}, {theName:”Interlingua”, numberOfTimes:1}, {theName:”Irish”, numberOfTimes:1}, {theName:”Italian”, numberOfTimes:98}, {theName:”Japanese”, numberOfTimes:147}, {theName:”Japanese (Japan)”, numberOfTimes:1}, {theName:”Kannada”, numberOfTimes:3}, {theName:”Kazakh”, numberOfTimes:1}, {theName:”Khmer”, numberOfTimes:1}, {theName:”Korean”, numberOfTimes:67}, {theName:”Kyrgyz”, numberOfTimes:1}, {theName:”Latvian”, numberOfTimes:7}, {theName:”Lithuanian”, numberOfTimes:6}, {theName:”Macedonian”, numberOfTimes:1}, {theName:”Malay”, numberOfTimes:36}, {theName:”Malayalam”, numberOfTimes:3}, {theName:”Marathi”, numberOfTimes:3}, {theName:”Mongolian”, numberOfTimes:2}, {theName:”Nepali”, numberOfTimes:1}, {theName:”Norwegian”, numberOfTimes:49}, {theName:”Norwegian Bokmål”, numberOfTimes:10}, {theName:”Norwegian Bokmål (Norway)”, numberOfTimes:1}, {theName:”Norwegian Nynorsk”, numberOfTimes:1}, {theName:”Occitan”, numberOfTimes:1}, {theName:”Oriya”, numberOfTimes:1}, {theName:”Pashto”, numberOfTimes:1}, {theName:”Persian”, numberOfTimes:4}, {theName:”Polish”, numberOfTimes:60}, {theName:”Portuguese”, numberOfTimes:61}, {theName:”Portuguese (Brazil)”, numberOfTimes:12}, {theName:”Portuguese (Portugal)”, numberOfTimes:44}, {theName:”Punjabi”, numberOfTimes:1}, {theName:”Romanian”, numberOfTimes:42}, {theName:”Russian”, numberOfTimes:70}, {theName:”Russian (Russia)”, numberOfTimes:1}, {theName:”Scottish Gaelic”, numberOfTimes:1}, {theName:”Serbian”, numberOfTimes:5}, {theName:”Serbo-Croatian”, numberOfTimes:1}, {theName:”Sinhala”, numberOfTimes:2}, {theName:”Slovak”, numberOfTimes:42}, {theName:”Slovenian”, numberOfTimes:7}, {theName:”Sorani Kurdish”, numberOfTimes:1}, {theName:”Spanish”, numberOfTimes:95}, {theName:”Spanish (Latin America)”, numberOfTimes:2}, {theName:”Spanish (Mexico)”, numberOfTimes:28}, {theName:”Spanish (Spain)”, numberOfTimes:2}, {theName:”Swahili”, numberOfTimes:1}, {theName:”Swedish”, numberOfTimes:64}, {theName:”Swedish (Sweden)”, numberOfTimes:1}, {theName:”Tagalog”, numberOfTimes:1}, {theName:”Tamil”, numberOfTimes:3}, {theName:”Telugu”, numberOfTimes:3}, {theName:”Tetum”, numberOfTimes:1}, {theName:”Thai”, numberOfTimes:40}, {theName:”Thai (Thailand)”, numberOfTimes:1}, {theName:”Turkish”, numberOfTimes:46}, {theName:”Ukrainian”, numberOfTimes:39}, {theName:”Ukrainian (Ukraine)”, numberOfTimes:2}, {theName:”Uzbek”, numberOfTimes:1}, {theName:”Vietnamese”, numberOfTimes:37}, {theName:”Walloon”, numberOfTimes:1}, {theName:”Welsh”, numberOfTimes:1}, {theName:”Zulu”, numberOfTimes:1}, {theName:”empty”, numberOfTimes:3}}

–> {{theName:”American”, numberOfTimes:1}, {theName:”Base”, numberOfTimes:30}, {theName:”Chinese”, numberOfTimes:2}, {theName:”Czech”, numberOfTimes:1}, {theName:”Danish”, numberOfTimes:4}, {theName:”Dutch”, numberOfTimes:38}, {theName:”English”, numberOfTimes:212}, {theName:”Finnish”, numberOfTimes:1}, {theName:”French”, numberOfTimes:67}, {theName:”German”, numberOfTimes:72}, {theName:”Greek”, numberOfTimes:1}, {theName:”Hungarian”, numberOfTimes:1}, {theName:”Italian”, numberOfTimes:50}, {theName:”Japanese”, numberOfTimes:80}, {theName:”Korean”, numberOfTimes:3}, {theName:”Polish”, numberOfTimes:3}, {theName:”Portuguese”, numberOfTimes:2}, {theName:”Russian”, numberOfTimes:3}, {theName:”Spanish”, numberOfTimes:45}, {theName:”Swedish”, numberOfTimes:5}, {theName:”empty”, numberOfTimes:3}, {theName:”アイスランド語”, numberOfTimes:3}, {theName:”アイルランド語”, numberOfTimes:1}, {theName:”アストゥリアス語”, numberOfTimes:1}, {theName:”アゼルバイジャン語”, numberOfTimes:1}, {theName:”アチョリ語”, numberOfTimes:1}, {theName:”アフリカーンス語”, numberOfTimes:1}, {theName:”アムハラ語”, numberOfTimes:2}, {theName:”アラゴン語”, numberOfTimes:1}, {theName:”アラビア語”, numberOfTimes:36}, {theName:”アルバニア語”, numberOfTimes:1}, {theName:”アルメニア語”, numberOfTimes:1}, {theName:”イタリア語”, numberOfTimes:48}, {theName:”インターリングア”, numberOfTimes:1}, {theName:”インドネシア語”, numberOfTimes:38}, {theName:”ウェールズ語”, numberOfTimes:1}, {theName:”ウクライナ語”, numberOfTimes:39}, {theName:”ウクライナ語 (ウクライナ)”, numberOfTimes:2}, {theName:”ウズベク語”, numberOfTimes:1}, {theName:”エストニア語”, numberOfTimes:6}, {theName:”オック語”, numberOfTimes:1}, {theName:”オランダ語”, numberOfTimes:39}, {theName:”オランダ語 (オランダ)”, numberOfTimes:1}, {theName:”オリヤー語”, numberOfTimes:1}, {theName:”ガリシア語”, numberOfTimes:2}, {theName:”ガンダ語”, numberOfTimes:1}, {theName:”カザフ語”, numberOfTimes:1}, {theName:”カタロニア語”, numberOfTimes:39}, {theName:”カンナダ語”, numberOfTimes:3}, {theName:”ギリシャ語”, numberOfTimes:42}, {theName:”キルギス語”, numberOfTimes:1}, {theName:”グジャラート語”, numberOfTimes:3}, {theName:”グルジア語”, numberOfTimes:2}, {theName:”クメール語”, numberOfTimes:1}, {theName:”クルド語(ソラニー)”, numberOfTimes:1}, {theName:”クロアチア語”, numberOfTimes:40}, {theName:”コルシカ語”, numberOfTimes:1}, {theName:”コーンウォール語”, numberOfTimes:1}, {theName:”シンハラ語”, numberOfTimes:2}, {theName:”ズールー語”, numberOfTimes:1}, {theName:”スウェーデン語”, numberOfTimes:59}, {theName:”スウェーデン語 (スウェーデン)”, numberOfTimes:1}, {theName:”スコットランド・ゲール語”, numberOfTimes:1}, {theName:”スペイン語”, numberOfTimes:50}, {theName:”スペイン語 (スペイン)”, numberOfTimes:2}, {theName:”スペイン語 (メキシコ)”, numberOfTimes:28}, {theName:”スペイン語 (ラテンアメリカ)”, numberOfTimes:2}, {theName:”スロバキア語”, numberOfTimes:42}, {theName:”スロベニア語”, numberOfTimes:7}, {theName:”スワヒリ語”, numberOfTimes:1}, {theName:”セルビア語”, numberOfTimes:5}, {theName:”セルボ・クロアチア語”, numberOfTimes:1}, {theName:”タイ語”, numberOfTimes:40}, {theName:”タイ語 (タイ)”, numberOfTimes:1}, {theName:”タガログ語”, numberOfTimes:1}, {theName:”タミル語”, numberOfTimes:3}, {theName:”チェコ語”, numberOfTimes:47}, {theName:”チガ語”, numberOfTimes:1}, {theName:”デンマーク語”, numberOfTimes:58}, {theName:”デンマーク語 (デンマーク)”, numberOfTimes:1}, {theName:”テトゥン語”, numberOfTimes:1}, {theName:”テルグ語”, numberOfTimes:3}, {theName:”ドイツ語”, numberOfTimes:63}, {theName:”トルコ語”, numberOfTimes:46}, {theName:”ネパール語”, numberOfTimes:1}, {theName:”ノルウェー語”, numberOfTimes:49}, {theName:”ノルウェー語(ニーノシュク)”, numberOfTimes:1}, {theName:”ノルウェー語(ブークモール)”, numberOfTimes:10}, {theName:”ノルウェー語(ブークモール) (ノルウェー)”, numberOfTimes:1}, {theName:”バスク語”, numberOfTimes:2}, {theName:”パシュトゥー語”, numberOfTimes:1}, {theName:”パンジャブ語”, numberOfTimes:1}, {theName:”ハンガリー語”, numberOfTimes:43}, {theName:”ビルマ語”, numberOfTimes:1}, {theName:”ヒンディー語”, numberOfTimes:5}, {theName:”ブルガリア語”, numberOfTimes:8}, {theName:”ブルトン語”, numberOfTimes:1}, {theName:”フィリピノ語”, numberOfTimes:4}, {theName:”フィンランド語”, numberOfTimes:55}, {theName:”フラニ語”, numberOfTimes:1}, {theName:”フランス語”, numberOfTimes:63}, {theName:”フリウリ語”, numberOfTimes:1}, {theName:”ベトナム語”, numberOfTimes:37}, {theName:”ベラルーシ語”, numberOfTimes:2}, {theName:”ベンガル語”, numberOfTimes:3}, {theName:”ベンガル語 (インド)”, numberOfTimes:1}, {theName:”ヘブライ語”, numberOfTimes:36}, {theName:”ペルシア語”, numberOfTimes:4}, {theName:”ボスニア語”, numberOfTimes:1}, {theName:”ポルトガル語”, numberOfTimes:59}, {theName:”ポルトガル語 (ブラジル)”, numberOfTimes:12}, {theName:”ポルトガル語 (ポルトガル)”, numberOfTimes:44}, {theName:”ポーランド語”, numberOfTimes:57}, {theName:”マケドニア語”, numberOfTimes:1}, {theName:”マラヤーラム語”, numberOfTimes:3}, {theName:”マラーティー語”, numberOfTimes:3}, {theName:”マレー語”, numberOfTimes:36}, {theName:”モンゴル語”, numberOfTimes:2}, {theName:”ラトビア語”, numberOfTimes:7}, {theName:”リトアニア語”, numberOfTimes:6}, {theName:”ルーマニア語”, numberOfTimes:42}, {theName:”ロシア語”, numberOfTimes:67}, {theName:”ロシア語 (ロシア)”, numberOfTimes:1}, {theName:”ワロン語”, numberOfTimes:1}, {theName:”中国語”, numberOfTimes:6}, {theName:”中国語 (中国)”, numberOfTimes:69}, {theName:”中国語 (中華人民共和国香港特別行政区)”, numberOfTimes:1}, {theName:”中国語 (台湾)”, numberOfTimes:64}, {theName:”中国語 (簡体字)”, numberOfTimes:14}, {theName:”中国語 (繁体字)”, numberOfTimes:8}, {theName:”中国語 (繁体字、中華人民共和国香港特別行政区)”, numberOfTimes:1}, {theName:”日本語”, numberOfTimes:67}, {theName:”日本語 (日本)”, numberOfTimes:1}, {theName:”英語”, numberOfTimes:95}, {theName:”英語 (アメリカ合衆国)”, numberOfTimes:1}, {theName:”英語 (イギリス)”, numberOfTimes:7}, {theName:”韓国語”, numberOfTimes:64}}

★Click Here to Open This Script 

動作原理を理解するために、指定アプリ1つのローカライズ言語を取得するScriptを単体で動作するようにしてみました。

AppleScript名:選択したアプリケーションのローカライズ言語名称を求める
– Created 2014-12-23 by Takaaki Naganoya
– Changed 2014-12-24 by Shane Stanley
– Created 2014-12-24 by Takaaki Naganoya
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “ASObjCExtras”

set a to choose file of type {“com.apple.application-bundle”}
set aRes to getSpecifiedAppFilesLocalizationList(a) of me
–> {”German”, “English”, “French”, “Japanese”}

–指定アプリケーションファイルの、指定Localeにおけるローカライズ言語リストを求める
on getSpecifiedAppFilesLocalizationList(anApp)
  
  
set aURL to (current application’s SMSFord’s URLFrom:anApp)
  
set aBundle to current application’s NSBundle’s bundleWithURL:aURL
  
  
set theNSLocale to current application’s NSLocale’s localeWithLocaleIdentifier:“en” –Output Locale Name in English (en)
  
  
–Get Localization Info
  
set locList to aBundle’s localizations()
  
–> {”de”, “English”, “fr”, “French”, “German”, “ja”, “Japanese”}
  
  
set outList to {}
  
  
repeat with i in locList
    set j to contents of i
    
set theName to (theNSLocale’s displayNameForKey:(current application’s NSLocaleIdentifier) value:j)
    
    
if theName is missing value then
      –”English”や”French”などは、missing valueが返ってくるので、”English”や”French”などをそのまま追加
      
if (j as string) is not in outList then
        set the end of outList to j as string
      end if
    else
      –”de”や”fr”などは、”German”や”French”が返ってくるので、それを追加
      
if theName as string is not in outList then
        set the end of outList to theName as string
      end if
    end if
  end repeat
  
  
return outList
  
end getSpecifiedAppFilesLocalizationList

★Click Here to Open This Script 

2014/12/24 アプリケーションのローカライズ分布を取得するv2

/Applicationsフォルダ内に入っているアプリケーションのローカライズ言語の度数分布を取得するAppleScriptのバージョンアップ版です。

Shane Stanleyから指摘があり、データ数が増えた場合にはNSCountedSetを利用した方が有利とのこと。NSCountedSetの内容を(前バージョンよりも読みやすい形式で)ログ出力して確認したりと、ASObjCExplorer 4の新バージョンの4.1の威力を実感できました(^ー^)

asoe4.png

AppleScript名:アプリケーションのローカライズ分布を取得する v2
– Created 2014-12-23 by Takaaki Naganoya
– Changed 2014-12-24 by Shane Stanley
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “ASObjCExtras”

set apPath to (path to applications folder) as string

tell application “Finder”
  tell folder apPath
    set aList to (every application file) as alias list
  end tell
end tell

set aDict to current application’s NSMutableDictionary’s alloc()’s init()
set theCountedSet to current application’s NSCountedSet’s |set|()

repeat with i in aList
  set j to contents of i
  
set aURL to (current application’s SMSFord’s URLFrom:j)
  
set aBundle to (current application’s NSBundle’s bundleWithURL:aURL)
  
  
–アプリケーションのローカリゼーションを取得する
  
set locList to aBundle’s localizations()’s ASify() as list
  (
theCountedSet’s addObjectsFromArray:locList)
  
  
log {“theCountedSet”, theCountedSet} –ASObjC Explorer 4だとCocoaのObjectも読める形式でログ出力可能
  
end repeat

–NSCountedSetをNSMutableDictionaryに変換してからASのrecordに変換
set theEnumerator to theCountedSet’s objectEnumerator()
repeat
  set aValue to theEnumerator’s nextObject()
  
if aValue is missing value then exit repeat
  
aDict’s setObject:(theCountedSet’s countForObject:aValue) forKey:aValue
end repeat

set bRec to aDict as record
–> {zh-Hant-HK:1, pt_BR:9, Finnish:1, Portuguese:2, ja:67, af:1, English:212, gu:3, es_419:1, zh:6, ps:1, Italian:50, uk_UA:1, pt:59, hr:40, ja_JP:1, bn_IN:1, Czech:1, ka:2, be:2, fur:1, en_GB:6, Russian:3, Korean:3, hu:43, bg:8, am:2, ca:39, an:1, ta:3, sh:1, si:2, is:3, es-419:1, hy:1, ro:42, it:48, ar:36, te:3, sk:42, da:58, Hungarian:1, pt_PT:41, sl:7, bn:3, ast:1, pt-BR:3, kk:1, zu:1, fil:4, th:40, ru:67, lg:1, de:63, zh_CN:69, da_DK:1, km:1, Base:30, br:1, kn:3, sq:1, ko:64, en_US:1, bs:1, tl:1, zh-Hant:8, sr:5, az:1, uk-UA:1, ach:1, co:1, nb-NO:1, Greek:1, en-GB:1, sv:59, nb:10, Dutch:38, ru-RU:1, uk:39, sw:1, cs:47, ckb:1, fa:4, Danish:4, tr:46, wa:1, kw:1, mk:1, ne:1, ml:3, vi:37, ky:1, mn:2, pt-PT:3, el:42, Spanish:45, th_TH:1, oc:1, cy:1, ga:1, lt:6, ff:1, lv:7, en:96, sv_SE:1, nl_NL:1, fi:55, mr:3, gd:1, nl:39, pa:1, ms:36, nn:1, German:72, es_MX:28, no:49, es:50, Polish:3, es_ES:2, French:67, et:6, eu:2, Swedish:5, uz:1, American:1, tet:1, my:1, he:36, cgg:1, fr:63, gl:2, ia:1, Chinese:2, zh_HK:1, zh-Hans:14, empty:3, hi:5, Japanese:80, pl:57, id:38, or:1, zh_TW:64}

★Click Here to Open This Script 

2014/12/23 選択したアプリケーションの実行ファイルを求める

選択したアプリケーションの実行ファイルを求め、ローカリゼーションの言語種別を求めるAppleScriptです。

AppleScript名:選択したアプリケーションの実行ファイルを求める
– Created 2014-12-23 by Takaaki Naganoya
– 2014 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “ASObjCExtras”

set anApp to choose file of type {“com.apple.application-bundle”}
set aURL to (current application’s SMSFord’s URLFrom:anApp)
set aBundle to current application’s NSBundle’s bundleWithURL:aURL

–実行ファイル本体のパスを求める
set theBundlePath to aBundle’s executablePath()
–> “/Applications/Transmit.app/Contents/MacOS/Transmit”

–アプリケーションのローカリゼーションを取得する
set localizationList to aBundle’s localizations()’s ASify() as list
–> {”de”, “English”, “fr”, “French”, “German”, “ja”, “Japanese”}

★Click Here to Open This Script 

2014/12/14 AppleScriptのカラーフォーマットを読み込む

Script Editorで設定したAppleScriptの構文色分けのフォーマットを読み込むAppleScriptです。

as_editor.png
▲Piyomaru Softwareが使用しており、本Blogにも反映させている構文色分け設定。似た色でも個別に識別できるよう、わざわざRGB値を微妙に変えてある

このように、Script Editor上で指定したカラー値(R、G、B)、フォント名、フォントサイズ(point)をまとめて返します。

オリジナルはShaneがAppleScript Users MLに投稿したScript(AppleScript Libraries用)だったのですが、普通のAppleScriptで使いやすいように(若干)書き換えました。

同様の機能を持つルーチンをCocoaの機能を使わずに(数年前に)実現していたのですが、このようにまっとうな方法で調査ができるのであれば、安心感がアップします。

# 実際に既存のAppleScript(構文カラーリングを検出して、構文要素区分にもとづいた処理を行うもの)に入れ替えてみたら・・・設定値と実際のカラー値が合わないらしくて、そのままでは使えませんでした。もう少し調べてみる必要があるようで、、、

AppleScript名:AppleScriptのカラーフォーマットを読み込む
– Created 2013-11-11 by Shane Stanley
– Changed 2014-12-14 by Takaaki Naganoya
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “ASObjCExtras”

set cList to getAppleScriptSourceColors()
–> {{redValue:145, greenValue:40, blueValue:144, fontName:”Osaka”, fontSize:12.0}, {redValue:95, greenValue:94, blueValue:94, fontName:”Osaka”, fontSize:12.0}, {redValue:14, greenValue:62, blueValue:251, fontName:”Osaka”, fontSize:12.0}, {redValue:120, greenValue:52, blueValue:203, fontName:”Osaka”, fontSize:12.0}, {redValue:252, greenValue:42, blueValue:28, fontName:”Osaka”, fontSize:12.0}, {redValue:0, greenValue:0, blueValue:0, fontName:”Osaka”, fontSize:12.0}, {redValue:145, greenValue:82, blueValue:17, fontName:”Osaka”, fontSize:12.0}, {redValue:0, greenValue:0, blueValue:0, fontName:”Osaka”, fontSize:12.0}, {redValue:39, greenValue:201, blueValue:201, fontName:”Osaka”, fontSize:12.0}, {redValue:15, greenValue:62, blueValue:251, fontName:”Osaka”, fontSize:12.0}, {redValue:31, greenValue:182, blueValue:252, fontName:”Osaka”, fontSize:12.0}, {redValue:129, greenValue:58, blueValue:217, fontName:”Osaka”, fontSize:12.0}, {redValue:93, greenValue:54, blueValue:146, fontName:”Osaka”, fontSize:12.0}, {redValue:9, greenValue:55, blueValue:187, fontName:”Osaka”, fontSize:12.0}, {redValue:8, greenValue:55, blueValue:187, fontName:”Osaka”, fontSize:12.0}, {redValue:9, greenValue:55, blueValue:186, fontName:”Osaka”, fontSize:12.0}, {redValue:86, greenValue:55, blueValue:189, fontName:”Osaka”, fontSize:12.0}, {redValue:52, greenValue:32, blueValue:99, fontName:”Osaka”, fontSize:12.0}}

–AppleScriptの構文色分けのカラー値をRGBで取得する
on getAppleScriptSourceColors()
  
  
– get the info as a dictionary
  
set thePath to current application’s NSString’s stringWithString:“~/Library/Preferences/com.apple.applescript.plist”
  
set thePath to thePath’s stringByExpandingTildeInPath()
  
set theInfo to current application’s NSDictionary’s dictionaryWithContentsOfFile:thePath
  
  
– extract relevant part and loop through
  
set theArray to (theInfo’s valueForKey:“AppleScriptSourceAttributes”) as list
  
  
set colList to {}
  
  
repeat with i from 1 to count of theArray
    set anEntry to item i of theArray
    
    
set colorData to NSColor of anEntry
    
set theColor to (current application’s NSUnarchiver’s unarchiveObjectWithData:colorData)
    
    
set rVal to round ((theColor’s redComponent()) * 255) rounding down
    
set gVal to round ((theColor’s greenComponent()) * 255) rounding down
    
set bVal to round ((theColor’s blueComponent()) * 255) rounding down
    
    
    
set fontData to NSFont of anEntry
    
set theFont to (current application’s NSUnarchiver’s unarchiveObjectWithData:fontData)
    
    
set aFontName to theFont’s displayName() as text
    
set aFontSize to theFont’s pointSize()
    
    
set aColRec to {redValue:rVal, greenValue:gVal, blueValue:bVal, fontName:aFontName, fontSize:aFontSize}
    
    
set the end of colList to aColRec
  end repeat
  
  
return colList
end getAppleScriptSourceColors

★Click Here to Open This Script 

2014/12/11 Bluetoothに接続中のデバイス名を取得するv3

Bluetoothに接続中のデバイス名を取得するAppleScriptの修正版です。

v2が「ペアリングされたデバイス名の一覧を取得する」という動作を行っていましたが、実際に接続中かどうかを確認して名称のリストを返すように修正しました。

ただ、

bt10.png

のように、PlayStation 3のコントローラーもつながっている状態なんですが、これだけ名前が返ってきません。

キーボードやマウスほどきちんとサポートされていない雰囲気なので、まーそんなもんなのかな、と思わないではないですが、まだいまひとつな感じがします。

AppleScript名:Bluetoothに接続中のデバイス名を取得するv3
– Created 2014-12-09 by Takaaki Naganoya
– 2014 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “IOBluetooth”

set aList to currentBluetoothDeviceNames(“displayName”) –Bluetoothメニューに出てくる名称
–> {”Piyomaru Mouse”, “Takaaki Naganoya のキーボード”, “AirTurn105v128-E36E”}

set bList to currentBluetoothDeviceNames(“realName”) –ほんまもんの名称
–> {”System Administrator’s Mouse”, “Takaaki Naganoya のキーボード”, “AirTurn105v128-E36E”}

—Bluetoothで接続中のデバイス名をリストで返す
on currentBluetoothDeviceNames(aParam)
  
  
–Bluetoothでペアリングされたデバイス一覧を取得
  
set bList to current application’s IOBluetoothDevice’s pairedDevices() –ペアリングしたデバイスを取得
  
set cList to bList as list
  
  
–デバイス名称を実際に取得  
  
set dNameList to {}
  
  
repeat with i in cList
    set j to contents of i
    
set aName to |name| of j
    
    
set aConnect to j’s isConnected() –接続中かどうかを確認
    
if aConnect = true then
      
      
if aParam = “displayName” then
        set dName to “”
        
try
          set dName to |displayName| of j
        end try
        
        
if dName is not equal to “” then
          copy dName to aName
        end if
      end if
      
      
set the end of dNameList to aName as string
      
    end if
    
  end repeat
  
  
return dNameList
  
end currentBluetoothDeviceNames

★Click Here to Open This Script 

2014/12/09 Bluetoothに接続中のデバイス名を取得するv2

Bluetoothに接続中のデバイス名を取得するAppleScriptの修正版です。

最初のバージョンでは、「recentDevices:」でBluetoothデバイスの接続ヒストリーから過去の履歴を取得して、接続ないしは接近したことのあるものだけを取り出していました。

本バージョンでは、「pairedDevices()」でMac本体とペアリングしたBluetoothデバイス名を取得します。本プログラムの名称を正しく表現すると「Bluetoothにペアリングしたデバイス名一覧を取得」ということになるでしょう。

また、実際にBluetoothデバイスが名乗っている名前(realName)と、名称変更して付けられた名前(Bluetoothデバイス一覧に出てくる名前、displayName)のどちらを取得するかを指定できるようにしました。

まだ、いろいろ試行錯誤中です。

bt1.png

bt2.png

AppleScript名:Bluetoothに接続中のデバイス名を取得するv2
– Created 2014-12-09 by Takaaki Naganoya
– 2014 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “IOBluetooth”

set aList to currentBluetoothDeviceNames(“displayName”) –Bluetoothメニューに出てくる名称
–> {”Piyomaru Mouse”, “Piyomaru iPad mini”, “Takaaki Naganoya のキーボード”, “Piyomaru iPhone”, “AirTurn105v128-E36E”, “Beats Wireless”}

set bList to currentBluetoothDeviceNames(“realName”) –ほんまもんの名称
–> {”System Administrator’s Mouse”, “Piyomaru iPad mini”, “Takaaki Naganoya のキーボード”, “Piyomaru iPhone”, “AirTurn105v128-E36E”, “Beats Wireless”}

—Bluetoothで接続中のデバイス名をリストで返す
on currentBluetoothDeviceNames(aParam)
  
  
–Bluetoothでペアリングされたデバイス一覧を取得
  
set bList to current application’s IOBluetoothDevice’s pairedDevices() –ペアリングしたデバイスを取得
  
set cList to bList as list
  
  
–デバイス名称を実際に取得  
  
set dNameList to {}
  
  
repeat with i in cList
    set j to contents of i
    
    
set aName to |name| of j
    
    
if aParam = “displayName” then
      set dName to “”
      
try
        set dName to |displayName| of j
      end try
      
      
if dName is not equal to “” then
        copy dName to aName
      end if
    end if
    
    
set the end of dNameList to aName as string
    
  end repeat
  
  
return dNameList
  
end currentBluetoothDeviceNames

★Click Here to Open This Script 

2014/12/03 指定アプリケーションがフルスクリーン状態かどうか調べる

指定名称のアプリケーションがフルスクリーン表示状態かどうか調べるAppleScriptです。

冒頭のdelay文はAppleScriptを実行させたあとにSafariを(手動で)フルスクリーン表示させて動作確認させたときのものです。

AppleScript名:指定アプリケーションがフルスクリーン状態かどうか調べる
– Created 2011-07-25 Bill Cheeseman
use AppleScript version “2.4″
use scripting additions

delay 10

set aRes to chkFullScreen(“Safari”) of me
–> false –Not Full Screen
–> true –Full Screen

–指定アプリケーションがフルスクリーン表示になっているかを調べる
on chkFullScreen(appName)
  try
    tell application “System Events”
      tell process appName
        set fRes to get value of attribute “AXFullScreen” of window 1
      end tell
    end tell
  on error
    set fRes to false
  end try
  
  
return fRes
  
end chkFullScreen

★Click Here to Open This Script 

2014/11/27 10.10でプリンタの情報を取得する

ASOCでCocoaの機能を呼び出してプリンタの情報を取得するAppleScriptです。

NSPrinterのドキュメントをながめつつ、いろいろ突っついてみていますが・・・Deprecatedだと書かれている機能がまだ呼び出せるようで、プリンターがカラーかどうか、紙排出時に逆方向に(裏面?)出せるかなど調べられるようです。

AppleScript名:10.10でプリンタの情報を取得する
– Created 2014-11-27 by Takaaki Naganoya
– 2014 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “ASObjCExtras”
use framework “AppKit”

–Get Printer Names
set pArray to current application’s NSPrinter’s printerNames
set pList to (pArray’s ASify()) as list
–> {”KING JIM TEPRA PRO SR3700P”, “NEC MultiWriter 5750C @ MBA13″, “PDFwriter”, “PM-T960-1″}

–Get Printer Type (Driver Name?)
set tArray to current application’s NSPrinter’s printerTypes
set tList to (tArray’s ASify()) as list
–> {”TEPRA PRO SR3700P”, “NEC MultiWriter 5750C v2.4″, “Lisanet PDFwriter”, “EPSON PM-T960″}

set colorPinterList to {}

repeat with i in pList
  set j to contents of i
  
  
–Is it a Printer?
  
set aPrinter to (current application’s NSPrinter’s printerWithName:j)
  
set aDesc to aPrinter’s deviceDescription
  
set aRec to aDesc’s ASify() as record
  
–> {NSDeviceIsPrinter:”YES”}
  
  
  
–Is it a Color Printer?
  
set aColor to (aPrinter’s isColor()) as boolean –isColor() deprecated? It works
  
if aColor = true then
    set the end of colorPinterList to j
  end if
  
end repeat

colorPinterList
–> {”NEC MultiWriter 5750C @ MBA13″, “PDFwriter”, “PM-T960-1″}

★Click Here to Open This Script 

2014/11/27 10.10でプリンタを選択して印刷

ASOCで、現在Macに接続されているプリンターの名称一覧を取得して、印刷を行うサンプルです。

一般的なアプリケーションでの印刷を意図しており、InDesignなどのAdobe系アプリケーションを意図しているものではありません(仕組みや機能が全然別物)。

LAN上で共有されているプリンター(”NEC MultiWriter 5750C @ MBA13”)を指定してみたところ、問題なく印刷できました。

プリンタ名称については、lpstatコマンドで取得した名称一覧とは返ってくる文字列が違う(”NEC_MultiWriter_5750C___MBA13”)のですが、、、どちらでも問題ありませんでした。

AppleScript名:10.10でプリンタを選択して印刷
– Created 2014-11-27 by Takaaki Naganoya
– 2014 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “ASObjCExtras”
use framework “AppKit”

set pArray to current application’s NSPrinter’s printerNames
set pList to (pArray’s ASify()) as list
–> {”KING JIM TEPRA PRO SR3700P”, “NEC MultiWriter 5750C @ MBA13″, “PDFwriter”, “PM-T960-1″}

set aPrinter to first item of (choose from list pList with prompt “出力先のプリンタを選択してください”)

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

★Click Here to Open This Script 

2014/11/06 Bluetoothに接続中のデバイス名を取得する

現在接続中のBluetoothデバイス名の一覧をリストで取得するAppleScriptです。

AppleScript名:asoc_Bluetoothに接続中のデバイス名を取得する
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "IOBluetooth"

set aList to currentBluetoothDeviceNames()
–> {"maro のマウス"}

—Bluetoothで接続中のデバイス名をリストで返す
on currentBluetoothDeviceNames()
  
  
–Bluetoothに最近接続されたデバイス履歴をaMax個まで取得する
  
set aMax to 255
  
set bList to (current application’s IOBluetoothDevice’s recentDevices:aMax)
  
set cList to bList as list
  
  
–デバイス名を実際に取得  
  
set dNameList to {}
  
  
try
    repeat with i in cList
      set j to contents of i
      
      
set aName to |Name| of j
      
set aConnection to (ConnectionHandle of j) as integer
      
      
–ConnectionHandleがffffだと非接続状態
      
if aConnection is not equal to 65535 then
        set the end of dNameList to aName as string
      end if
      
    end repeat
  end try
  
  
return dNameList
  
end currentBluetoothDeviceNames

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

2014/11/06 TTS音声リストを取得する(asoc)

OSで利用できるテキスト音声読み上げ(Text To Speech)音声の情報を取得するAppleScriptです。

以前のバージョンのOS Xで、特定フォルダ以下の「.SpeechVoice」ファイルをリストアップすることで、利用できる音声リストを取得できるものは作成してあったのですが、少々野蛮なやりかただったうえに現行のOS X 10.10ではうまく動作しませんでした。

読み上げ音声は、任意で選択して追加インストールできるわけですが、AppleScriptで取得した情報とつけ合わせると「現在インストールされていない音声」についての情報も返ってきているようです。

AppleScript名:asoc_TTS音声リストを取得する
use AppleScript version “2.4″
use framework “Foundation”
use framework “AppKit”
use scripting additions

set outList to {}

set aList to current application’s NSSpeechSynthesizer’s availableVoices()
set bList to aList as list
–> {”com.apple.speech.synthesis.voice.Agnes”, “com.apple.speech.synthesis.voice.Albert”, “com.apple.speech.synthesis.voice.Alex”, “com.apple.speech.synthesis.voice.alice”, “com.apple.speech.synthesis.voice.allison.premium”, “com.apple.speech.synthesis.voice.alva”, “com.apple.speech.synthesis.voice.amelie”, “com.apple.speech.synthesis.voice.anna”, “com.apple.speech.synthesis.voice.audrey.premium”, “com.apple.speech.synthesis.voice.ava.premium”, “com.apple.speech.synthesis.voice.BadNews”, “com.apple.speech.synthesis.voice.Bahh”, “com.apple.speech.synthesis.voice.Bells”, “com.apple.speech.synthesis.voice.Boing”, “com.apple.speech.synthesis.voice.Bruce”, “com.apple.speech.synthesis.voice.Bubbles”, “com.apple.speech.synthesis.voice.carmit”, “com.apple.speech.synthesis.voice.Cellos”, “com.apple.speech.synthesis.voice.damayanti”, “com.apple.speech.synthesis.voice.daniel.premium”, “com.apple.speech.synthesis.voice.Deranged”, “com.apple.speech.synthesis.voice.diego”, “com.apple.speech.synthesis.voice.ellen”, “com.apple.speech.synthesis.voice.emily.premium”, “com.apple.speech.synthesis.voice.fiona”, “com.apple.speech.synthesis.voice.Fred”, “com.apple.speech.synthesis.voice.GoodNews”, “com.apple.speech.synthesis.voice.Hysterical”, “com.apple.speech.synthesis.voice.ioana”, “com.apple.speech.synthesis.voice.jill.premium”, “com.apple.speech.synthesis.voice.joana”, “com.apple.speech.synthesis.voice.Junior”, “com.apple.speech.synthesis.voice.kanya”, “com.apple.speech.synthesis.voice.karen.premium”, “com.apple.speech.synthesis.voice.kate.premium”, “com.apple.speech.synthesis.voice.Kathy”, “com.apple.speech.synthesis.voice.kyoko.premium”, “com.apple.speech.synthesis.voice.laura”, “com.apple.speech.synthesis.voice.lee.premium”, “com.apple.speech.synthesis.voice.lekha”, “com.apple.speech.synthesis.voice.luciana”, “com.apple.speech.synthesis.voice.mariska”, “com.apple.speech.synthesis.voice.mei-jia”, “com.apple.speech.synthesis.voice.melina”, “com.apple.speech.synthesis.voice.milena”, “com.apple.speech.synthesis.voice.moira”, “com.apple.speech.synthesis.voice.monica”, “com.apple.speech.synthesis.voice.nora”, “com.apple.speech.synthesis.voice.otoya.premium”, “com.apple.speech.synthesis.voice.paulina”, “com.apple.speech.synthesis.voice.Organ”, “com.apple.speech.synthesis.voice.Princess”, “com.apple.speech.synthesis.voice.Ralph”, “com.apple.speech.synthesis.voice.samantha.premium”, “com.apple.speech.synthesis.voice.sara”, “com.apple.speech.synthesis.voice.satu”, “com.apple.speech.synthesis.voice.serena.premium”, “com.apple.speech.synthesis.voice.sin-ji”, “com.apple.speech.synthesis.voice.tarik”, “com.apple.speech.synthesis.voice.tessa”, “com.apple.speech.synthesis.voice.thomas”, “com.apple.speech.synthesis.voice.ting-ting.premium”, “com.apple.speech.synthesis.voice.tom.premium”, “com.apple.speech.synthesis.voice.Trinoids”, “com.apple.speech.synthesis.voice.veena”, “com.apple.speech.synthesis.voice.Vicki”, “com.apple.speech.synthesis.voice.Victoria”, “com.apple.speech.synthesis.voice.Whisper”, “com.apple.speech.synthesis.voice.xander”, “com.apple.speech.synthesis.voice.yelda”, “com.apple.speech.synthesis.voice.yuna.premium”, “com.apple.speech.synthesis.voice.Zarvox”, “com.apple.speech.synthesis.voice.zosia”, “com.apple.speech.synthesis.voice.zuzana”}

repeat with i in bList
  
  
set j to contents of i
  
set aInfo to (current application’s NSSpeechSynthesizer’s attributesForVoice:j)
  
set aInfoRec to aInfo as record
  
  
set aName to VoiceName of aInfoRec
  
set voiceLocale to VoiceLocaleIdentifier of aInfoRec
  
set voiceDemo to VoiceDemoText of aInfoRec
  
–set voiceList to VoiceShowInFullListOnly of aInfoRec
  
set voiceGender to voiceGender of aInfoRec
  
set voiceVer to VoiceVersion of aInfoRec
  
set voiceAge to voiceAge of aInfoRec
  
set voiceID to VoiceIdentifier of aInfoRec
  
–set voiceRelDes to VoiceRelativeDesirability of aInfoRec
  
set voiceLang to VoiceLanguage of aInfoRec
  
  
set the end of outList to {aName, voiceLocale, voiceDemo, voiceGender, voiceVer, voiceAge, voiceID, voiceLang}
  
end repeat

outList
–> {{”Agnes”, “en_US”, “Isn’t it nice to have a computer that will talk to you?”, “VoiceGenderFemale”, “3.6″, 35, “com.apple.speech.synthesis.voice.Agnes”, “en-US”}, {”Albert”, “en_US”, ” I have a frog in my throat. No, I mean a real frog!”, “VoiceGenderNeuter”, “3.6″, 30, “com.apple.speech.synthesis.voice.Albert”, “en-US”}………}

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

2014/11/04 現在のLocaleのカレンダーのTime Zoneを取得する

現在ログイン中のカレンダー(設定)を取得し、Time Zone名や時差の情報を取得するAppleScriptです。

sys1.png

sys2.png

言語設定によっては、OSレベルで管理しているカレンダーが「日曜日で始まる」か「月曜日で始まる」かといった違いがあります。こうした情報にアクセスするための習作として作成したものです。

GMTとの時差であれば、通常のAppleScriptでも(大昔から)取得できるようになっていますが、どの曜日からカレンダーが始まるかという情報は、Cocoaにアクセスしないとわからないため外せません。

AppleScript名:asoc_現在のLocaleのカレンダーのTime Zoneを取得する
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set aCalendar to current application’s NSCalendar’s currentCalendar()
set aTimeZone to (aCalendar’s timeZone)
set tzName to aTimeZone’s |name|() as string
–> “Asia/Tokyo”

set tDiff to (aTimeZone’s secondsFromGMT()) / 3600
–> 9.0

set aDesc to aTimeZone’s |description|() as string
–> “Asia/Tokyo (JST) offset 32400″

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

AppleScript名:普通のASでGMTとの時差を求める
set tDIff to (time to GMT) / 3600
–> 9.0

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

2014/07/23 Script Editorで最前面のアプリの用語辞書を表示する v3

AppleScriptエディタ/Script Editorで、最前面のアプリの用語辞書を表示するAppleScriptです。

バージョンアップして、最前面のアプリがAppleScript等のOSA(Open Scripting Architecture)言語によるScriptingに対応しているかどうかを判定したのちに、辞書のオープンを行います。

Script Menuに入れて、メニューから呼び出すことを前提としています。

前バージョンでは、とくに対象アプリケーションのScripting対応については調べていなかったため、非対応アプリを指定すると、Script Editorで対象アプリをバイナリモードでオープンしてしまうなどの問題があり、それに対処したものです。

本AppleScriptは、各アプリケーションのバンドル中にあるInfo.plistを走査してOSA対応の判定を行っていますが、これは「NSAppleScriptEnabled」のエントリがInfo.plist上に存在した場合、慣習的に「true」しか指定されていない(そもそも非対応である場合にはNSAppleScriptEnabledのエントリそのものを作らない)ことから、「NSAppleScriptEnabled」が入っていれば対応……という「手抜き判定」をやっています。

真剣に作るのであれば、NSAppleScriptEnabledのエントリを取得して属性値がどうなっているか判定すべきです。

スクリプト名:Script Editorで最前面のアプリの用語辞書を表示する v3
–最前面のプロセスのファイルシステム上の位置を取得してaliasに変換する
tell application “System Events”
  set frontProc to every process whose frontmost is true and visible is true
  
set aProc to contents of first item of frontProc
  
set aFile to file of aProc
  
set aBundleID to bundle identifier of aProc
end tell

set aFile to aFile as alias

–バンドルパッケージ中のInfo.plistファイルを走査してAppleScript対応かどうかを調べる
set aFilePosix to quoted form of POSIX path of aFile
set infoPath to aFilePosix & “Contents/Info.plist”
set aRec to extractInfoPlistAndFindString(infoPath, “NSAppleScriptEnabled”)

–スクリプト用語辞書をScript Editorでオープンする手順
if aRec = true then
  –OS X 10.10でScript Editor側からアプリをオープンしてもダメだったので、Finder側からScript Editorで指定アプリをオープンすることに
  
tell application “Finder”
    set apFile to (application file id “com.apple.scripteditor2″) as alias
    
open aFile using application file apFile
  end tell
else
  tell application id aBundleID
    display dialog “本アプリケーションは、各種OSA言語によるコントロールに対応していません。” buttons {“OK”} default button 1 with icon 2 with title “Scripting非対応”
  end tell
end if

–指定のInfoPlist(たぶん)をextractして指定文字列を含んでいるかチェック
on extractInfoPlistAndFindString(aPosix, findStr)
  
  
try
    set a to (do shell script “/usr/bin/plutil -p “ & aPosix)
  on error
    return 0 –エラー(指定のパスにファイルが存在しない)
  end try
  
  
set b to (a contains findStr)
  
return b
  
end extractInfoPlistAndFindString

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

2014/07/22 AS対応、非対応のアプリ数をカウントする

Macのローカルに存在するアプリケーションをすべてリストアップし、AppleScript対応のもの、AppleScript非対応のもの、Info.plistが所定の位置にないものをカウントして返すAppleScriptです。

下調べのために作ってみました。

すぐに「entire contentsで指定フォルダ以下のファイルをすべて取得してアプリのみ抽出するバージョン」に作り替えていますが……まだ、処理が返ってきません、、、

スクリプト名:AS対応、非対応のアプリ数をカウントする
script spd
  
  
property aList1 : {} –/Applications フォルダ以下のアプリケーションファイル一覧
  
property aList2 : {} –/Applications/Utilities フォルダ以下のアプリケーションファイル一覧
  
  
property bList : {} –aList1とaList2を連結
  
  
property asEnable : {} –AS対応のアプリ一覧
  
property asDisable : {} –AS非対応のアプリ一覧
  
property infoNotPresent : {} –Info.plistが所定の場所に指定のファイル名で存在しないもの一覧
  
end script

set aList1 of spd to {}
set aList2 of spd to {}

set bList of spd to {}

set asEnable of spd to {}
set asDisable of spd to {}
set infoNotPresent of spd to {}

set apPath1 to (path to applications folder) as string
set apPath2 to (path to utilities folder) as string

tell application “Finder”
  –/Applications Folder
  
tell folder apPath1
    set aList1 of spd to (every application file) as alias list
  end tell
  
  
–/Applications/Utilities Folder
  
tell folder apPath2
    set aList2 of spd to (every application file) as alias list
  end tell
end tell

set bList of spd to (contents of (aList1 of spd)) & (contents of (aList2 of spd))

repeat with i in (bList of spd)
  
  
set aFilePosix to quoted form of POSIX path of i
  
set infoPath to aFilePosix & “Contents/Info.plist”
  
  
set aRec to extractInfoPlistAndFindString(infoPath, “NSAppleScriptEnabled”)
  
  
if aRec = true then
    set the end of (asEnable of spd) to i
  else if aRec = false then
    set the end of (asDisable of spd) to i
  else
    set the end of (infoNotPresent of spd) to i
  end if
end repeat

return {length of (asEnable of spd), length of (asDisable of spd), length of (infoNotPresent of spd)}

–> {125, 235, 0}

–指定のInfoPlist(たぶん)をextractして指定文字列を含んでいるかチェック
on extractInfoPlistAndFindString(aPosix, findStr)
  
  
try
    set a to (do shell script “/usr/bin/plutil -p “ & aPosix)
  on error
    return 0 –エラー(指定のパスにファイルが存在しない)
  end try
  
  
set b to (a contains findStr)
  
return b
  
end extractInfoPlistAndFindString

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

2014/07/22 指定のInfoPlist(たぶん)をextractして指定文字列を含んでいるかチェック

指定のInfo.plistがバイナリモードであってもextractして、指定の文字列を含んでいるかどうかチェックするAppleScriptです。

先日掲載した「Script Editorで最前面のアプリの用語辞書を表示する」を実戦配備したところ……AppleScript未対応のアプリケーションもオープンできてしまいました。Scripting未対応アプリをScript Editorでバイナリ状態でオープンしてしまったりして、おかしな状態に。

オープン対象のアプリケーションがScriptableかどうかをチェックしてから処理しよう……とも思ったのですが、実際にSystem Events経由で調べてみると、「iBooks」などの非対応アプリまでプロセス情報を確認すると「Accepts High Level Events」がtrueになっています。

……というわけで、実際に各アプリケーションバンドル内のInfo.plistファイルのエントリを調べて、NSAppleScriptEnabledが入っているか(ちょっとこのあたり乱暴)どうかを調べるAppleScriptを書いてみた次第です。

スクリプト名:指定のInfoPlist(たぶん)をextractして指定文字列を含んでいるかチェック
set infoPath to choose file with showing package contents
set aRec to extractInfoPlistAndFindString(infoPath, “NSAppleScriptEnabled”)

–指定のInfoPlist(たぶん)をextractして指定文字列を含んでいるかチェック
on extractInfoPlistAndFindString(aFile, findStr)
  
  
set aPosix to quoted form of POSIX path of aFile
  
set a to (do shell script “/usr/bin/plutil -p “ & aPosix)
  
  
set b to (a contains findStr)
  
return b
  
end extractInfoPlistAndFindString

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

2014/05/12 Deskop Pictureのパスを取得する

AppleScriptで現在設定中のデスクトップピクチャを取得するAppleScriptです。

画面(=デスクトップ)が1つの場合だけとは限りません。複数のモニターを接続している場合には、それぞれについて調査する必要があります。

r0016321.JPG

Finderに問い合わせると、メインディスプレイ(プライマリ)のデスクトップピクチャのファイルパスを取得できます。

スクリプト名:デスクトップピクチャを取得1
tell application “Finder”
  set aDskP to (desktop picture) as alias
end tell

–> alias “Macintosh HD:Library:Desktop Pictures:Galaxy.jpg”

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

複数のモニタが接続されている場合の調べ方です。(単数か複数かで)いちいち場合分けするよりも、こちらの方法で取得すべきです。Finderに問い合わせるやり方は、「盲腸」みたいなものと考えるべきでしょう。

スクリプト名:すべてのデスクトップのデスクトップピクチャを取得
set pictList to {}

tell application “System Events”
  set dCount to count every desktop
  
repeat with i from 1 to dCount
    tell desktop i
      set aPic to (picture as POSIX file) as alias
      
set end of pictList to aPic
    end tell
  end repeat
end tell

pictList
–> {alias “Macintosh HD:Library:Desktop Pictures:Galaxy.jpg”, alias “Macintosh HD:Users:me:Pictures:Desktop Picrures HD:01543_falls_1920×1200.jpg”, alias “Macintosh HD:Library:Desktop Pictures:Wave.jpg”}

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

2014/04/30 指定のクリエータコードに該当するICC Profileをリストアップ v3

Image Events経由で指定のクリエータコードに該当するICC ProfileをリストアップするAppleScriptです。

ICC Profileの名称を「ぴよぴよ」と返す場合と「ぴよぴよ.icc」と返す場合があって(作成時のメーカー側のゆらぎ)、そのあたりの整合性がないあたりを埋めるために強制的に名称の末尾に「.icc」を付けて返す機能や、名称から「.icc」を外して返す機能などを備えています。

ICC Profileの存在確認は、

 (1)ファイルとして指定のフォルダに存在するかという確認
 (2)OS側が認識しているかどうか(Image Eventsが認識しているか)という確認
 (3)アプリケーション側が認識しているかという確認

という3レイヤーで行う必要があり、それぞれについて取得できる名称が異なったりする(「.icc」が付いていたりいなかったり)ため、拡張子を付けたり外したりして結果を返す機能を付けたのがv2。

逆に、(2)で取得した名称を一切いじくらない機能を付けたのがこのv3です。

スクリプト名:指定のクリエータコードに該当するICC Profileをリストアップ v3
–出力例:クリエータがAppleのICC Profileを出力。重複を許容、ファイルパスを出力しない、末尾に強制的に「.icc」を付加
set aList to getICCProfileDataByCreatorCode(“APPL”, true, false, “”) of me
–> {”Calib 20100428″, “calib 20110623″, “calib20091122″, “Calibed_Retina_1″, “Cinema HD”, “Cinema HD Display”, “Cinema HD Display_L”, “Cinema HD 補正済み(R)”, “Color LCD 10.4.7″, “Color LCD 2009_09″, “colorLCD”, “Display”, “Display”, “Display”, “Display”, “Display”, “Display”, “DTW17ASXS_cailblated”, “HD 709-A”, “MacBook3″, “S2231W 補正済み”, “SD 170M-A”, “W2442 20090102″, “Web セーフカラー”, “カメラ RGB プロファイル”, “カラー LCD”, “グレイ調”, “セピア調”, “ディスプレイ”, “ブルー調”, “一般 CMYK プロファイル”, “一般 Lab プロファイル”, “一般 RGB プロファイル”, “一般 XYZ プロファイル”, “一般グレイガンマ 2.2 プロファイル”, “一般グレイプロファイル”, “白黒”, “明度減少”, “明度増大”}

–creatorで抽出したICC Profileのリストを取得する(名称、パス)
–  aCode: ICC ProfileのCreator Code(=”XXXX”)
–  dupFlag: trueだとICC Profileの名称重複を許容、falseだと許容しない
–   filePathOut: trueだとファイルパスを出力する
–  extOut:名称に拡張子(.icc)を出力するかどうか。falseだと出力しない。trueだと強制付加して返す、ヌルだとそのまま操作しない
on getICCProfileDataByCreatorCode(aCode, dupFlag, filePathOut, extOut)
  
  
–Image Eventsが起動中にICC Profileを追加すると、その後にProfileの存在確認を
  
–行うと認識されないケースがあったので、念のために起動中だったImage Eventsを落とす
  
tell application “Image Events”
    if it is running then
      quit
      
launch
      
delay 0.5 –待たないとダメ!!(MacProでは未検証)
    end if
  end tell
  
  
  
tell application “Image Events”
    try
      set aList to properties of every profile whose creator is aCode
    on error
      return {}
    end try
    
    
set dupList to {} –重複回避用リスト(名称ベース)
    
    
set outList to {} –出力用リスト
    
    
repeat with i in aList
      
      
set aName to (name of i)
      
      
if extOut = false then
        –拡張子を削って返す
        
if aName ends with “.icc” then
          set aName to text 1 thru -5 of aName
        end if
      else if extOut = true then
        –拡張子を強制的に追加して返す
        
if aName does not end with “.icc” then
          set aName to aName & “.icc”
        end if
      else
        –それ以外だと何もしない
      end if
      
      
set aLoc to (location of i)
      
      
try
        set aLoc to aLoc as alias
        
set aLoc to (aLoc as string)
      on error
        set aLoc to “”
      end try
      
      
      
if aLoc is not equal to “” then
        if dupFlag = false then
          –重複を許容しない
          
if aName is not in dupList then
            if filePathOut = true then
              set the end of outList to {aName, aLoc}
            else
              set the end of outList to aName
            end if
          end if
        else
          –重複を許容する
          
if filePathOut = true then
            set the end of outList to {aName, aLoc}
          else
            set the end of outList to aName
          end if
        end if
        
        
set the end of dupList to aName
        
      end if
    end repeat
    
  end tell
  
  
return outList
  
end getICCProfileDataByCreatorCode

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

2014/04/19 アプリケーションのBundle IDを取得する

指定アプリケーションのBundle IDを取得するAppleScriptです。

実用性は皆無ですが、AppleScriptのプログラムを書いている最中に指定アプリのバンドルIDを調べたくなったような場合に手軽に調べられます。

やりかたは超かんたんで……id of application “ほにゃらら”と書けば、指定したアプリケーションのBundle IDを取得できます。

歴代AppleScriptのリリースノートを調査していたら見つけました。知らなくても全然困らない機能ですが、「知らない」と言えない状況もあるので(汗)。

chooseapp.png

スクリプト名:アプリケーションのBundle IDを取得する
–アプリケーション一覧のダイアログを表示して選択(まずやらない)
set anApp to choose application –テスト用にアプリを選択
set anID to id of anApp –ここ!
–> “com.adobe.Photoshop”

–アプリケーションを直接指定してBundle IDを取得
set bID to id of application “Finder”
–> “com.apple.finder”

set cID to id of current application
–> “com.apple.ScriptEditor2″ –tellブロックがなければScript Editor

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

2014/04/16 指定のクリエータコードに該当するICC Profileをリストアップ v2

Image Events経由で指定のクリエータコードに該当するICC ProfileをリストアップするAppleScriptです。

以前に作ったものは一応名前の検出だけできればよかったので、ラフに書いた記憶がありますが……実際に実戦投入してみたところ、検出されないProfileがあるとかいろいろ問題が出てきたので、書き直してみました(以前のものはなかったことにしたいぐらいダメダメでした)。

また、ICC Profileの名称を「ぴよぴよ」と返す場合と「ぴよぴよ.icc」と返す場合があって(作成時のメーカー側のゆらぎ)、そのあたりの整合性がないあたりを埋めるために強制的に名称の末尾に「.icc」を付けて返す機能や、名称から「.icc」を外して返す機能などを備えています。

OSにICC Profileを強制的にインストールしたりと、ICC Profileの状態を変更した後には、Image Eventsを一度終了させないと最新の状態を検知してくれないことが判明して、「起動中ならいったん終了して再立ち上げ」といった処理を書いていますが……正直、開発環境よりも高速でCPUのキャッシングのメカニズムが異なるMacProでちゃんと動くのかは不明です。

おそらく、MacProでも動くとは思うのですが……こうして載せておいてAppleStoreの店頭のデモ機で試してみるしかないですね。

スクリプト名:指定のクリエータコードに該当するICC Profileをリストアップ v2
–出力例:クリエータがAppleのICC Profileを出力。重複を許容、ファイルパスを出力しない、末尾に強制的に「.icc」を付加
set aList to getICCProfileDataByCreatorCode(“APPL”, true, false, true) of me
–> {”Calib 20100428.icc”, “calib 20110623.icc”, “calib20091122.icc”, “Calibed_Retina_1.icc”, “Cinema HD.icc”, “Cinema HD Display.icc”, “Cinema HD Display_L.icc”, “Cinema HD 補正済み(R).icc”, “Color LCD 10.4.7.icc”, “Color LCD 2009_09.icc”, “colorLCD.icc”, “Display.icc”, “Display.icc”, “Display.icc”, “Display.icc”, “Display.icc”, “Display.icc”, “DTW17ASXS_cailblated.icc”, “HD 709-A.icc”, “MacBook3.icc”, “S2231W 補正済み.icc”, “SD 170M-A.icc”, “W2442 20090102.icc”, “Web セーフカラー.icc”, “カメラ RGB プロファイル.icc”, “カラー LCD.icc”, “グレイ調.icc”, “セピア調.icc”, “ディスプレイ.icc”, “ブルー調.icc”, “一般 CMYK プロファイル.icc”, “一般 Lab プロファイル.icc”, “一般 RGB プロファイル.icc”, “一般 XYZ プロファイル.icc”, “一般グレイガンマ 2.2 プロファイル.icc”, “一般グレイプロファイル.icc”, “白黒.icc”, “明度減少.icc”, “明度増大.icc”}

–creatorで抽出したICC Profileのリストを取得する(名称、パス)
–  aCode: ICC ProfileのCreator Code(=”XXXX”)
–  dupFlag: trueだとICC Profileの名称重複を許容、falseだと許容しない
–   filePathOut: trueだとファイルパスを出力する
–  extOut:名称に拡張子(.icc)を出力するかどうか。falseだと出力しない。trueだと強制付加して返す
on getICCProfileDataByCreatorCode(aCode, dupFlag, filePathOut, extOut)
  
  
–Image Eventsが起動中にICC Profileを追加すると、その後にProfileの存在確認を
  
–行うと認識されないケースがあったので、念のために起動中だったImage Eventsを落とす
  
tell application “Image Events”
    if it is running then
      quit
      
launch
      
delay 0.5 –待たないとダメ!!(MacProでは未検証)
    end if
  end tell
  
  
  
tell application “Image Events”
    try
      set aList to properties of every profile whose creator is aCode
    on error
      return {}
    end try
    
    
set dupList to {} –重複回避用リスト(名称ベース)
    
    
set outList to {} –出力用リスト
    
    
repeat with i in aList
      
      
set aName to (name of i)
      
      
if extOut = false then
        –拡張子を削って返す
        
if aName ends with “.icc” then
          set aName to text 1 thru -5 of aName
        end if
      else
        –拡張子を強制的に追加して返す
        
if aName does not end with “.icc” then
          set aName to aName & “.icc”
        end if
      end if
      
      
set aLoc to (location of i)
      
      
try
        set aLoc to aLoc as alias
        
set aLoc to (aLoc as string)
      on error
        set aLoc to “”
      end try
      
      
      
if aLoc is not equal to “” then
        if dupFlag = false then
          –重複を許容しない
          
if aName is not in dupList then
            if filePathOut = true then
              set the end of outList to {aName, aLoc}
            else
              set the end of outList to aName
            end if
          end if
        else
          –重複を許容する
          
if filePathOut = true then
            set the end of outList to {aName, aLoc}
          else
            set the end of outList to aName
          end if
        end if
        
        
set the end of dupList to aName
        
      end if
    end repeat
    
  end tell
  
  
return outList
  
end getICCProfileDataByCreatorCode

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