Copy multiple files using AppleScript - applescript

I have to duplicate multiple files using an AppleScript. What this script should do is first, ask the user to select the folder which contains the files that have to be duplicated. Second, show a list of all of the files that there're in the folder that user have selected. In this step, the user can select multiple files. And the last step is duplicate the files. Here's t'he script I'm using:
--Get the folder
set theFolder to (choose folder with prompt "Select the folder that contains the files to copy. In the next step you'll be able to select the files to copy.") as text
--Get the path to de destination folder of the files
set destination_folder to (path to home folder) as text
--Generate the list of files inside theFolder
tell application "Finder"
set theItems to items of folder theFolder
set theNames to {}
repeat with anItem in theItems
set end of theNames to name of anItem
end repeat
end tell
-Let user select the files of the list
choose from list theNames with prompt "Select the files" OK button name "OK" cancel button name "Cancel" with multiple selections allowed
tell result
if it is false then error number -128 -- cancel
set theChoices to it
end tell
if (count of theChoices) is greater than or equal to 1 then
repeat with aChoice in theChoices
set thisItem to theFolder & aChoice
-- do something with thisItem
duplicate thisItem to destination_folder
end repeat
end if
The problem is that when the srcipt has to run the line "copy thisItem to destination_folder" it crashes. Here's the oputput that generates AppleScript Editor when I try to run:
tell application "AppleScript Editor"
choose from list {"Obres.xlsx", "Programa_sardanes", "Sardanes.xlsx"} with prompt "Escull els arxius o l'arxiu que vols afegir" OK button name "Acceptar" cancel button name "Cancelar" with multiple selections allowed
--> {"Sardanes.xlsx"}
-- 'core'\'clon'{ 'insh':'utxt'("Macintosh HD:Users:Joan:"), '----':'utxt'("Macintosh HD:Users:Joan:MEGA:Sardanes.xlsx"), &'subj':null(), &'csig':65536 }
--> error number -1700 from "Macintosh HD:Users:Joan:MEGA:Sardanes.xlsx" to reference
Result:
error "Can't generate \"Macintosh HD:Users:Joan:MEGA:Sardanes.xlsx\" on the type reference." number -1700 from "Macintosh HD:Users:Joan:MEGA:Sardanes.xlsx" to reference
I have been trying several hours to solve this problem but I don't know where is the error on the script. I hope someone could help me. And if someone knows a much more simple way to do this would be helpful also. Thank you!

I made some small changes to your script and it should work now...
Basically, you were missing a couple small portions. The "duplicate" command is a function of the "Finder", so I added a "Tell application "Finder"" to the duplicate portion. You were also storing your path to your file and folder as text, I modified them to be referenced as "alias".
on run
--Get the folder
set theFolder to (choose folder with prompt "Select the folder that contains the files to copy. In the next step you'll be able to select the files to copy.") as text
--Get the path to de destination folder of the files
set destination_folder to (path to home folder)
--Generate the list of files inside theFolder
tell application "Finder"
set theItems to items of folder theFolder
set theNames to {}
repeat with anItem in theItems
set end of theNames to name of anItem
end repeat
end tell
--Let user select the files of the list
choose from list theNames with prompt "Select the files" OK button name "OK" cancel button name "Cancel" with multiple selections allowed
tell result
if it is false then error number -128 -- cancel
set theChoices to it
end tell
if (count of theChoices) is greater than or equal to 1 then
repeat with aChoice in theChoices
set thisItem to (theFolder & aChoice) as alias
-- do something with thisItem
tell application "Finder" to duplicate thisItem to destination_folder
end repeat
end if
end run

Related

Apple script to export images from "Photos" application

