Menu

Skip to content
AppleScriptの穴
  • Home
  • Products
  • Books
  • Docs
  • Events
  • Forum
  • About This Blog
  • License
  • 仕事依頼

AppleScriptの穴

Useful & Practical AppleScript archive. Click '★Click Here to Open This Script' Link to download each AppleScript

カテゴリー: File path

ScriptDebuggerでオープン中のScriptをScriptBundleに

Posted on 5月 23, 2019 by Takaaki Naganoya

ScriptDebuggerを使っていて、この作業がひんぱんに発生するのでScriptで自動化しました。

AppleScript書類を編集していて、バンドル内にFrameworkなどを突っ込みたいのにフラットなAppleScript書類(.scpt)だったので、そのままでは突っ込めず、コピペで新規バンドル書類(.scptd)を作成して、同じ名前で保存し直す作業です。

とてもとても標準機能で実装されていそうな内容ですが、子細に調査して存在していなかったので(ASObjC Explorerにはあったような気が)、ささっとAppleScriptで実装してScriptDebuggerのスクリプトメニューに入れて使っています。

ウィンドウの表示座標をきっちりそろえるとか、オリジナルのScriptを新規Scriptの作成後にクローズするとか、作りたくなってウズウズしてくる(自分的な)完成度の低さですが、そこでかっちり作り込むと「仕事中にちょっとだけ作るScript」の域を超えてしまうので、自制した次第です。

「すでに、バンドル形式のScriptが同一フォルダ内に存在する場合には警告を出して処理を中止する」か、あるいは「ファイル名に子番号をつけて重複を回避する」ぐらいの処理は足してもいいような気がします。


▲初期状態。フラットなAppleScript(.scpt)で書かれていたので、バンドル内にいろいろ追加できない状態


▲本Scriptの実行後の状態。ファイル名は拡張子を「.scptd」に変更しただけの状態

AppleScript名:ScriptをScript Bundleに
— Created 2019-05-23 by Takaaki Naganoya
— 2019 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

tell application "Script Debugger"
  tell front document
    set myType to script type
    
if myType = bundled compiled script then
      display notification "There is no need to convert…."
      
return
    end if
    
    
set mySource to source text
    
set mySpec to file spec
    
    
try
      close with saving
    on error
      display notification "Can not save this Script. So I quited conversion process…."
      
return
    end try
  end tell
end tell

–ファイルパスの拡張子を付け替えてFileに変換
set pathString to current application’s NSString’s stringWithString:(POSIX path of mySpec)
set newPath to ((pathString’s stringByDeletingPathExtension())’s stringByAppendingPathExtension:"scptd") as string
set aFile to POSIX file newPath

–ファイル拡張子を付け替えた新規ファイル名で保存
tell application "Script Debugger"
  set aDoc to make new document with properties {source text:mySource, script type:bundled compiled script}
  
tell aDoc
    set aRes to compile –構文確認(ねんのため)
    
if aRes = false then return
    
    
–compileを通った場合のみファイル保存を行う
    
save in aFile
  end tell
end tell

★Click Here to Open This Script 

Posted in file File path | Tagged 10.12savvy 10.13savvy 10.14savvy ScriptDebugger | 1 Comment

指定フォルダ内のファイルのうち、指定UTIに該当するものをすべて取得してフルパスを返す

Posted on 4月 13, 2019 by Takaaki Naganoya

指定フォルダ内のファイルのうち、指定のUTIに該当するものをすべて取得してフルパス(file/POSIX)で返すAppleScriptです。

指定フォルダの直下のみを走査し、サブフォルダ内は走査しません。調べてみるとUTIでファイルを絞り込む機能は存在していないようなので(見落としているだけ?)、すべてファイルを取得してからループでUTIを調べつつ該当するかどうかチェックしています。

書けば書くほど「それってSpotlightでよくね?」という気がしますが、確実に取得したい(Spotlightインデックスが破損していたり、サーバー上のファイルではSpotlightが効かない場合もある)場合に使うとよいでしょうか。

AppleScript名:指定フォルダ内のファイルのうち、指定UTIに該当するものをすべて取得してフルパスを返す
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/04/13
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"

property |NSURL| : a reference to current application’s |NSURL|
property NSArray : a reference to current application’s NSArray
property NSPredicate : a reference to current application’s NSPredicate
property NSFileManager : a reference to current application’s NSFileManager
property NSURLTypeIdentifierKey : a reference to current application’s NSURLTypeIdentifierKey
property NSDirectoryEnumerationSkipsHiddenFiles : a reference to current application’s NSDirectoryEnumerationSkipsHiddenFiles

set aUTI to "com.adobe.pdf"
set libPath to ((path to documents folder) as string)
set posixLibPath to POSIX path of libPath

set f1List to getFilepathListByUTI(posixLibPath, aUTI, "file") of me
–> {file "Cherry:Users:me:Documents:0718kenpo.pdf", file "Cherry:Users:me:Documents:2013-09Rekihaku.pdf", file "Cherry:Users:maro:Documents:airserver.pdf"}

set f2List to getFilepathListByUTI(posixLibPath, aUTI, "POSIX") of me
–> {"/Users/me/Documents/0718kenpo.pdf", "/Users/me/Documents/2013-09Rekihaku.pdf", "/Users/me/Documents/airserver.pdf"}

on getFilepathListByUTI(aFolPOSIX, aUTI as string, aFileType as string)
  script spdFile
    property urlList : {}
  end script
  
  
if aFileType is not in {"file", "POSIX"} then return {}
  
  
set aFM to NSFileManager’s defaultManager()
  
set aFolExt to (aFM’s fileExistsAtPath:aFolPOSIX isDirectory:true) as boolean
  
if aFolExt = false then return {} –フォルダ自体が存在しなければヌルリストを返す
  
  
set aURL to |NSURL|’s fileURLWithPath:aFolPOSIX
  
set theOptions to ((current application’s NSDirectoryEnumerationSkipsPackageDescendants) as integer) + ((current application’s NSDirectoryEnumerationSkipsHiddenFiles) as integer)
  
set urlArray to (aFM’s contentsOfDirectoryAtURL:aURL includingPropertiesForKeys:{} options:theOptions |error|:(missing value))
  
if urlArray = missing value then return {}
  
  
set (urlList of spdFile) to urlArray as list
  
set newList to {}
  
  
repeat with i in (urlList of spdFile)
    set j to POSIX path of i
    
set tmpUTI to my retUTIfromPath(j)
    
set utiRes to my filterUTIList({tmpUTI}, aUTI)
    
    
if utiRes is not equal to {} then
      if aFileType = "POSIX" then
        set the end of newList to j
      else if aFileType = "file" then
        set the end of newList to POSIX file j
      end if
    end if
    
  end repeat
  
  
return newList
end getFilepathListByUTI

–指定のPOSIX pathのファイルのUTIを求める
on retUTIfromPath(aPOSIXPath)
  set aURL to |NSURL|’s fileURLWithPath:aPOSIXPath
  
set {theResult, theValue} to aURL’s getResourceValue:(reference) forKey:NSURLTypeIdentifierKey |error|:(missing value)
  
  
if theResult = true then
    return theValue as string
  else
    return theResult
  end if
end retUTIfromPath

–UTIリストが指定UTIに含まれているかどうか演算を行う
on filterUTIList(aUTIList, aUTIstr)
  set anArray to NSArray’s arrayWithArray:aUTIList
  
set aPred to NSPredicate’s predicateWithFormat_("SELF UTI-CONFORMS-TO %@", aUTIstr)
  
set bRes to (anArray’s filteredArrayUsingPredicate:aPred) as list
  
return bRes
end filterUTIList

★Click Here to Open This Script 

Posted in file File path list UTI | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy NSArray NSDirectoryEnumerationSkipsHiddenFiles NSFileManager NSPredicate NSURL NSURLTypeIdentifierKey | 3 Comments

頭のいいタイマー割り込み実行

Posted on 3月 27, 2019 by Takaaki Naganoya

頭のいいタイマー割り込み(on idle)実行のAppleScriptを追求してみました。

AppleScript開闢(かいびゃく)以来、すでに20年以上の時間が経過しているので、on idleによるタイマー割り込み処理なんて、探せばサンプルが山のように出てくるものです。

AppleScript名:timer interrupt
property targetTime : "9:37:00"
property timerInterval : 30

on run
  set timerInterval to 30
end run

on idle
  set curTime to current date
  
set cString to time string of curTime
  
  
if cString ≥ targetTime then
    display dialog "It’s time to take off!" buttons {"OK"} default button 1 giving up after 30
    
quit
  end if
  
  
return timerInterval
end idle

★Click Here to Open This Script 

これが基礎的な内容で、このScriptをScript Editor上でアプリケーション(アプレット)形式で、「ハンドラの実行後に終了しない」をオンにして書き出すとタイマー実行アプレットが出来上がります(3分間クッキング)。

ただ、実行時刻のパラメータがプログラム内に直打ちなのが気になります。知能レベルが低い感じがします。

そこで、実行時刻のパラメータの外部供給ということを考え出すわけですが、

 (1)設定ファイルから読み込み
 (2)アプレット自身のコメント(File Comment)から読み込み
 (3)ファイル名自体から読み込み
 (4)コマンドラインから実行し、実行時にパラメータ(argv)を指定

などの方法を考えつきます(20世紀にすでにさんざんやった内容)。ただし、全角数字を半角に変換したり、ファイル名の場合には時刻セパレータの「:」がmacOS上ではファイル名に使えない文字(ディレクトリ・セパレータ)だったり、Finderが管理しているファイル名はUnicodeのNormalize方式が異なる(処理しやすいようにNormalizeし直さないとダメ)など割と頭の痛い問題がいろいろあります。

そこで利用したいのが、CocoaのDataFormatter。自然言語風に書かれた「10時41分」(全角数字入り)といった文字列から日時データをピックアップします。

そうして書いたのがこれ(↓)です。

ファイル名に書かれた時刻から実行時刻を拾ってタイマー実行します。けっこう頭がいい感じがします。

実際に、こうした処理の延長線上にTanzakuで行なっているファイル名から取得した文字列に対する形態素解析&コマンドピックアップの処理があります。

AppleScript名:10時42分
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"

property targTime : missing value
property timerInterval : 1

on run
  set timerInterval to 1
  
  
–Get filename from this applet
  
set myPath to path to current application
  
tell application "System Events"
    set myName to name of myPath
  end tell
  
  
–Validate filename as a natural language format date by using NSDataDetector
  
set dList to getDatesIn(myName) of me
  
repeat while dList = {}
    set myName to text returned of (display dialog "There is no time elements in my filename. Input the target time in x時xx分" default answer "午後5時45分")
    
