A script to add Not Visible Metadata to COP keywords
***Edit*** 2020/07/05 The migrated version of this script likely will not complile because the Applescript symbols for "not equal", "less than" and "greater than" are not supported in the new forum
Image File Metadata contains a huge amount of information, much of it not available through CaptureOne or similar applications. For example, Light level, Depth of Field, Sensor Temperature.
Even some basic and critical information, like the Lens ID and the WhiteBalance is not available in CaptureOne for JPEG images from Panasonic cameras.
All of this information can be read using exiftool, which is a free unix application that is even used used by some of CaptureOne's competors. Download:
IF you want to see what is available, install the application form the DMG download, open terminal, type "exifitool " and drag an image file from the Finder into the terminal window. Hit enter and you will be surprised at what comes back.
Here is a script that uses exiftool to read information from the file assocauted with an image, and stores it in CaptureOne keywords of the variant. The first project is of course to get the Lens ID for Panasonic JPEGS.
***Code edited about an hour after initial posting to remove a section which was not required.
## Notes
-- Applescript to Copy Lens ID and Digital Teleconverter settings to keywords
-- Creates a report in Text Edit
-- Version 1.2 !! NO SUPPORT !! Eric Valk, Ottawa, Canada
-- *** Operation
-- Open the compiled and saved file
-- Open the Script Editor log window, and select the messages tab
-- Select only a small number of variants, from any collection
-- Run the script
-- Results appear first in Notifications, then the Script Editor Log and Text Edit when the search for each variant is completed, and in Display Dialog Window when all searching is completed
-- This script does not write or delete any information in the COP Catalog or Session or the image file
--
-- The user may elect to enable or disable results in Notifications, TextEdit and Script Editor by setting the "enable" variables at beginning of the script
-- The user may change the amount of reporting by setting the "debugLogLevel" and "ResultsFileMaxDebug" variables at beginning of the script
-- If you are having some issues, then set debugLogLevel to 3 and send me the results from Script Editors log window, or Text Edit.
## Values in this section are safe to change, within limits indicated. Support is likely but no commitment
set debugLogLevel to 0 -- 0...6 Values >1 result in increasing amounts of debug data that takes longer to report
set enableResultsFile to true -- (true/false)
set enableResultsByDialog to false -- (true/false)
set enableNotifications to false -- (true/false)
set ResultsFileMaxDebug to 2 -- 1...6 suggest not more than 2
set SearchSelectedImages to true -- If set to false, then every image in the current collection is searched, If true, only seleced images are searched
set SearchforMakerList to {"Panasonic"}
set SearchforFileTypeList to {"JPEG", "RW2"}
set updateExistingKeywords to true -- If set to false, existing keywords are not updated
## ***** Not safe to change stuff below this line, unless you have some background in SW development.
## I generally won't help much if you change stuff below this line. I may explain the design intent.
tell application "System Events" to set parent_name to name of current application
tell application "Finder"
set script_path to path to me
set Script_Title to name of file script_path as text
end tell
set SE_Logging to (parent_name = "Script Editor")
if enableResultsFile then
set Result_DocName to "COP_Image_Search.txt"
else
set Result_DocName to "Not Enabled"
end if
set ResultMethod to my InitializeLoqqing(Result_DocName, Script_Title)
loq_Results("Started from: " & parent_name, false, 0)
loq_Results("Action: Copy Lens ID and Digital Teleconverter settings to keywords", false, 0)
set minCOPversion to "11.0.1"
validateCOP(minCOPversion)
set {COPDocName, COPDocKind_s, COPDocRef} to validateCOPdoc({"catalog", "session"})
validateCOPcollections()
set max_search_coll_index to indexInCatalog - 1
set options_display_string to "Debug Level: " & debugLogLevel
set options_display_string to options_display_string & return & "Search Only Selected Images: " & SearchSelectedImages
set options_display_string to options_display_string & return & "Search for Maker: " & SearchforMakerList
set options_display_string to options_display_string & return & "Search for File Type: " & SearchforFileTypeList
set options_display_string to options_display_string & return & "Update Existing Keyword Sets: " & updateExistingKeywords
set options_display_string to options_display_string & return & "Highest Debug Level in Result File: " & ResultsFileMaxDebug
set options_display_string to options_display_string & return & "Enable Results in Text Edit: " & enableResultsFile
set options_display_string to options_display_string & return & "Display Dialog on Image Not Found: " & enableResultsByDialog
set options_display_string to options_display_string & return & "Enable Results in Notifications: " & enableNotifications
set options_display_string to options_display_string & return & "Results: " & ResultMethod
tell application "System Events" to set frontmost of process parent_name to true
try
set dialog_result to display dialog options_display_string with title Script_Title
on error errmess
my loqqedErrorHalt("User Cancelled the Script")
end try
loq_Results((return & "Options:" & return & options_display_string & return), false, 1)
if SearchSelectedImages = false then
tell application "Capture One 11" to set selectedVariantsList to every variant
else
tell application "Capture One 11"
set selectedVariantsList to every variant whose selected is true
end tell
end if
set countSelectedVariants to count of selectedVariantsList
loq_Results(("Processing " & countSelectedVariants & " Variants"), false, 3)
if countSelectedVariants = 0 then
display alert "No images selected - select one or more images"
my loqqed_exit("No images selected")
end if
## Start the search
tell application "System Events" to set frontmost of process "Capture One 11" to true
repeat with thisvariant in selectedVariantsList
tell application "Capture One 11" to tell thisvariant
set the imagepath to the path of the parent image
end tell
tell my application "Finder"
if not (exists imagepath as POSIX file) then
my loq_Results(("Unable to find image " & imagepath), false, 0)
exit repeat
end if
end tell
tell current application to set Results123 to do shell script "/usr/local/bin/exiftool -s3 -FileType -Make -DigitalZoomRatio " & quoted form of imagepath
set foundFileType to (get paragraph 1 of Results123)
set foundFileMaker to (get paragraph 2 of Results123)
if (SearchforFileTypeList contains foundFileType) and (SearchforMakerList contains foundFileMaker) then
tell application "Capture One 11" to tell thisvariant
set {variantName, variantID} to {name, id}
set {keywordNameList, keywordParentList} to {name, parent} of keywords
set keywordcount to count of keywordNameList
end tell
my loq_Results((return & "Path: " & imagepath & " ID: " & variantID & " Keywords: " & keywordcount), false, 2)
if (0 < keywordcount) and (debugLogLevel > 2) then
tell application "Capture One 11" to tell COPDocRef to tell thisvariant
repeat with keywordcounter from 1 to keywordcount
my loq_Results(("Keywd_" & keywordcounter & ": " & (get name of keyword keywordcounter) & " Parent: " & (get parent of keyword keywordcounter)), false, 3)
end repeat
end tell
end if
if (updateExistingKeywords = false) and (keywordParentList contains "LensID") then
-- do nothing
else
-- Add or Update the keyword set
tell current application to set LensNameList to do shell script "/usr/local/bin/exiftool -s3 -Lens -LensType -LensType2 -LensType3 -LensID -LensInfo -LensModel -LensMake " & quoted form of imagepath
--log {"Processing", imagepath, digZoomSetting, (get count of paragraphs of LensNameList), LensNameList}
if (get count of paragraphs of LensNameList) = 0 then
my loq_Results(("No LensID found:" & imagepath), false, 0)
else
set LensName to paragraph 1 of LensNameList
if keywordParentList contains "LensID" then
set keywordcountOffset to 0
tell application "Capture One 11" to tell COPDocRef to tell thisvariant
repeat with keywordcounter from 1 to keywordcount
set keywordIndex to keywordcounter + keywordcountOffset
if (get parent of keyword keywordIndex) = "LensID" then
my loq_Results(("Deleting: " & (get name of keyword keywordIndex)), false, 4)
delete keyword keywordIndex
set keywordcountOffset to keywordcountOffset - 1
end if
end repeat
end tell
else if keywordNameList does not contain "LensID" then
tell application "Capture One 11" to tell COPDocRef to tell thisvariant
tell thisvariant to make new keyword with properties {name:"LensID"}
my loq_Results(("Adding: " & "LensID"), false, 5)
end tell
end if
tell application "Capture One 11" to tell COPDocRef to tell thisvariant
tell thisvariant to make new keyword with properties {name:LensName, parent:"LensID"}
my loq_Results(("Adding: " & LensName), false, 4)
end tell
end if
tell application "Capture One 11" to tell thisvariant to set {keywordNameList, keywordParentList} to {name, parent} of keywords
set keywordcount to count of keywordNameList
end if
if ((updateExistingKeywords = false) and (keywordParentList contains "DigZoom")) or (foundFileType ≠"JPEG") then
-- do nothing
else
if (2 = (get count of paragraphs of Results123)) then
set digZoomName to "NotFound"
else
set digZoomName to "NotFound"
set digZoomSetting to paragraph 3 of Results123
if digZoomSetting = "0" then
set digZoomName to "Off"
else if digZoomSetting = "1" then
set digZoomName to "Off"
else if digZoomSetting = "2" then
set digZoomName to "DTC_2X"
else if digZoomSetting = "4" then
set digZoomName to "DTC_4X"
else
try
set digZoomName to (digZoomSetting as real)
set digZoomName to "Var_" & digZoomName & "X"
end try
end if
end if
if digZoomName = "NotFound" then
my loq_Results(("No Digital Zoom info found:" & imagepath), false, 0)
else
if keywordParentList contains "DigZoom" then
set keywordcountOffset to 0
tell application "Capture One 11" to tell COPDocRef to tell thisvariant
repeat with keywordcounter from 1 to keywordcount
set keywordIndex to keywordcounter + keywordcountOffset
if (get parent of keyword keywordIndex) = "DigZoom" then
my loq_Results(("Deleting: " & (get name of keyword keywordIndex)), false, 4)
delete keyword keywordIndex
set keywordcountOffset to keywordcountOffset - 1
end if
end repeat
end tell
else if keywordNameList does not contain "DigZoom" then
tell application "Capture One 11" to tell COPDocRef to tell thisvariant
tell thisvariant to make new keyword with properties {name:"DigZoom"}
my loq_Results(("Adding: " & "DigZoom"), false, 5)
end tell
end if
tell application "Capture One 11" to tell COPDocRef to tell thisvariant
tell thisvariant to make new keyword with properties {name:digZoomName, parent:"DigZoom"}
my loq_Results(("Adding: " & digZoomName), false, 4)
end tell
end if
end if
end if
end repeat
tell application "System Events" to set frontmost of process "Capture One 11" to true
my loq_Results((return & "*** Done ***"), true, 0)
--Handlers -------------------
on validateCOP(minCOPversionstr)
global debugLogLevel
tell application "System Events"
set COPProcList to every process whose name contains "Capture One" and background only is false
if debugLogLevel ≥ 2 then
set COPProcNameList to name of every process whose name contains "Capture One" and background only is false
my loq_Results("COP Processes:" & COPProcNameList, false, 2)
end if
end tell
if (count of COPProcList) = 0 then my loqqed_exit("COP is not running")
if (count of COPProcList) ≠1 then my loqqed_exit("Unexpected: >1 COP instances")
set theAppRef to item 1 of COPProcList
tell application "System Events" to set theAppName to ((get name of theAppRef) as text)
tell application "System Events" to set copDetailedVersion to get version of my application theAppName
tell application "Capture One 11" to set copVersion to (get app version)
if debugLogLevel ≥ 2 then
--properties of application "Capture One 11"
tell application "System Events"
my loq_Results(("All Processes: " & (get my joinListToString((get name of every process whose background only is false), ", "))), false, 2)
end tell
loq_Results(("theAppName: " & theAppName), false, 2)
loq_Results(("COP Version: " & copVersion), false, 2)
loq_Results(("COP Detailed Version: " & copDetailedVersion), false, 2)
end if
if the theAppName ≠"Capture One 11" then
display notification "Wrong COP Application"
my loqqed_exit("Found COP Application " & theAppName & " The only supported COP application is Capture One 11")
end if
set numCOPversion to (splitStringToList((word -1 of copVersion), "."))
set minCOPversion to (splitStringToList(minCOPversionstr, "."))
set digit_mult to 1000000
set Version_digit to 0
repeat with dig_ctr from 1 to count of numCOPversion
set digit_mult to digit_mult / 100
set Version_digit to Version_digit + (get item dig_ctr of numCOPversion as integer) * digit_mult
end repeat
set digit_mult to 1000000
set min_digit to 0
repeat with dig_ctr from 1 to count of minCOPversion
set digit_mult to digit_mult / 100
set min_digit to min_digit + (get item dig_ctr of minCOPversion as integer) * digit_mult
end repeat
if Version_digit < min_digit then
display notification "COP Version is too low"
my loqqed_exit("This COP Version is " & (word -1 of copVersion) & " - the minimum supported COP version is " & minCOPversionstr)
end if
tell application "System Events" to set frontmost of process theAppName to true
loq_Results(("Using Capture One " & copDetailedVersion), false, 0)
end validateCOP
on validateCOPdoc(COP_kind_list)
global debugLogLevel
tell application "Capture One 11"
set {current_doc_name, current_doc_kind_p} to (get {name, kind} of current document)
set current_doc_ref_list to (get every document whose name is current_doc_name and kind is current_doc_kind_p)
set number_of_hits to count of current_doc_ref_list
end tell
set current_doc_kind_s to convertKind(current_doc_kind_p)
loq_Results(("Is: " & current_doc_kind_s & " was: " & (get current_doc_kind_p as text)), false, 2)
loq_Results(("Found Documents: " & number_of_hits), false, 2)
if COP_kind_list does not contain current_doc_kind_s then loq_Results(current_doc_name & " is a " & current_doc_kind_s & " -- unsupported type of document", false, 0)
if number_of_hits = 0 then
loqqed_exit("Could not find find " & current_doc_kind_s & current_doc_name)
else if number_of_hits > 1 then
loqqed_exit("Found more than one " & current_doc_kind_s & " with the name " & current_doc_name)
else
tell application "Capture One 11" to set current_doc_ref to item 1 of current_doc_ref_list
end if
loq_Results(("Capture One document: " & current_doc_kind_s & " " & current_doc_name), false, 0)
return {current_doc_name, current_doc_kind_s, current_doc_ref}
end validateCOPdoc
on validateCOPcollections()
global debugLogLevel, COPDocName, everyTopCollection, namesTopCollections, kindsTopCollections_p, countTopCollections, selectedCollectionRef, selectedCollectionIndex, kindSelectedCollection_s, nameSelectedCollection, selectedCollectionAtTopEnd, selectedCollectionIsUser, indexInCatalog
tell application "Capture One 11" to tell document COPDocName
set selectedCollectionRef to get current collection
set {nameSelectedCollection, kindSelectedCollection_p} to {name, kind} of selectedCollectionRef
set everyTopCollection to get every collection
set {namesTopCollections, kindsTopCollections_p} to {name, kind} of every collection
end tell
set kindSelectedCollection_s to convertKind(kindSelectedCollection_p)
set countTopCollections to count of namesTopCollections
try
|| of {selectedCollectionRef} -- generate an error to capture error text containing the collection reference
on error CO11_errtxt number CO11_errnbr
end try
loq_Results(("***Error Message " & CO11_errtxt & "; number " & CO11_errnbr & " Current Collection: " & kindSelectedCollection_s & " " & nameSelectedCollection), false, 4)
## extract the collection number from the error text
if CO11_errnbr = -1728 then
set selectedCollectionIndex to (get last word of item 2 of splitStringToList(CO11_errtxt, "of")) as integer
else
loq_Results(("*****" & CO11_errtxt & "; number " & CO11_errnbr), false, 4)
loqqed_exit("Unexpected error when finding current collection index")
end if
if selectedCollectionIndex = countTopCollections then
## last collection IS the selected collection
set selectedCollectionAtTopEnd to true
else
## last collection is NOT the selected collection
set selectedCollectionAtTopEnd to false
end if
if ({"project", "album", "group", "smart album"} contains kindSelectedCollection_s) then
set selectedCollectionIsUser to true
else
set selectedCollectionIsUser to false
end if
tell application "Capture One 11" to tell document COPDocName to set countOfInCatalog to count of (get every collection whose name is "In Catalog")
if countOfInCatalog = 1 then
set indexInCatalog to getIndexOf("in Catalog", namesTopCollections)
else
loqqedexit("There is more than one collection with the name "In Catalog"")
end if
end validateCOPcollections
on InitializeLoqqing(DocName_Ext, sourceTitle)
global debugLogLevel, Script_Title, Result_Doc_ref, SE_Logging, enableResultsFile, enableResultsByDialog, DialogTextList
tell current application to set date_string to (current date) as text
set LogMethods to {}
if enableResultsFile then
set target_folder_name to "ScriptReports"
set target_folder_p to ((POSIX path of (get path to desktop as text)) & target_folder_name)
set target_folder_a to (POSIX file target_folder_p) as string
set Result_Doc_Path_p to target_folder_p & "/" & DocName_Ext
set Result_Doc_Path_a to (POSIX file Result_Doc_Path_p) as string
tell application "System Events" to if not (exists (alias (target_folder_a))) then ¬
tell application "Finder" to make new folder at desktop with properties {name:target_folder_name}
tell application "System Events" to if not (exists (alias (Result_Doc_Path_a))) then
set First_line to ("Created " & date_string & return)
do shell script "echo " & First_line & " > " & """ & Result_Doc_Path_p & """
if (debugLogLevel ≥ 1) and SE_Logging then log Result_Doc_Path_p & First_line
end if
tell application "TextEdit" to activate
tell application "TextEdit" to set Result_Doc_ref to open Result_Doc_Path_a as alias
set LogMethods to LogMethods & DocName_Ext
end if
if enableResultsByDialog then
set DialogTextList to {}
set LogMethods to LogMethods & "Display Dialog"
end if
loq_Results((sourceTitle & " results on " & date_string), false, 0)
return joinListToString(LogMethods, ", ")
end InitializeLoqqing
on loq_Results(logText, MakeFront, thisLogDebugLevel)
global Result_Doc_ref, debugLogLevel, SE_Logging, parent_name, ResultsFileMaxDebug, enableResultsFile, enableResultsByDialog, DialogTextList
if thisLogDebugLevel > debugLogLevel then return
set logText_class to ((get class of logText) as text)
if logText_class ≠"text" then
try
if logText_class = "list" then
set new_logText to joinListToString(logText, ", ")
else
set new_logText to logText as text
end if
set logText to new_logText
set logText_class to "text"
on error errmess
set logText to errmess
set logText_class to "text"
end try
end if
if ((thisLogDebugLevel ≤ ResultsFileMaxDebug) or not SE_Logging) then
if enableResultsFile then
tell application "TextEdit"
set numPara to count paragraphs of the text of Result_Doc_ref
set paragraph (numPara + 1) of the text of Result_Doc_ref to ((logText as text) & return)
end tell
tell application "System Events" to if MakeFront then set frontmost of process "TextEdit" to true
end if
if enableResultsByDialog then
set DialogTextList to DialogTextList & logText
if MakeFront then
tell application "System Events" to set frontmost of process parent_name to true
display dialog joinListToString(DialogTextList, return)
end if
end if
end if
if SE_Logging then log (logText as text)
end loq_Results
on loqqed_exit(error_text)
global debugLogLevel, Script_Title
loq_Results(("Script "" & Script_Title & "" has exited." & return & "Reason: " & error_text & return & return & "Halted"), true, 0)
display notification error_text
error error_text
end loqqed_exit
on splitStringToList(theString, theDelim)
set astid to AppleScript's text item delimiters
try
set AppleScript's text item delimiters to theDelim
set theList to text items of theString
on error
set AppleScript's text item delimiters to astid
end try
set AppleScript's text item delimiters to astid
return theList
end splitStringToList
to joinListToString(theList, theDelim)
set theString to ""
set astid to AppleScript's text item delimiters
try
set AppleScript's text item delimiters to theDelim
set theString to theList as string
on error
set AppleScript's text item delimiters to astid
end try
set AppleScript's text item delimiters to astid
return theString
end joinListToString
on getIndexOf(theItem, theList) -- credits Emmanuel Levy
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to return
set theList to return & theList & return
set AppleScript's text item delimiters to astid
try
-1 + (count (paragraphs of (text 1 thru (offset of (return & theItem & return) in theList) of theList)))
on error
0
end try
end getIndexOf
on convertKind(kind_p)
global debugLogLevel
set kind_s to kind_p as text
if (get text 1 of kind_s) ≠"«" then
return kind_s
else
set code_start to (get length of kind_s) - 4
set kind_code to get (text code_start thru (code_start + 3) of kind_s)
if kind_code = "CCpj" then
set kind_res to "project"
else if kind_code = "CCgp" then
set kind_res to "group"
else if kind_code = "CCal" then
set kind_res to "album"
else if kind_code = "CCsm" then
set kind_res to "smart album"
else if kind_code = "CCfv" then
set kind_res to "favorite"
else if kind_code = "CCff" then
set kind_res to "catalog folder"
else if kind_code = "COct" then
set kind_res to "catalog"
else if kind_code = "COsd" then
set kind_res to "session"
else
loqqed_exit("Unexpected Kind string: " & kind_s)
end if
end if
return kind_res
end convertKind
-
The script in the post above times out at 7000 variants . Here is a better version, it still times out with a large number of selected variants, but it does not time out if you set it to check all variants in the current collections;
## Notes
-- Applescript to Copy Lens ID and Digital Teleconverter settings to keywords
-- Creates a report in Text Edit
-- Version 1.2 !! NO SUPPORT !! Eric Valk, Ottawa, Canada
-- *** Operation
-- Open the compiled and saved file
-- Open the Script Editor log window, and select the messages tab
-- Select up to 3000 variants, from any collection
-- Run the script
-- Results appear first in Notifications, then the Script Editor Log and Text Edit when the search for each variant is completed, and in Display Dialog Window when all searching is completed
-- This script adds and removes keywords from images, this results in changes to your catalog or session.
--
-- The user may elect to enable or disable results in Notifications, TextEdit and Script Editor by setting the "enable" variables at beginning of the script
-- The user may change the amount of reporting by setting the "debugLogLevel" and "ResultsFileMaxDebug" variables at beginning of the script
-- If you are having some issues, then set debugLogLevel to 3 and send me the results from Script Editors log window, or Text Edit.
## Values in this section are safe to change, within limits indicated. Support is likely but no commitment
set debugLogLevel to 1 -- 0...6 Values >1 result in increasing amounts of debug data that takes longer to report
set enableResultsFile to true -- (true/false)
set enableResultsByDialog to false -- (true/false)
set enableNotifications to false -- (true/false)
set ResultsFileMaxDebug to 2 -- 1...6 suggest not more than 2
set SearchSelectedImages to false -- If set to false, then every image in the current collection is searched, If true, only seleced images are searched
set SearchforMakerList to {"Panasonic"}
set SearchforFileTypeList to {"JPEG", "RW2"}
set updateExistingKeywords to true -- If set to false, existing keywords are not updated
## ***** Not safe to change stuff below this line, unless you have some background in SW development.
## I generally won't help much if you change stuff below this line. I may explain the design intent.
tell application "System Events" to set parent_name to name of current application
tell application "Finder"
set script_path to path to me
set Script_Title to name of file script_path as text
end tell
set SE_Logging to (parent_name = "Script Editor")
if enableResultsFile then
set Result_DocName to "COP_Image_Search.txt"
else
set Result_DocName to "Not Enabled"
end if
set ResultMethod to my InitializeLoqqing(Result_DocName, Script_Title)
loq_Results(0, false, ("Started from: " & parent_name))
loq_Results(0, false, ("Action: Copy Lens ID and Digital Teleconverter settings to keywords"))
set minCOPversion to "11.0.1"
validateCOP(minCOPversion)
set {COPDocName, COPDocKind_s, COPDocRef} to validateCOPdoc({"catalog", "session"})
validateCOPcollections()
set max_search_coll_index to indexInCatalog - 1
set options_display_string to "Debug Level: " & debugLogLevel
set options_display_string to options_display_string & return & "Search Only Selected Images: " & SearchSelectedImages
set options_display_string to options_display_string & return & "Search for Maker: " & SearchforMakerList
set options_display_string to options_display_string & return & "Search for File Type: " & SearchforFileTypeList
set options_display_string to options_display_string & return & "Update Existing Keyword Sets: " & updateExistingKeywords
set options_display_string to options_display_string & return & "Highest Debug Level in Result File: " & ResultsFileMaxDebug
set options_display_string to options_display_string & return & "Enable Results in Text Edit: " & enableResultsFile
set options_display_string to options_display_string & return & "Display Dialog on Image Not Found: " & enableResultsByDialog
set options_display_string to options_display_string & return & "Enable Results in Notifications: " & enableNotifications
set options_display_string to options_display_string & return & "Results: " & ResultMethod
tell application "System Events" to set frontmost of process parent_name to true
try
set dialog_result to display dialog options_display_string with title Script_Title
on error errmess
my loqqed_Error_Halt("User Cancelled the Script")
end try
loq_Results(1, false, (return & "Options:" & return & options_display_string & return))
if SearchSelectedImages = false then
set Mark1 to get time of (get current date)
tell application "Capture One 11" to set countVariants to count of every variant
set Mark2 to get time of (get current date)
if countVariants = 0 then
my loqqed_Error_Halt("No images in " & kindSelectedCollection_s & " " & nameSelectedCollection)
end if
## Start the search
repeat with variantCounter from 1 to countVariants
tell application "Capture One 11" to set thisVariant to variant variantCounter
processVariant(thisVariant)
end repeat
set Mark3 to get time of (get current date)
else
set Mark1 to get time of (get current date)
try
tell application "Capture One 11" to set selectedVariantsList to selected variants
set Mark2 to get time of (get current date)
on error errmess
set Mark2 to get time of (get current date)
my loqqed_Error_Halt(errmess & " Elapsed: " & (Mark2 - Mark1) & " seconds")
end try
set countVariants to count of selectedVariantsList
if countVariants = 0 then
display alert "No images selected - select one or more images"
my loqqed_Error_Halt("No images selected")
end if
## Start the search
tell application "System Events" to set frontmost of process "Capture One 11" to true
repeat with thisVariant in selectedVariantsList
processVariant(thisVariant)
end repeat
set Mark3 to get time of (get current date)
end if
tell application "System Events" to set frontmost of process "Capture One 11" to true
tell current application to set date_string to (current date) as text
if debugLogLevel ≥ 1 then
set elapsedTime1 to Mark2 - Mark1
set elapsedTime2 to Mark3 - Mark2
set quantum to 0.01
set timePerVariant to (round (elapsedTime2 / countVariants / quantum) rounding to nearest) * quantum
my loq_Results(1, false, (return & "SetupTime: " & elapsedTime1 & "sec Process time: " & elapsedTime2 & "sec Per Variant: " & timePerVariant & "sec Variants: " & countVariants))
else
my loq_Results(1, false, (return))
end if
my loq_Results(0, true, ("*** Done at " & date_string & " ***"))
--Handlers -------------------
on processVariant(theVariant)
global debugLogLevel, SearchforMakerList, SearchforFileTypeList, updateExistingKeywords, COPDocRef
tell application "Capture One 11" to tell theVariant
set the imagepath to the path of the parent image
end tell
tell my application "Finder"
if not (exists imagepath as POSIX file) then
my loq_Results(0, false, ("Unable to find image " & imagepath))
exit repeat
end if
end tell
tell current application to set Results123 to do shell script "/usr/local/bin/exiftool -s3 -FileType -Make -DigitalZoomRatio " & quoted form of imagepath
set foundFileType to (get paragraph 1 of Results123)
set foundFileMaker to (get paragraph 2 of Results123)
if (SearchforFileTypeList contains foundFileType) and (SearchforMakerList contains foundFileMaker) then
tell application "Capture One 11" to tell theVariant
set {variantName, variantID} to {name, id}
set {keywordNameList, keywordParentList} to {name, parent} of keywords
set keywordcount to count of keywordNameList
end tell
my loq_Results(2, false, (return & "Path: " & imagepath & " ID: " & variantID & " Keywords: " & keywordcount))
if (0 < keywordcount) and (debugLogLevel > 2) then
tell application "Capture One 11" to tell COPDocRef to tell theVariant
repeat with keywordcounter from 1 to keywordcount
my loq_Results(3, false, ("Keywd_" & keywordcounter & ": " & (get name of keyword keywordcounter) & " Parent: " & (get parent of keyword keywordcounter)))
end repeat
end tell
end if
if (updateExistingKeywords = false) and (keywordParentList contains "LensID") then
-- do nothing
else
-- Add or Update the keyword set
tell current application to set LensNameList to do shell script "/usr/local/bin/exiftool -s3 -Lens -LensType -LensType2 -LensType3 -LensID -LensInfo -LensModel -LensMake " & quoted form of imagepath
--log {"Processing", imagepath, digZoomSetting, (get count of paragraphs of LensNameList), LensNameList}
if (get count of paragraphs of LensNameList) = 0 then
my loq_Results(0, false, ("No LensID found:" & imagepath))
else
set LensName to paragraph 1 of LensNameList
if keywordParentList contains "LensID" then
set keywordcountOffset to 0
tell application "Capture One 11" to tell COPDocRef to tell theVariant
repeat with keywordcounter from 1 to keywordcount
set keywordIndex to keywordcounter + keywordcountOffset
if (get parent of keyword keywordIndex) = "LensID" then
my loq_Results(4, false, ("Deleting: " & (get name of keyword keywordIndex)))
delete keyword keywordIndex
set keywordcountOffset to keywordcountOffset - 1
end if
end repeat
end tell
else if keywordNameList does not contain "LensID" then
tell application "Capture One 11" to tell COPDocRef to tell theVariant
tell theVariant to make new keyword with properties {name:"LensID"}
my loq_Results(5, false, ("Adding: " & "LensID"))
end tell
end if
tell application "Capture One 11" to tell COPDocRef to tell theVariant
tell theVariant to make new keyword with properties {name:LensName, parent:"LensID"}
my loq_Results(4, false, ("Adding: " & LensName))
end tell
end if
tell application "Capture One 11" to tell theVariant to set {keywordNameList, keywordParentList} to {name, parent} of keywords
set keywordcount to count of keywordNameList
end if
if ((updateExistingKeywords = false) and (keywordParentList contains "DigZoom")) or (foundFileType ≠"JPEG") then
-- do nothing
else
if (2 = (get count of paragraphs of Results123)) then
set digZoomName to "NotFound"
else
set digZoomName to "NotFound"
set digZoomSetting to paragraph 3 of Results123
if digZoomSetting = "0" then
set digZoomName to "Off"
else if digZoomSetting = "1" then
set digZoomName to "Off"
else if digZoomSetting = "2" then
set digZoomName to "DTC_2X"
else if digZoomSetting = "4" then
set digZoomName to "DTC_4X"
else
try
set digZoomName to (digZoomSetting as real)
set digZoomName to "Var_" & digZoomName & "X"
end try
end if
end if
if digZoomName = "NotFound" then
my loq_Results(0, false, ("No Digital Zoom info found:" & imagepath))
else
if keywordParentList contains "DigZoom" then
set keywordcountOffset to 0
tell application "Capture One 11" to tell COPDocRef to tell theVariant
repeat with keywordcounter from 1 to keywordcount
set keywordIndex to keywordcounter + keywordcountOffset
if (get parent of keyword keywordIndex) = "DigZoom" then
my loq_Results(4, false, ("Deleting: " & (get name of keyword keywordIndex)))
delete keyword keywordIndex
set keywordcountOffset to keywordcountOffset - 1
end if
end repeat
end tell
else if keywordNameList does not contain "DigZoom" then
tell application "Capture One 11" to tell COPDocRef to tell theVariant
tell theVariant to make new keyword with properties {name:"DigZoom"}
my loq_Results(5, false, ("Adding: " & "DigZoom"))
end tell
end if
tell application "Capture One 11" to tell COPDocRef to tell theVariant
tell theVariant to make new keyword with properties {name:digZoomName, parent:"DigZoom"}
my loq_Results(4, false, ("Adding: " & digZoomName))
end tell
end if
end if
end if
end processVariant
on validateCOP(minCOPversionstr)
global debugLogLevel
tell application "System Events"
set COPProcList to every process whose name contains "Capture One" and background only is false
if debugLogLevel ≥ 2 then
set COPProcNameList to name of every process whose name contains "Capture One" and background only is false
my loq_Results(2, false, ("COP Processes:" & COPProcNameList))
end if
end tell
if (count of COPProcList) = 0 then my loqqed_Error_Halt("COP is not running")
if (count of COPProcList) ≠1 then my loqqed_Error_Halt("Unexpected: >1 COP instances")
set theAppRef to item 1 of COPProcList
tell application "System Events" to set theAppName to ((get name of theAppRef) as text)
tell application "System Events" to set copDetailedVersion to get version of my application theAppName
tell application "Capture One 11" to set copVersion to (get app version)
if debugLogLevel ≥ 2 then
--properties of application "Capture One 11"
tell application "System Events"
my loq_Results(2, false, ("All Processes: " & (get my joinListToString((get name of every process whose background only is false), ", "))))
end tell
loq_Results(2, false, ("theAppName: " & theAppName))
loq_Results(2, false, ("COP Version: " & copVersion))
loq_Results(2, false, ("COP Detailed Version: " & copDetailedVersion))
end if
if the theAppName ≠"Capture One 11" then
display notification "Wrong COP Application"
my loqqed_Error_Halt("Found COP Application " & theAppName & " The only supported COP application is Capture One 11")
end if
set numCOPversion to (splitStringToList((word -1 of copVersion), "."))
set minCOPversion to (splitStringToList(minCOPversionstr, "."))
set digit_mult to 1000000
set Version_digit to 0
repeat with dig_ctr from 1 to count of numCOPversion
set digit_mult to digit_mult / 100
set Version_digit to Version_digit + (get item dig_ctr of numCOPversion as integer) * digit_mult
end repeat
set digit_mult to 1000000
set min_digit to 0
repeat with dig_ctr from 1 to count of minCOPversion
set digit_mult to digit_mult / 100
set min_digit to min_digit + (get item dig_ctr of minCOPversion as integer) * digit_mult
end repeat
if Version_digit < min_digit then
display notification "COP Version is too low"
my loqqed_Error_Halt("This COP Version is " & (word -1 of copVersion) & " - the minimum supported COP version is " & minCOPversionstr)
end if
tell application "System Events" to set frontmost of process theAppName to true
loq_Results(0, false, ("Using Capture One " & copDetailedVersion))
end validateCOP
on validateCOPdoc(COP_kind_list)
global debugLogLevel
tell application "Capture One 11"
set {current_doc_name, current_doc_kind_p} to (get {name, kind} of current document)
set current_doc_ref_list to (get every document whose name is current_doc_name and kind is current_doc_kind_p)
set number_of_hits to count of current_doc_ref_list
end tell
set current_doc_kind_s to convertKind(current_doc_kind_p)
loq_Results(2, false, ("Is: " & current_doc_kind_s & " was: " & (get current_doc_kind_p as text)))
loq_Results(2, false, ("Found Documents: " & number_of_hits))
if COP_kind_list does not contain current_doc_kind_s then loq_Results(0, false, (current_doc_name & " is a " & current_doc_kind_s & " -- unsupported type of document"))
if number_of_hits = 0 then
loqqed_Error_Halt("Could not find find " & current_doc_kind_s & current_doc_name)
else if number_of_hits > 1 then
loqqed_Error_Halt("Found more than one " & current_doc_kind_s & " with the name " & current_doc_name)
else
tell application "Capture One 11" to set current_doc_ref to item 1 of current_doc_ref_list
end if
loq_Results(0, false, ("Capture One document: " & current_doc_kind_s & " " & current_doc_name))
return {current_doc_name, current_doc_kind_s, current_doc_ref}
end validateCOPdoc
on validateCOPcollections()
global debugLogLevel, COPDocName, everyTopCollection, namesTopCollections, kindsTopCollections_p, countTopCollections, selectedCollectionRef, selectedCollectionIndex, kindSelectedCollection_s, nameSelectedCollection, selectedCollectionAtTopEnd, selectedCollectionIsUser, indexInCatalog
tell application "Capture One 11" to tell document COPDocName
set selectedCollectionRef to get current collection
set {nameSelectedCollection, kindSelectedCollection_p} to {name, kind} of selectedCollectionRef
set everyTopCollection to get every collection
set {namesTopCollections, kindsTopCollections_p} to {name, kind} of every collection
end tell
set kindSelectedCollection_s to convertKind(kindSelectedCollection_p)
set countTopCollections to count of namesTopCollections
try
|| of {selectedCollectionRef} -- generate an error to capture error text containing the collection reference
on error CO11_errtxt number CO11_errnbr
end try
loq_Results(4, false, ("***Error Message " & CO11_errtxt & "; number " & CO11_errnbr & " Current Collection: " & kindSelectedCollection_s & " " & nameSelectedCollection))
## extract the collection number from the error text
if CO11_errnbr = -1728 then
set selectedCollectionIndex to (get last word of item 2 of splitStringToList(CO11_errtxt, "of")) as integer
else
loq_Results(4, false, ("*****" & CO11_errtxt & "; number " & CO11_errnbr))
loqqed_Error_Halt("Unexpected error when finding current collection index")
end if
if selectedCollectionIndex = countTopCollections then
## last collection IS the selected collection
set selectedCollectionAtTopEnd to true
else
## last collection is NOT the selected collection
set selectedCollectionAtTopEnd to false
end if
if ({"project", "album", "group", "smart album"} contains kindSelectedCollection_s) then
set selectedCollectionIsUser to true
else
set selectedCollectionIsUser to false
end if
tell application "Capture One 11" to tell document COPDocName to set countOfInCatalog to count of (get every collection whose name is "In Catalog")
if countOfInCatalog = 1 then
set indexInCatalog to getIndexOf("in Catalog", namesTopCollections)
else
loqqedexit("There is more than one collection with the name "In Catalog"")
end if
end validateCOPcollections
on InitializeLoqqing(DocName_Ext, sourceTitle)
global debugLogLevel, Script_Title, Result_Doc_ref, SE_Logging, enableResultsFile, enableResultsByDialog, DialogTextList
tell current application to set date_string to (current date) as text
set LogMethods to {}
if enableResultsFile then
set target_folder_name to "ScriptReports"
set target_folder_p to ((POSIX path of (get path to desktop as text)) & target_folder_name)
set target_folder_a to (POSIX file target_folder_p) as string
set Result_Doc_Path_p to target_folder_p & "/" & DocName_Ext
set Result_Doc_Path_a to (POSIX file Result_Doc_Path_p) as string
tell application "System Events" to if not (exists (alias (target_folder_a))) then ¬
tell application "Finder" to make new folder at desktop with properties {name:target_folder_name}
tell application "System Events" to if not (exists (alias (Result_Doc_Path_a))) then
set First_line to ("Created " & date_string & return)
do shell script "echo " & First_line & " > " & """ & Result_Doc_Path_p & """
if (debugLogLevel ≥ 1) and SE_Logging then log Result_Doc_Path_p & First_line
end if
tell application "TextEdit" to activate
tell application "TextEdit" to set Result_Doc_ref to open Result_Doc_Path_a as alias
set LogMethods to LogMethods & DocName_Ext
end if
if enableResultsByDialog then
set DialogTextList to {}
set LogMethods to LogMethods & "Display Dialog"
end if
loq_Results(0, false, (sourceTitle & " results on " & date_string))
return joinListToString(LogMethods, ", ")
end InitializeLoqqing
on loq_Results(thisLogDebugLevel, MakeFront, logText)
global Result_Doc_ref, debugLogLevel, SE_Logging, parent_name, ResultsFileMaxDebug, enableResultsFile, enableResultsByDialog, DialogTextList
if thisLogDebugLevel > debugLogLevel then return
set logText_class to ((get class of logText) as text)
if logText_class ≠"text" then
try
if logText_class = "list" then
set new_logText to joinListToString(logText, ", ")
else
set new_logText to logText as text
end if
set logText to new_logText
set logText_class to "text"
on error errmess
set logText to errmess
set logText_class to "text"
end try
end if
if ((thisLogDebugLevel ≤ ResultsFileMaxDebug) or not SE_Logging) then
if enableResultsFile then
tell application "TextEdit"
set numPara to count paragraphs of the text of Result_Doc_ref
set paragraph (numPara + 1) of the text of Result_Doc_ref to ((logText as text) & return)
end tell
tell application "System Events" to if MakeFront then set frontmost of process "TextEdit" to true
end if
if enableResultsByDialog then
set DialogTextList to DialogTextList & logText
if MakeFront then
tell application "System Events" to set frontmost of process parent_name to true
display dialog joinListToString(DialogTextList, return)
end if
end if
end if
if SE_Logging then log (logText as text)
end loq_Results
on loqqed_Error_Halt(error_text)
global debugLogLevel, Script_Title
tell current application to set date_string to (current date) as text
loq_Results(0, true, ("Script "" & Script_Title & "" has exited at " & date_string & return & "Reason: " & error_text & return & return & "Halted"))
display notification error_text
error error_text
end loqqed_Error_Halt
on splitStringToList(theString, theDelim)
set astid to AppleScript's text item delimiters
try
set AppleScript's text item delimiters to theDelim
set theList to text items of theString
on error
set AppleScript's text item delimiters to astid
end try
set AppleScript's text item delimiters to astid
return theList
end splitStringToList
to joinListToString(theList, theDelim)
set theString to ""
set astid to AppleScript's text item delimiters
try
set AppleScript's text item delimiters to theDelim
set theString to theList as string
on error
set AppleScript's text item delimiters to astid
end try
set AppleScript's text item delimiters to astid
return theString
end joinListToString
on getIndexOf(theItem, theList) -- credits Emmanuel Levy
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to return
set theList to return & theList & return
set AppleScript's text item delimiters to astid
try
-1 + (count (paragraphs of (text 1 thru (offset of (return & theItem & return) in theList) of theList)))
on error
0
end try
end getIndexOf
on convertKind(kind_p)
global debugLogLevel
set kind_s to kind_p as text
if (get text 1 of kind_s) ≠"«" then
return kind_s
else
set code_start to (get length of kind_s) - 4
set kind_code to get (text code_start thru (code_start + 3) of kind_s)
if kind_code = "CCpj" then
set kind_res to "project"
else if kind_code = "CCgp" then
set kind_res to "group"
else if kind_code = "CCal" then
set kind_res to "album"
else if kind_code = "CCsm" then
set kind_res to "smart album"
else if kind_code = "CCfv" then
set kind_res to "favorite"
else if kind_code = "CCff" then
set kind_res to "catalog folder"
else if kind_code = "COct" then
set kind_res to "catalog"
else if kind_code = "COsd" then
set kind_res to "session"
else
loqqed_Error_Halt("Unexpected Kind string: " & kind_s)
end if
end if
return kind_res
end convertKind0
Post is closed for comments.
Comments
1 comment