Setting a custom label to a file with AppleScript [closed] - applescript

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
Here's what I got, but I ave a custom label with "Active Projects".
How do I assign?
tell application "Finder" to set label index of theFile to 5

You can't do that with vanilla AppleScript. The Finder dictionary does not support adding tags.
However you can do it with AppleScriptObjC which gives access to the Foundation framework
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
use framework "Foundation"
on addTagToPath(theTag, thePath)
set theURL to current application's NSURL's fileURLWithPath:thePath
set {success, tagArray, theError} to theURL's getResourceValue:(reference) forKey:(current application's NSURLTagNamesKey) |error|:(reference)
if theError is not missing value then error theError's localizedDescription() as text
if tagArray is not missing value and (tagArray's containsObject:theTag) as boolean is true then return
if tagArray is missing value then set tagArray to current application's NSMutableArray's array()
tagArray's addObject:theTag
set {success, theError} to theURL's setResourceValue:tagArray forKey:(current application's NSURLTagNamesKey) |error|:(reference)
if theError is not missing value then error theError's localizedDescription() as text
end addTagToPath
and use it
try
addTagToPath("MyTag", "/Users/myUser/path/to/file.ext")
on error e
log e
end try
The try block catches errors thrown by the NSURL methods

Related

How to get the text output from the terminal?

I would like to know if it is possible to get the text output that is displayed in the terminal by running a shell script and display it in a Scrollable Text View, using applescript.
for example:
The output that the command: git clone https://github.com/torvalds/linux.git displays as shown in the image below would be displayed in a Scrollable Text view, would that be possible?
P.S:I'm sorry if the explanation was not clear, I hope someone understands and can help me!!
The steps for getting output from an asynchronous task like this are:
Create an
NSTask;
set its output to an NSPipe's fileHandleForReading;
register for a notification so you can get data to put into the textView as it becomes available.
To help with converting from Objective-C, Apple provided a conversion guide with their AppleScriptObjC Release Notes, but other than examples posted on various web sites and forums, that is about it. In general, for specific information about the various Cocoa classes and methods, you will need to look them up in Apple's documentation (for Swift you can switch to the Objective-C equivalent).
Note that an NSTextView does not have any terminal emulation (ANSI escape codes, etc), which is not trivial (take a look at iTerm2 for an example terminal application), so there won't be any cursor control. Git is also a little weird in that the progress uses standard error, so that will need to be redirected to standard output.
For a plain Xcode example, create a new AppleScriptObjC project and add the following statements to the AppDelegate:
property textView : missing value -- IBOutlet
property task : missing value -- this will be the NSTask
to startTask()
tell current application's NSTask's alloc's init() -- set up the task
its setCurrentDirectoryURL:(current application's NSURL's fileURLWithPath:(POSIX path of (path to desktop folder))) -- currentDirectoryPath deprecated in 10.13
set gitPath to "/Applications/Xcode.app/Contents/Developer/usr/bin/git"
its setExecutableURL:(current application's NSURL's fileURLWithPath:"/bin/zsh") -- launchPath deprecated in 10.13
its setArguments:{"-c", gitPath & " clone --progress https://github.com/torvalds/linux.git 2>&1"} -- combine stderr with stdout
its setStandardOutput:(current application's NSPipe's pipe())
its standardOutput's fileHandleForReading's readInBackgroundAndNotify()
set my task to it -- update script property
end tell
# set up notification observers
set notificationCenter to current application's NSNotificationCenter's defaultCenter
set readNotification to current application's NSFileHandleReadCompletionNotification
notificationCenter's addObserver:me selector:"dataAvailable:" |name|:readNotification object:(task's standardOutput's fileHandleForReading)
set terminateNotification to current application's NSTaskDidTerminateNotification
notificationCenter's addObserver:me selector:"taskTerminated:" |name|:terminateNotification object:task
set {theResult, theError} to task's launchAndReturnError:(reference) -- |launch| deprecated in 10.13
if theError is missing value then
log "Task Launched"
else
log "Error launching task: " & (theError's localizedDescription() as text)
end if
end startTask
on dataAvailable:notification -- get some output from the task
set theData to notification's userInfo()'s objectForKey:(current application's NSFileHandleNotificationDataItem)
if theData is not missing value and theData's |length|() > 0 then showResult(theData)
notification's object's readInBackgroundAndNotify() -- notify again when more data is available
end dataAvailable:
to showResult(resultData) -- append data to the end of the text view
set resultString to current application's NSString's alloc()'s initWithData:resultData encoding:(current application's NSUTF8StringEncoding)
set attributedString to current application's NSMutableAttributedString's alloc()'s initWithString:resultString
set theFont to (current application's NSFont's fontWithName:"Menlo Regular" |size|:12)
set theRange to (current application's NSMakeRange(0, attributedString's |length|()))
attributedString's addAttribute:(current application's NSFontAttributeName) value:theFont range:theRange -- use monospaced font
textView's textStorage()'s appendAttributedString:attributedString
textView's scrollToEndOfDocument:me -- 10.14+
end showResult
on taskTerminated:notification
current application's NSNotificationCenter's defaultCenter's removeObserver:me
repeat -- get any early termination leftovers
set theData to notification's object's standardOutput's fileHandleForReading's availableData
if theData is not missing value and theData's |length|() > 0 then
showResult(theData)
else
exit repeat
end if
end repeat
set my task to missing value -- clear script property
log "Task Terminated"
end taskTerminated:
In the Interface Editor, add a scrollable text view to the main window and connect it to the textView property, edit the currentDirectory and gitPath locations as needed, and put a statement in the applicationWillFinishLaunching hander to call startTask().
For something a bit simpler (shorter) to test with that still has a little output, the task arguments can be changed to something like:
its setExecutableURL:(current application's NSURL's fileURLWithPath:"/usr/sbin/system_profiler")
its setArguments:{"-detailLevel", "basic"} -- mini, basic, full
-- or --
its setExecutableURL:(current application's NSURL's fileURLWithPath:"/bin/zsh")
its setArguments:{"-c", "find /Users/$USER -iname '*.scpt'" } -- find scripts

