Applescript - ghosted result with applescript set file label - applescript

I did make this script in automator.
property unset : 0
property orange : 1
property red : 2
property yellow : 3
property blue : 4
property purple : 5
property green : 6
property grey : 7
property tmplFileName : "__ReadMe" as string
property fileType : ".txt" as string
property labelTag : red
on run {input, parameters}
tell application "Finder"
set currentPath to insertion location as text
-- set filePath to POSIX path of currentPath
set txtfilename to tmplFileName & fileType
set txtFile to make new file at insertion location as alias with properties {name:txtfilename}
set the label index of the item (txtFile as alias) to my labelTag
select txtFile
open txtFile
end tell
return input
end run
It give's me the following result. A ghosted or visible only disabled file.
What do I wrong? This happens only when I set the label. Its about this line
set the label index of the item (txtFile as alias) to my labelTag
Any suggestions? Thank you.

Still don't understand why the file is disabled. Anyway and moving forward, after some reading I came with this as a test script, and it works. Need some error management like check existing file.
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
property |NSURL| : a reference to current application's NSURL
property tmplFileName : "__ReadMe" as string
property fileType : ".txt" as string
property labelTag : "red"
-- Replace tags;
-- setTags - pass a list with new tags and replacing any existing
-- forPath - POSIX path
on setTags:tagList forPath:POSIXPath
set aURL to current application's |NSURL|'s fileURLWithPath:POSIXPath
aURL's setResourceValue:tagList forKey:(current application's NSURLTagNamesKey) |error|:(missing value)
end setTags:forPath:
on run {input, parameters}
tell application "Finder"
set txtfilename to tmplFileName & fileType
set txtFile to make new file at insertion location as alias with properties {name:txtfilename}
set POSIXPath to POSIX path of (txtFile as text)
(my setTags:{labelTag} forPath:POSIXPath)
select txtFile
tell application "TextEdit"
activate
open txtFile as alias
end tell
end tell
return input
end run
Hope this help some other people as well. Do I get now a plus one vote back from above. As a side note, can some one explain why I did get a -1? just curious.
Thank you.

I took a stab in the dark and thought maybe the problem was the size of the file that was created, was 0 kb's. I decided to add a handler with the write to file command and added a single space as a character to the file. This made the file size 1 byte and then setting the label index worked. I made a few minor adjustments to your initial code, for my purposes but here are the changes I've made and my version of the code.
local unset, orange, red, yellow, blue, purple, green, grey
set {unset, orange, red, yellow, blue, purple, green, grey} to {0, 1, 2, 3, 4, 5, 6, 7}
set tmplFileName to "__ReadMe"
set nameExtension to ".txt"
set labelTag to red
tell application "Finder"
set currentPath to insertion location
set txtfilename to tmplFileName & nameExtension
set txtFile to make new file at insertion location as alias with properties {name:txtfilename, name extension:nameExtension}
my writeToTheFile(txtFile as alias)
set the label index of (txtFile as alias) to labelTag
open txtFile
end tell
on writeToTheFile(txtFile as alias)
set theFile to txtFile as alias
set theText to " "
try
set writeToFile to open for access theFile with write permission
write theText to writeToFile as text starting at eof
close access theFile
on error errMsg number errNum
try
close access theFile
end try
end try
end writeToTheFile

Related

Multipage tiff to pdf with a script

