AppleScript Photos folder reference doesn't work inside subroutine - why? - applescript

I'm a beginner with AppleScript. What I'm looking to do here is tell Apple's Photos app to create a new folder inside an existing folder. Ultimately I'm looking to recursively clone a folder structure, so I need to be able to pass the parent folder to a subroutine and have the subroutine create the folder.
I can create the subfolder within the parent folder if I do it all in the same context, but if I do the exact same thing inside a subroutine, passing in a reference to the parent folder, it fails with this error:
error "Can’t make folder id \"1632F3F7-D00F-42DB-B9B3-F781D5DDAFD8/L0/020\" of application \"Photos\" into the expected type." number -1700 from folder id "1632F3F7-D00F-42DB-B9B3-F781D5DDAFD8/L0/020"
I figure this has something to do with the fact that theParentFolder is passed to the subroutine by reference rather than by value, but I'm tried a few unsuccessful attempts to work around this and failed.
on createFolderInSubRoutine(parentFolder)
if not (folder named "bar" exists) then make new folder named "bar" at parentFolder -- fails
end createFolderInSubRoutine
tell application "Photos"
set theParentFolder to folder "My Parent Folder"
if not (folder named "foo" exists) then make new folder named "foo" at theParentFolder -- works
my createFolderInSubRoutine(theParentFolder)
return
end tell

Found a working solution:
on createFolderInSubRoutine(parentFolder)
tell parentFolder
if not (folder named "bar" exists) then make new folder named "bar" at parentFolder
end tell
end createFolderInSubRoutine
tell application "Photos"
set theParentFolder to folder "My Parent Folder"
my createFolderInSubRoutine(theParentFolder)
return
end tell
I don't fully understand why this works, but I'm happy to move on knowing that it does work.

Related

Automatically move files of a certain type from folder A to B whenever they are added to folder A on macOS

Using Automator, I created a "Folder Action" to move files of certain types (i.e. "Kind IS Movie") from folder "FolderA" to folder "FolderB" as soon as they are added to folder "FolderA". It works fine except that it doesn't move files from subfolders (e.g. doesn't work if the movie files are added to "FolderA/SubA/"), and apparently there's no option on Automator to make it work on the subfolders.
Does anyone have any idea about how to either change that on Automator or how could I create a script for that? Thanks!
This following AppleScript folder action code should give you a general idea of how to accomplish what you are looking for. When a file or folder is added to a folder that this folder action is attached to, it will search all folders and sub folders for files (I used QuickTime movie as the kind of file... But you can change that to whatever you want) then those files will be moved to the folder that you will define in property moveToFolder
You can save this following code in Script Editor.app directly into your /Users/Your_User_Name/Library/Workflows/Applications/Folder Actions folder, as a .scpt file. Once the script is saved into that folder, it will be available to attach to any folder as a folder action using the Folder Actions Setup.
-- Set This To The Folder You Want Your Videos Moved To
property moveToFolder : (path to desktop as text) & "moved_videos"
-- Set This To The Kind Of File To Act Upon
property fileKind : "QuickTime movie"
on adding folder items to theFolder after receiving theNewItems
tell application "Finder"
set movieFilesRef to a reference to (files of entire contents of folder theFolder ¬
whose kind is fileKind)
move movieFilesRef to alias moveToFolder
end tell
end adding folder items to
OR Here Is A Version Which Defines The Name Extensions Of The Files To Act Upon
-- Set This To The Folder You Want Your Videos Moved To
property moveToFolder : (path to desktop as text) & "moved_videos"
-- Set This To The Name Extensions Of Files To Act Upon
property videoFileExtensions : {"m4v", "mkv", "avi", "mp4", "mov", "wmv", "mpg"}
on adding folder items to theFolder after receiving theNewItems
tell application "Finder"
set movieFilesRef to a reference to (files of entire contents of folder theFolder ¬
whose name extension is in videoFileExtensions)
move movieFilesRef to alias moveToFolder
end tell
end adding folder items to

How to fix a ~10006 error in applescript when duplicating a file to another folder?

