Zum Hauptinhalt gehen

⚠️ Please note that this topic or post has been archived. The information contained here may no longer be accurate or up-to-date. ⚠️

duplicate images in collections

Kommentare

2 Kommentare

  • Eric Nepean
    I know of no way within Capture One to find out which collections an image is contained in.
    Consequently, I wrote an Applescript which does the job.
    You start by selecting the images you want reported, run the Applescript and it provides a report for each of the slected images in a text edit document.
    -- Applescript to search a COP 10 Catalog for Collections containing the Image of a selected variant
    -- Version 1.10 !! NO SUPPORT !!
    -- Copyright 2017 Eric Valk, Ottawa, Canada

    -- ***To Initialise
    -- Start Script Editor, open a new (blank) file, copy and paste all of this code into the file, compile (hammer symbol) and save.
    -- Best if you make "Scripts" folder somewhere handy in your Douments or Desktop

    -- *** 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 a TextEdit document when the search for each variant is completed.
    -- This script does not write or delete any information in the COP Catalog or Session or the image file

    set debug to 0
    set Results_max_debug to 0

    set maxSearchlevel to 100
    property searchTimePerVariant : 0
    set WarnMaxVariants to 3
    set WarnSearchTime to 30
    set SearchDiskFileSystem to false
    set SearchRecentImports to false
    set SearchRecentCaptures to false
    set SearchTrash to false

    if SearchDiskFileSystem then
    set ExcludedTopCollectionKinds to {""}
    else
    set ExcludedTopCollectionKinds to {"folder"}
    end if
    set ExcludedTopCollectionNames to {"Catalog", "All Images"}
    set ExcludedSubCollectionNames to {""} -- used for testing
    set StopSearchAtProject to false
    if not SearchRecentImports then set ExcludedTopCollectionNames to ExcludedTopCollectionNames & "Recent Imports"
    if not SearchRecentCaptures then set ExcludedTopCollectionNames to ExcludedTopCollectionNames & "Recent Captures"
    if not SearchTrash then set ExcludedTopCollectionNames to ExcludedTopCollectionNames & "Trash"

    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")

    set Result_DocName to "COP_Image_Search.txt"
    set Result_Doc_Path_p to my open_TextDoc(Result_DocName)
    my loq_TextDoc("Action: Find collections where images are located", false, 0)
    my loq_TextDoc(Script_Title & " started from: " & parent_name, false, 0)

    set minCOPversion to "10.1.2"
    validateCOP(minCOPversion)
    set {COPDocName, COPDocRef} to validateCOPdoc({"catalog", "session"})

    set options_display_string to "Debug Level: " & debug
    if SE_Logging then set options_display_string to options_display_string & return & "Highest Debug Class in Result File: " & Results_max_debug
    set options_display_string to options_display_string & return & "Maximum Search Level: " & maxSearchlevel
    set options_display_string to options_display_string & return & "Estimated Search Time per Variant: "
    if searchTimePerVariant = 0 then
    set options_display_string to options_display_string & "unknown"
    else
    set options_display_string to options_display_string & searchTimePerVariant
    end if
    set options_display_string to options_display_string & return & "Search Managed Files: " & false
    set options_display_string to options_display_string & return & "Search Referenced Files: " & SearchDiskFileSystem
    set options_display_string to options_display_string & return & "Search Recent Imports: " & SearchRecentImports
    set options_display_string to options_display_string & return & "Search Recent Captures: " & SearchRecentCaptures
    set options_display_string to options_display_string & return & "Search All Images: " & false
    set options_display_string to options_display_string & return & "Search COP Trash: " & false
    set options_display_string to options_display_string & return & "Other Excluded Collections: " & ExcludedSubCollectionNames
    set options_display_string to options_display_string & return & "Do Not Search below Projects: " & StopSearchAtProject
    set options_display_string to options_display_string & return & "Results File: " & Result_Doc_Path_p

    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_exit("User Cancelled the Script")
    end try

    if debug ≥ 1 then my loq_TextDoc((return & "Options:" & return & options_display_string & return), true, 1)

    tell application "Capture One 10" to set selectedVariants to (get selected variants)
    set countSelectedVariants to count of selectedVariants

    if debug ≥ 3 then my loq_TextDoc(("In this window " & (count of selectedVariants) & " Selected Variants"), false, 3)

    if countSelectedVariants = 0 then
    display alert "No images selected - select one or more images"
    my loqqed_exit("No images selected")
    else
    set estimatedDuration to countSelectedVariants * searchTimePerVariant

    tell application "System Events" to set frontmost of process parent_name to true
    try
    if countSelectedVariants > WarnMaxVariants and searchTimePerVariant = 0 then
    display dialog "Are you sure you want to search for " & countSelectedVariants & " variants? " with icon caution

    else if estimatedDuration > WarnSearchTime then
    display dialog "Are you sure you want to search for " & countSelectedVariants & " variants? Estimated time: " & estimatedDuration & " seconds" with icon caution
    end if
    on error errmess
    my loqqed_exit("User Cancelled the Script")
    end try

    set nameSelectedVariants to {}
    set idParentSelectedVariants to {}
    repeat with v_Counter from 1 to countSelectedVariants
    set thisVariant to item v_Counter of selectedVariants
    tell application "Capture One 10"
    set nameSelectedVariants to nameSelectedVariants & (get name of thisVariant)
    set idParentSelectedVariants to idParentSelectedVariants & (get id of parent image of thisVariant)
    end tell
    end repeat

    if debug ≥ 3 then
    log nameSelectedVariants
    log idParentSelectedVariants
    end if

    set startTime to get time of (get current date)
    tell application "Capture One 10" to set everyCollection to get every collection of document COPDocName

    set allResults to {}
    set search_executed to false
    set progress total steps to countSelectedVariants
    set progress completed steps to 0
    set progress description to "Searching for Variants ..."
    repeat with v_Counter from 1 to countSelectedVariants

    set thisVariant to item v_Counter of selectedVariants
    set searchedImageName to item v_Counter of nameSelectedVariants
    set searchedImageID to item v_Counter of idParentSelectedVariants

    set progress completed steps to v_Counter
    set progress description to "Searching for Variant " & searchedImageName
    if debug ≥ 2 then my loq_TextDoc((return & "Searching for " & searchedImageName & " ID: " & searchedImageID), false, 2)

    set isFound to false
    set foundPaths to ""
    set pathSeparator to ""
    set searchLevel to 0
    set nextSearchLevel to searchLevel + 1

    if nextSearchLevel ≤ maxSearchlevel then
    repeat with c_Counter from 1 to count of everyCollection
    set thisTopCollection to item c_Counter of everyCollection
    tell application "Capture One 10" to tell document COPDocName to tell thisTopCollection
    set {topCollName, topCollKind_p} to {name as text, kind}
    end tell
    set topCollKind to my convertKind(topCollKind_p)

    if (ExcludedTopCollectionNames does not contain topCollName) and ¬
    (ExcludedTopCollectionKinds does not contain topCollKind) then
    set search_executed to true

    set resultPaths to my search_collection(thisTopCollection, nextSearchLevel)
    set resultCount to count of resultPaths

    if debug ≥ 3 then my loq_TextDoc(("Result of search in " & topCollName & " (" & topCollKind & ") is: " & resultPaths), false, 3)

    if resultCount > 0 then
    set isFound to true
    repeat with p_counter from 1 to count of resultPaths
    set foundPaths to foundPaths & pathSeparator & item p_counter of resultPaths
    set pathSeparator to return -- after the first path is added the separator become the newline character /r
    end repeat
    end if

    end if
    end repeat
    end if

    if not search_executed then -- there are no top level collections to search - don't keep searching
    display notification "No Top Level Collections to Search"
    my loqqed_exit("No Top Level Collections to Search")
    end if

    if isFound then
    set thisResult to {v_Counter, searchedImageName, true, foundPaths}
    my loq_TextDoc((return & searchedImageName & " was found in:" & return & foundPaths), true, 0)
    if debug ≥ 2 then display notification searchedImageName & " was found"
    else
    set thisResult to {v_Counter, searchedImageName, false, foundPaths}
    my loq_TextDoc((return & searchedImageName & " was not found"), true, 0)
    display notification searchedImageName & " was not found"
    end if
    set allResults to allResults & thisResult

    end repeat

    set stopTime to get time of (get current date)
    if stopTime < startTime then set startTime to startTime - 86400 -- the search started yesterday and ended today
    set elapsedtime to stopTime - startTime
    set searchTimePerVariant to elapsedtime / countSelectedVariants
    my loq_TextDoc((return & "This search took " & elapsedtime & " seconds (" & searchTimePerVariant & "s per variant)" & return & return & "Done"), true, 0)

    say "Finished!"

    end if

    tell application "System Events" to set frontmost of process "Capture One 10" to true
    tell application "System Events" to set frontmost of process "TextEdit" to true

    --Handlers -------------------

    on search_collection(thisCollection, searchLevel)
    -- recursive handler to search a collection and it's subcollections
    -- if successful, returns a list of paths each as a text string

    global debug, maxSearchlevel, searchedImageID, COPDocName, StopSearchAtProject, ExcludedSubCollectionNames

    set found_paths to {} -- initialise the list
    tell application "Capture One 10" to tell document COPDocName to tell thisCollection
    set thisCollName to name as text
    set thisCollKind to my convertKind(kind)
    end tell
    set progress additional description to thisCollKind & " " & thisCollName

    if ExcludedSubCollectionNames contains thisCollName then return found_paths

    tell application "Capture One 10" to tell document COPDocName to tell thisCollection
    set CollsinthisColl to every collection
    set searchImageIDhits to count of (get every image whose id is searchedImageID)
    end tell
    set countCollsthisColl to count of CollsinthisColl


    if searchImageIDhits > 0 then
    set found_paths to found_paths & (thisCollName & "(" & thisCollKind & ")")
    if debug ≥ 4 then my loq_TextDoc(("Found " & searchImageIDhits & " hits in " & thisCollKind & " " & thisCollName), false, 4)
    end if

    if debug ≥ 5 then
    tell application "Capture One 10" to tell document COPDocName to tell thisCollection
    set countImages to count of every image
    set countVariants to count of every variant
    end tell
    my loq_TextDoc(("In " & thisCollKind & " " & thisCollName & " at level " & searchLevel & " found " & countImages & " images ," & countVariants & " variants ," & countCollsthisColl & " collections"), false, 5)
    end if

    set nextSearchLevel to searchLevel + 1
    if (nextSearchLevel ≤ maxSearchlevel) and ¬
    (not (StopSearchAtProject and thisCollKind = "project")) then

    repeat with c_Counter from 1 to countCollsthisColl

    set resultPaths to my search_collection((item c_Counter of CollsinthisColl), nextSearchLevel)
    set countResultPaths to count of resultPaths

    if debug ≥ 4 then
    tell application "Capture One 10" to tell document COPDocName to tell thisCollection
    set searchCollName to (get name of item c_Counter of CollsinthisColl) as text
    set searchCollKind_p to (get kind of item c_Counter of CollsinthisColl)
    end tell
    set searchCollKind to my convertKind(searchCollKind_p)
    my loq_TextDoc(("Result of search in " & searchCollName & " (" & searchCollKind & ") is: " & resultPaths), false, 4)
    end if

    if countResultPaths > 0 then
    repeat with p_counter from 1 to countResultPaths
    set found_paths to found_paths & (thisCollName & "<" & item p_counter of resultPaths)
    end repeat
    end if
    end repeat

    end if

    return found_paths

    end search_collection

    on validateCOP(minCOPversionstr)
    global debug
    tell application "System Events"
    set COPProcList to every process whose name contains "Capture One" and background only is false
    if debug ≥ 2 then
    set COPProcNameList to name of every process whose name contains "Capture One" and background only is false
    my loq_TextDoc(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 10" to set copVersion to (get app version)

    if debug ≥ 2 then
    --properties of application "Capture One 10"
    tell application "System Events"
    my loq_TextDoc((get name of every process whose background only is false), false, 2)
    end tell
    my loq_TextDoc(("theAppName: " & theAppName), false, 2)
    my loq_TextDoc(("COP Version: " & copVersion), false, 2)
    my loq_TextDoc(("COP Detailed Version: " & copDetailedVersion), false, 2)
    end if

    if the theAppName ≠ "Capture One 10" then
    display notification "Wrong COP Application"
    my loqqed_exit("Found COP Application " & theAppName & " The only supported COP application is Capture One 10")
    end if

    set numCOPversion to (extract_version_strings(".", (word -1 of copVersion)))
    set minCOPversion to (extract_version_strings(".", minCOPversionstr))

    set Version_digit to ((item 3 of numCOPversion) as integer) + ¬
    100 * ((item 2 of numCOPversion) as integer) + 10000 * ((item 1 of numCOPversion) as integer)
    set min_digit to ((item 3 of minCOPversion) as integer) + ¬
    100 * ((item 2 of minCOPversion) as integer) + 10000 * ((item 1 of minCOPversion) as integer)

    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
    my loq_TextDoc(("Capture One Version " & copDetailedVersion), false, 0)
    end validateCOP

    on validateCOPdoc(COP_kind_list)
    global debug
    tell application "Capture One 10"
    set {current_doc_name, current_doc_kind} to (get {name, kind} of current document)
    set current_doc_abs_list to (get every document whose name is current_doc_name and kind is current_doc_kind)
    end tell
    set current_doc_kind_s to my convertKind(current_doc_kind)
    if COP_kind_list does not contain current_doc_kind_s then my loqqed_exit(current_doc_name & " is a " & current_doc_kind_s & " unsupported type", true)

    set number_of_hits to count of current_doc_abs_list
    if number_of_hits = 0 then
    my loqqed_exit("Could not find find " & current_doc_kind_s & current_doc_name)
    else if number_of_hits > 1 then
    my loqqed_exit("Found more than one " & current_doc_kind_s & " with the name " & current_doc_name)
    else
    set current_doc_abs to item 1 of current_doc_abs_list
    end if
    my loq_TextDoc(("Capture One " & current_doc_kind_s & ": " & current_doc_name), false, 0)
    return {current_doc_name, current_doc_abs}
    end validateCOPdoc


    on extract_version_strings(d, t)
    set astid to AppleScript's text item delimiters
    try
    set AppleScript's text item delimiters to d
    set version_strings to text items of t
    on error
    set AppleScript's text item delimiters to astid
    end try
    set AppleScript's text item delimiters to astid

    return version_strings
    end extract_version_strings


    on open_TextDoc(DocName_Ext)
    global debug, Script_Title, Result_Doc_ref, SE_Logging

    set target_folder_name to "ScriptReports"
    tell current application to set date_string to (current date) as text
    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 (debug ≥ 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
    my loq_TextDoc((return & "Started on: " & date_string), false, 0)
    return Result_Doc_Path_p
    end open_TextDoc

    on loq_TextDoc(logText, MakeFront, debug_class)
    global Result_Doc_ref, debug, SE_Logging, Results_max_debug

    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 joinList(logText, ", ")
    else
    log logText_class
    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 (debug_class ≤ Results_max_debug) or not SE_Logging 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
    end if

    if (debug ≥ 1) and SE_Logging then log (logText as text)
    tell application "System Events" to if MakeFront then set frontmost of process "TextEdit" to true
    end loq_TextDoc

    on loqqed_exit(error_text)
    global debug, Script_Title
    my loq_TextDoc(("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 convertKind(kind_p)
    global debug

    tell application "Capture One 10" to 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) - 2
    set kind_code to get (text code_start thru (code_start + 1) of kind_s)

    if kind_code = "pj" then
    set kind_res to "project"
    else if kind_code = "gp" then
    set kind_res to "group"
    else if kind_code = "al" then
    set kind_res to "album"
    else if kind_code = "sm" then
    set kind_res to "smart album"
    else if kind_code = "fv" then
    set kind_res to "favorite"
    else if kind_code = "ff" then
    set kind_res to "folder"
    else if kind_code = "ct" then
    set kind_res to "catalog"
    else if kind_code = "sd" then
    set kind_res to "session"
    else
    error "Unexpected Kind string: " & kind_s
    end if
    end if
    return kind_res
    end convertKind

    to joinList(aList, delimiter)
    set retVal to ""
    set prevDelimiter to AppleScript's text item delimiters
    set AppleScript's text item delimiters to delimiter
    set retVal to aList as string
    set AppleScript's text item delimiters to prevDelimiter
    return retVal
    end joinList
    0
  • Mark Golledge
    huge thanks eric!!! I will give it a go!
    0

Post ist für Kommentare geschlossen.