Skip to main content

Duplicate last variant

Comments

34 comments

  • HansB
    I think you need to use the 'parent image' for that, not the 'variant'. But I'm not sure, and I cannot test it right now.
    Maybe you can give it a try.


    Regards,
    Hans
    0
  • Eric Valk
    I don't find a "duplicate" command in Capture One's Applescript dictionary.

    Finder has a "duplicate" command, and handles aliases.

    I think what you may want to do is to extract the path of the image file from Capture One, and then tell Finder to duplicate it.
    ## untested but similar to code I have written
    tell application "Capture One 11" to set theImageFilePath to get path of parent image of the last variant

    tell application "Finder"
    set backupFolder to alias "Macintosh HD:Users:fotograaf:Desktop:BackUp"
    duplicate theImageFilePath to backupFolder
    end tell
    0
  • Patrick de Gier
    Thanks Eric and Hans,

    I will test it. Thanks again!

    Patrick
    0
  • Patrick de Gier
    Hi Eric,

    I've tested the script but it is giving me this error

    Schermafbeelding%202018-10-10%20om%2011.07.27[/img]

    it says: Handler could not run objects of this class

    Do you know how to fix this?

    Thanks Patrick
    0
  • Eric Valk
    Hi Patrick

    It took some debugging but this works. Applescript has many complex ways to represent a file and navigating them is tricky.


    ##_ps indicates the string representation of the path in POSIX form
    ##_as indicates the string representation of the path in alias form
    tell application "Capture One 11" to set theImageFilePath_ps to get path of parent image of primary variant
    set backupFolder_as to (get path to desktop folder) & "Backup" as string
    set theImageFile_as to get (get alias POSIX file theImageFilePath_ps) as string
    tell application "Finder" to duplicate file theImageFile_as to folder backupFolder_as with replacing
    0
  • Patrick de Gier
    You're a genius Eric! this works.
    This was way to complex for me but I keep on learning.

    Thanks a lot!

    Patrick
    0
  • Eric Valk
    I keep on learning too, as I do this.

    BTW, Google search is a great tool, e.g. search for “AppleScript finder duplicate exampleâ€, hits from Stackexchange and MacScripter are often quite informative. MacScripter forum has many of the really deep AppleScript coders as members and you can get really good advice here.
    0
  • Patrick de Gier
    Thanks! I know Stackexchange indeed. Posted some questions on Stackexchange before, really helpfull applescripting for Capture One is still a bit specific.

    I've been playing around with your last script and made some changes to make it more flexible, by asking with a prompt for a backup folder. I only tried it by running it from the scripteditor,but running it with an capture done script, It will ask you to choose a backup folder when you shoot you're first image. After that you can keep shooting and the script will duplicate the images to that specific folder.

    What I want is when the backup folder is deleted or when you start a new Session, it should ask you to choose a new backup folder. But it does not exactly what I want at the moment. See script below.

    It works fine the first tim you run it. eWhen you delete your previous made backup folder and empty your trash. The script gives an error that it cannot find the backup folder but it is not asking to choose a new backup folder (What I want when the backup folder is missing). When you click on "Compile" again in the script editor it works fine again and it is asking for a new backup folder..

    See this script maybe you can try it:


    ##_ps indicates the string representation of the path in POSIX form
    ##_as indicates the string representation of the path in alias form
    property backupFolder_as : ""

    tell application "Capture One 11" to set theImageFilePath_ps to get path of parent image of primary variant
    if backupFolder_as = "" then
    set backupFolder_as to choose folder with prompt "Select backup folder:" as string
    else
    try
    --if the script has a property that has been deleted (i.e., the backup folder), it will cause
    --an error that resolves by asking for a new folder
    set backupFolder_as to backupFolder_as as alias
    on error
    set backupFolder_as to choose folder with prompt "Select backup folder:"
    end try
    end if
    set theImageFile_as to get (get alias POSIX file theImageFilePath_ps) as string
    tell application "Finder" to duplicate file theImageFile_as to folder backupFolder_as with replacing
    0
  • Eric Valk
    Hi ans
    Since I arrive home late I don't have a chance to fully debug this scrript.

    But one thing that I notice immediately is this line

    set backupFolder_as to choose folder with prompt "Select backup folder:" as string
    Adding a log statement I verified that the variable/property backupFolder_as is class "alias" not class "text". The as string command only converts "Select backup folder:" to a string (which it already was)

    The way Applescript works is that once defined, an alias always points to the same file or folder, even if you move it and I think even if you rename it. I think it is actually a reference to the inode of the file. (For this reason, an alias can only be defined for a file or folder which already exists. The string can be written, but trying to convert it to type alias will fail.)

    Now what happens when I use the script to create a Backup folder, use it a few times and then delete it, the i]Backup[/i] folder is moved to Trash. But it still exists, and has the same inode. The next time I run the script, it copies the image file to the Backup folder in the Trash. 😂 😂 Not useful.

    Then if you empty the Trash, the alias refers to a folder that doesn't exist, and the final line that uses backupFolder_as as a target location crashes.

    So the first fix is to rewrite that line like this

    set backupFolder_as to get (choose folder with prompt "Select backup folder:") as string
    Now choose folder creates an alias, which is immediately converted to a string. Now when the folder is deleted, the alias does not follow to the Trash.

    This far I have debugged.

    Then I think after the else statement, I would modify the try structure like this

    try
    --if the previously created backup folder has been deleted or moved, the alias cannot be created
    --the error that results causes the script to ask for a new folder
    get backupFolder_as as alias
    on error
    set backupFolder_as to get (choose folder with prompt "Select backup folder:") as string
    end try
    0
  • Patrick de Gier
    Hi Eric,

    I've made the changes and tested it. From the Scripteditor it works fine! But when it is triggered by a capture done script it is prompting for an backup after every shot now.. Help 😊

    Patrick
    0
  • Eric Valk
    Hi Patrick
    I think what may be happening is that the property value is reset when Capture done script. Hard to know. And I don't have a camera for tethered shooting.

    I will look at it in more detail this evening.

    Can you change the two dialogs for "choose folder" so that they are slightly different, perhps add a "1" in the title of one, and "2" in the other title.

    Then tell me which dialog is being triggered, the one triggered by the property as "" or the one triggered by failure of the alias to be created.

    From there we can devise a fix.
    0
  • Patrick de Gier
    Hi Eric,

    I changed the dialogs as you said. The one which is triggered over and over again when shooting tethered is the first line triggered by the property. So I think it has something to do with the capture done.

    This is how the code looks now:

    property backupFolder_as : ""

    tell application "Capture One 11" to set theImageFilePath_ps to get path of parent image of primary variant
    if backupFolder_as = "" then
    set backupFolder_as to get (choose folder with prompt "Select backup folder 1:") as string
    else
    try
    --if the previously created backup folder has been deleted or moved, the alias cannot be created
    --the error that results causes the script to ask for a new folder
    get backupFolder_as as alias
    on error
    set backupFolder_as to get (choose folder with prompt "Select backup folder 2:") as string
    end try
    end if
    set theImageFile_as to get (get alias POSIX file theImageFilePath_ps) as string
    tell application "Finder" to duplicate file theImageFile_as to folder backupFolder_as with replacing


    This is the capture done script which is triggering, pretty simple:

    tell application "Capture One 11"
    set capture done script to alias "Macintosh HD:Users:Shared:Scripts:Backup.scpt"
    end tell


    When triggering from the scripteditor it works perfect. After removing the specific folder, it triggers the second line by the failure.

    Thanks,

    Patrick
    0
  • Eric Valk
    Hmmmm a properties life (value is not reset) is until the script is recompiled. Since the script specified in the capture done handler is a "scpt" it is not complied - and therefore compiled everytime it is called.

    If the script is compiled and saved as an ".app", and the Capture Done Handler is modified to call the the compiled script, it should work as expected.

    In Script Editor, choose "Save "As" and then set File Format to be "Application"
    0
  • Patrick de Gier
    Hi Eric, No succes..
    I've compiled the script and saved it as an .app and i've modified the capture done script to trigger the .app.
    But same thing is happening.

    Also tried to save it as an compiled run only script, but same thing happening.

    When I just double click on the .app to duplicate the parent image, it does exactly what I want. But when triggered by the capture done script it goes wrong. So it has to be something to do with the capture done script.

    Can the "alias" in the script be the problem? Is there another way to write the capture done script shown below?


    tell application "Capture One 11"
    set capture done script to alias "Macintosh HD:Users:Shared:Scripts:Backup.app"
    end tell


    Thanks Patrick
    0
  • Eric Valk
    I guess that it's something about Capture One itself. But I don't know yet.

    The script call doesn't have to be "alias", the POSIX format should also work:


    ## untested
    tell application "Capture One 11"
    set capture done script to POSIX file "/Users/Shared/Scripts/Backup.app"
    end tell
    0
  • Eric Valk
    I note the following text from the Applescript Language Guide

    • property x: 3

      The scope of a property definition is the script object in which it is declared, including any handlers or nested script objects. A property definition specifies an initial value. You cannot declare a property in a handler.

      The value set by a property definition is not reset each time the script is run; instead, it persists until the script is recompiled.

    • global x

      The scope of a global variable can be limited to specific handlers or contained script objects or it can extend throughout a top-level script object. A global declaration doesn’t set an initial value—it must be initialized by a copy or set command before a script can access its value.

      The value of a global variable is not reset each time a script is run, unless its initialization statement is executed.
    Perhaps the "Capture Done Script" is being run as a handler. In such case, the clause "You cannot declare a property in a handler." means that the property value assignment does not work correctly.

    Then we can acheive the desired result with this:

    ##untested
    ## including these two lines is general good practice as it ensures repeatable behaviour in certain ambiguos circumstances
    use AppleScript version "2.4"
    use scripting additions

    global backupFolder_as

    try
    backupFolder_as -- test if the variable is defined
    set backup_exists to true
    on error
    set backup_exists to false
    end try

    tell application "Capture One 11" to set theImageFilePath_ps to get path of parent image of primary variant

    if not backup_exists then
    set backupFolder_as to get (choose folder with prompt "Select backup folder 1:") as string
    else
    try
    --if the previously created backup folder has been deleted or moved, the alias cannot be created
    --the error that results causes the script to ask for a new folder
    get backupFolder_as as alias
    on error
    set backupFolder_as to get (choose folder with prompt "Select backup folder 2:") as string
    end try
    end if
    set theImageFile_as to get (get alias POSIX file theImageFilePath_ps) as string
    tell application "Finder" to duplicate file theImageFile_as to folder backupFolder_as with replacing
    0
  • Patrick de Gier
    Aaah same thing happening again. It is asking for the backup folder after every shot..
    Maybe we are trying to achieve something which is not possible?..

    Thanks for al your efforts Eric
    0
  • Patrick de Gier
    Or do you think there's another solution?
    0
  • Eric Valk
    Hi Pat
    I think this problem cannot be solved with a property.

    Tonight I built some test scripts that generated the same behaviour as you have seen with Capture One. I have tried a number of different ways, but I cnnot find a way to make the script which is run by another process save the previous value of the property, it always goes to the initial value.

    The solution that is sure to work is to refer to a file called for example "BackupFolderAlias.txt" in the same folder as the Backup script. The Backup script checks for this file. If the file exists, and if it contains a string that can be made into an alias to a folder, then the alias is used.
    If not, a new folder is obtained, and the alias is written to the file.

    from already working AppleScript I have the following code which can be adapted, just not time to do it yet.

    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
    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 & """
    end if
    0
  • Patrick de Gier
    Hi Eric,

    I'm going to play around with your script. But I'm afraid it will be a bit to complicated for me at this point..
    So if it is not to much to ask and if you have any time? How would you adapt the script?


    If I see it right, is: "set target_folder_a to (POSIX file target_folder_p) as string" the check part with the string where you are talking about in your explanation?

    Thanks Patrick
    0
  • Eric Valk
    [quote="Pat78" wrote:
    Hi Eric,

    I'm going to play around with your script. But I'm afraid it will be a bit to complicated for me at this point..
    So if it is not to much to ask and if you have any time? How would you adapt the script?


    If I see it right, is: "set target_folder_a to (POSIX file target_folder_p) as string" the check part with the string where you are talking about in your explanation?

    Thanks Patrick


    Here is a first draft; I ran out of time last night. Partially tested.

    The logic is still abit reundant and can be improved.


    use AppleScript version "2.4"
    use scripting additions

    set cache_file_name to "BackupFolderAlias.txt"
    tell application "Finder" to set script_path_as to (get path to me as string)
    log {"script_path_as",script_path_as}
    set lastword to get (last word of script_path_as) as string
    set dropcount to -1 - (count of lastword)
    log {"dropcount",dropcount}
    if {"app", "scpt"} contains lastword then
    set lastword to get (word -2 of script_path_as) as string
    set dropcount to dropcount - 1 - (count of lastword)
    end if
    log {"dropcount",dropcount}
    set cache_file_as to (get text 1 thru dropcount of script_path_as) & cache_file_name
    set cache_file_p to get POSIX path of cache_file_as
    log{"cache_file_as",cache_file_as}

    try
    alias cache_file_as
    set cache_file_empty to false
    set backupFolder_as to do shell script "cat "" & cache_file_p & """
    on error
    set cache_file_empty to true
    set backup_exists to false
    do shell script "echo "" > " & """ & cache_file_p & """
    end try
    log{"cache_file_empty",cache_file_empty}

    if not cache_file_empty then
    try
    alias set backupFolder_as
    set backup_exists to true
    on error
    set backup_exists to false
    set cache_file_empty to true
    end try
    log {"cache_file_empty",cache_file_empty,"backup_exists",backup_exists}

    tell application "Capture One 11" to set theImageFilePath_ps to get path of parent image of primary variant

    if not backup_exists then
    set backupFolder_as to get (choose folder with prompt "Select backup folder 1:") as string
    else
    try
    --if the previously created backup folder has been deleted or moved, the alias cannot be created
    --the error that results causes the script to ask for a new folder
    get backupFolder_as as alias
    on error
    set backupFolder_as to get (choose folder with prompt "Select backup folder 2:") as string
    do shell script "echo "" & backupFolder_as & "" > " & """ & cache_file_p & """
    end try
    end if

    set theImageFile_as to get (get alias POSIX file theImageFilePath_ps) as string
    tell application "Finder" to duplicate file theImageFile_as to folder backupFolder_as with replacing
    0
  • Patrick de Gier
    Hi Eric,
    Wow, that was indeed way to complicated for me. But when diving into the log if learned a lot again.
    But.. no succes, sorry

    There were a few syntax errors, I debugged these lines:


    if not cache_file_empty then
    try
    alias set backupFolder_as -- I removed "set" in this line
    set backup_exists to true
    on error
    set backup_exists to false
    set cache_file_empty to true
    end try
    log {"cache_file_empty",cache_file_empty,"backup_exists",backup_exists}
    end if -- end if was missing here


    But when I run the script from the editor it keeps asking for the backup folder 1 every time I run the script.

    When I run it with a Capture Done from Capture One it gives me this error:

    "sh: /Macintosh HBackupFolderAlias.txt: Permission denied"
    0
  • Eric Valk
    Hi Pat

    The last draft was something I wrote quickly before leaving for work. Here is something much better.

    The logic is now much simpler, and better deugging is added.

    Because of the difficulty of finding the path to the script when Capture One runs it (and Capture One might actually copy the script and store it somewhere else) I have chosen to put the cache file in the user's ~/Library/Scripts folder. This at least exists, and the user has permission to write here, and we eliminate the difficulty of removing an item from the path string.

    ## EDITTED ONCE
    use AppleScript version "2.4"
    use scripting additions
    set debug_notify to true
    set debug_log to false
    local backupFolder_as

    ## The cache file is stored in the user's scripts folder: ~/Library/Scripts
    set cache_file_name to "BackupFolderAlias.txt"
    tell application "System Events" to set cache_file_path_a to (get path to scripts folder)
    set cache_file_ps to get POSIX path of (get cache_file_path_a as string) & cache_file_name
    if debug_notify then display notification "Backup alias cache file "" & cache_file_ps & """
    if debug_log then log "Backup alias cache file "" & cache_file_ps & """

    try
    set backupFolder_as to do shell script "cat "" & cache_file_ps & """ -- try to read the cache file
    ## simple checks for invalid alias strings
    if 100 < (get count of backupFolder_as) then ¬
    error "Backup alias string has more than 100 characters" number -1702
    if not ":" = (get text -1 of backupFolder_as) then ¬
    error "Backup alias string has no colon at end" number -1702
    if backupFolder_as contains return then ¬
    error "Backup alias string contains a return" number -1702
    tell application "System Events" to set thekind to get kind of alias backupFolder_as -- check the alias is valid
    if not "folder" = (get thekind as string) then ¬
    error "Backup alias string does not refer to a folder"
    on error eStr number eNum
    ## Error -1702 - corrupt data - is always reported
    if debug_notify or (-1702 = eNum) then display notification eStr
    if debug_log or (-1702 = eNum) then log eStr
    set backupFolder_as to get (choose folder with prompt "Select backup folder:") as string
    do shell script "echo "" & backupFolder_as & "" > " & """ & cache_file_ps & """
    end try
    if debug_notify then display notification "Backup Folder is "" & (get POSIX path of backupFolder_as) & """
    if debug_log then log "Backup Folder is "" & (get POSIX path of backupFolder_as) & """

    tell application "Capture One 11" to set theImageFilePath_ps to get path of parent image of primary variant

    set theImageFile_as to get (get alias POSIX file theImageFilePath_ps) as string
    tell application "Finder" to duplicate file theImageFile_as to folder backupFolder_as with replacing

    As usual, let me know how this goes.
    0
  • Patrick de Gier
    Hi Eric,

    Same thing is happening again. It is asking to set the backup folder after every shot again unfortunately.

    Now I am testing a "load script" command". So I set the variable (backup folder) with "script 1" (This script is loaded in de script menu from capture One, so I can set it from Capture One).

    The variable from script 1 is then called by a second script which is triggered by the Capture done. (with "load script").
    I hope working this way the handler from the Capture Done script isn't affecting the variable/property anymore.

    Tonight i'm a bit busy but I will keep you posted and will post the draft later today or tomorrow.

    Thanks!

    Patrick
    0
  • Eric Valk
    Hi Pat
    This time I have setup notifications so that it tells by display notification why it is making decisions.

    When you have time, can you run the script and tell me what notifications have been sent.
    0
  • Patrick de Gier
    Hi Eric,
    Ok great! I will have a look at the notifications later today.

    Thanks!
    0
  • Patrick de Gier
    Hi Eric,
    Ok great! I will have a look at the notifications later today.

    Thanks!
    0
  • Eric Valk
    There two or three notifications, you may have to open notification center to see them all.
    The first tells the name of the cache file, the second (if present) tells the error that forced the cache file to be rewritten, and the third tells the backup folder.
    0
  • Patrick de Gier
    Hi Eric,

    I've tested the script again, with capture done.
    First notification after taking the first tethered shot with the capture done = "Backup alias cache file path/to/BackupFolderAlias.txt" So that one is ok

    After that I set the backup folder, second notification= Backup folder is "path/to/desktop/Backup/"
    So that one is ok too. The backup folder is set.

    Then I take another tethered shot. i get this notification again: Backup alias cache file path/to/BackupFolderAlias.txt

    After that I get this notification: "Backup Alias String does not refer to a folder" and I have to set the backup folder again.

    When set, Notification: Backup folder is "path/to/desktop/Backup/"

    Next tethered shot, notification: "Backup alias cache file path/to/BackupFolderAlias.txt"
    followed by notification: "Backup Alias String does not refer to a folder"

    So it is not remembering the set backup folder somewhere in the second half of the script

    Hope this is enough information for you.

    Thank! Patrick
    0
  • Eric Valk
    Hi Pat

    I think we may have encountered a localisation problem.

    In my Applescript there is a line that checks that the alias does refer to a folder and not a file; this is done after the alias is determined to be valid. This is the only test that returns this error string.
    if not "folder" = (get thekind as string) then error "Backup alias string does not refer to a folder"
    The text string "folder" should be returned as the kind of the item which is the location of the backup.

    I think what may be returned instead is the German equivalent word for "folder", and so it does not match.

    So let's remove the check for this rather unlikely error. Then the Applescript becomes this:

    ## The cache file stores the alias of the backupfolder, as a string, no return at the end.
    ## The cache file is placed in the user's scripts folder which is usually /users/usersname/Library/Scripts
    use AppleScript version "2.4"
    use scripting additions

    set debug_notify to true -- set this to false to stop receiving notifications
    set debug_log to false -- set this to false to stop logging by Script Editor

    set cache_file_name to "BackupFolderAlias.txt"
    tell application "System Events" to set cache_file_path_a to (get path to scripts folder)
    set cache_file_ps to get POSIX path of (get cache_file_path_a as string) & cache_file_name
    if debug_notify then display notification "Backup alias cache file "" & cache_file_ps & """
    if debug_log then log "Backup alias cache file "" & cache_file_ps & """

    try
    set backupFolder_as to do shell script "cat "" & cache_file_ps & """ -- try to read the cache file
    ## simple checks for invalid alias strings
    if 100 < (get count of backupFolder_as) then ¬
    error "Backup alias string has more than 100 characters" number -1702
    if not ":" = (get text -1 of backupFolder_as) then ¬
    error "Backup alias string has no colon at end" number -1702
    if backupFolder_as contains return then ¬
    error "Backup alias string contains a return" number -1702
    get alias backupFolder_as -- check the alias is valid
    on error eStr number eNum
    if debug_notify or (-1702 = eNum) then display notification eStr
    if debug_log or (-1702 = eNum) then log eStr
    set backupFolder_as to get (choose folder with prompt "Select backup folder:") as string
    do shell script "echo "" & backupFolder_as & "" > " & """ & cache_file_ps & """
    end try
    if debug_notify then display notification "Backup Folder is "" & (get POSIX path of backupFolder_as) & """
    if debug_log then log "Backup Folder is "" & (get POSIX path of backupFolder_as) & """

    tell application "Capture One 11" to set theImageFilePath_ps to get path of parent image of primary variant

    set theImageFile_as to get (get alias POSIX file theImageFilePath_ps) as string
    tell application "Finder" to duplicate file theImageFile_as to folder backupFolder_as with replacing

    I think this should now work.
    0

Please sign in to leave a comment.