When trying to duplicate files to another folder, the script throws a ~10006 error. This only occurs on some Mac mini computers and works fine on others. I have no idea why it is working on some computers but not on others.
This is the error shown:
Can't set "Macintosh HD:Users:username:Documents:" to <> "Macintosh HD:Users:username:Downloads:new test:portal resources" of application "Finder". (~10006)
tell application "Finder"
set folderToBeMoved to (container of (path to me) as text) &
"portal_resources"
set destinationFolder to path to documents folder as text
set moveFolder to duplicate folder folderToBeMoved to destinationFolder with replacing
end tell
expected output is duplicating file to documents folder. But, when testing on certain Macs, the script shows an error ~10006. It works on other macs perfectly well.
You are going to copy the folder to a literal string (path) which can fail on machines running older system versions.
Remove the as text parameter to get an alias specifier
set destinationFolder to path to documents folder
Try this code:
tell application "Finder"
set folderToBeMoved to folder "portal_resources" of container of (path to me)
set destinationFolder to path to documents folder
set moveFolder to duplicate folderToBeMoved to destinationFolder with replacing
end tell
There were two issues here that I've changed. First, you convert things to text strings and try to modify the strings, but the Finder has a rich language for talking about file objects. You should just leave everything in object form. For instance, this:
folder "portal_resources" of container of (path to me)
tells the finder to find the folder of that name in that container and return an object specifier that you can use directly.
Second, once you have this object, you can't add the 'folder' specifier to it. Where you say:
duplicate folder folderToBeMoved
folderToBeMoved is already an object specifier (an object of the form 'folder [path]') so you're actually asking the Finder for 'folder folder [path],' which throws the error you're seeing. It's like saying to someone "pass the 'pass the salt.'" People are probably smart enough to figure that out; the Finder isn't.

What logic and why is AppleScript applying to folder names? Guess what this script is doing

I just stumbled across one of the most awkward behaviours of a programming language in my live.
Guess what this AppleScript is doing:
set workspace to "tmp"
set folder1 to "08_0000012_11"
set folder2 to "8_12_11"
tell application "Finder"
if (not (exists folder folder1 of (workspace as alias))) then
make new folder at workspace as alias with properties {name:folder1}
end if
if (not (exists folder folder2 of (workspace as alias))) then
make new folder at workspace as alias with properties {name:folder2}
else
log "Folder already exists " & folder2
end if
end tell
It should create create two folders 08_0000012_11 and 8_12_11 inside the /tmp, right? ..... Wrong! It creates first one and claims the other one already exists. But it does not!
It seems that it tries to apply some logic to these names. Splits them into 3 numbers and ignores zeroes. Please tell me there is some reasonable explanation to this. Or this is happening only to me...
That's a bug in Finder. It should only ignore leading zeros when sorting file names, not when comparing them. File a bug report.
The same logic works correctly in System Events, e.g.:
set fname to "001"
tell application "System Events"
if not exists folder fname of desktop folder then
make new folder at desktop folder with properties {name:fname}
end if
end tell

Applescript: Copy all contents of a folder into every folder in a directory

I'm in a bit of a bind and an Applescript noob. I've been stumbling through a script that would allow me to copy the contents of (TemplateFolder) into all of the client folders in a directory, with the added crux that all of the existing clients' folder contents be moved into a folder within the client labeled "Old Files" or something of the sort. I'll include images with my script thus far to illustrate what I'm trying to achieve. Thank you everyone in advance for all your help.
P.S. Since I don't have the rep required, I'll have to post links to my images.
http://imgur.com/a/lL9q7
The first image is the template folder (the folder I'd like all contents copied into each client folder).
The second image is an example of an existing client folder with all the bad structure (or lack thereof).
The final image is the expected results where the template folder's contents are moved into the client folder and the original content of the client's folder are moved into a separate folder titled "Old Structure Files".
Below is the applescript I've written, with help from others, to copy the contents. However there are missing components and some elements that need to change; currently the applescript simply copies the entire folder rather than just the contents and it makes a simple copy rather than inserting, the script is not recursive for an entire directory, and there's no function to move the existing client files into a "Old Structure Files" folder. Again, any and all help is greatly appreciated :)
on run
set source_folder to choose folder with prompt "Select folder to be duplicated:" as string
my do_main_script(source_folder)
end run
on open of source_folder_list
repeat with i from 1 to number of items in the source_folder_list
set this_folder_path to item i of the source_folder_list as string
if last character of this_folder_path is ":" then
my do_main_script(this_folder_path)
end if
end repeat
end open
on do_main_script(source_folder)
tell application "Finder" to set source_folder to folder (source_folder)
tell application "Finder" to set the target_folder to (parent of source_folder)
if source_folder is not "" and target_folder is not "" then
set new_folder_name to (name of source_folder as string) & " duplicate"
set source_folder to source_folder as string
set target_folder to target_folder as string
my create_new_folder(target_folder, new_folder_name)
my duplicate_folder_structure(source_folder, target_folder & new_folder_name & ":")
end if
end do_main_script
In the script bellow, the template folder is at fixed place on desktop, all the content of the customer selected folder is moved to a new folder "old structure", and after that, all content of the template folder is duplicated into the customer folder. If I well understand, this is what you're looking for :
set Templatefolder to "HD:Users:my_user:Desktop:Template"
set CustomerFolder to (choose folder with prompt "Select customer folder to be re-organised")
tell application "Finder"
set CustomerData to every item of CustomerFolder
set OldF to make new folder in CustomerFolder with properties {name:"Old Strutucture Files"}
move CustomerData to OldF
set Newstructure to every item of folder Templatefolder
duplicate Newstructure to CustomerFolder
end tell

