Trouble with edited applescript - compilation

I just edited the file new item alert.scpt in the /Macintosh HD/Library/Scripts/Folder Actions.../ folder. I managed to save it after editing some permissions, but when I click Run or Compile nothing happens.
Is this a common error, or do I have a problem in my applescript if someone wouldn't mind taking a look.
property Docs : "Macintosh HD:Users:Max:Downloads:Docs"
property Music : "Macintosh HD:Users:Max:Downloads:Music"
property Videos : "Macintosh HD:Users:Max:Downloads:Videos"
property Images : "Macintosh HD:Users:Max:Downloads:Images"
property Profiles : "Macintosh HD:Users:Max:Downloads:iPhone:Profiles"
property Zips : "Macintosh HD:Users:Max:Downloads:Zips"
property PSDs : "Macintosh HD:Users:Max:Downloads:PSDs"
on adding folder items to this_folder after receiving added_items
try
tell application "Finder"
--get the name of the folder
set the folder_name to the name of this_folder
if (name of eachitem ends with ".png") then
move eachitem to folder Images
end if
if (name of eachitem ends with ".JPEG") then
move eachitem to folder Images
end if
if (name of eachitem ends with ".gif") then
move eachitem to folder Images
end if
if (name of eachitem ends with ".jpg") then
move eachitem to folder Images
end if
if (name of eachitem ends with ".jpeg") then
move eachitem to folder Images
end if
if (name of eachitem ends with ".PNG") then
move eachitem to folder Images
end if
if (name of eachitem ends with ".mov") then
move eachitem to folder Videos
end if
if (name of eachitem ends with ".avi") then
move eachitem to folder Videos
end if
if (name of eachitem ends with ".wma") then
move eachitem to folder Videos
end if
if (name of eachitem ends with ".m4v") then
move eachitem to folder Videos
end if
if (name of eachitem ends with ".mp4") then
move eachitem to folder Music
end if
if (name of eachitem ends with ".mp3") then
move eachitem to folder Music
end if
if (name of eachitem ends with ".wav") then
move eachitem to folder Music
end if
if (name of eachitem ends with ".wma") then
move eachitem to folder Music
end if
if (name of eachitem ends with ".pdf") then
move eachitem to folder Docs
end if
if (name of eachitem ends with ".doc") then
move eachitem to folder Docs
end if
if (name of eachitem ends with ".docx") then
move eachitem to folder Docs
end if
if (name of eachitem ends with ".pages") then
move eachitem to folder Docs
end if
if (name of eachitem ends with ".ppt") then
move eachitem to folder Docs
end if
if (name of eachitem ends with ".pptx") then
move eachitem to folder Docs
end if
if (name of eachitem ends with ".mobileprovision") then
move eachitem to folder Profiles
end if
if (name of eachitem ends with ".zip") then
move eachitem to folder Zips
end if
if (name of eachitem ends with ".psd") then
move eachitem to folder PSDs
end if
end tell
-- find out how many new items have been placed in the folder
set the item_count to the number of items in the added_items
--create the alert string
set alert_message to ("Folder Actions Alert:" & return & return) as Unicode text
if the item_count is greater than 1 then
set alert_message to alert_message & (the item_count as text) & " new items have "
else
set alert_message to alert_message & "One new item has "
end if
set alert_message to alert_message & "been placed in folder " & «data utxt201C» & the folder_name & «data utxt201D» & "."
set the alert_message to (the alert_message & return & return & "Would you like to view the added items?")
display dialog the alert_message buttons {"Yes", "No"} default button 2 with icon 1 giving up after dialog_timeout
set the user_choice to the button returned of the result
if user_choice is "Yes" then
tell application "Finder"
--go to the desktop
activate
--open the folder
open this_folder
--select the items
reveal the added_items
end tell
end if
end try
end adding folder items to

Folder action scripts are not supposed to be run directly. It's associated to any number of folders via the context menu of those folders.
Then, whenever that folder's content change, the script is triggered, and the on adding folder items to handler is run.
So, you should just right-click the folder you want to attach the script, and choose Set folder action menu item.
Also, you're not supposed to overwrite the system-provided file... you can save your customized version in your own home directory and you can attach it to any folder.

