Locating Images in User Collections

Discussion regarding all scripting related questions
Please DO NOT post to this thread anything that is not directly related to scripting of Capture One.

Locating Images in User Collections

Postby Eric Nepean » Fri Jan 06, 2017 8:43 am

There have been a lnumber of users wishing for a feature that would find the location of an Image in the COP User Collections.

I have just written an Applescript Utility that does this. It's not short, but it is reasonably efficient.
Select all, copy and paste this code into the Applescript editor, and press run. Results appear in a dialog window, and also in the Applescript log window.

Code: Select all
-- Applescript to search a COP 10 Catalog for Collections containing the Image of a selected variant
-- Version 1.0 January 6, 2017 - posted on the the Phase One Forum, COP10 for Mac
-- Select only ONE or a small number of variants, from any collection.
-- Results appear first in the AppleScript Log when the search for each variant is completed, and in Display Dialog Windows when all searching is completed
-- This script will not search the All Images folder
-- This script has been tested on Catalogs up to 15000 images on an iMac 17,1 with external SSD and 24GB of RAM
-- This script has not been tested on COP Sessions
-- !!NO SUPPORT!!  any comments, please reply on the Phase One Forum, COP10 for Mac
-- This script does not write or delete any information. However when searching a very large catalog it is possible that it may cause a crash or a hang, although I have not observed this.
-- Eric Valk, Ottawa, Canada

global debug
set debug to false

global maxSearchLevel
set maxSearchLevel to 100

global searchedImageID

tell application "Capture One 10"
   
   if debug then
      set copVersion to (get app version)
      --properties of application "Capture One 10"   
      log "COP Version: " & copVersion
      log "Max Search Level" & maxSearchLevel
   end if
   
   if debug then
      set everyDoc to get every document
      repeat with doc_Counter from 1 to count of everyDoc
         set thisDocName to (get name of document doc_Counter) as text -- only index allowed is 1
         set thisDocFolder to (get folder of document thisDocName) as text
         set thisDocKind to (get kind of document thisDocName) as text
         set thisDocPath to (get path of document thisDocName) --subset of thisFolder
         log thisDocName & " " & thisDocKind & " is here --> " & thisDocPath
      end repeat
      
      tell document 1
         
         set everyCollection to get every collection
         repeat with c_Counter from 1 to count of everyCollection
            set thisCollName to (get name of collection c_Counter) as text
            set thisCollKind to (get kind of collection c_Counter) as text
            set thisCollColl to (get every collection of collection c_Counter)
            log "Contains: " & thisCollName & ", a " & thisCollKind & ", contains " & (count of thisCollColl) & " collections"
         end repeat
         
      end tell
   end if
   
   set selectedVariants to (get selected variants)
   if debug then log "In this window " & (count of selectedVariants) & " Selected Variants"
   
   
   if selectedVariants is {} then
      display alert "No images selected -  select one or more images"
      error "No images selected"
   else
      set countSelectedVariants to count of selectedVariants
      if countSelectedVariants > 15 then display dialog "Are you sure you want to search for " & countSelectedVariants & "variants?" with icon stop
      
      tell document 1
         
         set everyCollection to get every collection
         if (count of everyCollection) = 1 then -- If there are no user collections, there is only the "All Images" collection.
            display notification "No User Collections to Search"
            error "No User Collections to Search"
         end if
         
         set allResults to {}
         
         repeat with v_Counter from 1 to countSelectedVariants
            
            set thisVariant to item v_Counter of selectedVariants
            set searchedImage to (get parent image of thisVariant)
            set searchedImageName to (get name of searchedImage)
            set searchedImageID to (get id of searchedImage)
            
            if debug then log "Searching for " & searchedImageName & "     ID: " & searchedImageID
            display notification "Now searching for " & searchedImageID
            
            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 searchCollName to (get name of collection c_Counter) as text
                  set searchCollKind to (get kind of collection c_Counter) as text
                  
                  if searchCollName ≠ "All Images" then
                     
                     set resultPaths to my search_collection((collection c_Counter), nextSearchLevel)
                     set resultCount to count of resultPaths
                     
                     if debug then log "Result of search on" & searchCollName & " (" & searchCollKind & ") is: " & resultPaths
                     
                     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 isFound then
               set thisResult to {v_Counter, searchedImageName, true, foundPaths}
               log searchedImageName & " was found in:"
               log foundPaths
               display notification searchedImageName & " was found"
            else
               set thisResult to {v_Counter, searchedImageName, false, foundPaths}
               display notification searchedImageName & " was not found"
            end if
            set allResults to allResults & thisResult
         end repeat
         
         repeat with v_Counter0 from 0 to countSelectedVariants - 1
            set searchedImageName to (item ((v_Counter0 * 4) + 2) of allResults) as text
            set successImageName to (item ((v_Counter0 * 4) + 3) of allResults) as boolean
            set pathsImageName to (item ((v_Counter0 * 4) + 4) of allResults) as text
            if successImageName then
               set foundImagename to "found in"
            else
               set foundImagename to "not found"
            end if
            set junk1 to display alert searchedImageName & " was " & foundImagename & ":" message pathsImageName giving up after 180
         end repeat
         
      end tell
   end if
