[Illustrator][AppleScript][Ruby]Illustratorを開かずに配置ファイルを収集するの続編です。
2017/2/18追記
下記の環境で動作確認しました。
- OS X El Capitan(10.11.6)
- CC 2015.3
本編
上記エントリで公開したAppleScriptは結構たくさんの方から評価をしてもらっているようです。
Twitterなり勉強会なりで「使ってます!」「助かってます!」というお言葉も頂戴しており、嬉しい限りです。
ただ、いろいろな不具合も起きてしまっているようで、「早く修正してー」と言われてしまうこともしばしばありました。
直そう直そうと思ってはいたものの、仕事やレノくんもふもふするのが忙しくて延び延びになってしまっていました。
フィードバックしていただいた方々、申し訳ないです。
ということで、今日頑張って修正しました!
Rubyのコードを大幅に書き換えて、AppleScriptのほうもいろいろリファクタリングしました。
この数ヶ月、暇を見つけては会社でいろんなスクリプト(Ruby含む)を書きまくっていたので、その辺の経験と知識を反映したつもりです。
修正した箇所は
●バージョン判別をRuby内で行うように修正(Adobe Illustrator CS2という文字があるかどうか)
●XMPだけを取得するように修正
●XMPのフルパスが存在しないときは次にIllustratorの同階層の画像を複製できるか試すように修正
●Windows環境で作成されたファイルの配置画像収集も可能なように修正
●同じような処理を行うサブルーチンを一つに統合した
●AppleScriptにRubyをバンドルさせるのをやめた
まず重いIllustratorファイル対応のためXMPだけを変数に代入して、その中で文字列操作することにしました。
ただしXMPの終了タグを検知して例外を発生させているためCS2以降のファイルでしか効果はでません。
次に不安定だったAppleScriptでのIllustratorのバージョン判定をやめて、Rubyで処理することにしました。
判定方法はXMPの中に「Adobe Illustrator CS2」という文字があったら例外を発生させて処理を中止するというものです。
バージョンダウンしたファイルだとうまく動かないかもしれませんが、バージョンダウンしないよね?
次にXMPから取得したフルパスが存在しないときはIllustratorファイルと同階層にあるファイルを複製するようにして、それでも見つからないものだけエラーログに書き出すようにしました。
次にざっくりとではありますがWindows環境で作成されたIllustratorファイルからも配置画像を複製できるようにしました。
Windowsのフルパスの中にバックスラッシュが入っていることを利用しているのでWindowsのバージョンや環境によってはうまく動かないと思います。
おまけ程度の機能追加だと思ってもらえれば。
次にサブルーチンを整理しました。
最後にRubyのバンドルをやめました。
ついでにAppleScriptの名前も変えました。
今回の修正でだいぶ完成に近づいたと思います。
不具合などあればコメントなどでお知らせください。
ご自分で直せるのであれば、どこを直したか教えていただけるとうれしいです。
以下のコードでは10.9には対応できていません、。
更新が面倒になったのでコードを読みたい方はダウンロードして読んでください。
Ruby
#! ruby -Ku require 'CGI' require 'kconv' temp = "" linkFilePath = "" ; #リンクファイルのパスの入れ物 #XMP情報を抽出して変数に代入 def xmpRead(fileObj, temp) begin while line = fileObj.gets line = CGI.unescapeHTML(line)#HTMLエスケープされてるのでアンエスケープ line = line.toutf8 #XMP終了時に例外を発生させる if /^<\/x:xmpmeta>/ =~ line then raise "loop stop" #raiseで例外を発生できる end if temp == "" temp = line else temp = temp + line end end rescue return temp #tempを返す end end def illustratorPackage(temp, linkFilePath) if /Adobe Illustrator CS2/ =~ temp raise "before CS2" end linkFilePath = temp.scan(/^\s+?(.+?)<\/stRef:filePath>/) if linkFilePath == [] linkFilePath = "nil" end return linkFilePath #linkFilePathを返す rescue end temp = xmpRead(ARGF, temp) result = illustratorPackage(temp, linkFilePath) puts result
AppleScript
on open thisList tell application "Finder" --Rubyのバージョンチェック if exists ((home as text) & ".bash_profile") then set ruby_version to do shell script "source ~/.bash_profile; ruby -e 'print \"ERROR\" if RUBY_VERSION <= \"1.8.1\"'" else set ruby_version to do shell script "ruby -e 'print \"ERROR\" if RUBY_VERSION <= \"1.8.1\"'" end if if ruby_version is "ERROR" then display dialog "このスクリプトはRubyバージョンが1.8.2以上で動作します" error number -128 end if --変数初期化 set dPath to desktop as text --デスクトップのパス取得 set noExtractFileList to "" --エラーが出たリンクファイルのパスを入れる箱 set textFile to dPath & "収集できなかったリンクファイル.txt" --ログ書き出し 用のテキストファイルの名前 set errorFileLog to "" --エラーが出たファイルのパスを入れる箱 set skipFile to 0 --CS2以下のファイルのカウント用 --Rubyのファイルを取得 set my_script_name to "IllustratorPackage.rb" set my_script_folder to parent of (path to me) as Unicode text set my_script to my_script_folder & my_script_name set my_script to (quoted form of POSIX path of my_script) --ここからメイン処理 repeat with k in thisList set input_file to (quoted form of POSIX path of contents of k) as Unicode text --Unicode textに変換しないとダメ if exists ((home as text) & ".bash_profile") then do shell script "source ~/.bash_profile; ruby " & my_script & " " & input_file --Rubyで処理して戻り値を取得 else do shell script "ruby " & my_script & " " & input_file --Rubyで処理して戻り値を取得 end if set outputList to result --変数に代入 --Rubyの戻り値がnilじゃなかったら(CS3以上でリンクファイルがあれば) if outputList is not "nil" then set linkFileList to my serchSplit(outputList, ASCII character (13)) --リストにする --デスクトップにフォルダを作成しリンクファイルをコピーする処理へ set resultList to my LinkFilePackage(linkFileList, noExtractFileList, k) duplicate k to item 1 of resultList --デスクトップのbackFolに複製する if (item 2 of resultList) is not "" then set errorFilePath to k as string set errorFile to last item of (my serchSplit(errorFilePath, ":")) set errorFileLog to errorFileLog & "★" & errorFile & "で収集できなかったリンクファイル" & return & (item 2 of resultList) & return end if delay (0.5) --同名フォルダ作成のエラーを回避するため1秒待つ else if outputList is "nil" then --2012.09.24追記--リンクファイルなしも収集するように変更 set linkFileList to my serchSplit(outputList, ASCII character (13)) --リストにする set resultList to my LinkFilePackage(linkFileList, noExtractFileList, k) duplicate k to item 1 of resultList delay (0.5) else set skipFile to skipFile + 1 end if end repeat --エラーログの書き出し if errorFileLog is not "" then try set OutPutText to open for access textFile with write permission set eof OutPutText to 0 write "ここに書き出されたファイルは収集できませんでした。Illsutratorデータのリンク情報が正しくない可能性があります。Illustratorデータを再保存した後、再度スクリプトを使用してください。" & return & return to OutPutText write errorFileLog to OutPutText close access OutPutText on error errMsg display dialog errMsg close access OutPutText end try end if end tell if ((count thisList) - skipFile) > 0 then display dialog ((count thisList) as string) & "ファイル中の" & (((count thisList) - skipFile) as string) & "ファイルを収集しました" else display dialog "収集されませんでした" end if end open --デスクトップにフォルダを作成しリンクファイルをコピーする処理 to LinkFilePackage(linkFileList, noExtractFileList, k) tell application "Finder" --バックアップファイルのコピー用にデスクトップに現在時刻名のフォルダを作成する set dPath to desktop as text --デスクトップのパス取得 set folName to (do shell script "date '+%Y-%m-%d %H-%M-%S'") --現在時刻取得 set backFol to make new folder at dPath with properties {name:folName} --デスクトップにフォルダ作成 set label index of backFol to 2 --ラベルを付ける repeat with i from 1 to count linkFileList try set linkFilePath to (item i of linkFileList) as POSIX file --as POSIX fileで:区切りのパスに戻せる set linkFilePath to file linkFilePath --file 〜ってしないとダメ(ファイル参照させないとダメ) duplicate linkFilePath to backFol with replacing --デスクトップのbackFolに複製する(同名ファイルは上書き) on error --複製できなかったファイルの処理(Illustratorファイルと同階層のファイルを複製) --Windowsで作成されたデータもざっくり判別(パスの中に\があるかどうかで判別) if "\\" is in (item i of linkFileList) then set errorLinkName to last item of (my serchSplit((item i of linkFileList), "\\")) --ファイル名をサブルーチンで取得 else set errorLinkName to last item of (my serchSplit(linkFilePath as Unicode text, ":")) --ファイル名をサブルーチンで取得 end if --同一階層からリンクファイルをコピーする try set illFileFol to (container of k) as Unicode text --illustratorファイルの内包されているフォルダを取得 set linkFilePath2 to file (illFileFol & errorLinkName) as Unicode text --file 〜ってしないとダメ(ファイル参照させないとダメ) duplicate linkFilePath2 to backFol with replacing --デスクトップのbackFolに複製する(同名ファイルは上書き) on error --同階層からもコピーできなければエラーログに代入する set noExtractFileList to noExtractFileList & (errorLinkName as string) & return end try end try end repeat return {backFol, noExtractFileList} --メインルーチンにListで戻す end tell end LinkFilePackage --分割サブルーチン to serchSplit(targetStr, splitStr) set str to targetStr as Unicode text set OriginalDelimiters to AppleScript's text item delimiters set AppleScript's text item delimiters to splitStr set itemsList to text items of str set AppleScript's text item delimiters to OriginalDelimiters --itemsListにリストで代入されているからあとはご自由に return itemsList end serchSplit
ダウンロードはこちら。