"tell application" in XCode [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 4 years ago.
Improve this question
Very very newbie to XCode here, although I used it years ago to do all sorts of things in what they used to call Applescript Studio.
I'm trying to get the Finder to tell me the name of the file dropped on my app:
on |application|:theApp openFile:aFile
display alert "123"
tell application "Finder"
set theName to (name of aFile)
end tell
display alert theName
end
"123" is displayed, but theName is not. Surmising that my syntax is wrong -- I've taken a look at Scripting Bridge, but this seems to be about making my app be able to respond to apple events from other scripts, which is not what I want.
My apologies for straying into possible off-topic areas with my original post. I figured that it was better to find somewhere that I can solve my own problems than to have to come running for help every time I need it ;-)
Can someone please help me figure out how to get the Finder to tell me the name of a file?
aFile is an NSString, so you can use Cocoa to parse aFile itself. You have the full resources of Cocoa at your beck and call; involving the Finder is unnecessary. But you cannot display an NSString using AppleScript; you must cast it to an AppleScript string first. So, for example:
set lpc to aFile's lastPathComponent()
display alert (lpc as string)
If you must use AppleScript to do the parsing (e.g. asking the Finder to do it for you) because you're more comfortable that way, then just say aFile as string up front and then go ahead and parse further the resulting AppleScript string. For example:
set p to aFile as string
tell application "Finder"
set f to POSIX file p as alias
get name of f
display alert result
end tell
However, I think that's a very foolish approach; scripting another app is expensive, while using Cocoa directly is not.

AppleScript to get the active list in Reminders?