end tell

--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
   global maxSearchLevel
   global searchedImageID
   
   set nextSearchLevel to searchLevel + 1
   
   tell application "Capture One 10"
      tell document 1
         tell thisCollection
            
            set thisCollName to (get name) as text
            set thisCollKind to (get kind) as text
            set countCollsthisColl to count of every collection
            
            set everyImageIDList to get id of every image
            
            if debug then
               set nameCollsthisColl to (get name of every collection)
               set thisCollImages to get every image
               --set everyImageNameList to get name of every image
               log "In " & thisCollName & " at level " & searchLevel & " (" & thisCollKind & ")   has " & (count of thisCollImages) & " images   " & (count of thisCollColls) & " collections"
            end if
            
            set found_paths to {} -- initialise the list
            
            if everyImageIDList contains searchedImageID then
               set found_paths to found_paths & (thisCollName & "[" & thisCollKind & "]")
               if debug then log "Found here"
            end if
            
            set nextSearchLevel to searchLevel + 1
            if nextSearchLevel ≤ maxSearchLevel then
               
               if countCollsthisColl > 0 then
                  repeat with c_Counter from 1 to countCollsthisColl
                     
                     set resultPaths to my search_collection((collection c_Counter), nextSearchLevel)
                     set countResultPaths to count of resultPaths
                     
                     if debug then
                        set searchCollName to (get name of collection c_Counter) as text
                        set searchCollKind to (get kind of collection c_Counter) as text
                        log "Result of search on" & searchCollName & " (" & searchCollKind & ") is: " & resultPaths
                     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
            end if
            
         end tell
      end tell
   end tell
   return found_paths
end search_collection


I hope it works for you.
Cheers
Eric
(OSX 10.12, iMac and MacBook Air, Panasonic GX7,GM5,G5, Olympus E-M1)
Eric Nepean
 
Posts: 385
Joined: Sat Jun 28, 2014 8:54 pm
Location: Ontario, Canada

Re: Locating Images in User Collections

Postby peter.f » Fri Jan 06, 2017 4:06 pm

Hi Eric,

I will definitely give this a try when I get back home; this is a godsend! Thanks a lot!
My main use would be to be able to export files into a folder hierarchy that mimics the user collection structure. I hope I can learn a lot from your script.

Cheers,
Peter.

P.S. Hey Phase One, how hard can it be to provide this functionality? It's not the first time people ask for this!
X-T1, X100S; MBP 15" 2010, 8GB, OSX 10.11.4; Catalog on SSD, ref'd images on external USB2.
peter.f
 
Posts: 247
Joined: Sat Oct 25, 2014 6:38 pm
Location: Wilrijk, Belgium

Re: Locating Images in User Collections

Postby Eric Nepean » Fri Jan 06, 2017 7:30 pm