A folder action handler will fail silently, so if there is an error the script will abort. In your posted script, you are not going through the added items at all, and you are using an undefined variable - eachitem. Also note that using a try statement without the on error part will just eat any and all errors, which doesn't help with debugging, either. I know you are using one of Apple's example scripts, but that thing is pretty old.
I've found that the best approach when using folder actions is to put the main part(s) of the script outside of the folder action handler so that it can also be run normally (a script doesn't need to be dedicated to just being a folder action) - this helps with debugging, and can also give you an applet or droplet. For testing, you can also comment out the folder action handler declaration and add statements to get the folder and files.
I hope you don't mind, but I took the liberty of rearranging your script so that it can also be run from the Script Editor:
property Docs : "Macintosh HD:Users:Max:Downloads:Docs"
property Music : "Macintosh HD:Users:Max:Downloads:Music"
property Videos : "Macintosh HD:Users:Max:Downloads:Videos"
property Images : "Macintosh HD:Users:Max:Downloads:Images"
property Profiles : "Macintosh HD:Users:Max:Downloads:iPhone:Profiles"
property Zips : "Macintosh HD:Users:Max:Downloads:Zips"
property PSDs : "Macintosh HD:Users:Max:Downloads:PSDs"
property dialogTimeout : 10
on run -- script run as an application or from the Script Editor
set someFiles to (choose file with multiple selections allowed) -- manually get some files
tell application "Finder" to set containingFolder to (container of first item of someFiles) as alias
doStuff(containingFolder, someFiles)
end run
on adding folder items to this_folder after receiving added_items -- folder action handler
doStuff(this_folder, added_items)
end adding folder items to
on doStuff(theFolder, theStuff) -- do stuff with file items in a folder
set numberOfItems to (count theStuff)
tell application "Finder"
set folderName to name of theFolder
repeat with anItem in theStuff
if name extension of anItem is in {"png", "jpg", "jpeg", "gif"} then
move anItem to folder Images
else if name extension of anItem is in {"mov", "avi", "wma", "m4v"} then
move anItem to folder Videos
else if name extension of anItem is in {"mp4", "mp3", "wav", "wma"} then
move anItem to folder Music
else if name extension of anItem is in {"pdf", "doc", "docx", "pages", "ppt", "pptx"} then
move anItem to folder Docs
else if name extension of anItem is in {"mobileprovision"} then
move anItem to folder Profiles
else if name extension of anItem is in {"zip"} then
move anItem to folder Zips
else if name extension of anItem is in {"psd"} then
move anItem to folder PSDs
else
-- no match, so leave it
end if
end repeat
end tell
-- create the alert string
set alertText to ("Folder Actions Alert:" & return & return) as Unicode text
if numberOfItems is greater than 1 then
set alertText to alertText & numberOfItems & " new items have "
set plural to "s"
else
set alertText to alertText & "One new item has "
set plural to ""
end if
set alertText to alertText & "been added to the folder " & «data utxt201C» & folderName & «data utxt201D» & "."
set alertText to alertText & return & return & "Would you like to view the added item" & plural & "?"
display dialog alertText buttons {"Yes", "No"} default button 2 with icon 1 giving up after dialogTimeout
if (button returned of the result) is "Yes" then tell application "Finder"
activate
-- open theFolder
reveal theStuff
end tell
end doStuff

Related

How to get Apple music artwork using AppleScript