Can anyone help me to get the active list on display in the Reminders app on OS X?
According to the applescript dictionary for reminders, the application has a "default list" property which is "the list currently active in the Reminders application."
However, this property always seems to return the first list in order in the lists sidebar, not the list which is actually being displayed and is active. I have found that if I rearrange the order of the lists in the sidebar, I will always get whichever I have made the first list, regardless of which is actually being viewed and worked with.
My application is to create a Keyboard Maestro trigger to run an AppleScript to print the list I am currently working on, but it does not appear that the Reminders app functions as is documented in its dictionary. (I have temporarily used a workaround of having the script pop up a chooser listing all the lists so I can select the one i want to print, but that's inefficient and inelegant).
Thanks!
Yes, you can, but you will have to use the bad GUI scripting. And in a bad way. Look:
--Do some GUI scripting to get the decription of a specific group
tell application "Reminders" to activate
tell application "System Events"
tell process "Reminders"
tell window "Reminders"
tell splitter group 1
tell group 1
set des to get description
end tell
end tell
end tell
end tell
end tell
--This description is in the format "Viewing MyList, 1 reminder" so get the part to the "," from des.
set text item delimiters to ","
set texitems to text items of des
set firstPart to get text item 1 of texitems
--Setting the delimiters back
set text item delimiters to ""
--Jump to charcter 9 of firstPart then converting to text
set listname to characters 9 thru end of firstPart as text
--Now we know the name of the current list, so do whatever you want:
tell application "Reminders" to get list listname
This works. But only if Reminders is open. And if Apple changes Reminders structure...

Applescript for creating New Message with Mail application

I have an AppleScript for Mail.app which opens a new message window with pre-defined recipient address and subject. This script opens a new window every time I run it:
tell application "Mail"
set newMessage to make new outgoing message with properties {subject:"some subject", content:"" & return & return}
tell newMessage
set visible to true
make new to recipient at end of to recipients with properties {name:"some name", address:"some address"}
end tell
activate
end tell
But I want the script to open a new message window only when the previously opened window is closed – otherwise, the previously opened window should come to the front.
Can anyone please help me in modifying this script to achieve the above mentioned functionality?
I didn't test this but it should do what you need... at least it shows you the proper approach. You basically use a "property" to keep track of some value from the last time the script was run. In this case we check for the name of the frontmost window and see if it matches your criteria. If the window name doesn't do what you need then just find some other value to track between launches of the script. The basic approach should work.
EDIT: using the ID of the message, which is unique, the following will do what you want:
property lastWindowID : missing value
tell application "Mail"
set windowIDs to id of windows
if windowIDs does not contain lastWindowID then
set newMessage to make new outgoing message with properties {subject:"some subject", content:"" & return & return}
tell newMessage
set visible to true
make new to recipient at end of to recipients with properties {name:"some name", address:"some address"}
end tell
activate
set lastWindowID to id of window 1
else
tell window id lastWindowID
set visible to false
set visible to true
end tell
activate
end if
end tell
the visibility toggle seems to be the only way to get the window in front, as frontmost is a read-only property. The lastWindowID property will store the ID as long as the script is not re-compiled (caveat empteor: do not put this into an Automator service, as these get re-compiled every time the service is loaded).

Using AppleScript how do I click a button in a dialog within a window that has no name/title? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I'm trying to write an AppleScript that will empty the cache of Twitter for Mac and then restart the app. The problem I'm running into is that the confirmation dialog doesn't have a name (the title bar is empty) so I'm lost as to how I target the button with no context. Here's what I have so far:
tell application "Twitter"
activate
end tell
tell application "System Events"
tell process "Twitter"
tell menu bar 1
tell menu bar item "Twitter"
tell menu "Twitter"
click menu item "Empty Cache"
end tell
end tell
end tell
end tell
end tell
tell application "System Events"
click button "Empty Cache" of window "Empty Cache?"
end tell
tell application "Twitter"
quit
end tell
tell application "Twitter"
activate
end tell
There are numerous ways to refer to objects within the object hierarchy: name is only one way (see AppleScript Language Guide: Reference Forms. Your script already uses one of the other ways: Index.
tell menu bar 1
That's referring to the menu bar by its index: (unlike in many programming languages, items in a list in AppleScript are indexed starting at 1 rather than 0). The script below should accomplish what you want:
tell application "Twitter" to activate
tell application "System Events"
tell application process "Twitter"
click menu item "Empty Cache" of menu "Twitter" of menu bar item "Twitter" of menu bar 1
delay 1
--click button "Empty Cache" of front window
click button "Empty Cache" of window 1
end tell
end tell
tell application "Twitter"
quit
delay 1
activate
end tell
You can probably comment out the delay 1 lines; I added those to slow down the procedure so you can easier see what's happening.
When trying to figure out how to "get at" an object in an application via AppleScript, I often find it helpful to use AppleScript Editor to create little query scripts to try to discover more info about the app. For example, in Twitter, I chose Twitter > Empty Cache to bring up the Empty Cache window. I then ran the following script:
tell application "Twitter"
set theWindows to every window -- get a list of windows
(* turns out there's only one window listed,
so get the first item in the list *)
set theWindow to first item of theWindows
-- get the properties of the window
properties of theWindow
end tell
This script returned the following result:
{closeable:true, zoomed:false, class:window, index:1,
visible:true, name:missing value, miniaturizable:true,
id:28551, miniaturized:false, resizable:true,
bounds:{-618, 76, -128, 756}, zoomable:true}

Resources