Minor fix up. Debug mode now works.

Code: Select all
-- Applescript to search a COP 10 Catalog for Collections containing the Image of a selected variant
-- Version 1.0.1  (Version comments at the end)  !! NO SUPPORT !!  Eric Valk, Ottawa, Canada
-- Select only a small number of variants, from any collection.
-- Results appear first in the AppleScript Log when the search for each variant is completed, and in Display Dialog Windows when all searching is completed
-- This script does not write or delete any information in the COP Catalog or Session or the image file

global debug
set debug to true

global maxSearchLevel
set maxSearchLevel to 100

global searchedImageID
set searchedImageID to ""

tell application "Capture One 10"
   
   if debug then
      set copVersion to (get app version)
      --properties of application "Capture One 10"   
      log "COP Version: " & copVersion
      log "Max Search Level" & maxSearchLevel
   end if
   
   if debug then
      set everyDoc to get every document
      repeat with doc_Counter from 1 to count of everyDoc
         set thisDocName to (get name of document doc_Counter) as text -- only index allowed is 1
         set thisDocFolder to (get folder of document thisDocName) as text
         set thisDocKind to (get kind of document thisDocName) as text
         set thisDocPath to (get path of document thisDocName) --subset of thisFolder
         log thisDocName & " " & thisDocKind & " is here --> " & thisDocPath
      end repeat
      
      tell document 1
         
         set everyCollection to get every collection
         repeat with c_Counter from 1 to count of everyCollection
            set thisCollName to (get name of collection c_Counter) as text
            set thisCollKind to (get kind of collection c_Counter) as text
            set thisCollColl to (get every collection of collection c_Counter)
            log "Contains: " & thisCollName & ", a " & thisCollKind & ", contains " & (count of thisCollColl) & " collections"
         end repeat
         
      end tell
   end if
   
   set selectedVariants to (get selected variants)
   if debug then log "In this window " & (count of selectedVariants) & " Selected Variants"
   
   
   if selectedVariants is {} then
      display alert "No images selected -  select one or more images"
      error "No images selected"
   else
      set countSelectedVariants to count of selectedVariants
      if countSelectedVariants > 3 then display dialog "Are you sure you want to search for " & countSelectedVariants & "variants?" with icon stop
      
      tell document 1
         
         set everyCollection to get every collection
         if (count of everyCollection) = 1 then -- If there are no user collections, there is only the "All Images" collection.
            display notification "No User Collections to Search"
            error "No User Collections to Search"
         end if
         
         set allResults to {}
         
         repeat with v_Counter from 1 to countSelectedVariants
            
            set thisVariant to item v_Counter of selectedVariants
            set searchedImage to (get parent image of thisVariant)
            set searchedImageName to (get name of searchedImage)
            set searchedImageID to (get id of searchedImage)
            
            if debug then log "Searching for " & searchedImageName & "     ID: " & searchedImageID
            display notification "Now searching for " & searchedImageID
            
            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 searchCollName to (get name of collection c_Counter) as text
                  set searchCollKind to (get kind of collection c_Counter) as text
                  
                  if searchCollName ≠ "All Images" then
                     
                     set resultPaths to my search_collection((collection c_Counter), nextSearchLevel)
                     set resultCount to count of resultPaths
                     
                     if debug then log "Result of search on" & searchCollName & " (" & searchCollKind & ") is: " & resultPaths
                     
                     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 isFound then
               set thisResult to {v_Counter, searchedImageName, true, foundPaths}
               log searchedImageName & " was found in:"
               log foundPaths
               display notification searchedImageName & " was found"
            else
               set thisResult to {v_Counter, searchedImageName, false, foundPaths}
               display notification searchedImageName & " was not found"
            end if
            set allResults to allResults & thisResult
         end repeat
         
         repeat with v_Counter0 from 0 to countSelectedVariants - 1
            set searchedImageName to (item ((v_Counter0 * 4) + 2) of allResults) as text
            set successImageName to (item ((v_Counter0 * 4) + 3) of allResults) as boolean
            set pathsImageName to (item ((v_Counter0 * 4) + 4) of allResults) as text
            if successImageName then
               set foundImagename to "found in"
            else
               set foundImagename to "not found"
            end if
            set junk1 to display alert searchedImageName & " was " & foundImagename & ":" message pathsImageName giving up after 180
         end repeat
         
      end tell
   end if