set dList to getDatesIn(myName) of me
  end repeat
  
  
set targDate to first item of dList
  
set targTime to time string of targDate
  
display notification targTime
end run

on idle
  set curTime to current date
  
set curTimeStr to time string of curTime
  
  
if curTimeStr ≥ targTime then
    activate
    
display dialog "It’s time to take off!" buttons {"OK"} default button 1 giving up after 30
    
quit
  end if
  
  
return timerInterval
end idle

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 

Posted in File path Natural Language Processing | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy NSDataDetector NSString | Leave a comment

アラートダイアログ上にpath control x2を表示

Posted on 2月 18, 2019 by Takaaki Naganoya

アラートダイアログを作成し、その上にpath controlを2つ表示してパスの選択を行うAppleScriptです。

path controlには、対象のフォルダ/ファイルをドラッグ&ドロップしてファイルのパスを指定できます。使いやすい一方で、choose folderコマンドのようにフォルダの新規作成までサポートしているわけではありません。

スクリプトエディタ、Script Debugger、Appletなどでは正常に動作しますが、スクリプトメニュー上から呼び出すとアラートダイアログが最前面に表示されず、前に出す操作が必要になります。

AppleScript名:アラートダイアログ上のpath control x2を表示
— Created 2019-02-14 by Takaaki Naganoya
— 2019 Piyomaru Software
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"

property theResult : 0
property returnCode : 0

set paramObj to {myMessage:"項目選択", mySubMessage:"どれか選択してください。", fromPathMes:"移動元:", toPathMes:"移動先:"}
set segRes to my chooseTwoPath:paramObj
–> {fromPathRes:"/Users/me/Documents/AppleScript/パスコントロール", toPathRes:"/Users/me/Documents/AppleScript/タッチバー"}

on chooseTwoPath:paramObj
  set aMainMes to myMessage of paramObj
  
set aSubMes to mySubMessage of paramObj
  
set fromLabel to fromPathMes of paramObj
  
set toLabel to toPathMes of paramObj
  
  
— create a view
  
set theView to current application’s NSView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, 800, 60))
  
  
— create two path control & text field
  
set aPathControl to current application’s NSPathControl’s alloc()’s initWithFrame:(current application’s NSMakeRect(100, 35, 700, 20))
  
set bPathControl to current application’s NSPathControl’s alloc()’s initWithFrame:(current application’s NSMakeRect(100, 0, 700, 20))
  
aPathControl’s setBackgroundColor:(current application’s NSColor’s cyanColor())
  
bPathControl’s setBackgroundColor:(current application’s NSColor’s yellowColor())
  
  
set aHome to current application’s |NSURL|’s fileURLWithPath:(current application’s NSHomeDirectory()) –initial dir
  
aPathControl’s setURL:aHome
  
bPathControl’s setURL:aHome
  
  
set a1TF to current application’s NSTextField’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 35, 100, 20))
  
set a2TF to current application’s NSTextField’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, 100, 20))
  
a1TF’s setEditable:false
  
a2TF’s setEditable:false
  
a1TF’s setStringValue:fromLabel
  
a2TF’s setStringValue:toLabel
  
a1TF’s setDrawsBackground:false
  
a2TF’s setDrawsBackground:false
  
a1TF’s setBordered:false
  
a2TF’s setBordered:false
  
  
theView’s setSubviews:{a1TF, aPathControl, a2TF, bPathControl}
  
  
— set up alert
  
set theAlert to current application’s NSAlert’s alloc()’s init()
  
tell theAlert
    its setMessageText:aMainMes
    
its setInformativeText:aSubMes
    
its addButtonWithTitle:"OK"
    
its addButtonWithTitle:"Cancel"
    
its setAccessoryView:theView
  end tell
  
  
— show alert in modal loop
  
current application’s NSRunningApplication’s currentApplication()’s activateWithOptions:0
  
my performSelectorOnMainThread:"doModal:" withObject:(theAlert) waitUntilDone:true
  
if (my returnCode as number) = 1001 then error number -128
  
  
set s1Val to (aPathControl’s |URL|’s |path|()) as string
  
set s2Val to (bPathControl’s |URL|’s |path|()) as string
  
  
return {fromPathRes:s1Val, toPathRes:s2Val}
end chooseTwoPath:

on doModal:aParam
  set (my returnCode) to aParam’s runModal()
end doModal:

★Click Here to Open This Script 

Posted in File path GUI | Tagged 10.11savvy 10.12savvy 10.13savvy | Leave a comment

Finder上で選択中のAppleScriptの行数をカウントする

Posted on 2月 8, 2019 by Takaaki Naganoya

Finder上で選択中のAppleScript書類の行数や種別を取得して表UIで表示するAppleScriptです。

Myriad Tables Libを用いて結果を表UIで表示しています。

当初はAppleScript書類からソースを取得するのに/usr/bin/osadecompileコマンドを使っていたのですが、OSAKit経由で処理したほうが高速な印象があります。

–> Download Executable archive for macOS 10.14 (include Myriad Tables Lib)

macOS 10.14上で動作させるためには、Script Debugger上で本Scriptをオープンするか、本Scriptをバンドル形式で保存し、バンドル内(/Contents/Resources/Script Libraries フォルダ)にMyriad Tables Libを入れ、AppleScriptアプレットとして書き出す必要があります。

また、初回実行時には「セキュリティ」の承認ダイアログが表示されるため、これをOKする必要があります。AppleScriptアプレットはFinder上でアイコンをダブルクリックすると「Finder上で選択中のアイテム」を拾えないため(その瞬間、Finder上での選択アイテムはアプレット自身になってしまうため)、DockやmacOS標準装備のスクリプトメニューに登録して起動する必要があります。

AppleScript名:Finder上で選択中のAppleScriptの行数をカウントする v2.scpt
— Created 2019-02-04 by Takaaki Naganoya
— 2019 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "OSAKit"
use script "Myriad Tables Lib" version "1.0.8" –https://www.macosxautomation.com/applescript/apps/Script_Libs.html#MyriadTablesLib

property |NSURL| : a reference to current application’s |NSURL|
property NSArray : a reference to current application’s NSArray
property NSString : a reference to current application’s NSString
property OSAScript : a reference to current application’s OSAScript
property NSPredicate : a reference to current application’s NSPredicate
property NSURLIsPackageKey : a reference to current application’s NSURLIsPackageKey
property NSURLIsDirectoryKey : a reference to current application’s NSURLIsDirectoryKey
property NSURLTypeIdentifierKey : a reference to current application’s NSURLTypeIdentifierKey

–Finder上で選択中のファイルのうちAppleScript書類のみ抽出
tell application "Finder"
  set inFiles to selection as alias list
  
if inFiles = {} then return
end tell
set filRes1 to filterAliasListByUTIList(inFiles, {"com.apple.applescript.script", "com.apple.applescript.script-bundle"}) of me
if filRes1 = {} then return

–AppleScript書類の種別判定および行数カウント
set outList to {}
repeat with i in filRes1
  set aName to (NSString’s stringWithString:i)’s lastPathComponent() as string
  
set sInfo to detectScriptIsPureASorASOC(i) of me
  
set sText to scriptSource of getASsourceFor(i) of me
  
set sNum to count every paragraph of sText
  
set sUTI to retUTIfromPath(i) of me
  
if sUTI = "com.apple.applescript.script" then
    set sKind to "Script"
  else if sUTI = "com.apple.applescript.script-bundle" then
    set sKind to "Script Bundle"
  else
    set sKind to "Other"
  end if
  
  
set the end of outList to {aName, sInfo, sKind, sNum}
end repeat

–結果を表UIで表示する
tell script "Myriad Tables Lib"
  set aDispBounds to my makeInitialBounds:1200 withHeight:500
  
set theTable to make new table with data outList column headings {"script name", "ASOC", "Script Kind", "lines"} with title "AppleScript Line Count" with prompt "Your Selected Scripts" with row numbering and empty selection allowed –and can add and delete
  
modify table theTable initial position aDispBounds column widths pattern {1, 2, 3, 4} with hidden cancel button
  
modify columns in table theTable user date format {user format full, user format full} entry alignment align left
  (
display table theTable)
end tell

–Alias listから指定UTI Listに含まれるものをPOSIX pathのリストで返す
on filterAliasListByUTIList(aList as list, targUTIList as list)
  set outList to {}
  
repeat with i in targUTIList
    set j to contents of i
    
set aRes to filterAliasListByUTI(aList, j) of me
    
if aRes is not equal to {} then
      set outList to outList & aRes
    end if
  end repeat
  
return outList
end filterAliasListByUTIList

–Alias listから指定UTIに含まれるものをPOSIX pathのリストで返す
on filterAliasListByUTI(aList as list, targUTI)
  set newList to {}
  
repeat with i in aList
    set j to POSIX path of i
    
set tmpUTI to my retUTIfromPath(j)
    
set utiRes to my filterUTIList({tmpUTI}, targUTI)
    
if utiRes is not equal to {} then
      set the end of newList to j
    end if
  end repeat
  
return newList
end filterAliasListByUTI

–指定のPOSIX pathのファイルのUTIを求める
on retUTIfromPath(aPOSIXPath)
  set aURL to |NSURL|’s fileURLWithPath:aPOSIXPath
  
set {theResult, theValue} to aURL’s getResourceValue:(specifier) forKey:NSURLTypeIdentifierKey |error|:(missing value)
  
  
if theResult = true then
    return theValue as string
  else
    return theResult
  end if
end retUTIfromPath

–UTIリストが指定UTIに含まれているかどうか演算を行う
on filterUTIList(aUTIList, aUTIstr)
  set anArray to NSArray’s arrayWithArray:aUTIList
  
set aPred to NSPredicate’s predicateWithFormat_("SELF UTI-CONFORMS-TO %@", aUTIstr)
  
set bRes to (anArray’s filteredArrayUsingPredicate:aPred) as list
  
return bRes
end filterUTIList

on makeInitialBounds:(aTWidth as integer) withHeight:(aTHeight as integer)
  set aDispBounds to current application’s NSScreen’s mainScreen()’s frame()
  
if class of item 1 of aDispBounds = record then
    –macOS 10.10/10.11/10.12
    
set aWidth to (width of |size| of aDispBounds)
    
set aHeight to (height of |size| of aDispBounds)
  else
    –macOS 10.13 or later?
    
set aWidth to (item 1 of item 2 of aDispBounds)
    
set aHeight to (item 2 of item 2 of aDispBounds)
  end if
  
  
set xPos to (aWidth div 2) – (aTWidth div 2)
  