I have an AppleScript which retrieves several properties of the current track playing on apple music but I can't retrieve the artwork
if application "Music" is running then
tell application "Music"
if player state is playing or player state is paused then
set currentTrack to current track
return {get player state} & {get artist of currentTrack} & {get name of currentTrack} & {get album of currentTrack} & {get kind of currentTrack} & {get duration of currentTrack} & {player position} & {get genre of current track} & {get id of current track}
else
return "stopped"
end if
end tell
else
return "stopped"
end if
This is very simple i just couldn't find it, so Doug made a very simple script that you can find here and that i reworked a bit it save the current track artwork to the same location as the script and name it tmp.jpg or png
tell application "Music"
try
if player state is not stopped then
set alb to (get album of current track)
tell artwork 1 of current track
if format is JPEG picture then
set imgFormat to ".jpg"
else
set imgFormat to ".png"
end if
end tell
set rawData to (get raw data of artwork 1 of current track)
else
return
end if
on error
display dialog "Problem getting track info." buttons {"OK"}
return
end try
end tell
--get current path
tell application "Finder"
set current_path to container of (path to me) as alias
end tell
--create path to save image as jpg or png
set newPath to ((current_path as text) & "tmp" & imgFormat) as text
try
--create file
tell me to set fileRef to (open for access newPath with write permission)
--overwrite existing file
write rawData to fileRef starting at 0
tell me to close access fileRef
on error m number n
log n
log m
try
tell me to close access fileRef
end try
end try

macOS Photos and AppleScript: Quicker organization method