end tell

--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
   global maxSearchLevel
   global searchedImageID
   
   set nextSearchLevel to searchLevel + 1
   
   tell application "Capture One 10"
      tell document 1
         tell thisCollection
            
            set thisCollName to (get name) as text
            set thisCollKind to (get kind) as text
            set countCollsthisColl to count of every collection
            
            set everyImageIDList to get id of every image
            
            if debug then
               set nameCollsthisColl to (get name of every collection)
               set thisCollImages to get every image
               --set everyImageNameList to get name of every image
               log "In " & thisCollName & " at level " & searchLevel & " (" & thisCollKind & ")   has " & (count of thisCollImages) & " images   " & countCollsthisColl & " collections"
            end if
            
            set found_paths to {} -- initialise the list
            
            if everyImageIDList contains searchedImageID then
               set found_paths to found_paths & (thisCollName & "[" & thisCollKind & "]")
               if debug then log "Found here"
            end if
            
            set nextSearchLevel to searchLevel + 1
            if nextSearchLevel ≤ maxSearchLevel then
               
               if countCollsthisColl > 0 then
                  repeat with c_Counter from 1 to countCollsthisColl
                     
                     set resultPaths to my search_collection((collection c_Counter), nextSearchLevel)
                     set countResultPaths to count of resultPaths
                     
                     if debug then
                        set searchCollName to (get name of collection c_Counter) as text
                        set searchCollKind to (get kind of collection c_Counter) as text
                        log "Result of search on" & searchCollName & " (" & searchCollKind & ") is: " & resultPaths
                     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
            end if
            
         end tell
      end tell
   end tell
   return found_paths
end search_collection

--Notes
-- any comments, please reply on the Phase One Forum, COP 10 for Mac
-- Version 1.0
-- This script will not search the All Images folder
-- This script has been tested on Catalogs up to 15000 images on an iMac 17,1 with external SSD and 24GB of RAM
-- This script has not been tested on COP Sessions
--
-- Version 1.01
-- Fixed missing variable exposed in the debug mode
-- Moved some comments to end
-- Added initialisation of one Global variable (Global variables should always be initialised to a safe value)
Cheers
Eric
(OSX 10.12, iMac and MacBook Air, Panasonic GX7,GM5,G5, Olympus E-M1)
Eric Nepean
 
Posts: 385
Joined: Sat Jun 28, 2014 8:54 pm
Location: Ontario, Canada

Re: Locating Images in User Collections

Postby peter.f » Fri Jan 06, 2017 9:03 pm

No luck:

Running the script from within the script editor, with Capture One 9 running with 1 catalog open: ~/Pictures/Capture One Catalogs/Master 2016.cocatalog. Images on external HD.

When in debug mode, I get this:
error "Capture One 9 got an error: Can’t get folder of document \"Master 2016\"." number -1728 from folder of document "Master 2016"

Note: when I compile after pasting in the text, Script Editor converts that line (line 30) into "set thisDocFolder to (get «class COdf» of document thisDocName) as text".

When not in debug, I get this:
Result:
error "Capture One 9 got an error: Can’t get every image of collection 1 of document \"Master 2016\"." number -1728 from every image of collection 1 of document "Master 2016"

in the line "set everyImageIDList to get id of every image" of the function "search_collection".