set yPos to (aHeight div 2) – (aTHeight div 2)
  
  
return {xPos, yPos, aTWidth, aTHeight}
end makeInitialBounds:withHeight:

–指定AppleScriptファイルがPure ASかASOCかを判定して返す
on detectScriptIsPureASorASOC(aFile)
  set sRes to getASsourceFor(aFile) of me
  
set sName to scriptKind of sRes –Name
  
set sText to scriptSource of sRes –Source
  
if sText = "" or sText = missing value then return missing value
  
  
if sName = "AppleScript" then
    if sText contains "use framework \"Foundation\"" then
      return true –ASOC
    else
      return false –Pure AppleScript
    end if
  else
    –JXAなど他のOSA言語の場合
    
return sName
  end if
end detectScriptIsPureASorASOC

–指定AppleScriptファイルのソースコードを取得する(実行専用Scriptからは取得できない)
on getASsourceFor(aPOSIXPath)
  set aURL to |NSURL|’s fileURLWithPath:(aPOSIXPath)
  
set theScript to current application’s OSAScript’s alloc()’s initWithContentsOfURL:aURL |error|:(missing value)
  
set scriptName to theScript’s |language|()’s |name|() as string
  
set theSource to theScript’s source() as text
  
return {scriptKind:scriptName, scriptSource:theSource}
end getASsourceFor

★Click Here to Open This Script 

Posted in file File path GUI OSA | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy NSArray NSPredicate NSString NSURL OSAScript | Leave a comment

ZipZapで指定アーカイブをメモリ上で展開して指定ファイルのみ取り出す

Posted on 1月 11, 2019 by Takaaki Naganoya

オープンソースのZipZapをCocoa Framework化したものを呼び出して、指定のZipアーカイブをメモリ上で展開し、指定ファイルの内容を取り出すAppleScriptです。

–> ZipZap.framework(To ~/Library/Frameworks/)

ZipアーカイブでAppleScriptを固めておいて、XcodeのAppleScriptアプリケーションのプロジェクト中に入れておき、指定ファイルのScriptをZipアーカイブから取り出して実行するときに使っています。

ZipZapはXcode Projectに入れてよし、Cocoa Frameworkに入れて呼び出してよし、と自分にとってたいへんに使い勝手のよい部品であり、重要なパーツになっています。

AppleScript名:ZipZapで指定アーカイブをメモリ上で展開して指定ファイルのみ取り出す
— Created 2019-01-11 by Takaaki Naganoya
— 2019 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "ZipZap" –https://github.com/pixelglow/ZipZap
use framework "OSAKit"
use BPlus : script "BridgePlus" –https://www.macosxautomation.com/applescript/apps/BridgePlus.html

property |NSURL| : a reference to current application’s |NSURL|
property ZZArchive : a reference to current application’s ZZArchive
property OSAScript : a reference to current application’s OSAScript

set anArchive to POSIX path of (choose file of type {"public.zip-archive"})
set aRes to extractArchiveAndPickupAFile(anArchive, "", "02_script.scpt") of me

on extractArchiveAndPickupAFile(aPath, aPass, aTargFileName)
  set oldArchive to ZZArchive’s archiveWithURL:(|NSURL|’s fileURLWithPath:aPath) |error|:(missing value)
  
set aList to oldArchive’s entries() as list
  
  set outList to {}
  
  repeat with i in aList
    set encF to i’s encrypted() as boolean
    
set aFileName to (i’s fileName())
    
    if (aFileName as string) = aTargFileName then
      
      set aExt to (aFileName’s pathExtension()) as string
      
set aUTI to my retFileFormatUTI(aExt)
      
set aData to (i’s newDataWithError:(missing value)) –Uncompressed raw data
      
      if aData = missing value then
        set aData to (i’s newDataWithPassword:(aPass) |error|:(missing value))
        
if aData is equal to (missing value) then
          return false
        end if
      end if
      
      if aUTI = "public.plain-text" then
        –Plain Text
        
set aStr to (NSString’s alloc()’s initWithData:aData encoding:(NSUTF8StringEncoding)) as string
        
      else if aUTI = "com.apple.applescript.script" then
        –AppleScript .scpt file
        
set aScript to (OSAScript’s alloc()’s initWithCompiledData:aData |error|:(missing value))
        
set aStr to (aScript’s source()) as string
        
      end if
      
return aStr
      
    end if
  end repeat
  
end extractArchiveAndPickupAFile

on retFileFormatUTI(aExt as string)
  tell script "BridgePlus"
    load framework
    
return (current application’s SMSForder’s UTIForExtension:aExt) as string
  end tell
end retFileFormatUTI

★Click Here to Open This Script 

Posted in file File path OSA Text UTI | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy | Leave a comment

機械学習で学習したMSの画像を連邦・ジオン軍判定してフォルダ分け v2

Posted on 11月 20, 2018 by Takaaki Naganoya

Create MLでガンダムのMS画像(連邦、ジオン区分け)を学習したCore ML Modelをもとに、画像をどちらの軍所属機体かを判定してフォルダ分けするAppleScriptです。

機械学習(深層学習)データをもとに判定を行って対話型処理ではなくバッチ処理的なフローでデータを「なんとなく」推論して区分けを行うサンプルです。非力なIOT機器が機械学習データをもとに推論処理できるぐらいなので、機械学習データを使ってAppleScriptで推論処理できないはずがありません。推論処理時間もさほどかからず、機械学習データを一括処理的なワークフローの中で利用することが可能です。

例によって「戦場の絆」の公式ページから落としてきたMSの画像を連邦軍とジオン軍、および両軍の鹵獲機体の4フォルダに分けてCreate MLで学習させてみました。

実行するとMS画像が入っているフォルダ(各自ご用意ください)と、連邦軍機体(efsf)およびジオン軍機体(zeon)を仕分けるフォルダを聞かれます。あとはプログラム側がなんとなく推論して仕分けを行います。

前回掲載のモデルもそうですが、きちんと学習後にテストデータで評価を行っています。だいたい8割ぐらいのヒット率ではあるものの、特定の画像については間違えることがあらかじめわかっています。

実行にあたっては、macOS 10.14上でCoreML Modelを組み込んだフレームワーク「msDetector.framework」をインストールして、本ScriptをScript Debugger上で動作させてください。

–> Download msDetector.framework (To ~/Library/Frameworks/)

–> Download msDetector (Code Signed executable AppleScript applet with Framework and libraries in its bundle)

Core MLで判定時に詳細なデータを出力させ、その可能性が0.8を上回るものだけを処理するようにしてみました。ただ、全力で間違った判定を行うケースもあるため、単なる「気休め」です。

テストデータでは、連邦軍側が72機体中間違いが9個(正解87.5%)、ジオン軍側が57機体中間違いが3個(正解95%)。鹵獲機体のデータを排除すると、もう少しいい値が出るかもしれません。ただ、学習させたデータとほぼ同じデータ(数が少ない)で再度判定を行っているだけなので、このぐらいの確度が出ないと逆に困ります。

また、確度が高くないものは排除するように処理したので、確度が低い機体の画像バリエーションを増やして学習画像数を足すと正解の確率が上がるのではないか、などと「なんとなく」考えています。

Create MLでは、もっときちんとした表データやタグ付き自然言語テキストデータ(日本語だと形態素への区分けはあらかじめやっておく必要アリ?)の学習が行えるようなので(自然言語テキストの学習例は英語のものしか見かけないけれども)いろいろやっておきたいところです。

今回は「アニメとかゲームに出てくるMSの画像」の判定という、実用性をまったく考えないで行なってみたものですが、自分の身の回りで有用性の高そうな処理といえば……アイコンやプレゼン用資料の作成画像を学習させておおまかなジャンル分けをしておき(メール系のアイコンとか)、未知のアイコン素材をダウンロードしてきたら機械学習データをもとに自動でフォルダ分けするとかでしょうか。

さすがにアイコン画像だとデフォルメされすぎていて、MicrosoftのAzure Computer Vision APIとかでも画像認識してくれなさそうなので。

AppleScript名:機械学習で学習したMSの画像の連邦軍、ジオン軍判定してフォルダ分け v2.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2018/11/20
—
–  Copyright © 2018 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.7" — Mojave (10.14) or later & Script Debugger
use framework "Foundation"
use framework "AppKit"
use framework "msDetector"
use scripting additions

property |NSURL| : a reference to current application’s |NSURL|
property NSArray : a reference to current application’s NSArray
property NSString : a reference to current application’s NSString
property NSPredicate : a reference to current application’s NSPredicate
property NSFileManager : a reference to current application’s NSFileManager
property NSMutableArray : a reference to current application’s NSMutableArray
property NSSortDescriptor : a reference to current application’s NSSortDescriptor
property NSURLTypeIdentifierKey : a reference to current application’s NSURLTypeIdentifierKey

set aFol to POSIX path of (choose folder with prompt "Choose MS Image folder to go!")
set efsfFol to POSIX path of (choose folder with prompt "EFSF folder")
set zeonFol to POSIX path of (choose folder with prompt "Zeon folder")

–指定フォルダ以下のファイルをすべて取得(再帰ですべて取得)
set aSel to retFullpathsWithinAFolderWithRecursive(aFol) of me

–取得したファイルリストを指定UTIでフィルタリング
set filRes2 to filterPOSIXpathListByUTI(aSel, "public.image") of me

–機械学習モデルを用いて区分けを行い、任意の画像の連邦軍(efsf)、ジオン軍(zeon)へのフォルダ分け(コピー)
set msClassifier to current application’s msClassify’s alloc()’s init()

repeat with i in filRes2
  set aFile to contents of i
  
set aImage to (current application’s NSImage’s alloc()’s initWithContentsOfFile:aFile)
  
  
set resDict to (msClassifier’s ImageClassifierWithImageAndRetDict:aImage) –returns NSDictionary
  
  
–Dictinaryのvalueをソートして、最も値の大きいvalueのkeyを求める
  
set sortedArray to (current application’s NSMutableArray’s arrayWithArray:(resDict’s allValues()))
  (
sortedArray’s sortUsingSelector:"compare:")
  
set aRes to (last item of (sortedArray as list)) –末尾のアイテムが一番値の大きい数値
  
set resKey to first item of ((resDict’s allKeysForObject:aRes) as list) –最大値をもとにKeyを求める
  
  
–可能性の高いものだけ処理してみる(自信たっぷりに全力で間違えることもけっこうある)
  
if (aRes as real) > 0.8 then
    if resKey begins with "efsf" then
      –efsf & efsf_stolen
      
set aRes to (my copyFileAt:aFile toFolder:efsfFol)
    else
      –zeon & zeon_stolen
      
