Archive for the 'NSFileManager' Category

2017/02/09 Application Supportフォルダを求める

Application Supportフォルダを求めるAppleScriptです。

ただ、通常環境(Script Editorとか)を前提としたものではなく(動きますけど)、Xcode上のCocoa-AppleScript Applet内でCodeSignしてApp Sandboxを有効にした環境におけるApplication Supportフォルダを求めるためのものです。

一応、Script Editorや他のAppleScript開発環境でも動きますが、Sandbox環境では返ってくるパスが全然違います。そうした一種の極限環境でも値を取得していろいろやるための実験であります。

AppleScript名:Application Supportフォルダを求める
– Created 2017-02-09 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4450

set fileManager to current application’s NSFileManager’s alloc()’s init()
set bundleID to current application’s NSBundle’s mainBundle()’s bundleIdentifier()
set urlPaths to fileManager’s URLsForDirectory:(current application’s NSApplicationSupportDirectory) inDomains:(current application’s NSUserDomainMask)
set appDirectory to (((urlPaths’s objectAtIndex:0)’s URLByAppendingPathComponent:bundleID isDirectory:true)’s |path|()) as string

–> “/Users/me/Library/Application Support/au.com.myriad-com.ASObjC-Explorer-4″–ASObjC Explorer 4の場合
–> “/Users/me/Library/Application Support/com.apple.ScriptEditor2″–Apple純正のScript Editorの場合

★Click Here to Open This Script 

2016/10/25 指定ムービーを指定形式に変換する v2

指定のムービーファイルを指定形式に変換するAppleScriptの改良版です。

一晩たったら、旧石器時代から現代までタイムスリップしたぐらいの改良が加わっています(汗)。野蛮な手段でファイル拡張子からUTIを求めていたのが、フレームワーク呼び出し一発で、、、処理速度も大幅に向上しています。

AppleScript名:指定ムービーを指定形式に変換する v2
– Created 2016-10-24 by Shane Stanley
– Modified 2016-10-24 by Takaaki Naganoya
– Modified 2016-10-25 by Shane Stanley
use AppleScript version “2.4″
use framework “Foundation”
use framework “AVFoundation”
use scripting additions
use BridgePlus : script “BridgePlus” –Version 1.3.2以降

load framework
–http://piyocast.com/as/archives/4288

set posixPath to POSIX path of (choose file with prompt “Choose a Movie file:”)
my convertMovieAt:posixPath ToType:“AVAssetExportPresetAppleM4A” withExtension:“m4a” deleteOriginal:false

–指定のムービーを、指定の書き出しプリセットで、指定のファイル形式で、オリジナルファイルを削除するかどうか指定しつつ書き出し
on convertMovieAt:(posixPath as string) ToType:(assetTypeStr as string) withExtension:(aExt as string) deleteOriginal:(deleteFlag as boolean)
  set theURL to current application’s |NSURL|’s fileURLWithPath:posixPath
  
  
set aPreset to current application’s NSString’s stringWithString:assetTypeStr
  
  
– set destination to use same path, different extension
  
set destURL to theURL’s URLByDeletingPathExtension()’s URLByAppendingPathExtension:aExt
  
set theAsset to current application’s AVAsset’s assetWithURL:theURL
  
  
– check asset can be converted
  
set allowedPresets to current application’s AVAssetExportSession’s exportPresetsCompatibleWithAsset:theAsset
  
if (allowedPresets’s containsObject:aPreset) as boolean is false then
    error “Can’t export this file as an .” & aExt & ” file.”
  end if
  
  
– set up export session
  
set fileTypeUTIstr to retFileFormatUTI(aExt) of me –ファイル拡張子からFile Type UTIを求める
  
set theSession to current application’s AVAssetExportSession’s exportSessionWithAsset:theAsset presetName:aPreset
  
theSession’s setOutputFileType:fileTypeUTIstr
  
theSession’s setOutputURL:destURL
  
  
– begin export and poll for completion
  
theSession’s exportAsynchronouslyWithCompletionHandler:(missing value)
  
repeat
    set theStatus to theSession’s status() as integer
    
if theStatus < 3 then
      delay 0.2
    else
      exit repeat
    end if
  end repeat
  
  
– throw error if it failed
  
if theStatus = (current application’s AVAssetExportSessionStatusFailed) as integer then
    error (theSession’s |error|()’s localizedDescription() as text)
  end if
  
  
– delete original if required
  
if deleteFlag then
    current application’s NSFileManager’s defaultManager()’s removeItemAtURL:theURL |error|:(missing value)
  end if
end convertMovieAt:ToType:withExtension:deleteOriginal:

on retFileFormatUTI(aExt as string)
  return (current application’s SMSForder’s UTIForExtension:aExt)
end retFileFormatUTI

★Click Here to Open This Script 

2016/10/25 ムービー系の拡張子からFile Format UTIを取得する v2, v3

ムービー系のファイルの拡張子から、File Format UTIを取得するAppleScriptの改良版です。

Shane Stanleyから指摘があって、

(1)com.apple.quicktime-movieと current application’s AVFileTypeQuickTimeMovieは同じものなので変換する必要はないよ(なんとなく、そうじゃないかとは思ってました ^ー^;;)

(2)BridgePlus v1.3.2に拡張子からUTIを求めるメソッドが用意してあるよ(!!!)

