« [applescript] ExifToolインストール(ちょっと修正) | トップページ | [exiftool] exiftoolのhtmlDumpの内容をHTMLで保存する(画像系専用) »

[exiftool] exiftoolで取得したメタデータをHTML表示(少し修正)


【スクリプトエディタで開く】|

#!/usr/bin/env osascript
----+----1----+----2----+-----3----+----4----+----5----+----6----+----7
#
(* HTMLの保存先のデフォルトは再起動時に削除されるディレクトリですので
生成されたファイルを保存したい場合は別途保存してください
exiftoolのインストールはこちらをどうぞ
https://quicktimer.cocolog-nifty.com/icefloe/2024/01/post-e7e51d.html
*)
# com.cocolog-nifty.quicktimer.icefloe
----+----1----+----2----+-----3----+----4----+----5----+----6----+----7
use AppleScript version "2.8"
use framework "Foundation"
use framework "AppKit"
use scripting additions

property refMe : a reference to current application
set appFileManager to refMe's NSFileManager's defaultManager()

########################################
### 設定項目
### exiftoolへのパス
########################################
set strExifPath to "~/bin/exiftool/exiftool" as text

#
set ocidExifPathStr to refMe's NSString's stringWithString:(strExifPath)
set ocidExifPath to ocidExifPathStr's stringByStandardizingPath()
set ocidExifPathURL to (refMe's NSURL's alloc()'s initFileURLWithPath:(ocidExifPath) isDirectory:false)
set strExifPath to ocidExifPathURL's |path| as text

########################################
####出力先(再起動時に削除されます)
set ocidTemporaryDirPathURL to appFileManager's temporaryDirectory
set ocidVarFoldersDirURL to ocidTemporaryDirPathURL's URLByDeletingLastPathComponent()
set ocidTemporaryItemsPathURL to ocidVarFoldersDirURL's URLByAppendingPathComponent:"TemporaryItems"
##フォルダを作る
set appFileManager to refMe's NSFileManager's defaultManager()
set ocidAttrDict to refMe's NSMutableDictionary's alloc()'s initWithCapacity:0
# 777-->511 755-->493 700-->448 766-->502
ocidAttrDict's setValue:(448) forKey:(refMe's NSFilePosixPermissions)
set listDone to appFileManager's createDirectoryAtURL:(ocidTemporaryItemsPathURL) withIntermediateDirectories:(true) attributes:(ocidAttrDict) |error|:(reference)
set aliasTemporaryItems to (ocidTemporaryItemsPathURL's absoluteURL()) as alias
########################################
#######ファイル選択
#####ダイアログを前面に
tell current application
  set strName to name as text
end tell
####スクリプトメニューから実行したら
if strName is "osascript" then
  tell application "Finder" to activate
else
  tell current application to activate
end if
##
set appFileManager to refMe's NSFileManager's defaultManager()
set ocidURLsArray to (appFileManager's URLsForDirectory:(refMe's NSDesktopDirectory) inDomains:(refMe's NSUserDomainMask))
set ocidDesktopDirPathURL to ocidURLsArray's firstObject()
set aliasDefaultLocation to (ocidDesktopDirPathURL's absoluteURL()) as alias
set listUTI to {"public.data"}
set strPromptText to "ファイルを選んでください" as text
set strMesText to "ファイルを選んでください" as text
set aliasFilePath to (choose file strMesText with prompt strPromptText default location (aliasDefaultLocation) of type listUTI with invisibles without multiple selections allowed and showing package contents) as alias
####入力ファイル関連
set strFilePath to POSIX path of aliasFilePath as text
###NSストリングに
set ocidFilePath to refMe's NSString's stringWithString:(strFilePath)
###NSURLに
set ocidFilePathURL to refMe's NSURL's fileURLWithPath:(ocidFilePath)
##ファイル名取得
set strFileName to (ocidFilePathURL's lastPathComponent) as text
##コンテナ
set ocidContainerPathURL to ocidFilePathURL's URLByDeletingLastPathComponent()
set aliasContainerDirPath to (ocidContainerPathURL's absoluteURL()) as alias

########################################
######出力ファイル
##ファイル名
set strFileName to (strFileName & ".html") as text
set aliasSaveFilePath to (choose file name with prompt "htmlのファイル名を付けてください" default name strFileName default location aliasTemporaryItems) as «class furl»
set strSaveFilePath to (POSIX path of aliasSaveFilePath) as text
###NSストリングに
set ocidSaveFilePath to refMe's NSString's stringWithString:(strSaveFilePath)
###NSURLに
set ocidSaveFilePathURL to refMe's NSURL's fileURLWithPath:(ocidSaveFilePath)
##拡張子
set strFileExtension to (ocidSaveFilePathURL's pathExtension) as text
###拡張子つけ忘れ対策
if strFileExtension is not "html" then
  set strSaveFilePath to (POSIX path of aliasSaveFilePath & ".html") as text
end if

########################################
###【1】データ取得 JSON出力
try
  set theCommandText to ("\"" & strExifPath & "\" -json \"" & strFilePath & "\"") as text
  set strResponseJosn to (do shell script theCommandText) as text
on error
return "たぶんexiftoolの非対応のファイルタイプです"
end try
###【2】NSStringにテキストに格納して
set ocidReadDataJson to refMe's NSString's stringWithString:strResponseJosn
###【3】NSConcreteMutableDataに変換
set ocidReadDataUTF to ocidReadDataJson's dataUsingEncoding:(refMe's NSUTF8StringEncoding)
###【4】NSInlineDataデータ初期化
set ocidReadData to (refMe's NSData's alloc()'s initWithData:(ocidReadDataUTF))
###【5】NSJSONSerialization
set listJSONSerialization to (refMe's NSJSONSerialization's JSONObjectWithData:ocidReadData options:0 |error|:(reference))
set ocidJsonData to (item 1 of listJSONSerialization)
-->(*__NSSingleObjectArrayI*)
####解説
(*
exiftoolの書き出すJSONはrootがArray構造から始まっているので
PlistにするにはDictに変換なりする必要がある
幸い『[{}]』といったシングルArray構造なので
Arrayから最初のOBJECTを取り出せばDICTレコード構造になる
*)
set ocidJsonDict to (ocidJsonData's firstObject())
-->(*__NSDictionaryI*)
###【6】レコードをNSDictionaryとして格納
set ocidJsonDict to (refMe's NSDictionary's alloc()'s initWithDictionary:ocidJsonDict)
###【7】NSPropertyListSerialization's
set ocidFromat to (refMe's NSPropertyListXMLFormat_v1_0)
set listPlistData to refMe's NSPropertyListSerialization's dataWithPropertyList:(ocidJsonDict) format:(ocidFromat) options:0 |error|:(reference)
set ocidPlistData to item 1 of listPlistData

###保存先
set ocidSaveDirPathURL to ocidSaveFilePathURL's URLByDeletingLastPathComponent()
set aliasSaveDirPath to ocidSaveDirPathURL's absoluteURL() as alias

set strPlistFileName to (strFileName & ".plist") as text
set ocidPlistFilePathURL to ocidTemporaryItemsPathURL's URLByAppendingPathComponent:(strPlistFileName)
###【8】保存
set ocidOption to (refMe's NSDataWritingAtomic)
set boolWritetoUrlArray to ocidPlistData's writeToURL:(ocidPlistFilePathURL) options:(ocidOption) |error|:(reference)


########################################
#######HTML 基本構造
###スタイル
set strStylle to "<style>#bordertable {padding: 10px;width: 100%;margin: 0;border-collapse: collapse;border-spacing: 0;word-wrap: break-word;} #bordertable table { width: 580px;margin: 0px;padding: 0px;border: 0px;border-spacing:0px;border-collapse: collapse;} #bordertable caption { font-weight: 900;} #bordertable thead { font-weight: 600;border-spacing:0px;} #bordertable td {border: solid 1px #666666;padding: 3px;margin: 0px;word-wrap: break-word;border-spacing:0px;} #bordertable tr {border: solid 1px #666666;padding: 0px;margin: 0px;border-spacing:0px;} #bordertable th {border: solid 1px #666666;padding: 0px;margin: 0px;border-spacing:0px;}</style>"
###ヘッダー部
set strHead to "<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"utf-8\"><title>[Exif]" & strFileName & "</title>" & strStylle & "</head><body>"
###ボディ
set strBody to ""
###最後
set strHtmlEndBody to "</body></html>"
###HTML書き出し用のテキスト初期化
set ocidHTMLString to refMe's NSMutableString's alloc()'s initWithCapacity:0
####
(ocidHTMLString's appendString:strHead)
###テーブル構造
set strTableHeader to "<div id=\"bordertable\"><table><caption>Exif情報:" & strFileName & "</caption><thead title=\"表の項目について\"><tr><th title=\"項目の番号が最初\" style=\"width: 36px;\" scope=\"row\" >項番</th><th title=\"キーの名前が2番目\" scope=\"col\">キーの名前</th><th title=\"キーの値は3番目になっています\" scope=\"col\">キーの値</th></thead><tbody title=\"表の始まりです\">" as text
(ocidHTMLString's appendString:strTableHeader)

####JSONの全てのキーを取得して
set ocidAllKeys to ocidJsonDict's allKeys()
set numLineNO to 0
####キーの種類だけ繰り返し
repeat with objKey in ocidAllKeys
  set strKey to objKey as text
  ####キーの値を取り出し
  set ocidValue to (ocidJsonDict's objectForKey:(strKey))
  set strClass to className() of ocidValue as text
  if strClass contains "Array" then
    set strArray to (ocidValue's componentsJoinedByString:(","))
    set strKey to doHtmlEntitiesEnc(strKey)
    set strValue to doHtmlEntitiesEnc(strArray)
  else
    set strKey to doHtmlEntitiesEnc(strKey)
    set strValue to doHtmlEntitiesEnc(ocidValue)
  end if
  ####内容によって表示させるための分岐
  if strKey is "ExifToolVersion" then
    ###キーと値を保存
    set strHTMLTagFooterKey to strKey as text
    set strHTMLTagFooterValue to strValue as text
    ####例外処理
  else if strKey is "Directory" then
    set numLineNO to numLineNO + 1 as number
    set strHTMLTag to "<tr><th title=\"項番:" & strKey & "\" scope=\"row\">" & numLineNO & "</th><td title=\"キー:" & strKey & "について\">" & strKey & "</td><td title=\"キー:" & strKey & "の値\">非表示にしています</td></tr>" as text
  else if strKey is "SourceFile" then
    set numLineNO to numLineNO + 1 as number
    set strHTMLTag to "<tr><th title=\"項番:" & strKey & "\" scope=\"row\">" & numLineNO & "</th><td title=\"キー:" & strKey & "について\">" & strKey & "</td><td title=\"キー:" & strKey & "の値\">非表示にしています</td></tr>" as text
  else
    ###普通はこの処理
    set numLineNO to numLineNO + 1 as number
    set strHTMLTag to "<tr><th title=\"項番:" & strKey & "\" scope=\"row\">" & numLineNO & "</th><td title=\"キー:" & strKey & "について\">" & strKey & "</td><td title=\"キー:" & strKey & "の値\">" & strValue & "</td></tr>" as text
  end if
  ####できたタグを追加
(ocidHTMLString's appendString:strHTMLTag)
  
end repeat
###最後にバージョンを入れる
set numLineNO to numLineNO + 1 as number
###最後のtfoot項目
set strHTMLTagFooter to "</tbody><tfoot title=\"表の終わりです\"><tr><th title=\"項番:" & numLineNO & "\" scope=\"row\">" & numLineNO & "</th><td title=\"キーの名前\">ExifToolVersion</td><td title=\"キー:" & strHTMLTagFooterKey & "の値\">ExifTool:" & strHTMLTagFooterValue & "で作成しました</td></tr></tfoot></table></div>" as text
###タグを全部追加して
(ocidHTMLString's appendString:strHTMLTagFooter)
ocidHTMLString's appendString:strHtmlEndBody
###ファイルに書き出し
set boolWritetoUrlArray to ocidHTMLString's writeToFile:strSaveFilePath atomically:true encoding:(refMe's NSUTF8StringEncoding) |error|:(reference)
(*
####テキストエディタで開く
log strSaveFilePath
tell application "TextEdit"
activate
open (POSIX file strSaveFilePath as alias)
end tell
*)
####サファリで開く
set strOpenURL to ocidSaveFilePathURL's absoluteString() as text
tell application "Safari"
activate
make new document with properties {name:"MDLS2HTMLv2"}
  tell window 1
open location strOpenURL
  end tell
end tell
########################################
### キー名と値にHTMLの要素があるケースがあるので
### HtmlEntities変換
########################################

to doHtmlEntitiesEnc(argTEXT)
  
  ###置換レコード
  ## set recordEntityMap to {|&|:"&amp;", |<|:"&lt;", |>|:"&gt;", |"|:"&quot;", |'|:"&apos;", |=|:"&#x3D;", |+|:"&#x2B;"} as record
  set recordEntityMap to {|<|:"&lt;", |>|:"&gt;", |"|:"&quot;", |'|:"&apos;", |=|:"&#x3D;", |+|:"&#x2B;", |©|:"&copy;", |®|:"&reg;", |™|:"&trade;", |€|:"&euro;", |£|:"&pound;", |¥|:"&yen;", |...|:"&hellip;"} as record
  ###ディクショナリにして
  set ocidEntityMap to refMe's NSDictionary's alloc()'s initWithDictionary:(recordEntityMap)
  ###キーの一覧を取り出します
  set ocidAllKeys to ocidEntityMap's allKeys()
  
  ##通常テキストの場合
  set strText to argTEXT as text
  ###選択中テキスト
  set ocidText to refMe's NSString's stringWithString:(strText)
  ###可変テキストにして
  set ocidTextM to refMe's NSMutableString's alloc()'s initWithCapacity:0
ocidTextM's setString:(ocidText)
  ###&だけ先に処理しておく
  set ocidTextM to (ocidTextM's stringByReplacingOccurrencesOfString:("&") withString:("&amp;"))
  ###取り出したキー一覧を順番に処理
  repeat with itemAllKey in ocidAllKeys
    set strItemKey to itemAllKey as text
    ##キーの値を取り出して
    set strValue to (ocidEntityMap's valueForKey:(itemAllKey)) as text
    ##置換
    set ocidTextM to (ocidTextM's stringByReplacingOccurrencesOfString:(strItemKey) withString:(strValue))
    ##次の変換に備える
    set ocidTextM to ocidTextM
  end repeat
  
return (ocidTextM as text)
end doHtmlEntitiesEnc

|

« [applescript] ExifToolインストール(ちょっと修正) | トップページ | [exiftool] exiftoolのhtmlDumpの内容をHTMLで保存する(画像系専用) »

AppleScript EXIFData」カテゴリの記事