set aRes to (my copyFileAt:aFile toFolder:zeonFol)
    end if
  end if
end repeat

–POSIX path listから指定UTIに含まれるものをPOSIX pathのリストで返す
on filterPOSIXpathListByUTI(aList, targUTI)
  set newList to {}
  
repeat with i in aList
    set j to contents of i
    
set tmpUTI to my retUTIfromPath(j)
    
set utiRes to my filterUTIList({tmpUTI}, targUTI)
    
if utiRes is not equal to {} then
      set the end of newList to j
    end if
  end repeat
  
return newList
end filterPOSIXpathListByUTI

–指定のPOSIX pathのファイルのUTIを求める
on retUTIfromPath(aPOSIXPath)
  set aURL to |NSURL|’s fileURLWithPath:aPOSIXPath
  
set {theResult, theValue} to aURL’s getResourceValue:(reference) forKey:NSURLTypeIdentifierKey |error|:(missing value)
  
  
if theResult = true then
    return theValue as string
  else
    return theResult
  end if
end retUTIfromPath

–UTIリストが指定UTIに含まれているかどうか演算を行う
on filterUTIList(aUTIList, aUTIstr)
  set anArray to NSArray’s arrayWithArray:aUTIList
  
set aPred to NSPredicate’s predicateWithFormat_("SELF UTI-CONFORMS-TO %@", aUTIstr)
  
set bRes to (anArray’s filteredArrayUsingPredicate:aPred) as list
  
return bRes
end filterUTIList

–指定フォルダ以下のすべてのファイルを再帰で取得
on retFullpathsWithinAFolderWithRecursive(aFol)
  set anArray to NSMutableArray’s array()
  
set aPath to NSString’s stringWithString:aFol
  
set dirEnum to NSFileManager’s defaultManager()’s enumeratorAtPath:aPath
  
  
repeat
    set aName to (dirEnum’s nextObject())
    
if aName = missing value then exit repeat
    
set aFullPath to aPath’s stringByAppendingPathComponent:aName
    
anArray’s addObject:(aFullPath as string)
  end repeat
  
  
return anArray as list
end retFullpathsWithinAFolderWithRecursive

on copyFileAt:POSIXPath toFolder:folderPath
  set POSIXPath to NSString’s stringWithString:POSIXPath
  
set folderPOSIXPath to NSString’s stringWithString:folderPath
  
set theName to POSIXPath’s lastPathComponent()
  
set newPath to folderPOSIXPath’s stringByAppendingPathComponent:theName
  
set fileManager to NSFileManager’s defaultManager()
  
set theResult to fileManager’s copyItemAtPath:POSIXPath toPath:newPath |error|:(missing value)
  
return (theResult as integer = 1)
end copyFileAt:toFolder:

★Click Here to Open This Script 

Posted in file File path Image list Machine Learning Record | Tagged 10.14savvy NSArray NSFileManager NSMutableArray NSPredicate NSSortDescriptor NSString NSURL NSURLTypeIdentifierKey | 1 Comment

ハッシュ値から、メモリースティックに保存されたReplay Dataのステージ名とプレイ日時を求める v3

Posted on 10月 30, 2018 by Takaaki Naganoya

PSPのゲーム「戦場の絆ポータブル」のセーブデータについているステージ別のプレビュー画像のハッシュ値から対戦ステージと対戦日時を抽出してタブ区切りテキストで出力するAppleScriptです。

保存された対戦データの内容を集計するために作成したものです。

PSPでメモリースティックに保存された対戦データには、すべて同じファイル名(ICON0.PNG)で異なる画像が添付されていました。ファイル名で対戦ステージを判定しようにも同じファイル名なので区別できません。

そこで、Spotlightの機能を用いて各セーブデータの「ICON0.PNG」をピックアップし、画像の内容のハッシュ値(SHA-1)を計算して、対戦ステージ内容を判定しました。

直近の対戦データをメモリースティック経由でMacに読み込み、本Scriptで分析してみたところ、

ジャブロー地上	2017年9月18日月曜日 14:42:48
ジャブロー地上	2017年9月18日月曜日 14:50:02
ジャブロー地上	2017年9月18日月曜日 14:55:22
タクラマカン砂漠	2017年9月18日月曜日 15:02:32
サイド7	2017年9月18日月曜日 15:09:36
ジャブロー地下	2017年9月18日月曜日 15:17:06
ジャブロー地上	2017年9月18日月曜日 15:31:08
サイド7	2017年9月18日月曜日 15:38:28
ジャブロー地上	2017年9月18日月曜日 15:51:52
ジャブロー地上	2018年1月2日火曜日 16:13:30
サイド7	2018年1月2日火曜日 16:23:04
ジャブロー地下	2018年1月2日火曜日 16:57:22

のようになりました。正月と秋分の日に親戚で集まったときに甥っ子と対戦した様子がありありと記録されています。

本Scriptはたまたまゲームのセーブデータの集計を行っていますが、同様の形式のデータを集計したい場合には使えそうです。

–> md5Lib.framework(To ~/Library/Frameworks)

AppleScript名:チェックサム値から、メモリースティックに保存されたReplay Dataのステージ名とプレイ日時を求める v3.1
— Created 2015-04-17 by Takaaki Naganoya
— Modified 2018-10-29 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "md5Lib" –https://github.com/JoeKun/FileMD5Hash
use bPlus : script "BridgePlus" –https://www.macosxautomation.com/applescript/apps/BridgePlus.html
use mdLib : script "Metadata Lib" version "2.0.0" –https://www.macosxautomation.com/applescript/apps/

property FileHash : a reference to current application’s FileHash
property SMSForder : a reference to current application’s SMSForder
property NSPredicate : a reference to current application’s NSPredicate
property NSFileManager : a reference to current application’s NSFileManager
property NSMutableArray : a reference to current application’s NSMutableArray

–各SAVEDATAフォルダ中の「ICON0.PNG」のSHA-1ハッシュ値とステージ名の対応表
set shaArray to NSMutableArray’s arrayWithArray:{{stageName:"ニューヤーク", sha1:"dbb9e8e26e96dbb4dd3198e55b6cde41aba8e0a8"}, {stageName:"鉱山都市", sha1:"72f35456504b1957ec85fb6a1597ac1a2baa2ee9"}, {stageName:"グレートキャニオン", sha1:"9de93e8b853fe153bc73066fb07481c774499960"}, {stageName:"サイド7", sha1:"be22fa949bfd78b0cd97596929f07ce4ec501d7b"}, {stageName:"タクラマカン砂漠", sha1:"5284dc5f0f7a53ee5677908f66da1e00b80f76b6"}, {stageName:"トリントン・タワー", sha1:"9f080853dac45ecaf1672ff2230f2b9a80a00eb4"}, {stageName:"ジャブロー地下", sha1:"a93550099419f52444cf77366773192d0bf5f848"}, {stageName:"ヒマラヤ", sha1:"877f998d608dd267c380e59a17b2a95a139baef5"}, {stageName:"ジャブロー地上", sha1:"8c4ee44e8f2fbcbf061e6d5ea2b202b08f42c59a"}}

load framework

set apPath1 to choose folder with prompt "リプレイデータが入っているフォルダを選択してください"
set aRes to perform search in folders {apPath1} predicate string "kMDItemFSName == %@" search arguments {"ICON0.PNG"}

set outList to {}
set errorList to {}

repeat with i in aRes
  set j to contents of i
  
set sumRes to (FileHash’s sha1HashOfFileAtPath:(j)) as string
  
  
–チェックサムからステージ名を検索する
  
set aPredStr to "sha1 == ’" & sumRes & "’"
  
set aPredicate to (NSPredicate’s predicateWithFormat:aPredStr)
  
set filteredArray to (shaArray’s filteredArrayUsingPredicate:aPredicate)
  
  
if filteredArray as list = {} then
    set the end of errorList to j
  else
    set tmpStage to (filteredArray’s valueForKey:"stageName") as string
    
    
set fAttrib to (NSFileManager’s defaultManager()’s attributesOfItemAtPath:j |error|:(missing value))
    
set cDat to (fAttrib’s fileCreationDate()) as date
    
    
set tmpList to {tmpStage, cDat}
    
    
if tmpList is not in outList then
      set the end of outList to tmpList
    end if
  end if
end repeat

–2D Listのソート
set sortIndexes to {1} –Key Item id: begin from 0
set sortOrders to {true} –ascending = true
set sortTypes to {"compare:"}
set out2List to (SMSForder’s subarraysIn:(outList) sortedByIndexes:sortIndexes ascending:sortOrders sortTypes:sortTypes |error|:(missing value)) as list

–2D Listをタブ区切りテキストに変換して返す
set aText to retItemDelimedAndParagraphDelimedText(out2List, tab, return) of me

–入れ子のリストを、アイテム間のデリミタとパラグラフ間のデリミタを指定してテキスト化
–というか、入れ子のリストをタブ区切りテキストにするのが目的
on retItemDelimedAndParagraphDelimedText(aList, itemDelim, paragraphDelim)
  set aText to ""
  
  
repeat with i in aList
    set aStr to retDelimedText(i, itemDelim) of me
    
set aText to aText & aStr & paragraphDelim
  end repeat
  
  
return aText
end retItemDelimedAndParagraphDelimedText

on retDelimedText(aList, aDelim)
  set aText to ""
  
set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to aDelim
  
set aText to aList as text
  
set AppleScript’s text item delimiters to curDelim
  
return aText
end retDelimedText

★Click Here to Open This Script 

Posted in file File path list Record Spotlight | Tagged 10.11savvy 10.12savvy NSFileManager NSMutableArray NSPredicate | Leave a comment

ファイル作成日、修正日を変更する

Posted on 10月 29, 2018 by Takaaki Naganoya

指定ファイルの作成日、修正日を変更するAppleScriptです。

以前はsetFileコマンド(Xcodeのcommand lineユーティリティーをインストールすると入る)で行うパターンを掲載していたのですが、NSFileManagerの方が楽にできるのと、どの実行環境でも(開発ツールが入っていなくても)実行できていいと思います。

AppleScript名:ファイル作成日、修正日を変更する
— Created 2018-05-30 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"

set aFile to POSIX path of (choose file)
set targDate to current date
changeFileCreationDate(targDate, aFile) of me
changeFileModDate(targDate, aFile) of me

–指定パスのファイルの作成日時を変更する
on changeFileCreationDate(aDate, aFile)
  set aDic to current application’s NSMutableDictionary’s dictionaryWithObject:aDate forKey:(current application’s NSFileCreationDate)
  
set aFM to current application’s NSFileManager’s defaultManager()’s setAttributes:aDic ofItemAtPath:(POSIX path of aFile) |error|:(missing value)
end changeFileCreationDate