I have albums and nested albums and folders in Photos application. I want my applescript to export images maintaining the Album or Folder structure that I have the in the application.
I tried scripts available online :
tell application "Finder"
set location_1 to (choose folder with prompt "Choose a folder to export into") as text
end tell
tell application "Photos"
set x to name of every folder
choose from list x with prompt "Choose a project to export"
set theP to item 1 of result
tell application "Finder" to make new folder at alias location_1 with properties {name:theP}
tell folder theP
set initflist to every folder
set initalist to every album
if initflist is equal to {} then
log "process albums"
processAlbums(initalist, location_1 & theP) of me
else
if initalist is not equal to {} then
log "process albums"
processAlbums(initalist, location_1 & theP) of me
end if
log "process sub folders "
processSfolders(initflist, (location_1 & theP)) of me
end if
end tell
end tell
on processAlbums(alist, apath)
tell application "Photos"
repeat with a in alist
tell a
set theimages to get media items of album a
set thename to name of a
tell application "Finder"
if not (exists folder thename in alias apath) then
make new folder at alias apath with properties {name:thename}
end if
set destination to apath & ":" & thename & ":"
end tell
with timeout of 6000 seconds
tell a
set settings to "JPEG - Original Size"
export theimages to alias destination
end tell
end timeout
end tell
end repeat
end tell
end processAlbums
on processSfolders(flist, fpath)
tell application "Photos"
repeat with a in flist
try
set thename to name of a
tell application "Finder"
if not (exists folder thename in alias fpath) then
make new folder at alias fpath with properties {name:thename}
end if
end tell
tell a
set sAlist to every album
set sflist to every folder
if sflist is equal to {} then
processAlbums(sAlist, fpath & ":" & thename) of me
else
if sAlist is not equal to {} then
processAlbums(sAlist, fpath & ":" & thename) of me
end if
processSfolders(sflist, fpath & ":" & thename) of me
end if
end tell
on error errMsg
log "error"
end try
end repeat
end tell
end processSfolders
The issue is that it gets names of only child albums and not top level albums. I have to maintain the entire structure of album or folder.
I do not know AppleScript and I tried tweaking this one but no luck so far. can I get a direction please?
You can get the name of the folders, and the albums contained in the folder, which will enable you to create the top level and child directories. Albums can only contain media items, not albums. Top level albums are classified as folders or containers. In the Applescript dictionary for Photos, it gives the definitions for these items.
tell application "Finder"
set location_1 to (choose folder with prompt "Choose a folder to export into") as text
end tell
tell application "Photos"
activate
set fds to folders
repeat with fd in fds
set fdName to name of fd
set abNames to every album of fd
if parent of fd is missing value then
my createFolders(fdName, abNames, location_1, fd)
end if
end repeat
end tell
on createFolders(fName, aAlbums, fPath, fd)
tell application "Finder"
if not (exists folder fName in alias fPath) then
make new folder with properties {name:fName} at fPath
end if
repeat with a in aAlbums
set aName to name of a
set aPath to ((fPath as alias) as text) & fName
if not (exists folder aName in alias aPath) then
make new folder with properties {name:aName} at aPath
end if
set exPath to ((aPath as alias) as text) & aName
my exportImages(a, exPath)
end repeat
end tell
tell application "Photos"
set rcFolders to every folder of fd
repeat with rcFd in rcFolders
set rcAlbums to every album of rcFd
set rcName to name of rcFd
set rcPath to ((fPath as alias) as text) & fName
my createFolders(rcName, rcAlbums, rcPath, rcFd)
end repeat
end tell
end createFolders
on exportImages(photoAlbum, destination)
tell application "Photos"
set theimages to get media items of photoAlbum
with timeout of 6000 seconds
tell photoAlbum
set settings to "JPEG - Original Size"
export theimages to alias destination
end tell
end timeout
end tell
end exportImages
EDIT - Error Handling
To handle errors, locate the command that is causing the error and wrap it in a try block. Solution could be to quit the application, so that the process will end, and maybe add a short delay and then continue with the script.
try
export theimages to alias destination
on error
-- statements to execute in case of error
error "The exporting of images failed to complete"
quit
end try
From the developer reference - When a command fails to complete in the allotted time (whether the default of two minutes, or a time set by a with timeout statement), AppleScript stops running the script and returns the error "event timed out". AppleScript does not cancel the operation—it merely stops execution of the script. If you want the script to continue, you can wrap the statements in a try statement. However, whether your script can send a command to cancel an offending lengthy operation after a timeout is dependent on the application that is performing the command. Further info regarding try statements.

AppleScript / FolderAction - Rename files when dropped in folder > Endless Loop