The Goal:
In macOS Photos App, highlight/select a bulk of photos, iterate each one.
AppleScript will tell Photos to quickview the photo, ask what 'Album(s)' to add the photo to, then it will ask for a title and caption.
I'm doing this because the 'Info' panel that provides this function doesn't allow for rapid entry, and it's pretty small to work with.
So I suppose I need a couple things:
Show the picture (tell Photos to quick look it)
Identify the 'My Album' folders (eliminate the smart folders from the mix)
Prompt and Update the Title and the Caption (called name and description in the def)
Add the photo to the selected Albums.
I'm not sure if it's just me, but the AppleScript scripting on Photos is just not something I can wrap my head around very well.
Here's what I have so far, but I was hoping you can help.
tell application "Photos"
--Find All Albums
set thefullList to the name of every album of every folder
-- Need:Figure out how to strip Smart Albums out of this query
-- Set comma as the delim to separate the folders/albums
set oldDelimiters to AppleScript's text item delimiters
set AppleScript's text item delimiters to ","
set thefullList to every item of thefullList
set AppleScript's text item delimiters to oldDelimiters
-- Test the output (fails to delim, and won't display the string)
display dialog thefullList
-- Clean list of Albums
set albumNames to {thefullList}
-- Get the selected photos from Photos
set theSelection to (get selection)
-- Iterate through each photo
repeat with i in theSelection
-- Tell Photos to 'quick look'
-- Need:(no idea how to make that work yet)
-- Ask the user to choose the Album(s) this photo should go into
set theAlbumChoice to choose from list albumNames with prompt "Where should this photo go?"
-- Tell the Album that this photo is now added
set theAlbum to theAlbumChoice
add i to theAlbum
-- Ask for Title and Caption
display dialog "What's the Title of this Photo?"
set theTitle to text returned of result
display dialog "What's the Caption of this Photo?"
set theCaption to text returned of result
-- Get the Photo ID for adding MetaData
set selectionID to id of item i of theSelection
-- Set the Title and caption
set name of media item id selectionID to theTitle
set description of media item id selectionID to theCaption
end repeat
end tell
property albumNames : {}
property albumIDs : {}
tell application "Photos"
activate
my getAlbumNames(it) -- get all album names and IDs (recursively)
repeat with aPhoto in (get selection) -- process each selected photo
try -- Get the Photo ID
set selectionID to id of aPhoto
on error errorMessage
set ATID to AppleScript's text item delimiters
set AppleScript's text item delimiters to "\""
set selectionID to text item 2 of errorMessage
set AppleScript's text item delimiters to ATID
end try
spotlight media item id selectionID -- Tell Photos to 'quick look'
-- Ask the user to choose the Album(s) this photo should go into
set theAlbumChoice to choose from list albumNames with prompt "Where should this photo go?"
if theAlbumChoice is false then return
-- Find destination folder's ID and add photo to it
repeat with k from 1 to count albumNames
if (item 1 of theAlbumChoice) is (item k of albumNames) then
set theAlbumID to item k of albumIDs
exit repeat
end if
end repeat
add {media item id selectionID} to album id theAlbumID
-- Ask for Title and Caption, and set them
display dialog "What's the Title of this Photo?" default answer ""
set theTitle to text returned of result
display dialog "What's the Caption of this Photo?" default answer ""
set theCaption to text returned of result
set name of media item id selectionID to theTitle
set description of media item id selectionID to theCaption
end repeat
end tell
on getAlbumNames(aFolder) -- recursive handler
tell application "Photos"
set albumNames to albumNames & name of albums of aFolder
set albumIDs to albumIDs & id of albums of aFolder
repeat with subFolder in (get folders of aFolder)
my getAlbumNames(subFolder)
end repeat
end tell
end getAlbumNames

In Applescript: Copy the POSIX path of a selected file to the clipboard

If I select a file in the finder on my local or a remote server, I want the script to paste the POSIX path to the clipboard as text, for pasting in a chat window, etc.
This is what I have so far but it is not very clean:
on run
tell application "Finder"
copy selection to theSelected
set outputPathList to {}
set anItem to theSelected
copy (POSIX path of (anItem as alias)) to end of outputPathList
set AppleScript's text item delimiters to return
set outputString to outputPathList as string
set AppleScript's text item delimiters to ""
set the clipboard to outputString
end tell
end run
Any ideas on how to clean this up?
on run
tell application "Finder"
set theItem to selection as string
end tell
set posixForm to POSIX path of theItem
set the clipboard to posixForm
end run
The property selection of the Finder returns a list of Finder specifiers.
This script copies all POSIX paths (one per line) to the clipboard.
tell application "Finder" to set theSelection to (get selection)
if theSelection is {} then return
set outputPathList to {}
repeat with anItem in theSelection
set end of outputPathList to POSIX path of (anItem as text)
end repeat
set {TID, text item delimiters} to {text item delimiters, return}
set the clipboard to outputPathList as text
set text item delimiters to TID

I want to set variable once in an applescript droplet but it makes me set it for every file

I wrote an applescript droplet where I would like to:
drag one or more images onto the droplet
3 display dialogs appear asking 'width', 'height', 'format'
process all dropped images using the above text returned of the
3 display dialogs
Currently, the 3 display dialogs appear for each image (e.g. 3 images = 9 dialogs appear). Is there a way I can only answer these dialogs once? Here's my script:
on run
display dialog "This is a droplet"
end run
on open draggedItems
set tid to AppleScript's text item delimiters
--ask for new width
set newWidth to text returned of (display dialog "New Width" default answer ¬
"45" buttons {"Continue…", "Cancel"} ¬
default button 1)
--ask for new height
set newHeight to text returned of (display dialog "New Height" default answer ¬
"45" buttons {"Continue…", "Cancel"} ¬
default button 1)
--ask for formatType
set newFormat to text returned of (display dialog "Image Format" default answer ¬
"jpg" buttons {"Continue…", "Cancel"} ¬
default button 1)
--repeat
repeat with i in draggedItems
set theFile to (i as alias)
set theFilePath to (the POSIX path of theFile)
set fullFileName to name of (info for theFile without size)
set AppleScript's text item delimiters to "."
set fileNameNoExtension to first text item of fullFileName
--set fileExtension to second text item of fullFileName
set AppleScript's text item delimiters to tid
do shell script ("/usr/local/bin/convert " & quoted form of theFilePath & " -resize " & newWidth & "x" & newHeight & "\\! ~/desktop/" & fileNameNoExtension & "." & newFormat)
end repeat
end open
on open draggedItems is already an repeat loop, if you drop 4 files on this droplet
on open draggedItems
display dialog (draggedItems as text)
end open
you will get 4 different dialogs.
You could do something like this
property askingForNew : true
on open draggedItems
if askingForNew is true then
--display dialogs
set askingForNew to false
end if
display dialog (draggedItems as text)
end open
or drag the folder on the droplet and go through the files of it (like this).

Why won't Photoshop revert to earlier history state in script?

I've written an Applescript to automate watermarking and resizing images for my company. Everything generally works fine — the script saves the initial history state to a variable, resizes the image, adds the appropriate watermark, saves off a jpeg, then reverts to the initial history state for another resize and watermark loop.
The problem is when I try not to use a watermark and only resize by setting the variable wmColor to "None" or "None for all". It seems that after resizing and saving off a jpeg, Photoshop doesn't like it when I try to revert to the initial history state. This is super annoying, since clearly a resize should count as a history step, and I don't want to rewrite the script to implement multiple open/close operations on the original file. Does anyone know what might be going on? This is the line that's generating the problem (it's in both the doBig and doSmall methods, and throws an error every time I ask it just to do an image resize and change current history state:
set current history state of current document to initialState
and here's the whole script:
property type_list : {"JPEG", "TIFF", "PNGf", "8BPS", "BMPf", "GIFf", "PDF ", "PICT"}
property extension_list : {"jpg", "jpeg", "tif", "tiff", "png", "psd", "bmp", "gif", "jp2", "pdf", "pict", "pct", "sgi", "tga"}
property typeIDs_list : {"public.jpeg", "public.tiff", "public.png", "com.adobe.photoshop-image", "com.microsoft.bmp", "com.compuserve.gif", "public.jpeg-2000", "com.adobe.pdf", "com.apple.pict", "com.sgi.sgi-image", "com.truevision.tga-image"}
global myFolder
global wmYN
global wmColor
global nameUse
global rootName
global nameCount
property myFolder : ""
-- This droplet processes files dropped onto the applet
on open these_items
-- FILTER THE DRAGGED-ON ITEMS BY CHECKING THEIR PROPERTIES AGAINST THE LISTS ABOVE
set wmColor to null
set nameCount to 0
set nameUse to null
if myFolder is not "" then
set myFolder to choose folder with prompt "Choose where to put your finished images" default location myFolder -- where you're going to store the jpgs
else
set myFolder to choose folder with prompt "Choose where to put your finished images" default location (path to desktop)
end if
repeat with i from 1 to the count of these_items
set totalFiles to count of these_items
set this_item to item i of these_items
set the item_info to info for this_item without size
if folder of the item_info is true then
process_folder(this_item)
else
try
set this_extension to the name extension of item_info
on error
set this_extension to ""
end try
try
set this_filetype to the file type of item_info
on error
set this_filetype to ""
end try
try
set this_typeID to the type identifier of item_info
on error
set this_typeID to ""
end try
if (folder of the item_info is false) and (alias of the item_info is false) and ((this_filetype is in the type_list) or (this_extension is in the extension_list) or (this_typeID is in typeIDs_list)) then
-- THE ITEM IS AN IMAGE FILE AND CAN BE PROCESSED
process_item(this_item)
end if
end if
end repeat
end open
-- this sub-routine processes folders
on process_folder(this_folder)
set these_items to list folder this_folder without invisibles
repeat with i from 1 to the count of these_items
set this_item to alias ((this_folder as Unicode text) & (item i of these_items))
set the item_info to info for this_item without size
if folder of the item_info is true then
process_folder(this_item)
else
try
set this_extension to the name extension of item_info
on error
set this_extension to ""
end try
try
set this_filetype to the file type of item_info
on error
set this_filetype to ""
end try
try
set this_typeID to the type identifier of item_info
on error
set this_typeID to ""
end try
if (folder of the item_info is false) and (alias of the item_info is false) and ((this_filetype is in the type_list) or (this_extension is in the extension_list) or (this_typeID is in typeIDs_list)) then
-- THE ITEM IS AN IMAGE FILE AND CAN BE PROCESSED
process_item(this_item)
end if
end if
end repeat
end process_folder
-- this sub-routine processes files
on process_item(this_item)
set this_image to this_item as text
tell application id "com.adobe.photoshop"
set saveUnits to ruler units of settings
set display dialogs to never
open file this_image
if wmColor is not in {"None for all", "White for all", "Black for all"} then
set wmColor to choose from list {"None", "None for all", "Black", "Black for all", "White", "White for all"} with prompt "What color should the watermark be?" default items "White for all" without multiple selections allowed and empty selection allowed
end if
if wmColor is false then
error number -128
end if
if nameUse is not "Just increment this for all" then
set nameBox to display dialog "What should I call these things?" default answer ("image") with title "Choose the name stem for your images" buttons {"Cancel", "Just increment this for all", "OK"} default button "Just increment this for all"
set nameUse to button returned of nameBox -- this will determine whether or not to increment stem names
set rootName to text returned of nameBox -- this will be the root part of all of your file names
set currentName to rootName
else
set nameCount to nameCount + 1
set currentName to rootName & (nameCount as text)
end if
set thisDocument to current document
set initialState to current history state of thisDocument
set ruler units of settings to pixel units
end tell
DoSmall(thisDocument, currentName, initialState)
DoBig(thisDocument, currentName, initialState)
tell application id "com.adobe.photoshop"
close thisDocument without saving
set ruler units of settings to saveUnits
end tell
end process_item
to DoSmall(thisDocument, currentName, initialState)
tell application id "com.adobe.photoshop"
set initWidth to width of thisDocument
if initWidth < 640 then
resize image thisDocument width 640 resample method bicubic smoother
else if initWidth > 640 then
resize image thisDocument width 640 resample method bicubic sharper
end if
set myHeight to height of thisDocument
set myWidth to width of thisDocument
if wmColor is in {"White", "White for all"} then
set wmFile to (path to resource "water_250_white.png" in bundle path to me) as text
else if wmColor is in {"Black", "Black for all"} then
set wmFile to (path to resource "water_250_black.png" in bundle path to me) as text
end if
if wmColor is not in {"None", "None for all"} then
open file wmFile
set wmDocument to current document
set wmHeight to height of wmDocument
set wmWidth to width of wmDocument
duplicate current layer of wmDocument to thisDocument
close wmDocument without saving
translate current layer of thisDocument delta x (myWidth - wmWidth - 10) delta y (myHeight - wmHeight - 10)
set opacity of current layer of thisDocument to 20
end if
set myPath to (myFolder as text) & (currentName) & "_640"
set myOptions to {class:JPEG save options, embed color profile:false, quality:12}
save thisDocument as JPEG in file myPath with options myOptions appending lowercase extension
set current history state of current document to initialState
end tell
end DoSmall
to DoBig(thisDocument, currentName, initialState)
tell application id "com.adobe.photoshop"
set initWidth to width of thisDocument
if initWidth < 1020 then
resize image thisDocument width 1020 resample method bicubic smoother
else if initWidth > 1020 then
resize image thisDocument width 1020 resample method bicubic sharper
end if
set myHeight to height of thisDocument
set myWidth to width of thisDocument
if wmColor is in {"White", "White for all"} then
set wmFile to (path to resource "water_400_white.png" in bundle path to me) as text
else if wmColor is in {"Black", "Black for all"} then
set wmFile to (path to resource "water_400_black.png" in bundle path to me) as text
end if
if wmColor is not in {"None", "None for all"} then
open file wmFile
set wmDocument to current document
set wmHeight to height of wmDocument
set wmWidth to width of wmDocument
duplicate current layer of wmDocument to thisDocument
close wmDocument without saving
translate current layer of thisDocument delta x (myWidth - wmWidth - 16) delta y (myHeight - wmHeight - 16)
set opacity of current layer of thisDocument to 20
end if
set myPath to (myFolder as text) & (currentName) & "_1020"
set myOptions to {class:JPEG save options, embed color profile:false, quality:12}
save thisDocument as JPEG in file myPath with options myOptions appending lowercase extension
set current history state of current document to initialState
end tell
end DoBig
If you choose a color : save document "Ducky.tif" as JPEG in file ..... the current document will be document "Ducky.tif".
If you choose "None" or "None for all" : save document "Ducky.tif" as JPEG in file ...... the current document will be document "image_640".
So the variable initialState = history state 2 of document "Ducky.tif" give an error, because this document no longer exists.
To leaving original open, here's a solution , use copying true in your save command.
save thisDocument as JPEG in file myPath with options myOptions appending lowercase extension with copying

Resources