I'm trying to make a pdf of a multipage tiff file. We tried this solution on a newer version of macOS and it worked. Can someone else help me to fine tune this?
After the conversion I like to rejoin the two separate pdf's to one file and I want to run it automatacily when a file is added to a certain folder.
Create hot folder on your Mac. Attach following script to it. The script will convert 1 multipage TIFF to 1 multipage PDF, at once:
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "QuartzCore"
use framework "Quartz"
use framework "AppKit"
property |NSURL| : a reference to current application's |NSURL|
property NSString : a reference to current application's NSString
property PDFPage : a reference to current application's PDFPage
property NSImage : a reference to current application's NSImage
property PDFDocument : a reference to current application's PDFDocument
property NSBitmapImageRep : a reference to current application's NSBitmapImageRep
on adding folder items to this_folder after receiving these_items
set aRes to convertMultiPageTiffToPDF(item 1 of these_items) of me
end adding folder items to
on convertMultiPageTiffToPDF(anAlias)
--Make Output Path
set b to POSIX path of anAlias
set bb to changeExtensionInPath("pdf", b) --OutPath
--Read Multi-Page TIFF
set aURL to |NSURL|'s fileURLWithPath:b
set aImage to NSImage's alloc()'s initWithContentsOfURL:aURL
set aRawimg to aImage's TIFFRepresentation()
set eachTiffPages to (NSBitmapImageRep's imageRepsWithData:aRawimg) as list
--Make Blank PDF
set aPDFdoc to PDFDocument's alloc()'s init()
set pageNum to 0
repeat with curPage in eachTiffPages
set thisImage to contents of curPage
set aImg to (NSImage's alloc()'s initWithSize:(thisImage's |size|()))
(aImg's addRepresentation:thisImage)
(aPDFdoc's insertPage:(PDFPage's alloc()'s initWithImage:aImg) atIndex:pageNum)
set pageNum to pageNum + 1
end repeat
return (aPDFdoc's writeToFile:bb) as boolean
end convertMultiPageTiffToPDF
on changeExtensionInPath(extStr as string, aPath as string)
set pathString to NSString's stringWithString:aPath
set theExtension to pathString's pathExtension()
set thePathNoExt to pathString's stringByDeletingPathExtension()
set newPath to thePathNoExt's stringByAppendingPathExtension:extStr
return newPath as string
end changeExtensionInPath

Can I read/write the name of the Illustrator artboard in Applescript

Is it possible to get the name of an Illustrator artboard in Applescript?
This script works perfectly until I try to get the name of the artboard:
tell application "Adobe Illustrator"
tell document 1
set artboards_count to count of artboards
set c to 1
repeat while c <= artboards_count
log index of artboard c as text
log artboard rectangle of artboard c as text
log name of artboard c as text -- this line fails
set c to c + 1
end repeat
end tell
end tell
the line log name of artboard c as text fails - everything else works ok.
The message is:
Adobe Illustrator got an error: Can’t get name of artboard 1 of document 1. (-1728)
Any idea as to why?
Setting the name fails too, BTW. However if I do
tell application "Adobe Illustrator"
tell document 1
return properties of artboard 1
end tell
end tell
I get (carriage returns added for clarify):
artboard rectangle:0.0, 0.0, 841.889999999999, -595.280000000001,
ruler PAR:1.0, show center:false, show cross hairs:false,
show safe areas:false, ruler origin:0.0, 0.0, name:Artboard 1,
container:document 1, best type:reference, default type:reference,
class:artboard, index:1
from which one would think the property nameshould be there.
The name property is read-only so there is no way to change it once the artboard exists. And even though you can get the properties of an artboard, you can’t convert it to a string if you simply want to target a particular artboard. But there is a way to do it nonetheless that I discovered by accident. Suppose you have several artboards and want to target the artboard named "Squash this". Here's how to do that:
Tell application "Adobe Illustrator"
tell current document
set artCount to number of artboards
repeat with i from 1 to artCount
set artProp to get properties of artboard i
try
set propString to artProp as string --this will fail
on error
set errorDisp to text of result --this captures the text of the error
set errorDispText to errorDisp as string --changes the text to a ¬
searchable string
end try
if errorDispText contains "quash" then
display notification "errorDispText" --oddly enough, this displays just ¬
the artboard name
exit repeat
end if
end repeat
end tell
end tell
The best solution could be coercion; take the record returned from the Artboard properties and coerce the record into a list. So, your name property from the record becomes the 7th item in the list. The code below will get Artboard dimensions, name and index, and place them into a list for later use in your script.
Hope this helps!
tell application "Adobe Illustrator"
set artboardDetails to {}
tell front document
set allArtboards to every artboard
repeat with i from 1 to count of allArtboards
set thisArtboard to item i of allArtboards
set thisArtboardProps to properties of thisArtboard
set thisArtboardDimensions to artboard rectangle of thisArtboardProps
set thisArtboardIndex to index of thisArtboardProps
--WORKAROUND
set thisArtboardPropsCoerce to thisArtboardProps as list
set thisArtboardName to item 7 of thisArtboardPropsCoerce
set the end of artboardDetails to {thisArtboardName, thisArtboardIndex, thisArtboardDimensions}
end repeat
end tell
end tell
(*
--WORKAROUND
The following is a workaround for error returned from:
set anArtboardName to the name of anArtboard -- this line will not return a result, just errors out
BUT WE NEED TO WATCH OUT FOR THE COERCED LIST!
So, we have to coerce the properties record of artboard to a list first
WEIRD I KNOW!
The coercion then changes the record of 11 items to a list of 12 items
set anArtboardProps to properties of anArtboard as list
set anArtboardName to item 7 of anArtboardProps
NOW LETS MATCH UP THE COERCION ITEMS
The first lines are from the record properties, and the second lines are from the coerced to list versions.
01. artboard rectangle:{0.0, 768.0, 1366.0, 0.0},
01. {0.0, 768.0, 1366.0, 0.0},
02. ruler PAR:1.0,
02. 1.0,
03. show center:false,
03. false,
04. show cross hairs:false,
04. false,
05. show safe areas:false,
05. false,
06. ruler origin:{0.0, 0.0},
06. {0.0, 0.0},
07. name:"Artboard 1",
07. "Artboard 1",
08. container:document 1,
08. document 1,
09. best type:reference,
09. reference,
10. default type:reference,
10. reference,
11. index:1
11. artboard,
12. NULL - nothing in the record
12. 1 - so this line is the index of the artboard
*)
Here is my workaround. As the «class bAl9» vanishes every time you compile, you have to copy/paste every time, but it works. And yes, «class bAl9» will turn to "name" and will not compile correctly the next time. Thanks Adobe !
tell application "Adobe Illustrator"
tell document 1
repeat with x in (every artboard)
log index of x as text
log artboard rectangle of x as text
log «class bAl9» of x as text -- artboard's name property = «class bAl9»
end repeat
end tell
end tell
The name property of artboards is read/write, it's easy to rename artboards this way once you get the trick.
Edit : For the loop in a list, I always use the repeat with x in l statement. It's smart and fast.
Stu's answer was the best that I found. Coercing the record to a list is brilliant – I didn't even know you could do that. My code was:
repeat with i from 1 to the (count of AllArtBoards)
set ThisArtBoard to item i of AllArtBoards
set ThisArtBoardName to item 7 of ((properties of ThisArtBoard) as list)
set the end of AllArtBoardNames to ThisArtBoardName
end repeat

Save and restore Finder windows list

I don't remember exactly how I did it but I used to have keyboard shortcuts mapped with Butler that ran some AppleScript I wrote thanks to multiple sources.
One script was used to save all Finder windows properties to a text file (prompt for name), and the other would read the file (prompt for name again) and restore Finder windows accordingly.
Text files would look like that:
{
{
folder "Desktop"
of folder "Me"
of folder "Users"
of startup disk of application "Finder", {
0, 0, 1200, 315
}, column view, 192
}, {
folder "Backups"
of disk "SAFE"
of application "Finder", {
0, 380, 1200, 685
}, column view, 192
}
}
From there, I know how to restore the windows. I just lost the script I made, that retrieves all these values...
To restore windows :
tell application "Finder"
set windowList to {
{
folder "Desktop"
of folder "Me"
of folder "Users"
of startup disk of application "Finder", {
0, 0, 1200, 315
}, column view, 192
}, {
folder "Backups"
of disk "SAFE"
of application "Finder", {
0, 380, 1200, 685
}, column view, 192
}
}
close every window
repeat with i from 1 to count of windowList
set theseProps to item i of windowList
make new Finder window at front to item 1 of theseProps
tell window 1
set bounds to item 2 of theseProps
set current view to item 3 of theseProps
set sidebar width to item 4 of theseProps
end tell
end repeat
end tell
My question :
How to get all Finder windows and properties with AppleScript?
And how to save those to a file?
[EDIT]
Here is how to get all properties needed :
set windowsList to {}
tell application "Finder"
set theWindows to windows
repeat with theWindow in theWindows
set t to target of theWindow
set b to bounds of theWindow
set v to current view of theWindow
set w to sidebar width of theWindow
copy {t, b, v, w} to end of windowsList
end repeat
end tell
Now I need a way to save this in a file, being able to load it as a list later on...
[EDIT]
I'm able to write to a file this way :
set prefs_folder to path to preferences folder as string
set prefs_file to prefs_folder & "finderwindows"
try
set open_file to ¬
open for access file prefs_file with write permission
-- erase current contents of file:
set eof of open_file to 0
write windowList to open_file starting at eof
close access open_file
on error
try
close access file prefs_file
end try
end try
But the file remains empty. The script is exiting with error -10004...
My question is now :
How to convert the windowList to a file savable format I can then retrieve by reading from another script??
FYI: I have a program called Simple WindowSets that does exactly this... save and restore sets of Finder windows. It's very popular. So although you can do as you ask using applescript, maybe you'd be interested. Find it here.
By the way, to answer your specific question, here's a handler I use for writing to a file. Good luck.
on writeTo(targetFile, theData, dataType, apendData)
-- targetFile is the path to the file you want to write
-- theData is the data you want in the file.
-- dataType is the data type of theData and it can be text, list, record etc.
-- apendData is true to append theData to the end of the current contents of the file or false to overwrite it
try
set targetFile to targetFile as text
if targetFile does not contain ":" then set targetFile to POSIX file targetFile as text
set openFile to open for access file targetFile with write permission
if apendData is false then set eof of openFile to 0
write theData to openFile starting at eof as dataType
close access openFile
return true
on error
try
close access file targetFile
end try
return false
end try
end writeTo

Issue with applescript function

I'm trying to the function replaceChars in the below script but getting the following error:
error "Finder got an error: Can’t continue replace_chars." number -1708
The intention is to add the script to finder as a button so that I can simply click it to copy the path to my clipboard. I'm adding file://localhost/ so that the link can then be used when shared with users by email as a direct link to a folder on the local network. If possible I would also like to add to clipboard the same for Windows machines.
If you could offer any guidance as to the task above it would be much appreciated, this is my first attempt at programming with applescript so I'm not that knowledgable of how things are done.
Heres the code:
on appIsRunning(appName)
tell application "System Events"
set isRunning to ((application processes whose (name is equal to appName)) count)
end tell
if isRunning is greater than 0 then
return true
else
return false
end if
end appIsRunning
on replace_chars(this_text, search_string, replacement_string)
set AppleScript's text item delimiters to the search_string
set the item_list to every text item of this_text
set AppleScript's text item delimiters to the replacement_string
set this_text to the item_list as string
set AppleScript's text item delimiters to ""
return this_text
end replace_chars
if appIsRunning("Finder") then
tell application "Finder"
set thePath to "file://localhost/" as text
set theTarget to (target of front Finder window) as text
set the clipboard to thePath & replace_chars(theTarget, ":", "/") as text
end tell
end if
AppleScript is looking for a replace_chars handler in the Finder's scripting dictionary. You can either make it into my replace_chars to have AS look in the script, or (probably better) move the set the clipboard to thePath & replace_chars(theTarget, ":", "/") as text line out of the tell block altogether.
You can make it into a one-line script:
tell application "Finder" to set the clipboard to "file://localhost" & (target of front Finder window as text)'s POSIX path
Replace your replace_chars(theTarget, ":", "/") call with replace_chars(theTarget, ":", "/") of me:
set the clipboard to thePath & replace_chars(theTarget, ":", "/") of me as text

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