I am trying to do the following with a FolderAction and AppleScript:
Everytime I drop a file on a specific folder it should be renamed and then moved into another folder.
The problem is I get something like an infinite loop (I think) because when the file gets renamed the folder assumes that there is a new file in the folder and so on.
I really don't know how to avoid this and stop the endless loop. Here ist my script:
global newName
set newName to ""
on adding folder items to theAttachedFolder after receiving theNewItems
-- Get the name of the attached folder
tell application "Finder"
set theName to name of theAttachedFolder
-- Count the new items
set theCount to length of theNewItems
-- Display an alert indicating that the new items were received
activate
-- Loop through the newly detected items
repeat with anItem in theNewItems
set oldFileName to name of anItem
-- Rename the file
set the name of anItem to "NewFile" & oldFileName
-- Move the file to other folder
move anItem to "Macintosh HD:Users:blabla:blabla"
end repeat
end tell
tell application "Finder"
delete files of folder "Macintosh HD:Users:user:thisfolder
end tell
end adding folder items to
You are right, renaming the file triggers the folder action again.
The solution is to change the order: First move then rename.
-- Move the file to other folder
set movedItem to move anItem to "Macintosh HD:Users:blabla:blabla"
-- Rename the file
set the name of movedItem to "NewFile" & oldFileName

Add vcard to Contacts with Mail rules and Applescript

I receive a lot of customer vcards to a specific email address. I want to automatically add the vcards to my contacts through the Mail rules and an AppleScript.
I searched a lot and found something. I modified it a bit. And the opening and adding process works fine. But only when I choose a file. I can't get the file into a variable from the mail message. I tried it but it won't work.
Here is my code so far:
tell application "Mail"
set att to attachment
end tell
set thefile to att
tell application "Contacts"
activate
open thefile
end tell
tell application "System Events" to keystroke return
If I delete line 1, 2 and 3 and write in line 4 "set thefile to choose file" then it will work - if I choose a file.
But the first three lines I tried something out, but without any success.
So my question is, how can I get the file from the message?
Thank you
Yours sincerely,
Chris
Solution:
set Dest to ((path to desktop folder) as string)
tell application "Finder" to make new folder in Dest with properties {name:"TempFiles"} -- create TempFiles folder
Set Dest to Dest & "TempFiles:"
tell application "Mail"
activate -- not sure is mandatory, but I prefer to see selected mails !!
set ListMessage to selection -- get all selected messages
repeat with aMessage in ListMessage -- loop through each message selected
set AList to every mail attachment of aMessage -- get all attachements
repeat with aFile in AList -- for each attachement
if (downloaded of aFile) then
set Filepath to Dest & (name of aFile)
do shell script "touch " & (quoted form of (POSIX path of Filepath)) -- required because "Save" only works with existing file !
save aFile in (Filepath as alias) as native format
end if
end repeat -- next file
end repeat -- next message
end tell
tell application "Finder" to set CardList to every file of folder Dest whose name extension is {"vcf"}
tell application "Contacts"
activate
repeat with aCard in CardList
open aCard
delay 1
tell application "System Events" to keystroke return
end repeat
end tell
delay 2
-- tell application "Finder" to delete folder Dest
The file attached from email respond to the 'save" command, but not to 'open'. Then, you must first save the attached files, and later, move them to next application (add in 'Contacts' in your case).
The attachement is a member of a list of 'mail attachement' of a message : keep in mind that there could be many files attached.
Also, you can only save the attached file if its 'downloaded' attribute is true.
Last, but not least, it seems that the "save" instruction which was working nice in Snow Leopard, does not work the same in El Capitain : the file where to save must exist before the "save"...this is why I added the "touch" command to create it first (just create the entry in the tempFiles folder).
I also add at bottom of script the open vCard with the enter key to validate in Contact. You may have to add a delay to leave sometime for your computer to process the card.
if the keys broke does not work in your case, please check System Preferences accessibility settings to allow your computer to let your script control your Mac.
I added as much comments as possible to make it clear...may be too much !
set Dest to ((path to desktop folder) as string)
tell application "Finder" to make new folder in Dest with properties {name:"TempFiles"} -- create TempFiles folder
Set Dest to Dest & "TempFiles:"
tell application "Mail"
activate -- not sure is mandatory, but I prefer to see selected mails !!
set ListMessage to selection -- get all selected messages
repeat with aMessage in ListMessage -- loop through each message selected
set AList to every mail attachment of aMessage -- get all attachements
repeat with aFile in AList -- for each attachement
if (downloaded of aFile) then
set Filepath to Dest & (name of aFile)
do shell script "touch " & (quoted form of (POSIX path of Filepath)) -- required because "Save" only works with existing file !
save aFile in (Filepath as alias) as native format
end if
end repeat -- next file
end repeat -- next message
end tell
tell application "Finder" to set CardList to every file of folder Dest whose name extension is {"vcf"}
tell application "Contacts"
activate
repeat with aCard in CardList
open aCard
tell application "System Events" to keystroke return
end repeat
end tell
-- tell application "Finder" to delete folder Dest
As you can see, I filter the content of the temp folder with only files with extension 'vcd'...just in case your selected emails contain also other type of file which Contact can't handled.
At end of the script, I delete the temp folder. however, until you test it, I set this last row as a comment only (more safe !)

