Change icon of folder with AppleScript? - applescript

i've create an AppleScript very helpful to me and i wish if it is possible to automatically change the folder icon.
This script is very simple, it create one folder, then create one empty text file in the same folder.
Here is the script:
tell application "Finder"
set newfolder to make new folder with properties {name:My Folder}
make new file at newfolder with properties {name:"read_me.txt"}
end tell
Is it possible to automatically change the folder icon?
(I own my custom folder icon (.icns) in the same folder as the script, of course)

Heres a solution that uses a command line utility "seticon" found in this package: https://github.com/vasi/osxutils
It works on the assumption your script, icns file and new folder are all in the same directory.
tell application "Finder"
set parent_path to ((the container of the (path to me)) as text)
set target_folder_path to quoted form of POSIX path of (parent_path & "my folder")
set icon_path to quoted form of POSIX path of (parent_path & "icon.icns")
do shell script "/usr/local/bin/seticon -d " & icon_path & " " & target_folder_path
end tell

My Solution in 2021, using SF-Symbols
-- Help
-- folder_path : The folder whose icons will be changed (multiple selection in Finder possible)
-- icon_path : The Icon path
-- archiv_path : The Icon path for a folder named "Archiv"
-- Presets here as used by me
property folder_path : "/Users/ronny/Desktop/osxutils-master"
property icon_path : "/Volumes/Development/Developer/Xcode/LibPool/Icons/Folder.icns"
property archiv_path : "/Volumes/Development/Developer/Xcode/LibPool/Icons/Archiv.icns"
-- Frameworks and Additions
use framework "Foundation"
use framework "AppKit"
use scripting additions
-- Create list (array) with selected items
-- Be carefull, every icon will be changed
tell application "Finder"
set theListe to selection as list
end tell
repeat with i in theListe
set aName to name of i
log (aName)
set destPath to POSIX path of (i as text)
if aName is equal to "Archiv" then
set sourcePath to archiv_path
else
set sourcePath to icon_path
end if
set imageData to (current application's NSImage's alloc()'s initWithContentsOfFile:sourcePath)
(current application's NSWorkspace's sharedWorkspace()'s setIcon:imageData forFile:destPath options:2)
end repeat

Related

AppleScript find folder with specific file

I have a folder with file /resources/video.mov. This folder with video can located in any place, like /Users/UserName/Desktop/resources/video.mov or /Applications/resources/video.mov and etc. I need to find this folder with video and copy to specific place. I can't find path of folder with video to copy it.
tell application "Finder"
duplicate items in folder "_locatedPath_" to folder "_destiontionPath_" with replacing
end tell
This works for me using the latest version of Sierra
Change the value of variable destinationFolder to the output folder of your choice
property theContainer : missing value
property containingFolder : "resources" -- change if needed
property theSearch : "video.mov" -- change if needed
property destinationFolder : (path to desktop as text) -- change if needed
set findFile to do shell script "mdfind -name " & theSearch
repeat with i from 1 to number of paragraphs in findFile
set this_item to POSIX file (paragraph i of findFile) as alias
tell application "Finder"
if name of this_item is theSearch then
set theContainer to the container of this_item as text
if theContainer contains containingFolder then
set resultObject to duplicate this_item ¬
to destinationFolder ¬
replacing true ¬
routing suppressed true ¬
with exact copy
end if
end if
end tell
end repeat

AppleScript : How to get files in folder without hidden files?

I actually have two questions.
How to exclude hidden files like .DS_STORE, Icon when I try to get files in folder ?
I've tried "without invisibles" but it seems not working.
How to set my var the_new_folder as an existing folder if already exists ?
Thanks for answers.
My code:
--
-- Get all files in a selected folder
-- For each file, create a folder with the same name and put the file in
--
tell application "Finder"
set the_path to choose folder with prompt "Choose your folder..."
my file_to_folder(the_path)
end tell
on file_to_folder(the_folder)
tell application "Finder"
-- HELP NEEDED HERE
-- HOW TO EXCLUDE HIDDEN FILES (Like Icon, .DS_STORE, etc)
set the_files to files of the_folder
repeat with the_file in the_files
-- Exclude folder in selection
if kind of the_file is not "Folder" then
set the_path to container of the_file
set the_file_ext to name extension of the_file
-- Remove extension of the file name
set the_file_name to name of the_file as string
set the_file_name to text 1 thru ((offset of the_file_ext in (the_file_name)) - 2) of the_file_name
-- Make the new folder with the file name
try
set the_new_folder to make new folder at the_path with properties {name:the_file_name}
on error
-- HELP NEEDED HERE
-- HOW TO SET the_new_folder AS THE EXISTING FOLDER
end try
-- Move the file in the new folder
move the_file to the_new_folder
end if
end repeat
end tell
end file_to_folder
tell application "Finder"
(display dialog ("It's done!") buttons {"Perfect!"})
end tell
Using the System Events context instead of Finder:
bypasses the problem with the AppleShowAllFiles preference[1]
is much faster in general.
Using the visible property of file / folder objects in the System Events context allows you to predictably determine either all items, including hidden ones (by default), or only the visible ones (with whose visible is true):
# Sample input path.
set the_path to POSIX path of (path to home folder)
tell application "System Events"
set allVisibleFiles to files of folder the_path whose visible is true
end tell
Simply omit whose visible is true to include hidden files too.
The code for either referencing a preexisting folder or creating it on demand is essentially the same as in the Finder context:
# Sample input path.
set the_path to POSIX path of (path to home folder)
# Sample subfolder name
set the_subfolder_name to "subfolder"
tell application "System Events"
if folder (the_path & the_subfolder_name) exists then
set subfolder to folder (the_path & the_subfolder_name)
else
set subfolder to make new folder at folder the_path ¬
with properties {name: the_subfolder_name}
end if
end tell
[1] In order to predictably exclude hidden items, a Finder-based solution is not only cumbersome but has massive side effects:
You need to determine the current state of the the AppleShowAllFiles preference (defaults read com.apple.Finder AppleShowAllFiles),
then turn it off.
then kill Finder to make the change take effect (it restarts automatically) - this will be visually disruptive
then, after your code has run, restore it to its previous value.
then kill Finder again so that the restored value takes effect again.
I believe that your first question is not a problem. Your code works fine for me.
As for the second issue, the simplest method is to use the text representation of the_path, and simply build the new folder, and see if it already exists:
set the_path_Text to (the_path as text)
set try_Path to the_path_Text & the_file_name
if (folder try_Path) exists then
set the_new_folder to (folder try_Path)
else
set the_new_folder to make new folder at the_path with properties {name:the_file_name}
end if
If you are truly having difficulty with the first code section, please post a new question with more details, such as a copy of the Result section of the Script.
Thank you to all of you ! #mklement0 #craig-smith
You will find below the corrected code with your help!
If I share this code, you want to be cited for thanks?
--
-- Get all files in a selected folder
-- For each file, create a folder with the same name and put the file in
--
-- Get user folder
set the_path to choose folder with prompt "Choose your folder..."
my file_to_folder(the_path)
on file_to_folder(the_folder)
tell application "System Events"
-- Get all files without hidden
set the_files to files of the_folder whose visible is true
repeat with the_file in the_files
-- Remove extension of the file name
set the_file_ext to name extension of the_file
set the_file_name to name of the_file as string
set the_file_name to text 1 thru ((offset of the_file_ext in (the_file_name)) - 2) of the_file_name
-- Make a new folder or get the existing
set the_path to POSIX path of the_folder
if folder (the_path & the_file_name) exists then
set the_new_folder to folder (the_path & the_file_name)
else
set the_new_folder to make new folder at folder the_path with properties {name:the_file_name}
end if
-- Move the file to the new folder
move the_file to the_new_folder
end repeat
end tell
end file_to_folder
-- Ending dialog
display dialog ("It's done!") buttons {"Perfect!"}

how to use applescript to move files to new folder by extension, keeping subfolder name

Here's what I'm trying to do.
I've got a file structure that contains photos in both JPG and RAW formats. It's a folder called "Photos" with subfolders by date. I'd like to copy just the RAW photos to a new folder, "Photos RAW", but keep the structure by date taken/created.
I can copy just the files using automator or applescript a directory to a new one, but how do I walk the directory tree using applescript so I cover all the subfolders?
Try this. You'll see I used "entire contents" to get the files in the subfolders too.
set extensionToFind to "raw"
set topLevelFolder to (choose folder) as text
set pathCount to count of topLevelFolder
tell application "Finder"
-- get the files
set rawFiles to files of entire contents of folder topLevelFolder whose name extension is extensionToFind
if rawFiles is {} then return
-- setup the folder where the files will be moved
set rawFolder to ((container of folder topLevelFolder) as text) & "Photos_Raw:"
do shell script "mkdir -p " & quoted form of POSIX path of rawFolder
repeat with aFile in rawFiles
set aFileContainer to (container of aFile) as text
if topLevelFolder is equal to aFileContainer then
-- here the file is at the top level folder
set newPath to rawFolder
else
-- here we calculate the new path and make sure the folder structure is in place
set thisFile to aFile as text
set subFolderPath to text (pathCount + 1) thru -((count of (get name of aFile)) + 1) of thisFile
set newPath to rawFolder & subFolderPath
do shell script "mkdir -p " & quoted form of POSIX path of newPath
end if
move aFile to folder newPath
end repeat
end tell

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

Applescript: make new folder structure if it doesn't exist

I've been searching through message boards trying to figure out how to execute this script. Essentially the goal is to be able to run this script while inside a folder and if certain folders do not exist, these folders would then be created. If they do already exist, nothing happens. Here's what I've cobbled together so far:
property archivesFolder : "Archives"
property imagesFolder : "Images"
property proofreadFolder : "Proofreading"
property proofFolder : "Proofs"
property sourceFolder : "Source"
try
tell application "Finder" to set theLocation to (folder of the front window as alias)
end try
tell application "Finder"
if (exists folder archivesFolder) then
(* do nothing *)
else
make new folder at theLocation with properties {name:archivesFolder}
end if
if (exists folder imagesFolder) then
(* do nothing *)
else
make new folder at theLocation with properties {name:imagesFolder}
end if
if (exists folder proofreadFolder) then
(* do nothing *)
else
make new folder at theLocation with properties {name:proofreadFolder}
end if
if (exists folder proofFolder) then
(* do nothing *)
else
make new folder at theLocation with properties {name:proofFolder}
end if
if (exists folder sourceFolder) then
(* do nothing *)
else
make new folder at theLocation with properties {name:sourceFolder}
end if
end tell
What am I doing wrong ? (forgive my n00b code formatting, at work and can't figure out how to create code blocks) Also, is it possible to this not just on the front window, but on a folder that is just selected? Any help given would be awesome.
I suggest two options (to run the script):
Option 1: Take that code (assuming it does what you plan), and save it as an application (with Script Editor).
Then, just drag that application to your window toolbar (you need to have the toolbar visible). To do that, hold the command key while dragging.
Option 2: Use Butler: http://manytricks.com/butler/
(there is a free version, I don't know your OSX version).
It allows you to define system-wide shortcut keys for applescript scripts.
Create a smart item (applescript); paste the code there, and in the name of the script add the shortcut keys: example: create folder here ⇧⌥⌘N
EDIT:
According to your comment, I understand your problem and I can tell you that you were missing the path (the current folder, in your case theLocation)
So, in every case of if (exists folder archivesFolder) then you need to add the of theLocation like this: if not (exists folder archivesFolder of theLocation) then
Finally, knowing that you won't do any thing if the folder exists, just test the false case.
I tested this code and am posting it here:
property archivesFolder : "Archives"
property imagesFolder : "Images"
property proofreadFolder : "Proofreading"
property proofFolder : "Proofs"
property sourceFolder : "Source"
try
tell application "Finder" to set theLocation to (folder of the front window as alias)
end try
tell application "Finder"
if not (exists folder archivesFolder of theLocation) then
make new folder at theLocation with properties {name:archivesFolder}
end if
if not (exists folder imagesFolder of theLocation) then
make new folder at theLocation with properties {name:imagesFolder}
end if
if not (exists folder proofreadFolder of theLocation) then
make new folder at theLocation with properties {name:proofreadFolder}
end if
if not (exists folder proofFolder of theLocation) then
make new folder at theLocation with properties {name:proofFolder}
end if
if not (exists folder sourceFolder of theLocation) then
make new folder at theLocation with properties {name:sourceFolder}
end if
end tell
You can also use a shell script with mkdir, since the option to create intermediate folders won't error if the folder already exists.
# define a list of folders - items will need to be quoted if they contain spaces, etc.
property theFolders : {"Archives", "Images", "ProofReading", "Proofs", "Source"} -- can also nest, e.g. "Inside/One"
try
tell application "Finder" to set targetFolder to (target of the front window) as alias
on error -- no window
set targetFolder to (choose folder)
end try
# build a parameter string from the folder list
set {tempTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, space}
set {theFolders, AppleScript's text item delimiters} to {theFolders as text, tempTID}
do shell script "cd " & quoted form of POSIX path of targetFolder & "; mkdir -p " & theFolders
Try this:
tell application "Finder"
set theLocation to (target of front window) as string
set folderNames to {"archivesFolder", "imagesFolder", "proofreadFolder", "proofFolder", "sourceFolder"}
repeat with theFolder in folderNames
try
make new folder at theLocation with properties {name:"" & theFolder & ""}
end try
end repeat
end tell
This is a script I did to sort a bunch of medical files into subfolders based on the date of service (explaining the "text 5 thru 14" in the script; the files are named according to a pattern so the script can extract the date of service from the filename). Rather than check if the folder already exists, I just put the make folder instruction in a try block; if the folder already exists, the 'try' fails, but the script continues under the assumption that the folder already exists. Using the 'text' item instead of 'character' returns the extracted string as a single string and not as an array of characters that have to be converted back into a string.
tell application "Finder"
set theDirectory to "Internal Disk:Users:steven:Documents:Vondalee:Medical"
set theFiles to every file in folder theDirectory whose name extension is "pdf"
repeat with eachFile in theFiles
set theFileName to the name of eachFile
set theFolder to text 5 thru 14 of theFileName
try
make new folder at theDirectory with properties {name:theFolder}
end try
move eachFile to folder theFolder of folder theDirectory
end repeat
end tell

Resources