–指定パスのファイルの修正日時を変更する
on changeFileModDate(aDate, aFile)
  set aDic to current application’s NSMutableDictionary’s dictionaryWithObject:aDate forKey:(current application’s NSFileModificationDate)
  
set aFM to current application’s NSFileManager’s defaultManager()’s setAttributes:aDic ofItemAtPath:(POSIX path of aFile) |error|:(missing value)
end changeFileModDate

★Click Here to Open This Script 

Posted in Calendar file File path | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy NSFileManager NSMutableDictionary | 1 Comment

アプリケーションの各種記法からBundle IDを求める

Posted on 10月 26, 2018 by Takaaki Naganoya

各種記法で記述したアプリケーション名から、Bundle IDを求めるAppleScriptです。

アプリケーション名(本当の名前)、Bundle ID、アプリケーションのフルパス(POSIX path)の3形式で記述したアプリケーション名から、Bundle IDを求めます。

ただし、Localized Name(Reminders–>「リマインダー」、Notes–>「メモ」)からBundle IDの取得は本Scriptではサポートしていません。

AppleScript名:アプリケーションの各種記法からBundle IDを求める
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"

set apList to {"Finder", "System Events", "com.apple.Finder", "/Applications/Safari"}
set bIDList to retAppBundleID(apList) of me
–> {"com.apple.finder", "com.apple.systemevents", "com.apple.Finder", "com.apple.Safari"}

–Application name list –> Bundle ID list
on retAppBundleID(appNameList)
  set resList to {}
  
  
repeat with i in appNameList
    set j to contents of i
    
    
if j starts with "/Applications/" then
      –POSIX path
      
if j does not end with ".app" then
        set j to j & ".app"
      end if
      
set aRes to getBundleIDFromPath(j) of me
      
    else if j contains "." then
      –Bundle ID (maybe)
      
copy j to aRes
    else
      –Application Name
      
set aRes to getBundleIDFromAppName(j) of me
    end if
    
    
set the end of resList to aRes
  end repeat
  
  
return resList
end retAppBundleID

–Application path –> Bundle ID
on getBundleIDFromPath(aPOSIXpath)
  set aURL to current application’s |NSURL|’s fileURLWithPath:aPOSIXpath
  
set aWorkspace to current application’s NSWorkspace’s sharedWorkspace()
  
set appURL to aWorkspace’s URLForApplicationToOpenURL:aURL
  
set aBundle to current application’s NSBundle’s bundleWithURL:appURL
  
set anID to aBundle’s bundleIdentifier()
  
return anID as string
end getBundleIDFromPath

–Application Name –> path –> Bundle ID
on getBundleIDFromAppName(appName)
  try
    –Localized Name will require choose application dialog
    
set appPath to POSIX path of (path to application appName)
  on error
    return ""
  end try
  
return getBundleIDFromPath(appPath) of me
end getBundleIDFromAppName

★Click Here to Open This Script 

Posted in file File path System | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy | Leave a comment

iCloud Driveフォルダへのパスを求める

Posted on 9月 16, 2018 by Takaaki Naganoya

iCloud Driveフォルダへのパスを求めるAppleScriptです。

ただ、これほどわかりにくいものも珍しいことでしょう。自分も避けておきたい仕様です。

パスについての仕様はあり、ファイルの読み書きなどはできそうですが、求めたパスをFinder上で指定すると不思議なことになります。

Finderのサイドバーから「iCloud Drive」アイコンをクリックすると、

のような表示になります。このときのFinder Windowのtargetを取得すると、~/Library/Mobile Documentsが返ってきます(形式はFinder Objectですけれども)。ただ、これと同じことをAppleScript側から行なっても、同じ結果が得られないというジレンマがあります。

~/Library/Mobile Documents

AppleScript名:iCloud Drivegフォルダへのパスを求める
set iCloudPath to ((path to library folder from user domain as string)) & "Mobile Documents:"
tell application "Finder"
  make new Finder window
  
set target of Finder window 1 to (iCloudPath as alias)
end tell

★Click Here to Open This Script 

これは、~/Library/Mobile Documentsをオープンするものですが、これを実行すると、

のようになります。

~/Library/Mobile Documents/com~apple~CloudDocs

これみたいですね。

AppleScript名:iCloud Drivegフォルダへのパスを求める(com~apple~CloudDocs フォルダ)
set iCloudPath to ((path to library folder from user domain as string)) & "Mobile Documents:com~apple~CloudDocs"
tell application "Finder"
  make new Finder window
  
set target of Finder window 1 to (iCloudPath as alias)
end tell

★Click Here to Open This Script 

これは、~/Library/iCloud Drive/com~apple~CloudDocsをオープンするものですが、これを実行すると、

となります。

Terminal上で当該フォルダを表示させてフォルダ名を再度確認してみたところ、きっとこれです。

Posted in File path System | Tagged 10.11savvy 10.12savvy Finder | Leave a comment

Stickiesからのデータ取り出し v2

Posted on 9月 6, 2018 by Takaaki Naganoya

スティッキーズ(Stickies.app)のデータをまとめて引っこ抜いてListに入れるAppleScriptです。色情報、1行目の内容をタイトルとみなしてタイトル情報も付加して出力するようにしてみました。

オープンソースのStickiesViewerをFramework化したstickiesLib.frameworkを経由してデータを読み出します。データベースファイルから情報を直接読み取るので、Stickies.appが起動している必要はありません。

–> Download stickiesLib.framework(To ~/Library/Frameworks/)

–> {creationDate:date “2006年1月15日日曜日 11:02:32″, aTitle:”WX-310Kの画像サイズ”, modificationDate:date “2006年1月15日日曜日 11:03:09″, aContents:”WX-310Kの画像サイズ
ケータイ:120×160
壁紙:240×320″, colorName:”Yellow”}

StickiesDatabaseからまとめて一括で全部抽出するので、個別に何かのIDで指定して抽出するといった動作にはなりません。

93個のスティッキーズ書類(93個のウィンドウが表示されている状態、1つのDBを指定)から、全データを取得して本AppleScriptで0.1秒程度です。

AppleScript名:Stickiesからのデータ取り出し v2.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2018/09/05
—
–  Copyright © 2018 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.5" — El Capitan (10.11) or later
use framework "Foundation"
use framework "AppKit"
use framework "stickiesLib"
use scripting additions

property NSColor : a reference to current application’s NSColor
property |NSURL| : a reference to current application’s |NSURL|
property SVReader : a reference to current application’s SVReader
property NSFileManager : a reference to current application’s NSFileManager
property NSMutableArray : a reference to current application’s NSMutableArray