Folder Action to resize images in Leopard 10.5.8

I know nothing about AppleScript, so please forgive me.
Goal is to create a folder that our graphics guy can drop stock photos into and have them resized to 1280. The chosen folder is a network folder, so don't know if that's part of the issue or not. He will be pasting the images into the folder from his Windows workstation.
Here is what I have pieced together so far:
on adding folder items to this_folder after receiving added_items
repeat with this_item in added_items
try
rescale_and_save(this_item)
end try
end repeat
end adding folder items to
to rescale_and_save(this_item)
tell application "Image Events"
launch
set the target_height to 1280
-- open the image file
set this_image to open this_item
set typ to this_image's file type
copy dimensions of this_image to {current_width, current_height}
if current_height is greater than current_width then
scale this_image to size target_height
else
-- figure out new height
-- y2 = (y1 * x2) / x1
set the new_width to (current_width * target_height) / current_height
scale this_image to size new_width
end if
tell application "Finder" to set new_item to ¬
(container of this_item as string) & "ex" & (name of this_item)
save this_image in new_item as typ
end tell
end rescale_and_save
I've right clicked on the folder, enabled folder actions, and added my script. I copy in the test file but nothing happens.
Any ideas?
EDIT:
I looked at the samples and came up with the following script that WORKS!:
property done_foldername : "Scaled Images"
property target_height : 1280
-- the list of file types which will be processed
-- eg: {"PICT", "JPEG", "TIFF", "GIFf"}
property type_list : {"JPEG", "TIFF", "PNGf"}
-- since file types are optional in Mac OS X,
-- check the name extension if there is no file type
-- NOTE: do not use periods (.) with the items in the name extensions list
-- eg: {"txt", "text", "jpg", "jpeg"}, NOT: {".txt", ".text", ".jpg", ".jpeg"}
property extension_list : {"jpg", "jpeg", "tif", "tiff", "png"}
on adding folder items to this_folder after receiving these_items
-- CHECK FOR THE DESTINATION FOLDER WITHIN THE ATTACHED FOLDER
-- IF IT DOESN'T EXIST, THEN CREATE IT
tell application "Finder"
if not (exists folder done_foldername of this_folder) then
make new folder at this_folder with properties {name:done_foldername}
set current view of container window of this_folder to list view
end if
set the target_folder to folder done_foldername of this_folder
end tell
-- PROCESS EACH OF THE ITEMS ADDED TO THE ATTACHED FOLDER
try
repeat with i from 1 to number of items in these_items
set this_item to item i of these_items
set the item_info to the info for this_item
-- CHECK TO SEE IF THE ITEM IS AN IMAGE FILE OF THE ACCEPTED FILE TYPE
if (alias of the item_info is false and the file type of the item_info is in the type_list) or (the name extension of the item_info is in the extension_list) then
tell application "Finder"
-- LOOK FOR EXISTING MATCHING ITEMS IN THE DESTINATION FOLDER
-- IF THERE ARE MATCHES, THEN RENAME THE CONFLICTING FILES INCREMENTALLY
my resolve_conflicts(this_item, target_folder)
-- MOVE THE ITEM TO THE DESTINATION FOLDER
set the target_file to (move this_item to the target_folder with replacing) as alias
end tell
-- PROCESS THE ITEM
process_item(target_file)
end if
end repeat
on error error_message number error_number
if the error_number is not -128 then
tell application "Finder"
activate
display dialog error_message buttons {"Cancel"} default button 1 giving up after 120
end tell
end if
end try
end adding folder items to
on resolve_conflicts(this_item, target_folder)
tell application "Finder"
set the file_name to the name of this_item
if (exists document file file_name of target_folder) then
set file_extension to the name extension of this_item
if the file_extension is "" then
set the trimmed_name to the file_name
else
set the trimmed_name to text 1 thru -((length of file_extension) + 2) of the file_name
end if
set the name_increment to 1
repeat
set the new_name to (the trimmed_name & "." & (name_increment as string) & "." & file_extension) as string
if not (exists document file new_name of the target_folder) then
-- rename to conflicting file
set the name of document file file_name of the target_folder to the new_name
exit repeat
else
set the name_increment to the name_increment + 1
end if
end repeat
end if
end tell
end resolve_conflicts
-- this sub-routine processes files
on process_item(this_item)
-- NOTE that the variable this_item is a file reference in alias format
-- FILE PROCESSING STATEMENTS GOES HERE
try
-- convert alias reference to string
set this_item to this_item as string
with timeout of 900 seconds
tell application "Image Events"
launch -- always use with Folder Actions
set this_image to open file this_item
scale this_image to size target_height
save this_image with icon
close this_image
end tell
end timeout
on error error_message
tell application "Finder"
activate
display dialog error_message buttons {"Cancel"} default button 1 giving up after 120
end tell
end try
end process_item
I just tested your script on a folder dropping 1 image in, and it turns out it runs repeatedly because the resulting (resized) image is also added to that folder. Here's what it looked like after a couple of seconds, before I interrupted it:
You should have a look at the default image processing scripts inside /Library/Scripts/Folder Action Scripts and maybe use one of them as a template. They basically use a sub-folder for the processed images and contain some possibly useful filename conflict resolving function, too.