what is the correct path to the iMovie Projects folder to use in an AppleScript

I'm working on a simple AppleScript to make a copy of an iMovie project file. I have added this property to the script:
property iMovieProjects : alias (home directory of (system info) as string) & "Movies:iMovie Projects"
This gives me the error
File alias Macintosh HD:Users:my user name:Movies:iMovie Projects of wasn't found
What's the correct path? I tried iMovie Project.localized but that doesn't work either.
Try this, looks like you need to use the Finder. Also i added a little simplification on getting the home path.
property iMovieProjects : ""
tell application "Finder" to set iMovieProjects to alias ((home as string) & "Movies:iMovie Projects")
EDIT: Heres a one line solution that does not use the Finder, based on ideas from mklement0 & regulus6633
property iMovieProjects : alias ((path to movies folder as text) & "iMovie Projects.localized")
It appears this folder is some kind of special bundle type folder and thats why we were needing the finder to parse it correctly. Using its full .localized name resolves it.
UPDATE: As adamh discovered, the reason for the alias error is because the real name of the folder is "iMovie Projects.localized". Get info on the folder and you will see it.
I would add that an easier method to get to a folder is using the "path to" command. Using that you can get to virtually every known folder. In your case we can get directly to the Movies folder. You can look in the applescript dictionary of the standard additions to see all of the folders it knows. As such I would reference that folder as follows.
set iMovieProjects to alias ((path to movies folder as text) & "iMovie Projects.localized:")
Finally you'll notice that I did not use a property for iMovieProjects. That's because when you compile a script a property will hard-code the path into the script... meaning that the script will only work for this particular user. If the script is used by another user it will still point to the Movies folder of the person at compile time. Thus we don't use a property and the script will work for any user.
Good luck.
Update2 (thanks, #adamh): Even though the iMovie projects folder name appears as "iMovie Projects" in Finder in English-language locales, the actual - locale-independent - name is "iMovie Projects.localized". (If you want to refer to the folder by its localized name, prefix the set command with tell application "Finder", as in #adamh's answer's first snippet.)
You simply need to change how you parenthesize - the string to pass to alias must be built in its entirety inside parentheses:
property iMovieProjects : ""
set iMovieProjects to alias ( ¬
(home directory of (system info) as string) & "Movies:iMovie Projects.localized" ¬
)
Update1: #regulus6633 makes the excellent point that you shouldn't initialize a property with a specific user's path, as it will get compiled into the script. Thus, the above snippet initializes the property to an empty string and then assigns a value dynamically - which will then reflect the current user's path - in a separate set ... to statement.
Your original statement inadvertently creates a list with 2 elements, whose first element is a an alias of your home directory and whose second element is the string "Movies:iMovie Projects".
Simplified version with the path to command demonstrated in #regulus6633's answer (the same need to parenthesize applies):
property iMovieProjects : ""
set iMovieProjects to alias ( ¬
(path to movies folder as text) & "iMovie Projects.localized" ¬
)

Resources