set sRes to retStickiesData() of me
–>
(*
{{creationDate:date "2006年1月15日日曜日 11:02:32", aTitle:"WX-310Kの画像サイズ", modificationDate:date "2006年1月15日日曜日 11:03:09", aContents:"WX-310Kの画像サイズ
ケータイ:120×160
壁紙:240×320", colorName:"Yellow"}, ….}
*)

on retStickiesData()
  set dbPath to POSIX path of (path to library folder from user domain) & "StickiesDatabase"
  
set aExt to (NSFileManager’s defaultManager()’s fileExistsAtPath:dbPath) as boolean
  
  
if aExt = false then
    set dbPath to POSIX path of (choose file with prompt "Select StickiesDatabase file")
  end if
  
  
set aURL to |NSURL|’s fileURLWithPath:dbPath
  
set aStickDB to SVReader’s notesWithContentsOfURL:aURL
  
  
set aList to aStickDB as list
  
  
–スティッキーズの色データ
  
set cList to {{"Yellow", {254, 244, 156}}, {"Blue", {173, 244, 255}}, {"Green", {178, 255, 161}}, {"Pink", {255, 199, 199}}, {"Purple", {182, 202, 255}}, {"Gray", {238, 238, 238}}}
  
  
  
set outArray to NSMutableArray’s new()
  
  
repeat with i in aList
    set anAttrStr to i’s attributedString()
    
set aStr to (anAttrStr’s |string|()) as string
    
    
set curTitle to first paragraph of aStr
    
    
set aColor to i’s |color|()
    
set cDate to i’s dateCreated() as date
    
set mDate to i’s dateModified() as date
    
    
set c1List to retColListFromNSColor(aColor, 255) of me
    
    
–Find Color Name
    
set hitF to false
    
repeat with ii in cList
      set {colName, colList} to ii
      
if c1List = colList then
        set hitF to true
        
exit repeat
      end if
    end repeat
    
    
if hitF = false then error "Color name did not hit"
    
    
set curName to colName
    (
outArray’s addObject:{creationDate:cDate, modificationDate:mDate, aContents:aStr, colorName:curName, aTitle:curTitle})
    
  end repeat
  
  
return outArray as list
end retStickiesData

on retColorFromRGBnum(r, g, b)
  return (NSColor’s colorWithCalibratedRed:r / 255.0 green:g / 255.0 blue:b / 255.0 alpha:1.0)
end retColorFromRGBnum

–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 

Posted in Color File path RTF System | Tagged 10.11savvy 10.12savvy 10.13savvy NSColor NSFileManager NSMutableArray NSURL Stickies | Leave a comment

心配性のリネームプログラム

Posted on 8月 15, 2018 by Takaaki Naganoya

安全策の上に安全策を講じた、心配性のファイル名称変更AppleScriptです。

基本的にはファイルのリネームプログラムであり、Finder上で選択中のファイルについてリネームを行います。

ただし、ファイルのリネーム時に同じファイル名のファイルがすでに存在していて、普段であれば衝突回避のために子番号を振るなどの対処を行うところが、そういう対応が許されていないようなケースに直面しました。

同じフォルダ内にある3つの画像ファイルを、名称が衝突するような他の名称に変更するようなケースです。

1.jpg --> 2.jpg(すでに2.jpgが存在)
2.jpg --> 3.jpg(すでに3.jpgが存在)
3.jpg --> 1.jpg

少々、頭を抱えてしまいました。

そこで、テンポラリフォルダをファイル1つごとに作成し、テンポラリフォルダにファイルを移動。

1.jpg --> /temp/uuid0001/1.jpg

そのタコツボ的なテンポラリフォルダの中でリネームを実施。

/temp/uuid0001/1.jpg --> /temp/uuid0001/2.jpg

リネームしたファイルを元のフォルダに戻すというリネームルーチンを作成した次第です。もちろん、作成したテンポラリフォルダは削除しておきます。

/temp/uuid0001/2.jpg --> 2.jpg

最近はこのAppleScriptのように、ファイル操作処理はNSFileManagerで実行し、Finderには「選択中のファイルの情報を取得」ぐらいしか行わせていません。そのため、ファイル処理が従来よりもはるかに高速に行えて、ちょっと楽しいぐらいです。

数千ファイルのコピー(込み入ったルールに従いJANコードなどのデータを参照して名前を決定したり、フォルダ名を製品名で作成したりとか)が1・2秒というオーダーで終わってしまうのは、SSD上で処理しているせいもありますが、NSFileManager経由でのファイル処理を行っているおかげです(64bit化したCocoa Finderはとにかく処理が遅いのでAppleScriptからのファイル操作用に使うとダメ)。

AppleScript名:tempフォルダに移動しつつリネームして、終了後に元フォルダに戻す v2.scptd
— Created 2018-08-14 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

property NSUUID : a reference to current application’s NSUUID
property NSString : a reference to current application’s NSString
property NSFileManager : a reference to current application’s NSFileManager

property tResList : {}
property tFol : ""
property newNameTemplate : "test_"

set tResList to {}
set tFol to POSIX path of (path to temporary items)

tell application "Finder"
  set aSel to selection as alias list
  
if aSel = {} then
    display notification "No Selection"
    
return
  end if
end tell

–コピー元ファイルの親フォルダを求める(リネーム後に戻す)
set origFol to POSIX path of (contents of first item of aSel)
set origFolStr to ((NSString’s stringWithString:origFol)’s stringByDeletingLastPathComponent()) as string

–一時フォルダに移動してリネーム
set aCount to 1
repeat with i1 in aSel
  set j1 to POSIX path of (contents of i1)
  
set newName to newNameTemplate & (aCount as string)
  
set j1Res to renameSafely(j1, newName) of me
  
set the end of tResList to (j1Res as string)
  
set aCount to aCount + 1
end repeat

–元のフォルダに戻して一時フォルダ削除
repeat with i2 in tResList
  set j2 to contents of i2
  
set j2Res to (my moveFileAt:j2 toFolder:origFolStr)
  
set j2Res to deleteParentFol(j2) of me
end repeat

–安全なリネーム(個別のテンポラリフォルダに移動してリネーム)
on renameSafely(aFile, newName)
  –set tFol to POSIX path of (path to temporary items)
  
set aUUIDstr to ((NSUUID’s UUID()’s UUIDString()) as string)
  
set aTmpFol to tFol & aUUIDstr
  
  
set dRes to makeDirAbsolutely(aTmpFol) of me
  
set mRes to my moveFileAt:aFile toFolder:aTmpFol
  
  
set aStr to (NSString’s stringWithString:aFile)
  
set newFullPath to aTmpFol & "/" & aStr’s lastPathComponent()
  
set aExt to aStr’s pathExtension()
  
  
set fRes to renameFileItem(newFullPath, newName) of me
  
  
set renamedPath to aTmpFol & "/" & newName & "." & aExt
  
  
return renamedPath
end renameSafely

–指定パスににフォルダを作成する
on makeDirAbsolutely(dirStr)
  set fileManager to NSFileManager’s defaultManager()
  
set aRes to fileManager’s createDirectoryAtPath:dirStr withIntermediateDirectories:true attributes:(missing value) |error|:(reference)
  
copy aRes to {aFlag, aError}
  
return aFlag as boolean
end makeDirAbsolutely

on moveFileAt:POSIXPath toFolder:folderPOSIXPath
  set POSIXPath to NSString’s stringWithString:POSIXPath
  
set theName to POSIXPath’s lastPathComponent()
  
set folderPOSIXPath to NSString’s stringWithString:folderPOSIXPath
  
set theNewPath to folderPOSIXPath’s stringByAppendingPathComponent:theName
  
set fileManager to NSFileManager’s defaultManager()
  
set theResult to fileManager’s moveItemAtPath:POSIXPath toPath:theNewPath |error|:(missing value)
  
return theNewPath
end moveFileAt:toFolder:

on renameFileItem(aPOSIXpath as string, newName as string)
  set theNSFileManager to NSFileManager’s defaultManager()
  
set POSIXPathNSString to NSString’s stringWithString:(aPOSIXpath)
  
  
–Make New File Path
  
set anExtension to POSIXPathNSString’s pathExtension()
  
set newPath to (POSIXPathNSString’s stringByDeletingLastPathComponent()’s stringByAppendingPathComponent:newName)’s stringByAppendingPathExtension:anExtension
  
  
–Rename
  
if theNSFileManager’s fileExistsAtPath:newPath then
    return false
  else
    set theResult to theNSFileManager’s moveItemAtPath:POSIXPathNSString toPath:newPath |error|:(missing value)
    
if (theResult as integer = 1) then
      return (newPath as string)
    else
      return false
    end if
  end if
end renameFileItem

on deleteParentFol(aPOSIX)
  set aStr to NSString’s stringWithString:aPOSIX
  
set parentFol to aStr’s stringByDeletingLastPathComponent()
  
set aRes to deleteItemAt(parentFol) of me
  
return aRes
end deleteParentFol

on deleteItemAt(aPOSIX)
  set theNSFileManager to NSFileManager’s defaultManager()
  
set theResult to theNSFileManager’s removeItemAtPath:(aPOSIX) |error|:(missing value)
  
return (theResult as integer = 1) as boolean
end deleteItemAt

★Click Here to Open This Script 

Posted in file File path | Tagged 10.11savvy 10.12savvy NSFileManager NSString NSUUID | Leave a comment

複数のアートボードを持つAI書類を、デスクトップにアートボードごとに分割して保存

Posted on 8月 11, 2018 by Takaaki Naganoya

Adobe Illustrator CC 2018(バージョン22.1)で、複数のアートボードを持つAdobe Illustrator書類をアートボードごとに分割保存するAppleScriptです。

オプションの指定方法にものすごく納得しづらいものを感じるものの、これで動くので仕方ないだろうかというところ。

AppleScript名:複数のアートボードを持つAI書類を、デスクトップにアートボードごとに分割して保存.scptd
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set dtPath to ((path to desktop) as string) & "template.ai"

tell application "Adobe Illustrator"
  tell front document
    set aCount to (count every artboard) as string
    
set sOpt to {class:Illustrator save options, save multiple artboards:true, artboard range:"1-" & aCount}
    
save as Illustrator in file dtPath with options sOpt
  end tell
end tell

★Click Here to Open This Script 

Posted in file File path | Tagged 10.11savvy 10.12savvy Illustrator | Leave a comment

オープン中のIllustrator書類をartboardごとに分割 v3

Posted on 8月 9, 2018 by Takaaki Naganoya

Adobe Illustrator CC 2018(バージョン22.1)で、オープン中の(複数のアートボードを持つ)書類を、アートボード単位で別書類に分けるAppleScriptの改修版です。

書類は(とりあえず)デスクトップに書き込まれます。前バージョンのように、アートボード外のオブジェクトが残るといったことはありません。

「exportSelectedArtwork」という長いコマンドを見つけて、ためしてみたら期待どおりの挙動であったために使ってみました。

……すると、なおのことAppleScriptからartworkのselectができないのか?(実行すると100% Illustratorがクラッシュする) artworkからnameの取得ができないのか?(実行するとエラーになる)というあたりが謎です。

artboardも選択状態になっている(はず)だと思って、そのまま実行してみたところ、artboardのサイズでは書き出されていないようです。少し別の方法を試す必要があり、自分は前バージョンのScriptにもどって作業を行っています。

AppleScript名:オープン中のIllustrator書類をartboardごとに分割 v3.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2018/08/07
–  Modified on: 2018/08/09
–  Copyright © 2018 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.5" — El Capitan (10.11) or later
use framework "Foundation"
use scripting additions

set dPath to (path to desktop) as string
set namesList to {}

tell application "Adobe Illustrator"
  tell front document
    set aCount to count every artboard
    
set aPath to (file path) as string
  end tell
  
  
repeat with i from 1 to aCount
    set aName to getArtboardName(i – 1) of me –index base correction (1 –> 0)
    
set outPath to dPath & aName & ".ai"
    
    
selectArtboard(i – 1) of me –index base correction (1 –> 0)
    
    
tell front document
      selectobjectsonactiveartboard
      
exportSelectedArtwork to file outPath
    end tell
  end repeat
end tell

–https://lists.apple.com/archives/applescript-users/2015/Jul/msg00104.html
on selectArtboard(theArtboardIndex as string)
  tell application "Adobe Illustrator"
    tell front document
      –Index is 0 based
      
do javascript ("app.activeDocument.artboards.setActiveArtboardIndex(" & theArtboardIndex & ")")
    end tell
  end tell
end selectArtboard

on getArtboardName(theArtboardIndex as string)
  tell application "Adobe Illustrator"
    tell front document
      –Index is 0 based
      
do javascript ("app.activeDocument.artboards[" & theArtboardIndex & "].name")
    end tell
  end tell
end getArtboardName

★Click Here to Open This Script 

Posted in file File path | Tagged 10.12savvy Illustrator | Leave a comment

オープン中のIllustrator書類をartboardごとに分割 v2

Posted on 8月 9, 2018 by Takaaki Naganoya

Adobe Illustrator CC 2018(バージョン22.1)で、オープン中の(複数のアートボードを持つ)書類を、アートボード単位で別書類に分けるAppleScriptです。

書類は(とりあえず)デスクトップに書き込まれます。

こういうコマンドが最初からあってもおかしくないところですが、存在していないようなので書いてみました。まずは、オープン中の書類のパスを取得し、各アートボードの名称を取得して書き出し時のファイル名として使用します。

元ファイルをクローズしては、デスクトップに新規名称でコピーし、コピーした書類をオープン、書き出し対象外のアートボードを順次選択してはアートボード上のオブジェクトを削除してアートボード自体も削除、すべて削除したら保存してクローズという動作を行います。

本来であれば高速化のために複数のアートボードを一括で削除することを考えるところですが、アートボードの削除だけであればできるものの、アートボード上のオブジェクトの削除が行えなくなってしまうので、順次削除に落ち着きました。また、本Scriptが本気でスピードを求められるようなハードな用途ではなく、文字や画像の流し込みテンプレートのメンテナンス用という「平和な用途」のために作成したものであるため、高速化処理については考慮していません。

最初からアートボード外に置かれたオブジェクトについては削除していません。あくまで自分用のツールなので作り込む必要性を感じません。気が向いたら削除するのではないでしょうか。

本Scriptの作成中にも、単にAppleScriptで命令を出しただけで派手にクラッシュしまくるAdobe Illustrator。バージョンが上がって見た目が変わっても、あの出来の悪いIllustratorであることに変わりはないのだと思い知らされました。

AppleScript名:オープン中のIllustrator書類をartboardごとに分割 v2.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2018/08/07
—
–  Copyright © 2018 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.5" — El Capitan (10.11) or later
use framework "Foundation"
use scripting additions

set dPath to (path to desktop) as string
set namesList to {}

tell application "Adobe Illustrator"
  tell front document
    set aCount to count every artboard
    
set aPath to (file path) as string
  end tell
  
  
repeat with i from 1 to aCount
    set aName to getArtboardName(i – 1) of me –index base correction (1 –> 0)
    
set the end of namesList to aName
  end repeat
  
  
close every document saving no
end tell

repeat with i from 1 to aCount
  
  
set aRes to retSerialListWithExclusion(1, aCount, i) of me
  
set aaRes to reverse of aRes –artboardをIndex値で指定するため、先頭から削除するとIndex値が変わる。そのため逆順に処理
  
  
set tmpName to contents of item i of namesList
  
  
set fromFile to POSIX path of aPath
  
set fromFilePOSIX to quoted form of POSIX path of fromFile
  
  
set toFile to (dPath & tmpName & ".ai")
  
set toFilePOSIX to quoted form of POSIX path of toFile
  
  
set shText to "cp " & fromFilePOSIX & " " & toFilePOSIX
  
do shell script shText
  
  
tell application "Adobe Illustrator"
    open file toFile
    
tell front document
      repeat with ii in aaRes
        set jj to ii as integer
        
selectArtboard(jj – 1) of me –index base correction (1 –> 0)
        
selectobjectsonactiveartboard
        
delete selection
        
delete artboard jj
      end repeat
      
      
close with saving
    end tell
  end tell
  
end repeat

–https://lists.apple.com/archives/applescript-users/2015/Jul/msg00104.html
on selectArtboard(theArtboardIndex as string)
  tell application "Adobe Illustrator"
    tell front document
      –Index is 0 based
      
do javascript ("app.activeDocument.artboards.setActiveArtboardIndex(" & theArtboardIndex & ")")
    end tell
  end tell
end selectArtboard

on getArtboardName(theArtboardIndex as string)
  tell application "Adobe Illustrator"
    tell front document
      –Index is 0 based
      
do javascript ("app.activeDocument.artboards[" & theArtboardIndex & "].name")
    end tell
  end tell
end getArtboardName

on retSerialListWithExclusion(aFromNum as integer, aToNum as integer, anEXnum as integer)
  set outList to {}
  
repeat with i from aFromNum to aToNum
    if i = anEXnum then
      —
    else
      set the end of outList to i
    end if
  end repeat
  
  
return outList
end retSerialListWithExclusion

★Click Here to Open This Script 

Posted in file File path shell script | Tagged 10.12savvy Illustrator | Leave a comment

Finder上で選択中のPDFのファイル名の数字部分で小さいものから大きなものへとソート

Posted on 6月 27, 2018 by Takaaki Naganoya

Finder上で選択中のPDFのうち、ファイル名中の数字が小さいものから大きなものへソートを行うAppleScriptです。

Finder上で選択中のPDFをファイル名順でソートするような用途に使用します。選択中のファイルのうちPDFに該当しないものは無視します。

Finderで選択中の各PDFファイルに数字以外の文字がファイル名に混入していても無視します。

ファイル名はいったん数値として評価してソートするため、ファイル名にゼロパディングしてある場合には無視します。

Finder上で選択中のPDFを連結するさいに、ファイル名順で連結するScriptがあったほうが便利なので、そのために作ったものです。

ソートを行う際に、ファイル名の中の数字以外の部分をすべて無視するようにしています。そのため、Finder上の並び順と関係なく、ファイル名の中の数字部分のみをピックアップしてソートします。Finder自体にもFinderのルールでファイル名をソートして返すAppleScriptの機能がありますが、あれに甘えているとまともな処理はできません。

「test1_0004.pdf」というファイル名があった場合には10004という数値を検出するため、こうしたケースに対応する必要があるかもしれませんが、現時点では無用な数字の除去はしていません(それこそ一括処理で行うものではなくユーザーの目で見て判断してもらうような処理なので)。

AppleScript名:Finder上で選択中のPDFの数字のファイル名で小さいものから大きなものへとソート
— Created 2018-06-26 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use mdLib : script "Metadata Lib" version "1.0.0" –https://www.macosxautomation.com/applescript/apps/
use bPlus : script "BridgePlus" –https://www.macosxautomation.com/applescript/apps/BridgePlus.html

property |NSURL| : a reference to current application’s |NSURL|
property NSArray : a reference to current application’s NSArray
property NSPredicate : a reference to current application’s NSPredicate
property NSURLTypeIdentifierKey : a reference to current application’s NSURLTypeIdentifierKey

tell application "Finder"
  set inFiles to selection as alias list
end tell

if inFiles = {} then return

–指定のAlias listのうちPDFのみ抽出
set filRes1 to filterAliasListByUTI(inFiles, "com.adobe.pdf") of me

–ファイル名
set cList to {}
repeat with i in (filRes1 as list)
  set j to contents of i
  
set aFileName to ((current application’s NSString’s stringWithString:j)’s valueForKeyPath:"lastPathComponent.stringByDeletingPathExtension")
  
  
set aNumF to returnNumberCharsOnly(aFileName) of me
  
set the end of cList to {numDat:(aNumF as integer), pathDat:j}
end repeat

set aResList to sortRecListByLabel(cList, "numDat", true) of me –昇順ソート
set bResList to (aResList’s valueForKeyPath:"pathDat") as list of string or string
–>  {​​​​​"/Users/me/Pictures/243.pdf", ​​​​​"/Users/me/Pictures/244.pdf", ​​​​​"/Users/me/Pictures/245.pdf", ​​​​​"/Users/me/Pictures/246.pdf", ​​​​​"/Users/me/Pictures/247.pdf", ​​​​​"/Users/me/Pictures/248.pdf", ​​​​​"/Users/me/Pictures/249.pdf", ​​​​​"/Users/me/Pictures/250.pdf", ​​​​​"/Users/me/Pictures/251.pdf", ​​​​​"/Users/me/Pictures/252.pdf", ​​​​​"/Users/me/Pictures/253.pdf", ​​​​​"/Users/me/Pictures/254.pdf", ​​​​​"/Users/me/Pictures/255.pdf", ​​​​​"/Users/me/Pictures/256.pdf", ​​​​​"/Users/me/Pictures/257.pdf"​​​}

–文字列中から
on returnNumberCharsOnly(aStr)
  set anNSString to current application’s NSString’s stringWithString:aStr
  
set anNSString to anNSString’s stringByReplacingOccurrencesOfString:"[^0-9]" withString:"" options:(current application’s NSRegularExpressionSearch) range:{0, anNSString’s |length|()}
  
return anNSString as text
end returnNumberCharsOnly

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

–Alias listから指定UTIに含まれるものをPOSIX pathのリストで返す
on filterAliasListByUTI(aList, targUTI)
  set newList to {}
  
repeat with i in aList
    set j to POSIX path of i
    
set tmpUTI to my retUTIfromPath(j)
    
set utiRes to my filterUTIList({tmpUTI}, targUTI)
    
if utiRes is not equal to {} then
      set the end of newList to j
    end if
  end repeat
  
return newList
end filterAliasListByUTI

–指定のPOSIX pathのファイルのUTIを求める
on retUTIfromPath(aPOSIXPath)
  set aURL to |NSURL|’s fileURLWithPath:aPOSIXPath
  
set {theResult, theValue} to aURL’s getResourceValue:(reference) forKey:NSURLTypeIdentifierKey |error|:(missing value)
  
  
if theResult = true then
    return theValue as string
  else
    return theResult
  end if
end retUTIfromPath

–UTIリストが指定UTIに含まれているかどうか演算を行う
on filterUTIList(aUTIList, aUTIstr)
  set anArray to NSArray’s arrayWithArray:aUTIList
  
set aPred to NSPredicate’s predicateWithFormat_("SELF UTI-CONFORMS-TO %@", aUTIstr)
  
set bRes to (anArray’s filteredArrayUsingPredicate:aPred) as list
  
return bRes
end filterUTIList

★Click Here to Open This Script 

Posted in file File path PDF Sort | Tagged 10.11savvy 10.12savvy 10.13savvy Finder | Leave a comment

指定パスの所属するドライブ名を取得する v2

Posted on 5月 22, 2018 by Takaaki Naganoya

指定パスの所属するドライブ名を取得するAppleScriptです。

ドライブ名さえ求めてしまえば、Finderに問い合わせてそれが起動ドライブ(startup = true)かどうか確認できるため、起動ドライブ以外であれば外付けディスクやファイルサーバーであるかの判定も行えます。

AppleScript名:指定パスの所属するドライブ名を取得する v2
— Created 2017-09-03 by Takaaki Naganoya
— 2017 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

property |NSURL| : a reference to current application’s |NSURL|
property NSURLVolumeNameKey : a reference to current application’s NSURLVolumeNameKey

set aPath to POSIX path of (choose folder)
set dRes to retDiskNameOfTheFolder(aPath) of me

on retDiskNameOfTheFolder(aPath)
  set aURL to |NSURL|’s fileURLWithPath:aPath
  
set aVlomeName to ""
  
set {aRes, driveName} to aURL’s getResourceValue:(reference) forKey:(NSURLVolumeNameKey) |error|:(missing value)
  
return driveName as string
end retDiskNameOfTheFolder

★Click Here to Open This Script 

Posted in drive File path | Tagged 10.11savvy 10.12savvy 10.13savvy | Leave a comment

Previewでオープン中のファイルのパスを求める(macOS 10.12限定)

Posted on 5月 21, 2018 by Takaaki Naganoya

Preview.appでオープン中の画像のファイルパスをすべてPOSIX pathで求めるAppleScriptです。


▲大昔にあった「日本語AppleScript」(Japanese Dialect)を擬似的に書いたRTFを画像化したもの。AppleScriptがいまでも日本語で書けるとかいうデモではありません(大事なことなので書いておきました)

Preview.appでオープン中の画像のパスをためしに求めてみたところ(macOS 10.12.6)、実際のファイルが、

  /Users/me/Desktop/image.png

であるものが、

  /Users/me/Library/Containers/com.apple.Preview/Data/Desktop/image.png

と返ってきました。一時的に、ライブラリフォルダの下にコピーしてオープンしているのでしょうか。そういう「舞台裏」をそのまま見せてしまうのはどうかと思います。オリジナルのファイルパスをそのまま返せばいいのに。

そこで、Preview.appから返ってきたパスを加工してオリジナルのパスを求めてみました。

ファイルサーバー上にある画像や外部HDD上にある画像などについては検証していないので、それについては、別途パスを求め直す必要があることでしょう。

macOS 10.13.5beta上でためしてみたら、こちらでは直っていました。そーーですよねーーーーー、10.12上の仕様の方がおかしいですよねーーー(ーー;;

AppleScript名:Previewでオープン中のファイルのパスを求める
— Created 2018-05-21 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

tell application "Preview"
  set dList to path of every document
  
–> {"/Users/me/Library/Containers/com.apple.Preview/Data/Desktop/スクリーンショット 2018-02-28 14.01.09.png", "/Users/me/Library/Containers/com.apple.Preview/Data/Desktop/スクリーンショット 2018-02-28 14.01.11.png"}
end tell

set mePath to POSIX path of (path to home folder)
set origStr to mePath & "Library/Containers/com.apple.Preview/Data"

set outPathList to {}

repeat with i in dList
  set j to contents of i
  
set the end of outPathList to repChar(j, origStr, (text 1 thru -2 of mePath)) of me
end repeat

return outPathList

on repChar(origText as string, targStr as string, repStr as string)
  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 

Posted in File path Image Text | Tagged 10.12savvy Preview | Leave a comment

Xcodeでオープン中のソースコードのパスを求める

Posted on 5月 19, 2018 by Takaaki Naganoya

Xcodeでオープン中のソースコードのファイルパスを求めるAppleScriptです。

Xcode v9.2+macOS 10.12.6、Xcode v9.3.1+macOS 10.13.5betaで確認しました。

おおまかにいえば、Xcodeは大きくわけて2種類の書類を扱っています。1つは、拡張子「.xcodeproj」のXcodeプロジェクト(Workspace)書類。

そして、個別のソースコード書類(SwiftとかObjective-CとかAppleScriptとか)。

そんなわけで、普通のGUIアプリケーションとはdocumentの概念がやや異なり、少々めんどくさい上にXcodeのAppleScript用語辞書に載っている用例自体も「え、そんな書き方を推奨するの?」という、なんとも不思議な仕上がりになっていますが、まあいいんでしょう。

ちなみに、本ScriptはXcodeのメインウィンドウ上でソースコードを表示する場合と、個別のウィンドウで表示する場合に対応しています。

また、Xcodeのウィンドウ上でXibファイルやInfo.plistやアイコンのAssetsなどソースコード書類以外のものを表示している場合には、エラートラップをかけてfalseを返すようにしています。


▲XcodeのAppleScript用語辞書に書かれている記述例。Workspace Documentのオープン完了待ちをpropertyを確認しつつループで待つという仕様。そんなとこ、非同期実行してドーする、という不思議感満載

AppleScript名:Xcodeでオープン中のソースコードのパスを求める
— Created 2018-05-19 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

tell application "Xcode"
  –最前面のWindowの情報を取得
  
set winProp to properties of front window
  
set aDoc to document of winProp –Xcode のworkspace document(xcodeproj)
  
–> workspace document "WKWebViewDemo.xcodeproj" of application "Xcode"
  
  
set docProp to properties of aDoc
  
set xcodeDocPath to path of docProp
  
–> "/Users/me/Documents/Objective-C/WKWebViewDemo_MAC-master/WKWebViewDemo.xcodeproj"
  
  
set aFileDoc to name of winProp
  
–> "ViewController.m"
  
  
try
    set aDoc to file document aFileDoc
    
–> source document "ViewController.m" of application "Xcode"
  on error
    –Storyboard/Xib file/info.plist/Assetsなどを表示中の場合にはエラーになる
    
return false
  end try
  
  
set aDocPath to path of aDoc
  
–> "/Users/me/Documents/Objective-C/WKWebViewDemo_MAC-master/WKWebViewDemo/ViewController.m"
end tell

★Click Here to Open This Script 

Posted in File path | Tagged 10.12savvy 10.13savvy Xcode | Leave a comment

Post navigation

  • Older posts
  • Newer posts

電子書籍(PDF)をオンラインストアで販売中!

Google Search

Popular posts

  • 開発機としてM2 Mac miniが来たのでガチレビュー
  • CotEditorで2つの書類の行単位での差分検出
  • macOS 13.6.5 AS系のバグ、一切直らず
  • macOS 15, Sequoia
  • 初心者がつまづきやすい「log」コマンド
  • 指定のWordファイルをPDFに書き出す
  • Pages本執筆中に、2つの書類モード切り替えに気がついた
  • Adobe AcrobatをAppleScriptから操作してPDF圧縮
  • メキシカンハットの描画
  • 与えられた文字列の1D Listのすべての順列組み合わせパターン文字列を返す v3(ベンチマーク用)
  • 2023年に書いた価値あるAppleScript
  • Pixelmator Pro v3.6.4でAppleScriptからの操作時の挙動に違和感が
  • Numbersで選択範囲のセルの前後の空白を削除
  • AdobeがInDesign v19.4からPOSIX pathを採用
  • Safariで「プロファイル」機能を使うとAppleScriptの処理に影響
  • Cocoa Scripting Course 続刊計画
  • AppleScriptによる並列処理
  • macOS 14.xでScript Menuの実行速度が大幅に下がるバグ
  • NaturalLanguage.frameworkでNLEmbeddingの処理が可能な言語をチェック
  • AppleScript入門③AppleScriptを使った「自動化」とは?

Tags

10.11savvy (1102) 10.12savvy (1243) 10.13savvy (1392) 10.14savvy (587) 10.15savvy (438) 11.0savvy (283) 12.0savvy (212) 13.0savvy (187) 14.0savvy (137) 15.0savvy (115) CotEditor (64) Finder (51) iTunes (19) Keynote (115) NSAlert (61) NSArray (51) NSBitmapImageRep (20) NSBundle (20) NSButton (34) NSColor (53) NSDictionary (28) NSFileManager (23) NSFont (21) NSImage (41) NSJSONSerialization (21) NSMutableArray (63) NSMutableDictionary (22) NSPredicate (36) NSRunningApplication (56) NSScreen (30) NSScrollView (22) NSString (119) NSURL (98) NSURLRequest (23) NSUTF8StringEncoding (30) NSView (33) NSWorkspace (20) Numbers (75) Pages (54) Safari (44) Script Editor (27) WKUserContentController (21) WKUserScript (20) WKWebView (23) WKWebViewConfiguration (22)

カテゴリー

  • 2D Bin Packing
  • 3D
  • AirDrop
  • AirPlay
  • Animation
  • AppleScript Application on Xcode
  • Beginner
  • Benchmark
  • beta
  • Bluetooth
  • Books
  • boolean
  • bounds
  • Bug
  • Calendar
  • call by reference
  • check sum
  • Clipboard
  • Cocoa-AppleScript Applet
  • Code Sign
  • Color
  • Custom Class
  • dialog
  • diff
  • drive
  • Droplet
  • exif
  • file
  • File path
  • filter
  • folder
  • Font
  • Font
  • GAME
  • geolocation
  • GUI
  • GUI Scripting
  • Hex
  • History
  • How To
  • iCloud
  • Icon
  • Image
  • Input Method
  • Internet
  • iOS App
  • JavaScript
  • JSON
  • JXA
  • Keychain
  • Keychain
  • Language
  • Library
  • list
  • Locale
  • Localize
  • Machine Learning
  • Map
  • Markdown
  • Menu
  • Metadata
  • MIDI
  • MIME
  • Natural Language Processing
  • Network
  • news
  • Noification
  • Notarization
  • Number
  • Object control
  • OCR
  • OSA
  • parallel processing
  • PDF
  • Peripheral
  • PRODUCTS
  • QR Code
  • Raw AppleEvent Code
  • Record
  • rectangle
  • recursive call
  • regexp
  • Release
  • Remote Control
  • Require Control-Command-R to run
  • REST API
  • Review
  • RTF
  • Sandbox
  • Screen Saver
  • Script Libraries
  • sdef
  • search
  • Security
  • selection
  • shell script
  • Shortcuts Workflow
  • Sort
  • Sound
  • Spellchecker
  • Spotlight
  • SVG
  • System
  • Tag
  • Telephony
  • Text
  • Text to Speech
  • timezone
  • Tools
  • Update
  • URL
  • UTI
  • Web Contents Control
  • WiFi
  • XML
  • XML-RPC
  • イベント(Event)
  • 未分類

アーカイブ

  • 2025年2月
  • 2025年1月
  • 2024年12月
  • 2024年11月
  • 2024年10月
  • 2024年9月
  • 2024年8月
  • 2024年7月
  • 2024年6月
  • 2024年5月
  • 2024年4月
  • 2024年3月
  • 2024年2月
  • 2024年1月
  • 2023年12月
  • 2023年11月
  • 2023年10月
  • 2023年9月
  • 2023年8月
  • 2023年7月
  • 2023年6月
  • 2023年5月
  • 2023年4月
  • 2023年3月
  • 2023年2月
  • 2023年1月
  • 2022年12月
  • 2022年11月
  • 2022年10月
  • 2022年9月
  • 2022年8月
  • 2022年7月
  • 2022年6月
  • 2022年5月
  • 2022年4月
  • 2022年3月
  • 2022年2月
  • 2022年1月
  • 2021年12月
  • 2021年11月
  • 2021年10月
  • 2021年9月
  • 2021年8月
  • 2021年7月
  • 2021年6月
  • 2021年5月
  • 2021年4月
  • 2021年3月
  • 2021年2月
  • 2021年1月
  • 2020年12月
  • 2020年11月
  • 2020年10月
  • 2020年9月
  • 2020年8月
  • 2020年7月
  • 2020年6月
  • 2020年5月
  • 2020年4月
  • 2020年3月
  • 2020年2月
  • 2020年1月
  • 2019年12月
  • 2019年11月
  • 2019年10月
  • 2019年9月
  • 2019年8月
  • 2019年7月
  • 2019年6月
  • 2019年5月
  • 2019年4月
  • 2019年3月
  • 2019年2月
  • 2019年1月
  • 2018年12月
  • 2018年11月
  • 2018年10月
  • 2018年9月
  • 2018年8月
  • 2018年7月
  • 2018年6月
  • 2018年5月
  • 2018年4月
  • 2018年3月
  • 2018年2月

https://piyomarusoft.booth.pm/items/301502

メタ情報

  • ログイン
  • 投稿フィード
  • コメントフィード
  • WordPress.org

Forum Posts

  • 人気のトピック
  • 返信がないトピック

メタ情報

  • ログイン
  • 投稿フィード
  • コメントフィード
  • WordPress.org
Proudly powered by WordPress
Theme: Flint by Star Verte LLC