Automator/AppleScript to find same file name with different extension in same directory

I'd like to create an automator action to help manage DNG/XMP files. I'd like to be able to drag a DNG (or several) onto the action which will send the DNG and the matching XMP file to the trash. The files have the same name except for the extension, they are in the same directory. For example, IMGP1361.DNG and IMGP1361.xmp
This would be a simple task for a shell script, but is there an Automator way to do it (to learn more about Automator)? Is there a way to get at the file name of the input finder item, change it in a variable and use that as input to another action?
Thanks.
This script for Automator will delete all of the files that share the same prefix and whose name extension is listed in the grep command. You may add additional extensions as well. (xmp|DNG|pdf|xls)
on run {input, parameters}
try
repeat with anItem in input
tell (info for anItem) to set {theName, theExt} to {name, name extension}
set shortName to text 1 thru ((get offset of "." & theExt in theName) - 1) of theName
tell application "Finder"
set parentFolder to parent of anItem as alias
set matchList to every paragraph of (do shell script "ls " & POSIX path of parentFolder & " | grep -E '" & shortName & ".(xmp|DNG)'")
delete (every file of parentFolder whose name is in matchList)
end tell
end repeat
end try
end run
OK, got it. You can use the AppleScript given below inside an Automator workflow like this:
For every selected file in the Finder, if its extension is in ext_list, it will be moved to the Trash, and so will all other files of the same name in the same folder whose extension is one of those in also_these_extensions.
It can be useful, e.g. also for cleaning a folder with auxiliary LaTeX files: just put "tex" into ext_list and all the other extensions (such as "aux", "dvi", "log") into also_these_extensions.
The selected files don't need to be inside the same folder; you can also select several items in a Spotlight search results window.
on run {input, parameters}
-- for every item having one of these extensions:
set ext_list to {"dng"}
-- also process items with same name but these extensions:
set other_ext_list to {"xmp"}
tell application "Finder"
set the_delete_list to {}
set delete_list to a reference to the_delete_list
-- populate list of items to delete
repeat with the_item in input
set the_item to (the_item as alias)
if name extension of the_item is in ext_list then
copy the_item to the end of delete_list
set parent_folder to (container of the_item) as alias as text
set item_name to text 1 thru ((length of (the_item's name as text)) - (length of (the_item's name extension as text))) of (the_item's name as text)
repeat with ext in other_ext_list
try
copy ((parent_folder & item_name & ext) as alias) to the end of delete_list
end try
end repeat
end if
end repeat
-- delete the items, show info dialog
move the_delete_list to the trash
display dialog "Moved " & (length of the_delete_list) & " files to the Trash." buttons {"OK"}
end tell
end run

Resources