というわけで、(1)を反映させたv2、(2)まで反映させたv3を作成してみましたが、v3にいたってはたったの1行。どこかにもっとスマートな解決策が転がっていると思っていましたが、ここまでスマートになるとは(^ー^;;;

一応、試した範囲ではv1もv2もv3も実行結果は同じです。

AppleScript名:ムービー系の拡張子からFile Format UTIを取得する v2
– Created 2016-10-24 by Takaaki Naganoya
– Modified 2016-10-25 by Takaaki Naganoya
– Modified 2016-10-25 by Shane Stanley
– 2016 Piyomaru Software
use AppleScript version “2.4″
use framework “Foundation”
use framework “AVFoundation”
use framework “AppKit”
use scripting additions
–http://piyocast.com/as/archives/4287

set aRes to retFileFormatUTI(“mov”) of me
–>  (NSString) “com.apple.quicktime-movie”

set aRes to retFileFormatUTI(“mp4″) of me
–>  (NSString) “public.mpeg-4″

set aRes to retFileFormatUTI(“m4v”) of me
–>  (NSString) “com.apple.m4v-video”

set aRes to retFileFormatUTI(“m4a”) of me
–>  (NSString) “com.apple.m4a-audio”

set aRes to retFileFormatUTI(“3gp”) of me
–>  (NSString) “public.3gpp”

set aRes to retFileFormatUTI(“3gp2″) of me
–>  (NSString) “public.3gpp2″

set aRes to retFileFormatUTI(“caf”) of me
–>  (NSString) “com.apple.coreaudio-format”

set aRes to retFileFormatUTI(“wav”) of me
–>  (NSString) “com.microsoft.waveform-audio”

set aRes to retFileFormatUTI(“aif”) of me
–>  (NSString) “public.aifc-audio”

set aRes to retFileFormatUTI(“aifc”) of me
–>  (NSString) “public.aifc-audio”

set aRes to retFileFormatUTI(“amr”) of me
–>  (NSString) “org.3gpp.adaptive-multi-rate-audio”

set aRes to retFileFormatUTI(“mp3″) of me
–>  (NSString) “public.mp3″

set aRes to retFileFormatUTI(“au”) of me
–>  (NSString) “public.au-audio”

set aRes to retFileFormatUTI(“ac3″) of me
–>  (NSString) “public.ac3-audio”

on retFileFormatUTI(aExt)
  set theWorkspace to current application’s NSWorkspace’s sharedWorkspace()
  
set valList to {“com.apple.quicktime-movie”, “public.mpeg-4″, “com.apple.m4v-video”, “com.apple.m4a-audio”, “public.3gpp”, “public.3gpp2″, “com.apple.coreaudio-format”, “com.microsoft.waveform-audio”, “public.aiff-audio”, “public.aifc-audio”, “org.3gpp.adaptive-multi-rate-audio”, “public.mp3″, “public.au-audio”, “public.ac3-audio”}
  
repeat with aUTI in valList
    if (theWorkspace’s filenameExtension:aExt isValidForType:aUTI) as boolean then
      return (current application’s NSString’s stringWithString:aUTI)
    end if
  end repeat
  
error “Invalid Constant String”
end retFileFormatUTI

★Click Here to Open This Script 

AppleScript名:ムービー系の拡張子からFile Format UTIを取得する v3
– Created 2016-10-24 by Takaaki Naganoya
– Modified 2016-10-25 by Shane Stanley
– 2016 Piyomaru Software
use AppleScript version “2.4″
use framework “Foundation”
use framework “AVFoundation”
use scripting additions
use BridgePlus : script “BridgePlus” –Version 1.3.2以降
load framework

–http://piyocast.com/as/archives/4287

set aRes to retFileFormatUTI(“mov”) of me
–>  (NSString) “com.apple.quicktime-movie”

set aRes to retFileFormatUTI(“mp4″) of me
–>  (NSString) “public.mpeg-4″

set aRes to retFileFormatUTI(“m4v”) of me
–>  (NSString) “com.apple.m4v-video”

set aRes to retFileFormatUTI(“m4a”) of me
–>  (NSString) “com.apple.m4a-audio”

set aRes to retFileFormatUTI(“3gp”) of me
–>  (NSString) “public.3gpp”

set aRes to retFileFormatUTI(“3gp2″) of me
–>  (NSString) “public.3gpp2″

set aRes to retFileFormatUTI(“caf”) of me
–>  (NSString) “com.apple.coreaudio-format”

set aRes to retFileFormatUTI(“wav”) of me
–>  (NSString) “com.microsoft.waveform-audio”

set aRes to retFileFormatUTI(“aif”) of me
–>  (NSString) “public.aifc-audio”

set aRes to retFileFormatUTI(“aifc”) of me
–>  (NSString) “public.aifc-audio”

set aRes to retFileFormatUTI(“amr”) of me
–>  (NSString) “org.3gpp.adaptive-multi-rate-audio”

set aRes to retFileFormatUTI(“mp3″) of me
–>  (NSString) “public.mp3″

set aRes to retFileFormatUTI(“au”) of me
–>  (NSString) “public.au-audio”

set aRes to retFileFormatUTI(“ac3″) of me
–>  (NSString) “public.ac3-audio”

on retFileFormatUTI(aExt as string)
  return (current application’s SMSForder’s UTIForExtension:aExt)
end retFileFormatUTI

★Click Here to Open This Script 

2016/10/24 指定ムービーを指定形式に変換する

指定のムービーファイルを指定形式に変換するAppleScriptです。

オリジナルはShane StanleyがAppleScript Users-MLに投稿したものですが、変換(エクスポート)形式が固定で指定されていました(ムービーからオーディオ部のみ書き出し)。

たいへんに有用性が高いものの、エクスポート形式固定のままでは使い勝手がいまひとつだったので、形式を可変指定できるように改修してみました。

エクスポート形式で指定可能なものは、このように一覧を取得できます。この中から選択してください。

本Scriptをそのまま実行すると、指定のムービーファイルから音声部分のみ、同一ファイル名で拡張子を「m4a」にした別ファイルをオリジナルのファイルと同一フォルダ内に書き出します。オリジナルのファイルは消去せずにそのまま残す設定です。

AppleScript名:指定ムービーを指定形式に変換する
– Created 2016-10-24 by Shane Stanley
– Modified 2016-10-24 by Takaaki Naganoya
use AppleScript version “2.4″
use framework “Foundation”
use framework “AVFoundation”
use scripting additions
–http://piyocast.com/as/archives/4286

set posixPath to POSIX path of (choose file with prompt “Choose a Movie file:”)
my convertMovieAt:posixPath ToType:“AVAssetExportPresetAppleM4A” withExtension:“m4a” deleteOriginal:false

–指定のムービーを、指定の書き出しプリセットで、指定のファイル形式で、オリジナルファイルを削除するかどうか指定しつつ書き出し
on convertMovieAt:(posixPath as string) ToType:(assetTypeStr as string) withExtension:(aExt as string) deleteOriginal:(deleteFlag as boolean)
  set theURL to current application’s |NSURL|’s fileURLWithPath:posixPath
  
  
set aPreset to current application’s NSString’s stringWithString:assetTypeStr
  
  
– set destination to use same path, different extension
  
set destURL to theURL’s URLByDeletingPathExtension()’s URLByAppendingPathExtension:aExt
  
set theAsset to current application’s AVAsset’s assetWithURL:theURL
  
  
– check asset can be converted
  
set allowedPresets to current application’s AVAssetExportSession’s exportPresetsCompatibleWithAsset:theAsset
  
if (allowedPresets’s containsObject:aPreset) as boolean is false then
    error “Can’t export this file as an .” & aExt & ” file.”
  end if
  
  
– set up export session
  
set fileTypeUTIstr to retFileFormatUTI(aExt) of me –ファイル拡張子からFile Type UTIを求める
  
set theSession to current application’s AVAssetExportSession’s exportSessionWithAsset:theAsset presetName:aPreset
  
theSession’s setOutputFileType:fileTypeUTIstr
  
theSession’s setOutputURL:destURL
  
  
– begin export and poll for completion
  
theSession’s exportAsynchronouslyWithCompletionHandler:(missing value)
  
repeat
    set theStatus to theSession’s status() as integer
    
if theStatus < 3 then
      delay 0.2
    else
      exit repeat
    end if
  end repeat
  
  
– throw error if it failed
  
if theStatus = (current application’s AVAssetExportSessionStatusFailed) as integer then
    error (theSession’s |error|()’s localizedDescription() as text)
  end if
  
  
– delete original if required
  
if deleteFlag then
    current application’s NSFileManager’s defaultManager()’s removeItemAtURL:theURL |error|:(missing value)
  end if
end convertMovieAt:ToType:withExtension:deleteOriginal:

on retFileFormatUTI(aExt as string)
  set aUTIstr to getUTIfromNameExtension(aExt) of me
  
set keyList to {current application’s AVFileTypeQuickTimeMovie, current application’s AVFileTypeMPEG4, current application’s AVFileTypeAppleM4V, current application’s AVFileTypeAppleM4A, current application’s AVFileType3GPP, current application’s AVFileType3GPP2, current application’s AVFileTypeCoreAudioFormat, current application’s AVFileTypeWAVE, current application’s AVFileTypeAIFF, current application’s AVFileTypeAIFC, current application’s AVFileTypeAMR, current application’s AVFileTypeMPEGLayer3, current application’s AVFileTypeSunAU, current application’s AVFileTypeAC3}
  
set valList to {“com.apple.quicktime-movie”, “public.mpeg-4″, “com.apple.m4v-video”, “com.apple.m4a-audio”, “public.3gpp”, “public.3gpp2″, “com.apple.coreaudio-format”, “com.microsoft.waveform-audio”, “public.aiff-audio”, “public.aifc-audio”, “org.3gpp.adaptive-multi-rate-audio”, “public.mp3″, “public.au-audio”, “public.ac3-audio”}
  
if aUTIstr is not in valList then
    error “Invalid Constant String”
  end if
  
  
set aPos to offsetOf(valList, aUTIstr) of me
  
set cRes to contents of item aPos of keyList
  
return cRes
end retFileFormatUTI

on offsetOf(aList as list, aTarg)
  set aArray to current application’s NSArray’s arrayWithArray:aList
  
set aIndex to (aArray’s indexOfObject:aTarg) as number
  
return (aIndex + 1)
end offsetOf

–ファイル拡張子からUTI文字列を取得する
on getUTIfromNameExtension(anExtStr as string)
  set aTempPath to (POSIX path of (path to temporary items from user domain))
  
set aTempName to (current application’s NSUUID’s UUID()’s UUIDString()) as string
  
set bTempPath to (aTempPath & aTempName & “.” & anExtStr)
  
do shell script “touch “ & quoted form of bTempPath
  
set utiStr to current application’s NSWorkspace’s sharedWorkspace()’s typeOfFile:bTempPath |error|:(missing value)
  
do shell script “rm -f “ & quoted form of bTempPath
  
return utiStr as string
end getUTIfromNameExtension

★Click Here to Open This Script 

2016/09/20 連番JPEGファイルを読み込んで連結したPDFを作成(新規作成)

連番JPEG画像を番号順にソートして、順次連結したPDFを新規作成するAppleScriptです。

jpeg_catfiles.jpg

このような連番画像を連結して任意のファイル名のPDFに合成します。出来上がるPDFは、元のJPEGファイルの圧縮度に応じて大きくなります。

新規作成よりも、すでに存在しているPDFにJPEGファイルを連結するほうが実用的だと思います。

AppleScript名:連番JPEGファイルを読み込んで連結したPDFを作成(新規作成)
– Created 2016-09-20 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “QuartzCore”
use framework “Quartz”
use framework “AppKit”

set aExt to “.jpg”
set aFol to choose folder
set fList to getFilePathList(aFol, aExt) of me
set f2List to my sort1DList:fList ascOrder:true –sort by ascending

set newFile to POSIX path of (choose file name with prompt “新規PDFファイルの名称を選択”)
set newFilePath to current application’s NSString’s stringWithString:newFile

–Make Blank PDF
set aPDFdoc to current application’s PDFDocument’s alloc()’s init()

set pageNum to 0

repeat with i in f2List
  set j to contents of i
  
set aURL to (current application’s |NSURL|’s fileURLWithPath:j)
  
set bImg to (current application’s NSImage’s alloc()’s initWithContentsOfURL:aURL)
  (
aPDFdoc’s insertPage:(current application’s PDFPage’s alloc()’s initWithImage:bImg) atIndex:pageNum)
  
set pageNum to pageNum + 1
end repeat

aPDFdoc’s writeToFile:newFilePath

–ASOCで指定フォルダのファイルパス一覧取得(拡張子指定つき)
on getFilePathList(aFol, aExt)
  set aPath to current application’s NSString’s stringWithString:(POSIX path of aFol)
  
set aFM to current application’s NSFileManager’s defaultManager()
  
set nameList to (aFM’s contentsOfDirectoryAtPath:aPath |error|:(missing value)) as list
  
set anArray to current application’s NSMutableArray’s alloc()’s init()
  
  
repeat with i in nameList
    set j to i as text
    
if (j ends with aExt) and (j does not start with “.”) then –exclude invisible files
      set newPath to (aPath’s stringByAppendingString:j)
      (
anArray’s addObject:newPath)
    end if
  end repeat
  
  
return anArray as list
end getFilePathList

–1D List(文字)をsort / ascOrderがtrueだと昇順ソート、falseだと降順ソート
on sort1DList:theList ascOrder:aBool
  set aDdesc to current application’s NSSortDescriptor’s sortDescriptorWithKey:“self” ascending:aBool selector:“localizedCaseInsensitiveCompare:”
  
set theArray to current application’s NSArray’s arrayWithArray:theList
  
return (theArray’s sortedArrayUsingDescriptors:{aDdesc}) as list
end sort1DList:ascOrder:

★Click Here to Open This Script 

2016/09/07 PDFのしおりを追加

Edama2さんからの投稿Scriptです(ありがとうございますー)。以下、その内容です。

(投稿ここから)
内容は、指定したPDFにしおりを追加します。変更したPDFは同じフォルダに別名保存します。サンプルScript中のしおりデータは、book2_2.0.pdf(最新事情がわかるAppleScript 10大最新技術)用です。

しおりがあると今度は、章だけではなく大見出しも欲しくなり作ってみました。

preview1.png
▲処理前のPDF(Adobe Acrobat Professionalで表示)

pdfindex3.png
▲処理前のPDFのしおり部分(AppleScriptで処理すると一旦削除)

pdfindex4.png
▲処理後のPDF。新規作成したしおり部分。階層構造を持っている

階層表示の一階層しか対応していませんが、もっと深い階層も作れるようにしたかったが、…時間がなくてできませんでした。再帰処理で出来そうな気はするんですが…。

実用的にはもう一階層分あったほうがうれしいです。この辺は好みもあるので自分でもDTPする時に悩みます。

#1 他人のマシン上でも動くAppleScriptを書く
  他人のマシン上でも動くAppleScriptを書く
    準備しよう!
      他人のユーザーアカウント上で動かすための最低条件
      OSAXを極力使わない

メインの処理をrunハンドラでなく、別ハンドラにしているのは、「Objective-Cポインタは保存できません」エラーに対応するためです。

→ AppleScriptのダウンロード(20KB)

リファレンスv2は、ページ数の多さもあり気になった項目から読んでいるので、まだ全部読み終えてませんが主に文法編をよく活用しています。(投稿ここまで)

「AppleScript最新リファレンス」については、書いた本人でも、「あれ、こんなの書いたっけ?」と、自分で読んで発見があります(汗)

プログラムの内容について、自分もひととおり美味しそうなPDF関連のCocoaの機能は試した気になっていたのですが、しおりは試していませんでした。

自分がいつも使っている「AppleScriptのプログラムを書式つきのHTMLに変換」するAppleScriptでお送りいただいたScriptを変換したところ、WordPress側でエラー発生。やむなくダウンロードしていただく形式にしました(なんでだ?!)。

書籍の話に戻りますが……PDFが出来上がったあとでゴニョゴニョを後処理を行うよりも制作フローそのものを見直すべきだとは自分も思っています(MarkdownからPDFを書き出すだけというのは無茶すぎ、、、)。その割に、世間に転がっている情報のウラをとって(実際に確認して)みると、Pandocも割と役立たずで、MarkdownをIDMLに変換できるとかいいつつ、いざInDesignに読ませてみると「互換性がない」エラーに遭遇するやらで、実に「自分で何か作らないとダメ」な雰囲気です。

2016/07/18 PDFの指定ページを削除

指定PDF中の指定ページを削除するAppleScriptです。

CocoaのAPIをひととおり調べて、PDFのページ削除を行うメソッドなどが存在していないことがよくわかりました。

存在しない=できない、ということではないのでAppleScriptで組んでみました。動作確認した範囲ではちゃんと機能しています。

pdfremove.png

削除機能を削除機能として考えただけでは実現できませんが、これを「新規PDFへのページコピー」と考えれば不可能ではありません。つまり、削除を「新規PDFにコピーしない」ことと定義し直してみました。

 /卦PDFに指定ページ以外のページをコピー
 ▲リジナルのPDFを削除
 新規PDFをオリジナルのPDF名で保存

と処理すれば、指定ページを削除したのと同じことです。

このルーチンを用いて、「複数ファイルのPDFを連結、末尾が空白ページだったら削除しつつ連結」という動作を行うAppleScriptを簡単に書くことができました。

ただ、この処理方法がSandbox環境で(Xcode上で作成するCocoa-AppleScript Applet内で)許可されるものなのかは、試してみないといけないでしょう。

AppleScript名:PDFの指定ページを削除
– Modified 2016-07-18 by Takaaki Naganoya
–Original By Shane Stanley
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “Quartz”
use framework “QuartzCore”

set inFile to (choose file of type {“pdf”} with prompt “Choose your PDF files:”)
set targPage to 2
set maxPage to pdfPageCount(inFile) of me
if 0 < targPage and targPage maxPage then
  –Skip
else
  display dialog “Page Number Range Error”
  
return
end if

removeSpecificPageInPDF(inFile, targPage) of me

on removeSpecificPageInPDF(inFile, targPageNum)
  – make URL of the first PDF
  
set inNSURL to current application’s |NSURL|’s fileURLWithPath:(POSIX path of inFile)
  
set theDoc to current application’s PDFDocument’s alloc()’s initWithURL:inNSURL
  
  set oldDocCount to ((theDoc’s pageCount()) - 1)
  
  –Make Blank PDF (deleted PDF)
  
set newPDFdoc to current application’s PDFDocument’s alloc()’s init()
  
  set newDocCount to 0
  
  repeat with i from 0 to oldDocCount
    if i is equal to (targPageNum - 1) then
      log {“skip page at:”, i}
    else
      log {i}
      
set thePDFPage to (theDoc’s pageAtIndex:i) – zero-based indexes
      (
newPDFdoc’s insertPage:thePDFPage atIndex:newDocCount)
      
set newDocCount to newDocCount + 1
    end if
  end repeat
  
  –元ファイルを削除して問題がなければ、指定ページを削除したPDFを同名で新規保存
  
set aRes to deleteFile(inFile) of me
  
if aRes = true then
    set aRes to (newPDFdoc’s writeToURL:inNSURL)
  end if
  
  return aRes
  
end removeSpecificPageInPDF

–指定PDFのページ数をかぞえる
on pdfPageCount(aFile)
  set aFile to POSIX path of aFile
  
set theURL to current application’s |NSURL|’s fileURLWithPath:aFile
  
set aPDFdoc to current application’s PDFDocument’s alloc()’s initWithURL:theURL
  
set aRes to aPDFdoc’s pageCount()
  
return aRes as integer
end pdfPageCount

–指定ファイルの削除
on deleteFile(aFile)
  set aPath to POSIX path of aFile
  
set filePath to current application’s NSString’s stringWithString:aPath
  
set fileManager to current application’s NSFileManager’s defaultManager()
  
set aRes to fileManager’s removeItemAtPath:filePath |error|:(reference)
  
–>  {true, missing value}
  
–>  {false, (NSError) Error}
  
copy aRes to {aFlag, aReason}
  
return aFlag
end deleteFile

★Click Here to Open This Script 

2015/12/22 2フォルダ間のファイル内容比較

Cocoaの機能を用いて、2つのフォルダ内のファイルの内容比較を行うAppleScriptです。

folders.png

複数バージョンのAppleScriptで、処理結果がきちんと同じかどうか比較したいケースがあります。そこで手作業で比較・・・していたのでは意味がありません。

たまたま仕事でCSVを書き出すAppleScriptをバージョンアップしていて、前バージョンの処理結果ととくに変化がないことを検証するために、

 。殴侫ルダ間のファイル名一覧に変更がないこと
 同一ファイル名のファイルで内容が同一であること

をチェックする必要がありました。Pure AppleScriptで書こうとすると、けっこうめんどくさい処理です(書いたことがあるような気がしますが、書き捨てしてしまったのかも)。

Cocoaの機能を使って書くとどうなるのか? 調べてみてあまりに簡潔に書けるので、「本当にこれでいいの?」と、わざと2フォルダ間でファイル数を変えてみたり、同名でまったく内容の違うファイルを入れてみたりしましたが、きちんと検出してくれました。

2フォルダにそれぞれ1050個のCSVファイルを入れた状態で、MacBook Pro Retina 2012で(SSD上で)実行すると比較に1秒かかりません。HDD上で比較を行うとそれなりに時間はかかりますが、Mac mini 2014(Core i5 2.6GHz)上で3秒程度でした。

AppleScript名:2フォルダ間の内容比較
– Created 2015-12-22 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set aFol to (choose folder with prompt "Select Folder A")
set bFol to (choose folder with prompt "Select Folder B")

set aPath to POSIX path of aFol
set bPath to POSIX path of bFol

set aFM to current application’s NSFileManager’s defaultManager()
set aRes to (aFM’s contentsEqualAtPath:aPath andPath:bPath) as boolean

★Click Here to Open This Script 

2015/11/07 Systemのアラートサウンド名称を取得して鳴らす v2

Cocoaの機能を無理やり使って、Systemに入っている警告音の名称一覧を取得して鳴らすAppleScriptです。

Shane Stanleyから、「Script中で使っているgetFilePathListFromPOSIXpathの仕様だと、OS X 10.11では動くが10.10ではエラーになるよ」との指摘があり、書き換え例(v2)がナイスな内容だったので、少し試してみました(v2.1)。

NSArrayの中に入っている全要素を加工しつつ別のArrayに出力する(しかもループしない)という書き方はスマートなので、ぜひ覚えておきたいと思います。

AppleScript名:ASOCでSystemのアラートサウンド名称を取得して鳴らす v2
– Created 2015-11-06 by Takaaki Naganoya
– Modified 2015-11-07 by Shane Stanley–Recovery the compatibility for OS X 10.10.x
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”

set sList to getSystemAlertSoundNames() of me
–>  {”Basso.aiff”, “Blow.aiff”, “Bottle.aiff”, “Frog.aiff”, “Funk.aiff”, “Glass.aiff”, “Hero.aiff”, “Morse.aiff”, “Ping.aiff”, “Pop.aiff”, “Purr.aiff”, “Sosumi.aiff”, “Submarine.aiff”, “Tink.aiff”}

repeat with i in sList
  tell (current application’s NSSound’s soundNamed:i) to play()
  
delay 0.5 –時間待ちしないと全部一緒に鳴るので(Let’s Challenge!)
end repeat

–Get System Alert FileName List
on getSystemAlertSoundNames()
  set aExt to “aiff” – no dot
  
set aFol to “/System/Library/Sounds”
  
set fList to getFileNameListFromPOSIXpath(aFol, aExt) of me
  
return fList
end getSystemAlertSoundNames

–Get File Name List from POSIX path and file Extensions
on getFileNameListFromPOSIXpath(aFol, aExt)
  set aFM to current application’s NSFileManager’s defaultManager()
  
set aURL to current application’s |NSURL|’s fileURLWithPath:aFol
  
set urlArray to aFM’s contentsOfDirectoryAtURL:aURL includingPropertiesForKeys:{} options:(current application’s NSDirectoryEnumerationSkipsHiddenFiles) |error|:(missing value)
  
set thePred to current application’s NSPredicate’s predicateWithFormat:“pathExtension == [c]%@” argumentArray:{aExt}
  
set anArray to urlArray’s filteredArrayUsingPredicate:thePred
  
return (anArray’s valueForKey:“lastPathComponent”) as list –便利!!
end getFileNameListFromPOSIXpath

★Click Here to Open This Script 

AppleScript名:ASOCでSystemのアラートサウンド名称を取得して鳴らす v2.1
– Created 2015-11-06 by Takaaki Naganoya
– Modified 2015-11-07 by Shane Stanley–Recovery the compatibility for OS X 10.10.x
– Modified 2015-11-07 by Takaaki Naganoya–NSArrayからvalueForKeyで加工しつつ一気にArrayで値を返す内容を検証
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”

set sList to getSystemAlertSoundNames() of me
–>  {”Basso”, “Blow”, “Bottle”, “Frog”, “Funk”, “Glass”, “Hero”, “Morse”, “Ping”, “Pop”, “Purr”, “Sosumi”, “Submarine”, “Tink”}

repeat with i in sList
  tell (current application’s NSSound’s soundNamed:i) to play()
  
delay 0.5 –時間待ちしないと全部一緒に鳴るので(Let’s Challenge!)
end repeat

–Get System Alert FileName List
on getSystemAlertSoundNames()
  set aExt to “aiff” – no dot
  
set aFol to “/System/Library/Sounds”
  
set fList to getFileNameListFromPOSIXpath(aFol, aExt) of me
  
return fList
end getSystemAlertSoundNames

–Get File Name List from POSIX path and file Extensions
on getFileNameListFromPOSIXpath(aFol, aExt)
  set aFM to current application’s NSFileManager’s defaultManager()
  
set aURL to current application’s |NSURL|’s fileURLWithPath:aFol
  
set urlArray to aFM’s contentsOfDirectoryAtURL:aURL includingPropertiesForKeys:{} options:(current application’s NSDirectoryEnumerationSkipsHiddenFiles) |error|:(missing value)
  
set thePred to current application’s NSPredicate’s predicateWithFormat:“pathExtension == [c]%@” argumentArray:{aExt}
  
set anArray to urlArray’s filteredArrayUsingPredicate:thePred
  
set bArray to (anArray’s valueForKey:“lastPathComponent”) –便利!!
  
set cArray to (bArray’s valueForKey:“stringByDeletingPathExtension”) –便利!!
  
return cArray as list
end getFileNameListFromPOSIXpath

★Click Here to Open This Script 

AppleScript名:ASOCでSystemのアラートサウンド名称を取得して鳴らす v2.2
– Created 2015-11-06 by Takaaki Naganoya
– Modified 2015-11-07 by Shane Stanley–Recovery the compatibility for OS X 10.10.x
– Modified 2015-11-07 by Takaaki Naganoya–NSArrayからvalueForKeyで加工しつつ一気にArrayで値を返す内容を検証
– Modified 2015-11-07 by Shane Stanley–Cooler processing
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”

set sList to getSystemAlertSoundNames() of me
–>  {”Basso”, “Blow”, “Bottle”, “Frog”, “Funk”, “Glass”, “Hero”, “Morse”, “Ping”, “Pop”, “Purr”, “Sosumi”, “Submarine”, “Tink”}

repeat with i in sList
  tell (current application’s NSSound’s soundNamed:i) to play()
  
delay 0.5 –時間待ちしないと全部一緒に鳴るので(Let’s Challenge!)
end repeat

–Get System Alert FileName List
on getSystemAlertSoundNames()
  set aExt to “aiff” – no dot
  
set aFol to “/System/Library/Sounds”
  
set fList to getFileNameListFromPOSIXpath(aFol, aExt) of me
  
return fList
end getSystemAlertSoundNames

–Get File Name List from POSIX path and file Extensions
on getFileNameListFromPOSIXpath(aFol, aExt)
  set aFM to current application’s NSFileManager’s defaultManager()
  
set aURL to current application’s |NSURL|’s fileURLWithPath:aFol
  
set urlArray to aFM’s contentsOfDirectoryAtURL:aURL includingPropertiesForKeys:{} options:(current application’s NSDirectoryEnumerationSkipsHiddenFiles) |error|:(missing value)
  
set thePred to current application’s NSPredicate’s predicateWithFormat:“pathExtension == [c]%@” argumentArray:{aExt}
  
set anArray to urlArray’s filteredArrayUsingPredicate:thePred
  
set bArray to (anArray’s valueForKeyPath:“lastPathComponent.stringByDeletingPathExtension”) –Cool !!
  
return bArray as list
end getFileNameListFromPOSIXpath

★Click Here to Open This Script 

2015/11/06 Systemのアラートサウンド名称を取得して鳴らす

Cocoaの機能を無理やり使って、Systemに入っている警告音の名称一覧を取得して鳴らすAppleScriptです。

sounds.png

そういう「OSの警告音一覧を取得する」といったサービスがあるのかと思って探していたら、どうも存在していない雰囲気なので、Cocoaの機能を使ってものすごく常識的かつ地道に/System/Library/Soundsの中に入っているaiffファイルのファイル名の一覧を取得というところに落ち着きました。

AppleScript名:ASOCでSystemのアラートサウンド名称を取得して鳴らす
– Created 2015-11-06 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"

set sList to getSystemAlertSoundNames() of me
–>  {"Basso", "Blow", "Bottle", "Frog", "Funk", "Glass", "Hero", "Morse", "Ping", "Pop", "Purr", "Sosumi", "Submarine", "Tink"}

repeat with i in sList
  tell (current application’s NSSound’s soundNamed:i) to play()
  
delay 0.5 –時間待ちしないと全部一緒に鳴るので(Let’s Challenge!)
end repeat

on getSystemAlertSoundNames()
  set sList to getSystemAlertSoundPathList() of me
  
set nameList to {}
  
repeat with i in sList
    set j to contents of i
    
set aPOSIX to POSIX path of j
    
set pathString to (current application’s NSString’s stringWithString:aPOSIX)
    
set aFileName to pathString’s lastPathComponent()
    
set aFileName2 to aFileName’s stringByDeletingPathExtension()
    
set the end of nameList to (aFileName2 as text)
  end repeat
  
  return nameList
end getSystemAlertSoundNames

–Get System Alert Path List
on getSystemAlertSoundPathList()
  set aExt to "aiff" – no dot
  
set aFol to "/System/Library/Sounds"
  
set fList to getFilePathListFromPOSIXpath(aFol, aExt) of me
  
return fList
end getSystemAlertSoundPathList

–Get File List from POSIX path and file Extensions
on getFilePathListFromPOSIXpath(aFol, aExt)
  set aFM to current application’s NSFileManager’s defaultManager()
  
set aURL to current application’s |NSURL|’s fileURLWithPath:aFol
  
set urlArray to aFM’s contentsOfDirectoryAtURL:aURL includingPropertiesForKeys:{} options:(current application’s NSDirectoryEnumerationSkipsHiddenFiles) |error|:(missing value)
  
set thePred to current application’s NSPredicate’s predicateWithFormat:"pathExtension == [c]%@" argumentArray:{aExt}
  
set anArray to urlArray’s filteredArrayUsingPredicate:thePred
  
return anArray as list
end getFilePathListFromPOSIXpath

★Click Here to Open This Script 

2015/10/29 指定フォルダ内のフォルダのみを取得する

Cocoaの機能を用いて、指定フォルダ以下のフォルダだけを取得するAppleScriptです。

こちらも、US AppleのAppleScript Users MLにShane Stanleyが投稿したものです。ただ、まっとうに処理しているので・・・実行にはそれなりに時間がかかります。Spotlightの機能を用いて取得した方がはるかに高速です。

フォルダだけを抽出するのであればSpotlightを用いることになるでしょうけれど、この用途「以外」で何か別の用途で活用できる雰囲気がしています。

AppleScript名:ASOCで指定フォルダ内のフォルダのみを取得する
– Created 2015-10-13 by Shane Stanley
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set thePath to POSIX path of (choose folder)
set fListRes to my getFoldersIn:thePath
–>  {file "Macintosh HD:Users:me:Pictures:2014カレンダー表紙?", file "Macintosh HD:Users:me:Pictures:ASBook", file "Macintosh HD:Users:me:Pictures:ASBook:AS_beginner", file "Macintosh HD:Users:me:Pictures:Camera Roll", file "Macintosh HD:Users:me:Pictures:DESIGN GARDEN PROJECT", ….

on getFoldersIn:posixPath
  script spd
    property allItems : {}
  end script
  
  
set allItems of spd to {}
  
  
– make URL
  
set theNSURL to current application’s |NSURL|’s fileURLWithPath:posixPath
  
  
– make file manager
  
set theNSFileManager to current application’s NSFileManager’s new()
  
  
– get URL enumerator
  
set theNSFileEnumerator to theNSFileManager’s enumeratorAtURL:theNSURL includingPropertiesForKeys:{current application’s NSURLIsDirectoryKey, current application’s NSURLIsPackageKey} options:((current application’s NSDirectoryEnumerationSkipsPackageDescendants) + (current application’s NSDirectoryEnumerationSkipsHiddenFiles as integer)) errorHandler:(missing value)
  
  
– get all items from enumerator
  
set (allItems of spd) to theNSFileEnumerator’s allObjects()
  
set theFolders to {} – to store folders
  
  
– loop through
  
repeat with i from 1 to count of (allItems of spd)
    – is it a directory?
    
set {theResult, isDirectory} to ((item i of (allItems of spd))’s getResourceValue:(reference) forKey:(current application’s NSURLIsDirectoryKey) |error|:(missing value))
    
if isDirectory as boolean then
      set {theResult, isPackage} to ((item i of (allItems of spd))’s getResourceValue:(reference) forKey:(current application’s NSURLIsPackageKey) |error|:(missing value))
      
      
– is it not a package?
      
if not isPackage as boolean then
        set end of theFolders to (item i of (allItems of spd))’s |path|() as «class furl»
      end if
    end if
  end repeat
  
  
return theFolders
end getFoldersIn:

★Click Here to Open This Script 

2015/10/26 ASOCによるファイルの移動

Cocoaの機能を用いてファイルを移動(move)するじっけんです。

Pure AppleScriptであればFinder経由でmove… to …with replacingで強制移動。do shell script経由でmvしてもいいですし、それほど大変な内容ではない「ファイルの移動」。

これを、Cocoaの機能(NSFileManager)経由で書いて、共有フォルダの内容を(処理後に)処理終了フォルダへ移動させようとしたところ、エラーが出て行えませんでした。正確にいえば・・・移動できることもあれば、移動できないこともありました。

ただ、Pure AppleScriptで書くとなんてことはない処理なので、Pure AppleScript版にルーチンだけ差し替えてそのまま使いましたが、NSFileManagerでなぜうまく処理できなかったのかをUS AppleのAppleScript Users ML上で質問。

ShaneとML上でやりとりして、「移動先に同名のファイルが存在していたから」という、ちょっと恥ずかしい初歩的な原因が判明。移動先フォルダにすでに同じ名前のファイルが存在していたら、削除するというあたりの処理を教えてもらいました。

一応、3回トライするように書き変えてみたものがこれです。NSFileManagerについては、US AppleのCocoa Dev MLでいろいろと揉めた形跡を見つけており「NSFileManagerで埒があかない場合には、NSFileHandle経由でファイルをreadしてmove先にwriteしろ」とかいう、体育会系の回答を見つけており、そういう手段をとらずにすんで本当に助かりました(^ー^;;;

AppleScript名:ファイルの移動テスト v1.3
– Created 2015-10-26 by Takaaki Naganoya
– Modified 2015-10-26 by Shane Stanley
– Modified 2015-10-26 by Takaaki Naganoya

– ネットワークごしにコピーされたファイルの取得と移動に関するテスト

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

set inFolAlias to choose folder

set pdfList to getFilePathList(inFolAlias, “.pdf”) of me
–>  {”/Users/xxxxxxx/Desktop/XXXXXPDF/00064452.PDF”, “/Users/xxxxxxx/Desktop/XXXXXPDF/00064453.PDF”, “/Users/xxxxxxx/Desktop/XXXXXPDF/00064455.PDF”}

my moveFilesWithPOSIXstrList(pdfList, “~/Pictures/DonePDF”)

–POSIX pathのリストを指定フォルダに移動
on moveFilesWithPOSIXstrList(aFileList, toFolStr)
  set pathString to current application’s NSString’s stringWithString:toFolStr
  
set newPath to pathString’s stringByExpandingTildeInPath()
  
set defM to current application’s NSFileManager’s defaultManager
  
  
repeat with i in aFileList
    if (defM’s isReadableFileAtPath:i) as boolean = true then
      set fromPath to (current application’s |NSURL|’s fileURLWithPath:i)
      
      
set fileName to fromPath’s lastPathComponent()
      
set newPathStr to (newPath’s stringByAppendingPathComponent:fileName)
      
set toPath to (current application’s |NSURL|’s fileURLWithPath:newPathStr)
      
set hitF to false
      
      
repeat 3 times
        set {theResult, theError} to (defM’s moveItemAtURL:fromPath toURL:toPath |error|:(reference))
        
        
–試してダメだった場合
        
if (theResult as boolean) = false then
          log {“Error: Something wrong with file moving…”, (theError’s |description|() as text), toPath}
          
if (toPath’s checkResourceIsReachableAndReturnError:(missing value)) as boolean then – it already exists, so try deleting
            –いったんmove先のファイルを削除
            (
defM’s removeItemAtURL:toPath |error|:(missing value))
          end if
        else
          –moveが成功した場合
          
set hitF to true
          
exit repeat
        end if
      end repeat
      
      
if hitF = false then
        tell current application
          display dialog “Serious error occured in moving files….”
        end tell
        
return
      end if
    else
      log {“Can not get originate file”} –move元のファイルが存在していなかった場合
    end if
  end repeat
end moveFilesWithPOSIXstrList

–ASOCで指定フォルダのファイルパス一覧取得(拡張子指定つき)
on getFilePathList(aFol, aExt)
  set aPath to current application’s NSString’s stringWithString:(POSIX path of aFol)
  
set aFM to current application’s NSFileManager’s defaultManager()
  
set nameList to (aFM’s contentsOfDirectoryAtPath:aPath |error|:(missing value))
  
set anArray to current application’s NSMutableArray’s alloc()’s init()
  
  
repeat with i from 1 to nameList’s |count|()
    set j to (nameList’s objectAtIndex:(i - 1)) as text
    
if (j ends with aExt) and (j does not start with “.”) then –exclude invisible files
      set newPath to (aPath’s stringByAppendingString:j)
      (
anArray’s addObject:newPath)
    end if
  end repeat
  
  
return anArray as list
end getFilePathList

★Click Here to Open This Script 

2015/10/02 続・指定フォルダのファイルパス一覧取得(拡張子指定つき)

Cocoaの機能を利用して指定フォルダ内のファイル(POSIX path)一覧を(拡張子を指定しつつ)リストで取得するAppleScriptの、Shane Stanleyによる「もっとCocoa的なやり方でファイル一覧を条件抽出してみた」バージョンです(Thanks!!)。

OS X 10.11ではScripting Bridgeの機能が強化(バグ修正?)され、Cocoaのファイルパス(NSURL)が、AppleScriptのfileにCastされるようになりました。その機能を用いてcastするものです。OS X 10.11では、結果がfileのlistで返ってきます。

AppleScript名:ASOCで指定フォルダのファイルパス一覧取得(拡張子指定つき)v2(10.10, 10.11)
– Created 2015-10-01 by Takaaki Naganoya
– Modified 2015-10-01 by Shane Stanley–With Cocoa-Style Filtering
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set aExt to "pdf" – no dot
set aFol to choose folder
set fList to getFilePathList(aFol, aExt) of me
–>  {file "Macintosh HD:Users:me:Desktop:ASObjCExtras_scripting_guide.pdf"}

on getFilePathList(aFol, aExt)
  considering numeric strings
    if AppleScript’s version < "2.5" then
      – only need to create URL if before 10.11; otherwise bridge does it for us
      
set aFol to current application’s class "NSURL"’s fileURLWithPath:(POSIX path of aFol)
    end if
  end considering
  
set aFM to current application’s NSFileManager’s defaultManager()
  
set urlArray to aFM’s contentsOfDirectoryAtURL:aFol includingPropertiesForKeys:{} options:(current application’s NSDirectoryEnumerationSkipsHiddenFiles) |error|:(missing value)
  
set thePred to current application’s NSPredicate’s predicateWithFormat:"pathExtension == [c]%@" argumentArray:{aExt}
  
set anArray to urlArray’s filteredArrayUsingPredicate:thePred
  
return anArray as list – URLs pre-10.11, files under 10.11
end getFilePathList

★Click Here to Open This Script 

ただ、OS X 10.10.x上で実行すると、NSURLのlistが返ってくるので、OS X 10.10.x向けには、BridgePlusを併用して、このように(↓)書くことになるかと。

「OS X 10.10との互換性維持問題」については、どの程度考慮すべきかなかなか悩ましいところです。

AppleScript名:ASOCで指定フォルダのファイルパス一覧取得(拡張子指定つき)v2.1
– Created 2015-10-01 by Takaaki Naganoya
– Modified 2015-10-01 by Shane Stanley–With Cocoa-Style Filtering
– Modified 2015-10-01 by Takaaki Naganoya –Optimized for 10.10.x

use AppleScript version "2.4" –for OS X 10.10.x
use scripting additions
use framework "Foundation"
use BridgePlus : script "BridgePlus"
load framework

set aExt to "pdf" – no dot
set aFol to choose folder
set fList to getFilePathList(aFol, aExt) of me
–>  {file "Macintosh HD:Users:me:Desktop:ASObjCExtras_scripting_guide.pdf"}

on getFilePathList(aFol, aExt)
  set aFol to current application’s class "NSURL"’s fileURLWithPath:(POSIX path of aFol)
  
set aFM to current application’s NSFileManager’s defaultManager()
  
set urlArray to aFM’s contentsOfDirectoryAtURL:aFol includingPropertiesForKeys:{} options:(current application’s NSDirectoryEnumerationSkipsHiddenFiles) |error|:(missing value)
  
set thePred to current application’s NSPredicate’s predicateWithFormat:"pathExtension == [c]%@" argumentArray:{aExt}
  
set anArray to urlArray’s filteredArrayUsingPredicate:thePred
  
return (ASify from anArray) as list
end getFilePathList

★Click Here to Open This Script 

2015/10/01 指定フォルダのファイルパス一覧取得(拡張子指定つき)

Cocoaの機能を利用して指定フォルダ内のファイル(POSIX path)一覧を(拡張子を指定しつつ)リストで取得するAppleScriptです。

El Capitanにメインマシンをアップデートして、「あれ? AppleScriptからFinderにファイル一覧を取得させると遅いなー」という違和感があり、あわてずさわがずNSFileManagerで一覧取得してみたものです。もうちょっとうまい書き方もありそうですが、だいたいこんなところで。

AppleScript名:ASOCで指定フォルダのファイルパス一覧取得(拡張子指定つき)
– Created 2015-10-01 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set aExt to “.pdf”
set aFol to choose folder
set fList to getFilePathList(aFol, aExt) of me

–ASOCで指定フォルダのファイルパス一覧取得(拡張子指定つき)
on getFilePathList(aFol, aExt)
  set aPath to current application’s NSString’s stringWithString:(POSIX path of aFol)
  
set aFM to current application’s NSFileManager’s defaultManager()
  
set nameList to (aFM’s contentsOfDirectoryAtPath:aPath |error|:(missing value)) as list
  
set anArray to current application’s NSMutableArray’s alloc()’s init()
  
  
repeat with i in nameList
    set j to i as text
    
if (j ends with aExt) and (j does not start with “.”) then –exclude invisible files
      set newPath to (aPath’s stringByAppendingString:j)
      (
anArray’s addObject:newPath)
    end if
  end repeat
  
  
return anArray as list
end getFilePathList

★Click Here to Open This Script 

2015/08/06 指定の画像を別形式に変換する v3

指定の画像を別形式に変換するAppleScriptのアップデート版です。Shane Stanleyからツッコミがあって、一部(無意味な処理を削除するなどの)修正をしています。

v2で使っていた「連番の追加によるファイル名の重複回避」ルーチン「chkExistAndIncrementChildNumber(aa)」内において、

set bRes to ((tmpStr’s caseInsensitiveCompare:eStr) is not equal to (current application’s NSOrderedSame)) as boolean

の処理を行っていましたが、冷静に考えればここでこの処理を行う必然性がないので削除。その他、さまざまな場所にあった「as string」を念のために「as text」に置き換え。また、chkExistAndIncrementChildNumberの名称を少し変更しました。こうして、徐々に完成度が上がっていったものについてはライブラリに突っ込んで使い回すことになることでしょう。

AppleScript名:指定の画像を別形式に変換する v3
– Created 2015-08-05 by Takaaki Naganoya
– Modified 2015-08-06 by Shane Stanley
– 2015 Piyomaru Software

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

set targFormat to “pdf”
set aImage to choose file of type {“public.image”} with prompt (“Choose image file to convert to “ & targFormat & “.”)
set aRes to convertImageToANY(aImage, targFormat) of me
–> “/Users/me/Desktop/301b3607.pdf”
–> “/Users/me/Desktop/301b3607_1.pdf” (同一ファイルの変換を2度行った結果、子番号を付与して衝突を回避)

–指定の画像をsipsで別形式に変換する
on convertImageToANY(aImage as alias, outFormat as text)
  
  
set aExt to chkExtension(outFormat) of me
  
if aExt = false then return false
  
  
tell application “Finder”
    set bExt to name extension of aImage
  end tell
  
–指定画像と変換後の画像フォーマットが同じだった
  
set bExt to chkExtension(bExt) of me
  
if aExt = bExt then return “There is no need to convert (same format)”
  
if bExt = false then return false –出力ファイルフォーマットエラー
  
  
–変換後のファイル名として、オリジナルの拡張子を新規拡張子に付け替え
  
set bImagePosix to POSIX path of aImage
  
set bPathString to current application’s NSString’s stringWithString:bImagePosix
  
set newPath to ((bPathString’s stringByDeletingPathExtension()) as text) & “.” & aExt
  
  
–新規ファイル作成時にファイルの重複があるかチェック。存在する場合にはファイル名に子番号を付与して重複を回避する
  
set newPath to chkExistAndAddIncrementalChildNumber(newPath)
  
  
set sText to “sips -s format “ & aExt & ” “ & quoted form of POSIX path of aImage & ” –out “ & quoted form of newPath
  
  
try
    do shell script sText
  on error erM
    return false –shell scriptの実行時にエラーが発生した
  end try
  
  
return newPath
  
end convertImageToANY

–複数表記形式のファイル名拡張子のチェックおよびsipsが受付可能なものに変換
on chkExtension(aExtension)
  –acceptable file name extensions
  
set formatList to {{“jpeg”, “jpg”}, {“tiff”, “tif”}, {“png”}, {“gif”, “giff”}, {“jp2″}, {“pict”}, {“bmp”}, {“qtif”}, {“psd”}, {“sgi”}, {“tga”}, {“pdf”}}
  
set hitF to false
  
  
ignoring case
    repeat with i in formatList
      set j to contents of i
      
if aExtension is in j then
        set aExt to contents of first item of j
        
set hitF to true
        
exit repeat
      end if
    end repeat
  end ignoring
  
  
if hitF = false then
    return false –No Hit  
  else
    return aExt –Hit
  end if
  
end chkExtension

–連番の追加によるファイル名の重複回避
on chkExistAndAddIncrementalChildNumber(aa)
  set aStr to current application’s NSString’s stringWithString:aa
  
  
–ファイルパス(フルパス)からファイル名部分を取得
  
set bStr to aStr’s lastPathComponent()
  
–> “P0000_000.csv”
  
  
–ファイル名から拡張子を取得
  
set cStr to (bStr’s pathExtension()) as text
  
–> “csv”
  
  
–ファイル名から拡張子を削除
  
set dStr to (bStr’s stringByDeletingPathExtension()) as text
  
–> “P0000_000″
  
  
–ファイルパス(フルパス)から親フォルダを取得(ただし末尾はスラッシュになっていない)
  
set eStr to (aStr’s stringByDeletingLastPathComponent()) as text
  
–>  ”/Users/me/Desktop”
  
  
set aManager to current application’s NSFileManager’s defaultManager()
  
set aRes to (aManager’s fileExistsAtPath:aStr) as boolean
  
if aRes = false then return aa –重複がない場合、与えられたフルパスをそのまま返す
  
  
  
–ファイル名の重複があった場合の重複回避処理  
  
set hitF to false
  
repeat with i from 1 to 65535
    
    
set tmpPath to (eStr & “/” & dStr & “_” & (i as text) & “.” & cStr)
    
set tmpStr to (current application’s NSString’s stringWithString:tmpPath)
    
set aRes to (aManager’s fileExistsAtPath:tmpStr) as boolean
    
    
if aRes = false then
      set hitF to true
      
exit repeat
    end if
    
  end repeat
  
  
if hitF = false then return false –65,535回繰り返したがファイル名の衝突を回避できなかった、など
  
  
return tmpStr as text
  
end chkExistAndAddIncrementalChildNumber

★Click Here to Open This Script 

2015/08/05 指定の画像を別形式に変換する v2

指定の画像を別形式に変換するAppleScriptのアップデート版です(前バージョンはこちら)。

(儡晃紊離侫.ぅ詭召髻aaa.jpg→aaa.jpg.pdf」から「aaa.jpg→aaa.pdf」となるよう拡張子の付け替えを行うようにしました

∧儡晃紊離侫.ぅ詭召粘存のファイル名との衝突が発生する場合には、子番号を付与して衝突を回避するようにしました(子番号は最大で65,535)

AppleScript名:指定の画像を別形式に変換する v2
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set targFormat to “pdf”
set aImage to choose file of type {“public.image”} with prompt (“Choose image file to convert to “ & targFormat & “.”)
set aRes to convertImageToANY(aImage, targFormat) of me
–> “/Users/me/Desktop/301b3607.pdf”
–> “/Users/me/Desktop/301b3607_1.pdf” (同一ファイルの変換を2度行った結果、子番号を付与して衝突を回避)

–指定の画像をsipsで別形式に変換する
on convertImageToANY(aImage as alias, outFormat as string)
  
  
set aExt to chkExtension(outFormat) of me
  
if aExt = false then return false
  
  
tell application “Finder”
    set bExt to name extension of aImage
  end tell
  
–指定画像と変換後の画像フォーマットが同じだった
  
set bExt to chkExtension(bExt) of me
  
if aExt = bExt then return “There is no need to convert (same format)”
  
if bExt = false then return false –出力ファイルフォーマットエラー
  
  
–変換後のファイル名として、オリジナルの拡張子を新規拡張子に付け替え
  
set bImagePosix to POSIX path of aImage
  
set bPathString to current application’s NSString’s stringWithString:bImagePosix
  
set newPath to ((bPathString’s stringByDeletingPathExtension()) as text) & “.” & aExt
  
  
–新規ファイル作成時にファイルの重複があるかチェック。存在する場合にはファイル名に子番号を付与して重複を回避する
  
set newPath to chkExistAndIncrementChildNumber(newPath)
  
  
set sText to “sips -s format “ & aExt & ” “ & quoted form of POSIX path of aImage & ” –out “ & quoted form of newPath
  
  
try
    do shell script sText
  on error erM
    return false –shell scriptの実行時にエラーが発生した
  end try
  
  
return newPath
  
end convertImageToANY

–複数表記形式のファイル名拡張子のチェックおよびsipsが受付可能なものに変換
on chkExtension(aExtension)
  –acceptable file name extensions
  
set formatList to {{“jpeg”, “jpg”}, {“tiff”, “tif”}, {“png”}, {“gif”, “giff”}, {“jp2″}, {“pict”}, {“bmp”}, {“qtif”}, {“psd”}, {“sgi”}, {“tga”}, {“pdf”}}
  
set hitF to false
  
  
ignoring case
    repeat with i in formatList
      set j to contents of i
      
if aExtension is in j then
        set aExt to contents of first item of j
        
set hitF to true
        
exit repeat
      end if
    end repeat
  end ignoring
  
  
if hitF = false then
    return false –No Hit  
  else
    return aExt –Hit
  end if
  
end chkExtension

–連番の追加によるファイル名の重複回避
on chkExistAndIncrementChildNumber(aa)
  set aStr to current application’s NSString’s stringWithString:aa
  
  
–ファイルパス(フルパス)からファイル名部分を取得
  
set bStr to aStr’s lastPathComponent()
  
–> “P0000_000.csv”
  
  
–ファイル名から拡張子を取得
  
set cStr to (bStr’s pathExtension()) as string
  
–> “csv”
  
  
–ファイル名から拡張子を削除
  
set dStr to (bStr’s stringByDeletingPathExtension()) as string
  
–> “P0000_000″
  
  
–ファイルパス(フルパス)から親フォルダを取得(ただし末尾はスラッシュになっていない)
  
set eStr to (aStr’s stringByDeletingLastPathComponent()) as string
  
–>  ”/Users/me/Desktop”
  
  
set aManager to current application’s NSFileManager’s defaultManager()
  
set aRes to (aManager’s fileExistsAtPath:aStr) as boolean
  
if aRes = false then return aa
  
  
set hitF to false
  
repeat with i from 1 to 65535
    
    
set tmpPath to (eStr & “/” & dStr & “_” & (i as string) & “.” & cStr)
    
set tmpStr to (current application’s NSString’s stringWithString:tmpPath)
    
set aRes to (aManager’s fileExistsAtPath:tmpStr) as boolean
    
set bRes to ((tmpStr’s caseInsensitiveCompare:eStr) is not equal to (current application’s NSOrderedSame)) as boolean
    
    
if {aRes, bRes} = {false, true} then
      set hitF to true
      
exit repeat
    end if
    
  end repeat
  
  
if hitF = false then return false
  
  
return tmpStr as string
  
end chkExistAndIncrementChildNumber

★Click Here to Open This Script 

2015/07/23 ASOCでフォルダの連続作成1万個

ASOCでCocoaの機能を用いたフォルダ作成のテストを行いました。比較用にCocoaの機能を用いずにFinder経由で作成したものと、do shell script経由でシェルコマンドの機能を用いたものを用意して比較。

filegraph1.png

Cocoa経由で作成したものが非常に高速(Finder経由の7倍速ぐらい)ということが分かりました。ただし、テスト所要時間が実行するたびに変わり、ブレがあるのが特徴です(Finder経由で作成したときにはあまり見られない現象)。

テストはMacBook Pro Retina 2012 (Core i7 2.6GHz)、OS X 10.10.5上で実施。もちろん、HDDではなくSSDを使っていればこその速度です。

ASOCのテスト1は常識的なフォルダ作成のルーチンを作って呼び出したもの、テスト2は速度をかせぐために「連番のフォルダを作成する」という機能のかたまりを作成して、サブルーチンにはしなかったものです。ねらいどおり、若干後者の方が高速ですが・・・逆に、NSFileManager’s defaultManager() を1万回呼び出して無駄にオブジェクトを生成しても(テスト1)たいしたオーバーヘッドにならないんだなーということが体感的によく分かりました。

念のため、do shell scirpt経由でのフォルダ作成をためしてみたところ、予想外に時間がかかりました。do shell scirptコマンドによるシェルコマンド呼び出しのオーバーヘッドが大きいことが分かります(シェルコマンドが遅いのではなく、呼び出しのためのオーバーヘッドが大きい。シェル側からosascriptコマンドでAppleScriptを呼び出すと同様の現象が起こる)。

あまりにdo shell script使用バージョンが遅かったので、「mkdir -p」ではなく「mkdir」で実行してみたものの、大差はありませんでした。

Shane Stanleyが「do shell scriptコマンドなんか使うのやめようよ」(Cocoaの機能を呼び出したほうがいいぞ)と言っていた理由がよ〜くわかりました。

AppleScript名:ASOCでフォルダ作成テスト1
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

–計時用
set a1Dat to current application’s NSDate’s timeIntervalSinceReferenceDate()

repeat with i from 1 to 10000
  set aDirStr to “Desktop/test/” & (i as string)
  
set aRes to makeDirUnderHome(aDirStr) of me
end repeat

–計時用
set b1Dat to current application’s NSDate’s timeIntervalSinceReferenceDate()
set c1Dat to b1Dat - a1Dat
–> 5.814414978027 (MacBook Pro Retina 2012, Core i7 2.6GHz)

on makeDirUnderHome(dirStr)
  
  
set homeDir to current application’s NSHomeDirectory()
  
set dirPath to homeDir’s stringByAppendingPathComponent:dirStr
  
set fileManager to current application’s NSFileManager’s defaultManager()
  
  
  
–Sample with continuation mark (¬) , similar to Objective-C format
  
set aRes to fileManager’s createDirectoryAtPath:dirPath ¬
    withIntermediateDirectories:true ¬
    
attributes:(missing value) ¬
    
|error|:(reference)
  
  
–Sample without continuation mark (¬)
  
–set aRes to fileManager’s createDirectoryAtPath:dirPath withIntermediateDirectories:true attributes:(missing value) |error|:(reference)
  
  
copy aRes to {aFlag, aError}
  
return aFlag as boolean
  
end makeDirUnderHome

★Click Here to Open This Script 

AppleScript名:ASOCでフォルダ作成テスト2
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

–計時用
set a1Dat to current application’s NSDate’s timeIntervalSinceReferenceDate()

set homeDir to current application’s NSHomeDirectory()
set fileManager to current application’s NSFileManager’s defaultManager()

repeat with i from 1 to 10000
  
  
set aDirText to “Desktop/test/” & (i as string)
  
set dirPath to (homeDir’s stringByAppendingPathComponent:aDirText)
  
  
set aRes to (fileManager’s createDirectoryAtPath:dirPath withIntermediateDirectories:true attributes:(missing value) |error|:(reference))
  
end repeat

–計時用
set b1Dat to current application’s NSDate’s timeIntervalSinceReferenceDate()
set c1Dat to b1Dat - a1Dat
–> 4.124059021473 (MacBook Pro Retina 2012, Core i7 2.6GHz)

★Click Here to Open This Script 

AppleScript名:ASで(Finder経由で)フォルダ作成テスト(比較用)
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

–計時用
set a1Dat to current application’s NSDate’s timeIntervalSinceReferenceDate()

set dtPath to path to desktop
set dtPathStr to dtPath as string
set tFolStr to dtPathStr & “test:”

tell application “Finder”
  
  
tell folder dtPath
    if (exists of folder “test”) = false then
      (make new folder with properties {name:“test”})
    end if
  end tell
  
  
repeat with i from 1 to 10000
    make new folder with properties {name:(i as string)} at folder tFolStr
  end repeat
  
end tell

–計時用
set b1Dat to current application’s NSDate’s timeIntervalSinceReferenceDate()
set c1Dat to b1Dat - a1Dat
–> 37.555700004101

★Click Here to Open This Script 

AppleScript名:ASでフォルダ作成テスト(比較用2)
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

–計時用
set a1Dat to current application’s NSDate’s timeIntervalSinceReferenceDate()

set dtPath to path to desktop
set dtPathStr to dtPath as string
set tFolStr to dtPathStr & “test:”
set tFolPosix to POSIX path of tFolStr

repeat with i from 1 to 10000
  set tPath to tFolPosix & (i as string)
  
do shell script “mkdir -p “ & tPath
end repeat

–計時用
set b1Dat to current application’s NSDate’s timeIntervalSinceReferenceDate()
set c1Dat to b1Dat - a1Dat
–> 272.857131958008

★Click Here to Open This Script 

AppleScript名:ASでフォルダ作成テスト(比較用3)
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

–計時用
set a1Dat to current application’s NSDate’s timeIntervalSinceReferenceDate()

set dtPath to path to desktop
set dtPathStr to dtPath as string
set tFolStr to dtPathStr & “test:”
set tFolPosix to POSIX path of tFolStr

do shell script “mkdir -p “ & tFolPosix

repeat with i from 1 to 10000
  set tPath to tFolPosix & (i as string)
  
do shell script “mkdir “ & tPath
end repeat

–計時用
set b1Dat to current application’s NSDate’s timeIntervalSinceReferenceDate()
set c1Dat to b1Dat - a1Dat
–> 283.687083005905

★Click Here to Open This Script 

2015/07/13 ASOCでDict書き込み_3(Bridge Plus)

完全に趣味の内容のAppleScriptを、Shane Stanleyがアップデートして送ってくれました(汗)。趣味のScriptというのは、完全に作り捨てに近いというか、あまり後先考えずに作ってしまうことが多いですが・・・

書き換えポイントは、

 (1)ASObjcExtras.frameworkではなくBridgePlusライブラリを使用
 (2)NSFileManagerでディレクトリを作成
 (3)パスの組み立て時に「URLByAppendingPathComponent:」を使うことにより、フォルダを示すパスの末尾に「:」がついていなかったとか、「::」といった誤った表記を行ってしまった場合に備えている

とのこと。do shell scriptなんてダサいぜ、的なShaneのご意見もありましたが、使って簡潔になる箇所(dateコマンドとか)は使ってもいいんじゃないかと。いえ、意見はとってもわかるんですけど、「使えるものはなんでも使う派」なんで(^ー^;;

OS X 10.11ではaliasやfileとNSURLが正確にBridgeされるようになるので、パスの取り扱いについては機能向上(簡潔な記述)が期待ができそうです。”NSURL”を書くと予約語とぶつかる、とかいうダサダサな仕様が直ることは10.11に期待したいです。

しかし、英語圏のShaneから正確な日本語データの入ったプログラムが送られてくると(リスト内のリンクをクリックすればScript Editorに転送されるのはわかっているとはいえ)、かなりビビります(^ー^;;

AppleScript名:ASOCでDict書き込み_3(Bridge Plus)
use AppleScript version “2.4″
use framework “Foundation”
use scripting additions
use script “BridgePlus” – instead of ASOBjCExtras framework

load framework – BridgePlus command to load

set a1List to {“msName”, “sortieTimes”}
set b1List to {{“近 装甲強化型ジム 獲得済 COST: 200″, 66}, {“遠 ジム・キャノン 獲得済 COST: 160″, 43}, {“近 ザクII(F2) 獲得済 COST: 160″, 42}, {“近 ジム・コマンド 獲得済 COST: 200″, 32}, {“近 ジム(WD隊) 獲得済 COST: 160″, 28}, {“近 陸戦型ガンダム 獲得済 COST: 220″, 24}, {“近 ジム改 獲得済 COST: 240″, 22}, {“遠 ガンタンク 獲得済 COST: 200″, 22}, {“格 ジム(指揮官機) 獲得済 COST: 160″, 20}, {“近 ジム 獲得済 COST: 120″, 19}, {“遠 量産型ガンタンク 獲得済 COST: 160″, 14}, {“格 陸戦型ジム 獲得済 COST: 120″, 12}, {“格 ガンダム 獲得済 COST: 280″, 11}, {“近 ジム・トレーナー 獲得済 COST: 120″, 9}, {“射 ジム・スナイパーII(WD隊) 獲得済 COST: 220″, 9}, {“射 陸戦型ガンダム(ジム頭) 獲得済 COST: 200″, 7}, {“格 ガンダムEz8 獲得済 COST: 240″, 6}, {“近 ジム・寒冷地仕様 獲得済 COST: 200″, 6}, {“狙 ジム・スナイパーカスタム 獲得済 COST: 200″, 6}, {“格 ジム・ストライカー 獲得済 COST: 180″, 4}, {“格 ガンキャノン重装型 獲得済 COST: 160″, 3}, {“近 アクア・ジム 獲得済 COST: 160″, 2}, {“射 ガンキャノン 獲得済 COST: 200″, 2}, {“近 ジム・コマンドライトアーマー 獲得済 COST: 160″, 1}, {“格 ボールK型 獲得済 COST: 120″, 0}, {“格 B.D.2号機 獲得済 COST: 260″, 0}, {“格 プロトタイプガンダム 獲得済 COST: 280″, 0}, {“近 パワード・ジム 獲得済 COST: 240″, 0}, {“射 デザート・ジム 獲得済 COST: 160″, 0}, {“遠 量産型ガンキャノン 獲得済 COST: 200″, 0}}

– BridgePlus uses SMSForder instead of SMSFord in ASOBjCExtras, but method is the same
set aArray to current application’s SMSForder’s subarraysIn:b1List asDictionariesUsingLabels:a1List |error|:(missing value)

set cRec to {msList:aArray, sortieDate:date string of (current date)}

set aName to “efsf.plist”
saveRecordToFolAsPlist(cRec, “戦場の絆”, aName) of me

on saveRecordToFolAsPlist(theRecord, folName, aName)
  
  
set myAppSupDir to POSIX path of (path to application support from user domain)
  
set folderURL to (current application’s class “NSURL”’s fileURLWithPath:myAppSupDir)’s URLByAppendingPathComponent:folName
  
  
–do shell script(mkdir -p)のかわりに、指定ディレクトリまで作成
  
current application’s NSFileManager’s defaultManager()’s createDirectoryAtURL:folderURL withIntermediateDirectories:true attributes:(missing value) |error|:(missing value)
  
  
set theDict to current application’s NSDictionary’s dictionaryWithDictionary:theRecord
  
set aRes to theDict’s writeToURL:(folderURL’s URLByAppendingPathComponent:aName) atomically:true
  
  
return aRes as boolean
  
end saveRecordToFolAsPlist

★Click Here to Open This Script 

2015/04/12 指定のPOSIX pathがFolder (Directory)かどうかを返す。実在しないpathならerrorを返す

This ASOC script detect the specified path is whether directory or not. Detect directory is important with NSPathControl. So, I wrote this.

特定のパスがディレクトリ(フォルダ)かどうかを判定するASOCのscriptです。

ディレクトリ検出は、NSPathControlをASOCアプリで使うときに、ドラッグ&ドロップされたfile pathがフォルダの時には処理し、フォルダでなければ処理しないといった条件分岐を書くために作りました。

AppleScript名:指定のPOSIX pathがFolder (Directory)かどうかを返す。実在しないpathならerrorを返す
– Created 2015-04-12 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set aa to POSIX path of (choose folder)
set ab to isDir(aa)
–> true

set bb to POSIX path of (choose file)
set bc to isDir(bb)
–> false

–指定のPOSIX pathがFolder (Directory)かどうかを返す。実在しないpathならerrorを返す。
on isDir(aa)
  set {aRes, dirF} to current application’s NSFileManager’s defaultManager()’s fileExistsAtPath:aa isDirectory:(reference)
  
set aRes to aRes as boolean
  
set dirF to dirF as boolean
  
  
if aRes = true then
    return dirF
  else
    error
  end if
end isDir

★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/04/01 DiskSpaceを求める

These scripts get free space of storage. Finder’s “free space” command returns specified disk’s free space by bytes. Cocoa’s NSFileSystemFreeSize return percentage of used space. I like the former. But ASOC in Xcode, sometimes we can not use Finder command. So I checked the cocoa way.

通常のAppleScriptとASOCのscriptでディスクの空きを求めるものです。Finderの「free space」コマンドは指定ディスクの空き容量をバイト単位で返します。CocoaのNSFileSystemFreeSizeは使用ずみ容量をパーセントで返します。どちらかといえば、前者の方が好みですが・・・ASOC in XcodeではFinderのコマンドが通じないケースが出てくるため、Cocoa風のやり方を調べておきました。

AppleScript名:Pure ASでDiskSpace(GBytes)を求める
– Created 2015-04-01 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions

tell application “Finder”
  set aFree to (free space of startup disk) / 1.0E+9
end tell
–>  102.829194753

★Click Here to Open This Script 

AppleScript名:CocoaでDiskSpace(%)を求める
– Created 2015-04-01 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set aPath to current application’s NSString’s stringWithString:“/”
set fileAttr to current application’s NSFileManager’s defaultManager()’s attributesOfFileSystemForPath:aPath |error|:(missing value)
set fRes to (fileAttr’s objectForKey:(current application’s NSFileSystemFreeSize)) as string

set aDecNum to current application’s NSDecimalNumber’s decimalNumberWithString:fRes
set aFreeNum to aDecNum’s decimalNumberByDividingBy:(current application’s NSDecimalNumber’s decimalNumberWithString:“1000000000″) –”G” Bytes for Storage
set bFreeNum to aFreeNum as real
–> 84.058387756348

★Click Here to Open This Script 

2015/03/23 連番の追加によるファイル名の重複回避

This is a typical file name collision checking & generating child number process AppleScriptObjC script. The child number’s max is 65535.

Pure AppleScript version is here.

ファイル名の重複チェックと、重複時の回避のために子番号(1〜65535)を付加するAppleScriptObjCのScriptです。

純粋なAppleScriptだけで書いた(Cocoaの機能を利用していない)ものがこちらです(完全に同じ機能ではないものの、同様の機能を実現)。

AppleScript名:連番の追加によるファイル名の重複回避
– Created 2015-03-23 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set aa to “/Users/me/Desktop/P0000_000.csv”

set ab to chkExistAndIncrementChildNumber(aa)
–>  ”/Users/me/Desktop/P0000_000_1.csv” –Case: there is file name conflict
–>  ”/Users/me/Desktop/P0000_000.csv”–Case: there is No file name conflict

on chkExistAndIncrementChildNumber(aa)
  set aStr to current application’s NSString’s stringWithString:aa
  
  
–ファイルパス(フルパス)からファイル名部分を取得
  
set bStr to aStr’s lastPathComponent()
  
–> “P0000_000.csv”
  
  
–ファイル名から拡張子を取得
  
set cStr to (bStr’s pathExtension()) as string
  
–> “csv”
  
  
–ファイル名から拡張子を削除
  
set dStr to (bStr’s stringByDeletingPathExtension()) as string
  
–> “P0000_000″
  
  
–ファイルパス(フルパス)から親フォルダを取得(ただし末尾はスラッシュになっていない)
  
set eStr to (aStr’s stringByDeletingLastPathComponent()) as string
  
–>  ”/Users/me/Desktop”
  
  
set aManager to current application’s NSFileManager’s defaultManager()
  
set aRes to (aManager’s fileExistsAtPath:aStr) as boolean
  
if aRes = false then return aa
  
  
set hitF to false
  
repeat with i from 1 to 65535
    
    
set tmpPath to (eStr & “/” & dStr & “_” & (i as string) & “.” & cStr)
    
set tmpStr to (current application’s NSString’s stringWithString:tmpPath)
    
set aRes to (aManager’s fileExistsAtPath:tmpStr) as boolean
    
set bRes to ((tmpStr’s caseInsensitiveCompare:eStr) is not equal to (current application’s NSOrderedSame)) as boolean
    
    
if {aRes, bRes} = {false, true} then
      set hitF to true
      
exit repeat
    end if
    
  end repeat
  
  
if hitF = false then return false
  
  
return tmpStr as string
  
end chkExistAndIncrementChildNumber

★Click Here to Open This Script 

2015/03/06 ワイルドカードでSafariのダウンロードフォルダ中のファイルを抽出

This AppleScript gets pattern-matched file names in Safari’s Download folder.

Safariのダウンロードフォルダ中のファイルから、与えられたパターンに該当するファイル名のリストを取得するAppleScriptです。

(2015/8/10更新)チルダ付きのパスをechoコマンドで展開していたので、ASOC版のルーチンに差し替えました。

AppleScript名:ワイルドカードでSafariのダウンロードフォルダ中のファイルを抽出 v2
– Created 2015-03-06 by Takaaki Naganoya
– Created 2015-08-10 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

–Get Safari Download Folder Path
set downloadFolder to POSIX path of getSafariDownloadFolder()

–Make Filtering Predicates with WIldcard
set matchPattern to current application’s NSString’s stringWithString:“*.zip” –can use “*” , “?”
set aPredicate to current application’s NSPredicate’s predicateWithFormat_(“SELF like %@”, matchPattern)

–Get every file name in Safari Download Folder
set aFM to current application’s NSFileManager’s defaultManager()
set aConArray to aFM’s contentsOfDirectoryAtPath:downloadFolder |error|:(missing value)

–Filtering with Predicates
set aResArray to aConArray’s filteredArrayUsingPredicate:aPredicate
set aResList to aResArray as list
–>  {”33_fusagamepad_0.3.zip”, “expressmaci.zip”, “filer6.6.zip”, “Glyphs2.1.1-768.zip”, “LinCastor.zip”, “recordpadmaci.zip”, “TessOCR-1.08.zip”, “wavepadmaci.zip”}

–Safariのダウンロードフォルダーを取得する–Updated
on getSafariDownloadFolder()
  set theID to id of application “Safari” –> “com.apple.Safari”
  
set storedDefaults to (current application’s NSUserDefaults’s standardUserDefaults()’s persistentDomainForName:theID)
  
set downloadFolder to storedDefaults’s valueForKeyPath:“DownloadsPath.stringByExpandingTildeInPath”
  
return downloadFolder as «class furl»
end getSafariDownloadFolder

★Click Here to Open This Script 

2015/03/05 特定フォルダの更新通知を受け、特定ファイルが存在しているかを確認

I made an AppleScript program to download data file by using Safari. And the program detect the downloaded file then rename it and move it to another folder.

The program use OS built-in Folder Action Script mechanism (well known). Main program and Folder Action Script has a simple sync way using a plist to share the renaming rule and the state of renaming (finished or not). So, programs have to access the plist very frequently.

But sometimes Finder crashed. So, the process has been stopped.

I had to study another way to detect downloaded file. Notification seems very smart. Except FSEvents have to use blocks construction which can not be written in AppleScriptObjC.

This ASOC on Xcode project is originally written by StefanK@MacScripters. I changed a little (ARC etc.).

——-

Safariを使ってデータファイルをダウンロードするAppleScriptを作成。同プログラムは、Folder Action Scriptを使ってダウンロードされたファイルを検出し、リネームしたうえで別フォルダに移動するようになっていました。

しかし、ときどきFinderがクラッシュし(Yosemiteなのに搭載メモリーが4GBと少ないことが原因か?)、そのためにダウンロード検出を行えずに処理が止まることがあり、ファイルのダウンロード検出を行う別の仕組みを検討する必要に迫られました(ASOCでWebブラウザを作ることも検討したものの、あまり問題の解決にならず、、、)。

オリジナルのASOC on Xcodeのプログラムは、MacScriptersのStefanK氏が作ったものです。ARCに対応させるためにObjective-Cのプログラムを少しだけ書き換えました。

ご注意:本Script内ではSafariのダウンロードフォルダの設定ファイルから実際のパスを求めるさいにechoコマンドによるチルダの展開を行っていますが、ASOCによる展開に差し替えてご利用ください。

→ Download Xcode Project (33KB)

AppleScript名:AppDelegate

– AppDelegate.applescript
– dirWatcher

– http://macscripter.net/viewtopic.php?pid=161125
– Created by StefanK on 2013-03-11 02:05:32 am

– Changed by Takaaki Naganoya on 2015-03-05
– Copyright (c) 2015年 Takaaki Naganoya. All rights reserved.

script AppDelegate
  
  
property parent : class “NSObject”
  
  
property DirectoryWatcher : class “FSEDirectoryWatcher”
  
  
property statusImage1 : missing value – image view 1
  
property statusImage2 : missing value – image view 2
  
  
property watchFileName : “” –File Name to detect the existence
  
  
  
on applicationWillFinishLaunching:aNotification
    
    
set my watchFileName to “logfile0.log”
    
    
–Get Safari Download Folder Path
    
set preferencesPath to POSIX path of (path to preferences)
    
set bundleId to bundle identifier of (info for (path to application “Safari”))
    
set safariPrefsFile to preferencesPath & bundleId & “.plist”
    
tell application “System Events” to set folderName to get value of property list item “DownloadsPath” of property list file safariPrefsFile
    
tell current application
      set downloadFolder to (do shell script “echo “ & folderName)
    end tell
    
    
    
–Set Watch Folder Path
    
set hotFolder to current application’s NSString’s stringWithString:downloadFolder
    
directoryDidChange_(hotFolder)
    
set watcher to DirectoryWatcher’s directoryWatcherWithPath:hotFolder delegate:me
    
    
watcher’s start()
    
  end applicationWillFinishLaunching:
  
  
  
on directoryDidChange:directoryPath
    
    
set filePath to directoryPath’s stringByAppendingPathComponent:(my watchFileName)
    
set fileExists to (current application’s NSFileManager’s defaultManager()’s fileExistsAtPath:filePath) as boolean
    
    
log {“fileExists”, fileExists}
    
  end directoryDidChange:
  
  
end script

★Click Here to Open This Script