The full log is:
Code: Select all
tell application "Capture One 9"
   get selected variants
      --> {variant 1 of document "Master 2016"}
   get every collection of document 1
      --> {collection 1 of document "Master 2016", collection 2 of document "Master 2016", collection 3 of document "Master 2016", collection 4 of document "Master 2016", collection 5 of document "Master 2016", collection 6 of document "Master 2016", collection 7 of document "Master 2016", collection 8 of document "Master 2016", collection 9 of document "Master 2016", collection 10 of document "Master 2016"}
   get parent image of variant 1 of document "Master 2016"
      --> image id "/Volumes/PHOTOS MASTER DISK 1/RAW Originals/2016/11/VARIA tuinkabouter-20161128-100X9131.RAF" of document "Master 2016"
   get name of image id "/Volumes/PHOTOS MASTER DISK 1/RAW Originals/2016/11/VARIA tuinkabouter-20161128-100X9131.RAF" of document "Master 2016"
      --> "VARIA tuinkabouter-20161128-100X9131.RAF"
   get id of image id "/Volumes/PHOTOS MASTER DISK 1/RAW Originals/2016/11/VARIA tuinkabouter-20161128-100X9131.RAF" of document "Master 2016"
      --> "/Volumes/PHOTOS MASTER DISK 1/RAW Originals/2016/11/VARIA tuinkabouter-20161128-100X9131.RAF"
   display notification "Now searching for /Volumes/PHOTOS MASTER DISK 1/RAW Originals/2016/11/VARIA tuinkabouter-20161128-100X9131.RAF"
      --> error number -10004
end tell
tell application "Script Editor"
   display notification "Now searching for /Volumes/PHOTOS MASTER DISK 1/RAW Originals/2016/11/VARIA tuinkabouter-20161128-100X9131.RAF"
end tell
tell application "Capture One 9"
   get name of collection 1 of document 1
      --> "Quick selects"
   get kind of collection 1 of document 1
      --> album
   get collection 1 of document 1
      --> collection 1 of document "Master 2016"
   get name of collection 1 of document "Master 2016"
      --> "Quick selects"
   get kind of collection 1 of document "Master 2016"
      --> album
   count every collection of collection 1 of document "Master 2016"
      --> 0
   get id of every image of collection 1 of document "Master 2016"
      --> error number -1728 from every image of collection 1 of document "Master 2016"
Result:
error "Capture One 9 got an error: Can’t get every image of collection 1 of document \"Master 2016\"." number -1728 from every image of collection 1 of document "Master 2016"


I also tried adding an image to the first collection, but that did not help.

Suggestions to troubleshoot?

Cheers,
Peter.
X-T1, X100S; MBP 15" 2010, 8GB, OSX 10.11.4; Catalog on SSD, ref'd images on external USB2.
peter.f
 
Posts: 247
Joined: Sat Oct 25, 2014 6:38 pm
Location: Wilrijk, Belgium

Re: Locating Images in User Collections

Postby Eric Nepean » Fri Jan 06, 2017 10:25 pm

Hi Peter

I see that you are running Capture One 9.

In Capture One 9 Applescript is not able to ask a Collection (i.e. Project, Group, Album or Smart Album) what images it contains.

The Applescript dictionary for COP 9 shows that a collection only holds other collections (that doesn't mean that images and variants are not there, but that the SW interface for Applescript to retreive this information is not present).

In COP 10 a collection also holds images and variants.

So unfortunately this script will not work at all in in COP 9, and I don't see a workaround since Applescript also cannot ask a variant or an image what collection it is in.
Cheers
Eric
(OSX 10.12, iMac and MacBook Air, Panasonic GX7,GM5,G5, Olympus E-M1)
Eric Nepean
 
Posts: 385
Joined: Sat Jun 28, 2014 8:54 pm
Location: Ontario, Canada

Re: Locating Images in User Collections

Postby peter.f » Sun Jan 08, 2017 11:31 am

Hi Eric,

that's a bummer. Thanks for the info!

Cheers,
Peter.
X-T1, X100S; MBP 15" 2010, 8GB, OSX 10.11.4; Catalog on SSD, ref'd images on external USB2.
peter.f
 
Posts: 247
Joined: Sat Oct 25, 2014 6:38 pm
Location: Wilrijk, Belgium


Return to Scripting



Who is online

Users browsing this forum: No registered users and 1 guest