Skip to content

Instantly share code, notes, and snippets.

@jerrykrinock
Last active March 21, 2023 11:52
Show Gist options
  • Save jerrykrinock/2a6ce62a1676aa1cc659 to your computer and use it in GitHub Desktop.
Save jerrykrinock/2a6ce62a1676aa1cc659 to your computer and use it in GitHub Desktop.
My personal utility library of AppleScript handlers, and some one-liners
-- To load this library, see section titled "-- Using a handler in a .scpt library" at the top of One_Liners.scpt.
on testJerryLib()
return 0
end testJerryLib
(* The bad thing about this handler is that it always asks the user for admin credentials whether or not they are actually needed to answer the question on the given path.
Obviously, you can remove the 'with adminstrator privileges'. Unfortunately, this will cause the method to return 'false' if an existing path cannot be probed because of bad permissions. I can't see any way to differentiate between inadequate permissions and nonexisting file because they both set errNumber = 54.
The -e checks for directories or files. To require that the given path be a directory, use -d. For file, use -f. For more variations, see:
http://www.cyberciti.biz/tips/find-out-if-file-exists-with-conditional-expressions.html *)
on pathExistsWithAdmin(path)
local fileExists -- boolean
try
set result to (do shell script "if [ -e " & quoted form of path & " ] ; then exit 0 ; else exit 1 ; fi" with administrator privileges)
set fileExists to true
on error errMsg number errNumber
set fileExists to false
end try
return fileExists
end pathExistsWithAdmin
on pathExists(path)
local fileExists -- boolean
try
set result to (do shell script "if [ -e " & quoted form of path & " ] ; then exit 0 ; else exit 1 ; fi")
set fileExists to true
on error errMsg number errNumber
set fileExists to false
end try
return fileExists
end pathExists
-- This works with a POSIX package. Never tried with HFS or Alias
on fileExists(theFile)
tell application "System Events"
if exists file theFile then
return true
else
return false
end if
end tell
end fileExists
on addTrailingSlashIfMissing(aString)
set chars to characters of aString
if ((count of chars) is greater than 1) then
if (last item of chars) is not "/" then
set aString to aString & "/"
end if
else
set aString to "/"
end if
return aString
end addTrailingSlashIfMissing
on removeTrailingSlash(aString)
return trim(aString, "/", 1)
end removeTrailingSlash
(* Replaces the "~" POSIX shorthand for home folder with its actual path and returns the resulting path. *)
on expandHomeTildePathPrefix(aPath)
if ((characters of aPath) is equal to (characters of "~")) then
set aPath to (POSIX path of (path to home folder))
-- Remove the trailing /
set aPath to characters 1 thru ((count of characters of aPath) - 1) of aPath as string
else if ((characters of aPath) is equal to (characters of "~/")) then
set aPath to (POSIX path of (path to home folder))
else if aPath begins with "~" then
set home_posix_path to POSIX path of (path to home folder)
set aPath to home_posix_path & characters 3 thru end of aPath
end if
return aPath
end expandHomeTildePathPrefix
(*
Performs POSIX chmod command on a given path
optionModeString is a string, the option(s) and/or mode will be sandwiched between the chmod program name and the path to be modified. Examples…
"700" Change mode of aPath to 700
"-N" Remove all ACLs from aPath
"-RN" Remove all ACLs from directory aPath, and from all of its contents
This method returns a human-readable string that says if it succeeded or failed, why &/or how.
*)
on chmodPath(optionModeString, aPath, doEscalate)
set resultString to missing value
set aPath to expandHomeTildePathPrefix(aPath)
set cmd to "/bin/chmod " & optionModeString & " " & quoted form of aPath
set errNum to missing value
set errMsg to missing value
set cmdResult to missing value
try
set cmdResult to do shell script cmd
on error errMsg number errNum
end try
if ((cmdResult is missing value) or (length of cmdResult is 0) or (cmdResult is equal to 0)) and errNum is missing value then
set resultString to "Succeeded without administrator privileges"
else
set errNum to missing value
set errMsg to missing value
set cmdResult to missing value
try
set cmdResult to do shell script cmd with administrator privileges
on error errMsg number errNum
end try
if ((cmdResult is missing value) or (length of cmdResult is 0) or (cmdResult is equal to 0)) and errNum is missing value then
set resultString to "Succeeded with administrator privileges"
else
set resultString to "Failed even with administrator privileges. Command returned " & cmdResult & " with Error " & errNum & ": " & errMsg
end if
end if
return resultString
end chmodPath
(* Use this to get an alias if you are not sure that the folder exists. The parentAlias must exist *)
on getFolderAlias_MakeIfNeeded(parentAlias, folderName)
tell application "Finder"
if not (exists (folder folderName of parentAlias)) then
make new folder at parentAlias with properties {name:folderName}
end if
set targetAlias to (folder folderName of parentAlias) as alias
end tell
return targetAlias
end getFolderAlias_MakeIfNeeded
on pathSpelledOut(aliasPath)
set aPathComps to split(aliasPath as string, ":")
if (count of last item of aPathComps) is 0 then
set nParents to (count of aPathComps) - 1
set aPathComps to (items 1 thru nParents) of aPathComps
end if
set aName to last item in aPathComps
set aPathSpelledOut to aName & " is located "
set nParents to (count of aPathComps) - 1
set parents to (items 1 thru nParents) of aPathComps
set i to 0
repeat with dirName in parents
if i is greater than 0 then
repeat with j from 0 to i - 1
set aPathSpelledOut to aPathSpelledOut & " "
end repeat
end if
if i is 0 then
set aPathSpelledOut to aPathSpelledOut & "on volume \"" & dirName & "\""
else if i is 1 then
set aPathSpelledOut to aPathSpelledOut & "in folder \"" & dirName & "\""
else
set aPathSpelledOut to aPathSpelledOut & "in subfolder \"" & dirName & "\""
end if
if i is less than nParents - 1 then
set aPathSpelledOut to aPathSpelledOut & return
end if
set i to i + 1
end repeat
return aPathSpelledOut
end pathSpelledOut
(* returns a string of the form "20100816j230115" where that "j" is a given joiner string *)
on geekDateTime(joiner)
return geekDateDaysAgo(0) & joiner & geekTime()
end geekDateTime
(* returns an 8-character string of the form "20100816", which expresses the date that it was daysAgo ago. Pass daysAgo=0 to get today's date. If daysAgo is positive, the answer will be in the past. If daysAgo is negative, the answer will be in the future *)
to geekDateDaysAgo(daysAgo) -- Old_date is text, not a date.
set old_date to ((current date) - 24 * 3600 * daysAgo) as string
set {year:y, month:m, day:d} to date old_date
tell (y * 10000 + m * 100 + d) as string to text 1 thru 4 & text 5 thru 6 & text 7 thru 8
end geekDateDaysAgo
-- Returns the number of hours relative to GMT. California is -7 or -8.
on timeZone()
return (time to GMT) / hours -- hours is 3600, a built-in constant
end timeZone
-- Returns a 6-digit string representing the current time's hours, minutes and seconds. For example, if the time is 23:01:15, returns 230115
on geekTime()
set secsPastMidnight to time of (current date)
set currentHour to ((secsPastMidnight - 1799) / 3600) as integer
set secsPastHour to secsPastMidnight - 3600 * currentHour
set currentMin to ((secsPastHour - 29) / 60) as integer
set currentSec to secsPastHour - 60 * currentMin
return padZeros(currentHour, 2) & padZeros(currentMin, 2) & padZeros(currentSec, 2)
end geekTime
(*
# Converts the specified object - which may be of any type - into a string representation for logging/debugging.
# Tries hard to find a readable representation - sadly, simple conversion with `as text` mostly doesn't work with non-primitive types.
# An attempt is made to list the properties of non-primitive types (does not always work), and the result is prefixed with the type (class) name
# and, if present, the object's name and ID.
# EXAMPLE
# toString(path to desktop) # -> "[alias] Macintosh HD:Users:mklement:Desktop:"
# To test this subroutine and see the various representations, use the following:
# repeat with elem in {42, 3.14, "two", true, (current date), {"one", "two", "three"}, {one:1, two:"deux", three:false}, missing value, me, path to desktop, front window of application (path to frontmost application as text)}
# log my toString(contents of elem)
# end repeat
Source: http://stackoverflow.com/questions/13653358/how-to-log-objects-to-a-console-with-applescript?rq=1
*)
on toString(anyObj)
local i, txt, errMsg, orgTids, oName, oId, prefix
set txt to ""
repeat with i from 1 to 2
try
if i is 1 then
if class of anyObj is list then
set {orgTids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, {", "}}
set txt to ("{" & anyObj as string) & "}"
set AppleScript's text item delimiters to orgTids # '
else
set txt to anyObj as string
end if
else
set txt to properties of anyObj as string
end if
on error errMsg
# Trick for records and record-*like* objects:
# We exploit the fact that the error message contains the desired string representation of the record, so we extract it from there. This (still) works as of AS 2.3 (OS X 10.9).
try
set txt to do shell script "egrep -o '\\{.*\\}' <<< " & quoted form of errMsg
end try
end try
if txt is not "" then exit repeat
end repeat
set prefix to ""
if class of anyObj is not in {text, integer, real, boolean, date, list, record} and anyObj is not missing value then
set prefix to "[" & class of anyObj
set oName to ""
set oId to ""
try
set oName to name of anyObj
if oName is not missing value then set prefix to prefix & " name=\"" & oName & "\""
end try
try
set oId to id of anyObj
if oId is not missing value then set prefix to prefix & " id=" & oId
end try
set prefix to prefix & "] "
end if
return prefix & txt
end toString
-- Returns a string of digits representing n, padded on the left by as many leading zeros as are needed to make the length of the string equal to targLen
on padZeros(n, targLen)
set nS to n as string
set nNeeded to targLen - (count of nS)
set zeros to ""
repeat with i from 1 to nNeeded
set zeros to "0" & zeros
end repeat
return zeros & nS
end padZeros
(* The handlers below use the File Read/Write suite http://developer.apple.com/documentation/AppleScript/Conceptual/AppleScriptLangGuide/reference/ASLR_cmds.html *)
on ClearOutDesktopLogFile(filename)
(* Warning: filename must not end in ".log" or else a "file already open" error will result. Maybe some system logging daemon takes over all .log files?? Some stupid bug in AppleScript? *)
set filePath to (path to desktop as string) & filename
set fileRef to open for access filePath with write permission
set eof fileRef to 0
set newText to "Beginning New Log at " & (current date) as string
write newText to fileRef
close access fileRef
end ClearOutDesktopLogFile
-- This reads non-ASCII characters properly provided that the file is encoded as UTF8, with or without BOM.
-- If file is not found, returns 'missing value'
-- If file exists but is empty, returns an empty string
on readTextFile(posixPath)
try
-- 'info for' could return a value, but we ignore it
info for posixPath
on error
return missing value
end try
open for access (posixPath as POSIX file)
try
set fileContents to (read posixPath for (get eof posixPath) as «class utf8»)
on error
return ""
end try
close access posixPath
return fileContents
end readTextFile
-- Writes given text to a given file path
-- filename must not end in ".log" or else a "file already open" error will result.
-- Maybe some system logging daemon takes over all .log files??
-- Uses File Read/Write suite of the Standard Additions scripting addition
-- If doAppend is true, appends. If doAppend is false, overwrites.
on writeTextToPosixPath(aPath, newText, doAppend)
set oldastid to AppleScript's text item delimiters
set AppleScript's text item delimiters to {""}
if aPath begins with "~" then
set home_posix_path to POSIX path of (path to home folder)
set aPath to home_posix_path & characters 2 thru end of aPath
end if
log "aPath: " & aPath
set filePath to (POSIX file aPath as text)
set fileRef to open for access filePath with write permission
if doAppend is true then
write newText to fileRef starting at eof
else
-- Wipe out all existing text first
set eof of fileRef to 0
write newText to fileRef
end if
close access fileRef
set AppleScript's text item delimiters to oldastid
end writeTextToPosixPath
-- Writes given text to a given file path, appending a line feed at the end
-- filename must not end in ".log" or else a "file already open" error will result.
-- Maybe some system logging daemon takes over all .log files??
-- Uses File Read/Write suite of the Standard Additions scripting addition
-- aPath is the path to which text will be written. It may begin with "~" to indicate home.
-- If doAppend is true, appends. If doAppend is false, overwrites.
on writeLineToPosixPath(aPath, newText, doAppend)
set oldastid to AppleScript's text item delimiters
set AppleScript's text item delimiters to {""}
if aPath begins with "~" then
set home_posix_path to POSIX path of (path to home folder)
set aPath to home_posix_path & characters 2 thru end of aPath
end if
log "aPath: " & aPath
set filePath to (POSIX file aPath as text)
set fileRef to open for access filePath with write permission
-- See http://lists.apple.com/archives/applescript-users/2002/Feb/msg00994.html
-- Note that it may be better to do as Chris suggests, so that *all* 'return' in all text will be unix line feeds. In particular, if the first line written contains a regular AppleScript Old Mac 'return', BBEdit will think that the whole file has Old Mac line feeds.
set unixLineFeed to ASCII character 10
set newText to newText & unixLineFeed
if doAppend is true then
write newText to fileRef starting at eof
else
-- Wipe out all existing text first
set eof of fileRef to 0
write newText to fileRef
end if
close access fileRef
set AppleScript's text item delimiters to oldastid
end writeLineToPosixPath
on WriteToDesktopTextFile(filename, newText, doAppend)
-- filename must not end in ".log" or else a "file already open" error will result.
-- Maybe some system logging daemon takes over all .log files??
-- Uses File Read/Write suite of the Standard Additions scripting addition
set filePath to (path to desktop as string) & filename
set fileRef to open for access filePath with write permission
set newText to (return & return & (current date) & ": " & newText) as string
if doAppend is true then
write newText to fileRef starting at eof
else
write newText to fileRef
end if
close access fileRef
end WriteToDesktopTextFile
-- Handler for directly writing to a file. Handy for logging, etc.
on AppendToDesktopLogFile(filename, newText)
-- filename must not end in ".log" or else a "file already open" error will result.
-- Maybe some system logging daemon takes over all .log files??
-- Uses File Read/Write suite of the Standard Additions scripting addition
set filePath to (path to desktop as string) & filename
set fileRef to open for access filePath with write permission
set newText to (return & return & (current date) & ": " & newText) as string
write newText to fileRef starting at eof
close access fileRef
end AppendToDesktopLogFile
-- Returns a list.
-- If you're looking to split at line feeds, try to pass for delimiter either 'return' (without the quotes) or "\n" (with the quotes). I've seen both work and both fail. Probably it depends on the type of line feed. For splitting data read from a file with unix line endings, "\n" works.
on split(aString, delimiter)
if aString is missing value then
return {}
else
set oldastid to AppleScript's text item delimiters
set AppleScript's text item delimiters to delimiter
set pieces to aString's text items
set AppleScript's text item delimiters to oldastid
return pieces
end if
end split
on join(joiner, aList)
set nJoiners to ((count of aList) - 1)
set answer to ""
set i to 0
repeat with aItem in aList
set answer to answer & aItem
if i is less than nJoiners then
set answer to answer & joiner
end if
set i to i + 1
end repeat
return answer
end join
to unquote(someText)
set AppleScript's text item delimiters to "\""
set someText to someText's text items
set AppleScript's text item delimiters to {""} --> restore delimiters to default value
-- Item 1 will be the opening quote, item 3 is closing quote, item 2 is what we want
return item 2 of someText
end unquote
on searchAndReplace(this_text, search_string, replacement_string)
set oldastid to AppleScript's text item delimiters
set AppleScript's text item delimiters to search_string
-- We're going to split this_text at each searchString. However, this will miss search_string if it is at the beginning or ending of this_text, since no split will be made there. We fix that by temporarily appending a prefix and suffix "X".
set this_text to "X" & this_text & "X"
set the item_list to every text item of this_text
set AppleScript's text item delimiters to replacement_string
set this_text to item_list as string
set AppleScript's text item delimiters to oldastid
-- Remove the temporary prefix and suffix
set aLength to ((count of characters of this_text) - 1)
set this_text to characters 2 thru aLength of this_text as string
return this_text
end searchAndReplace
on percentEscapeEncode(aText)
return percentEscapeEncodeSelectively(aText, true, true)
end percentEscapeEncode
on encode_char(this_char)
set the ASCII_num to (the ASCII number this_char)
set the hex_list to {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"}
set x to item ((ASCII_num div 16) + 1) of the hex_list
set y to item ((ASCII_num mod 16) + 1) of the hex_list
return ("%" & x & y) as string
end encode_char
(*
Parameters encode_URL_A and says encode_URL_B say whether or not to encode certain printable ASCII characters, as you can see. For most purposes, both should be 'true' *)
on percentEscapeEncodeSelectively(this_text, encode_URL_A, encode_URL_B)
set the standard_characters to "abcdefghijklmnopqrstuvwxyz0123456789"
set the URL_A_chars to "$+!'/?;&@=#%><{}[]\"~`^\\|*"
set the URL_B_chars to ".-_:"
set the acceptable_characters to the standard_characters
if encode_URL_A is false then set the acceptable_characters to the acceptable_characters & the URL_A_chars
if encode_URL_B is false then set the acceptable_characters to the acceptable_characters & the URL_B_chars
set the encoded_text to ""
repeat with this_char in this_text
if this_char is in the acceptable_characters then
set the encoded_text to (the encoded_text & this_char)
else
set the encoded_text to (the encoded_text & encode_char(this_char)) as string
end if
end repeat
return the encoded_text
end percentEscapeEncodeSelectively
(* Collapses all runs of consecutive tab characters, consecutive space characters, or consecutive combinations of tab characters and space characters each into a single space character, and returns the result *)
on coalesceTabsAndSpaces(aString)
if aString is missing value then
return aString
end if
set oldLength to count of aString
set newLength to 0
repeat while oldLength is not equal to newLength
set oldLength to count of aString
set aString to searchAndReplace(aString, " ", " ")
set aString to searchAndReplace(aString, " ", " ")
set newLength to count of aString
end repeat
return aString
end coalesceTabsAndSpaces
on backslashEscapeSpaces(this_text)
return searchAndReplace(this_text, " ", "\\ ")
end backslashEscapeSpaces
on clipboardSearchAndReplace(search_string, replacement_string)
set the_string to the clipboard
set the_string to searchAndReplace(the_string, search_string, replacement_string)
set the clipboard to the_string
end clipboardSearchAndReplace
on verifyTextContains(aText, aTarget)
set oldastid to AppleScript's text item delimiters
set AppleScript's text item delimiters to aTarget
set answer to false
try
set textItems to text items of aText
set nParts to count of textItems
if nParts is greater than 1 then
set answer to true
end if
end try
set AppleScript's text item delimiters to oldastid
return answer
end verifyTextContains
on removeFilenameExtension(this_name)
if this_name contains "." then
set this_name to ¬
(the reverse of every character of this_name) as string
set x to the offset of "." in this_name
set this_name to (text (x + 1) thru -1 of this_name)
set this_name to (the reverse of every character of this_name) as string
end if
return this_name
end removeFilenameExtension
(* Splits the input aText into three substrings and returns a record containing these three substrings as properties: preAsterisks, body, and postAsterisks *)
on trimAndReturnAsterisks(aText)
-- Separate prefix Asterisks
set originalText to aText
set aText to my trim(aText, "*", 0)
set preAsterisks to ""
if aText is not equal to originalText then
repeat with i from 1 to (length of originalText) - (length of aText)
set preAsterisks to preAsterisks & "*"
end repeat
end if
-- Separate suffix Asterisks
set originalText to aText
set aText to my trim(aText, "*", 2)
set postAsterisks to ""
if aText is not equal to originalText then
repeat with i from 1 to (length of originalText) - (length of aText)
set postAsterisks to postAsterisks & "*"
end repeat
end if
set myRecord to {body:aText, preAsterisks:preAsterisks, postAsterisks:postAsterisks}
return myRecord
end trimAndReturnAsterisks
on trimChars(aString, character_list, trim_indicator)
-- trim_indicator: trim from 0 = beginning, 1 = end, 2 = both
set newLength to -1
set oldLength to length of aString
repeat while newLength is not equal to oldLength
set oldLength to length of aString
repeat with aChar in character_list
set aString to trim(aString, aChar, trim_indicator)
end repeat
set newLength to length of aString
end repeat
return aString
end trimChars
on trimwhitespace(aString, trim_indicator)
-- trim_indicator: trim from 0 = beginning, 1 = end, 2 = both
trimChars(aString, {" ", ASCII character 9, ASCII character 10, ASCII character 13}, trim_indicator)
end trimwhitespace
on trim(this_text, trim_substring, trim_indicator)
-- trim_substring: A string to trim.
-- trim_indicator: trim from 0 = beginning, 1 = end, 2 = both
set x to the length of the trim_substring
-- TRIM BEGINNING
if the trim_indicator is in {0, 2} then
repeat while this_text begins with the trim_substring
try
set this_text to characters (x + 1) thru -1 of this_text as string
on error
-- the text contains nothing but the trim characters
return ""
end try
end repeat
end if
-- TRIM ENDING
if the trim_indicator is in {1, 2} then
repeat while this_text ends with the trim_substring
try
set this_text to characters 1 thru -(x + 1) of this_text as string
on error
-- the text contains nothing but the trim characters
return ""
end try
end repeat
end if
return this_text
end trim
-- Returns 'true' or 'false'. Case-insensitive. If aSuffix is an empty string, returns 'true'.
on hasSuffix(aString, aSuffix)
set stringLength to length of aString
set suffixLength to length of aSuffix
--log (stringLength & " -- " & suffixLength)
if stringLength is less than suffixLength then
return false
end if
if stringLength is 0 then
if suffixLength is 0 then
return true
else
return false
end if
end if
if suffixLength is 0 then
return true
end if
set theEnd to characters (stringLength - suffixLength + 1) thru stringLength of aString as string
-- It appears that AppleScript does a case-insensitive comparison in the following:
if theEnd is aSuffix then
return true
end if
return false
end hasSuffix
on systemVersion()
set n to system attribute "sysv"
set major to (n div 4096 * 10) + (n div 256 mod 16)
set minor to n div 16 mod 16
set bugfix to n mod 16
return {major, minor, bugfix}
end systemVersion
-- Takes > 1 minute
on miniSystemProfile()
return do shell script "/usr/sbin/system_profiler -detailLevel mini"
end miniSystemProfile
-- Takes, oh, 30 seconds
on microSystemProfile()
return do shell script "/usr/sbin/system_profiler SPHardwareDataType SPMemoryDataType SPSoftwareDataType SPUniversalAccessDataType SPFrameworksDataType SPApplicationsDataType"
end microSystemProfile
-- Takes, oh, 10 seconds
on nanoSystemProfile()
return do shell script "/usr/sbin/system_profiler SPHardwareDataType SPSoftwareDataType SPUniversalAccessDataType"
end nanoSystemProfile
on reportVersionOfApplicationId(appId)
set v to "not found"
try
set v to get version of application id appId
end try
set comps to split(appId, ".")
try
set appName to item 3 of comps
on error
set appName to appId
end try
return appName & " version is " & v
end reportVersionOfApplicationId
on versionOfApplicationPath(path)
set v to missing value
try
set v to get version of application path
end try
return v
end versionOfApplicationPath
-- The following reduces the 100 or so lines generated by miniSystemProfile to the half dozen most interesting lines, but it is a kludge and is not recommended unless you're really short on space.
on miniMiniSystemProfile()
set sysText to miniSystemProfile()
set sysLines to split(sysText, return)
set profile to ""
repeat with aLine in sysLines
set wantedLine to ""
if verifyTextContains(aLine, "Mac OS X") then
if verifyTextContains(aLine, "System Version:") then
set aLine to item 2 of split(aLine, ":") & return
set wantedLine to aLine
end if
else if verifyTextContains(aLine, " Memory:") then
set wantedLine to aLine
-- The following work only in Leopard
else if verifyTextContains(aLine, "Model Name") then
set wantedLine to aLine
else if verifyTextContains(aLine, "Model Identifier") then
set wantedLine to aLine
else if verifyTextContains(aLine, "Processor Name") then
set wantedLine to aLine
else if verifyTextContains(aLine, "Processor Speed") then
set wantedLine to aLine
else if verifyTextContains(aLine, "Number of Processors") then
set wantedLine to aLine
else if verifyTextContains(aLine, "Total Number of Cores") then
set wantedLine to aLine
-- The following work only in Tiger
else if verifyTextContains(aLine, "Machine Name") then
set wantedLine to aLine
else if verifyTextContains(aLine, "Machine Model") then
set wantedLine to aLine
else if verifyTextContains(aLine, "CPU Type") then
set wantedLine to aLine
else if verifyTextContains(aLine, "CPU Speed") then
set wantedLine to aLine
else if verifyTextContains(aLine, "Number of CPUs") then
set wantedLine to aLine
end if
if length of wantedLine > 0 then
set wantedLine to trim_line(wantedLine, " ", 2)
set profile to profile & wantedLine & return
end if
end repeat
return profile
end miniMiniSystemProfile
(* Opens a document on aPath with a specified application aApp *)
on launchPathWithApp(aPath, aApp)
set hfsDoc to POSIX file aPath
tell application aApp
set newDoc to open hfsDoc
set newWindow to window 1
end tell
return newWindow
end launchPathWithApp
(* Starting in, I think it was Mac OS X 10.5, AppleScript opens applications as hidden. This handler takes advantage of that fact. *)
on openAppAsHidden(appNameOrPosixPath)
tell application appNameOrPosixPath
(* According to the AppleScript Language Guide > Class Reference > application, the 'application' class has about 5 properties, but only one of them, id (the bundle identifier), seems guaranteed to launch the app.. So we use id.¬
Apparently, AppleScript is sometimes smart enough to discard a statement if it has no effect. In this case, I've found we need to *do* something with x, or the app won't launch. Trying to be neat, I tried this:¬
set x to id
set cmd to "/bin/echo " & x & " > /dev/null"
tell me to do shell script cmd
But it was insufficient; the app does not launch. Oddly, and smelly, the following line works. *)
log id
(* Maybe *you* can find a better way! *)
end tell
end openAppAsHidden
(* Will launch an app, quitting first if already running. Unlike MiniGlot, this has the advantage of working for apps which have their localizations buried in frameworks, such as Bookdog and BookMacster.
languageCode is one of:
two-letter ISO language code. Examples: "en", "ja", "de"
"default" for the current system default language
"ask" to get a dialog
*)
on relaunchApp(appParentDir, appName, languageCode)
quitAppIfRunning(appName, ask, true, 8.0)
set appPath to appParentDir & "/" & appName
set contentsPath to appPath & ".app/Contents"
set cmd to "~/Documents/Programming/Builds/Release/plistread " & "CFBundleExecutable" & " " & contentsPath & "/" & "Info.plist"
set executableName to do shell script cmd
set executablePath to contentsPath & "/MacOS/" & executableName
set languageArg to missing value
if languageCode is "ask" then
set aPrompt to "Choose localization to re-launch:" & return & appPath
choose from list {"de", "en", "es", "fr", "it", "ja"} with prompt aPrompt
try
set languageCode to item 1 of result
set languageArg to "-AppleLanguages '(" & languageCode & ")'"
end try
else
set languageArg to ""
end if
if languageArg is not missing value then
set cmd to executablePath & " " & languageArg & " &> /dev/null &"
-- The &> /dev/null & at the end tells the command to send both stdout and stderr to /dev/null. This is so that the "do shell script" will not block until appName is quit.
do shell script cmd
end if
end relaunchApp
(* This handler may not work for apps with multiple names, for example, "Chrome" vs. "Google Chrome" *)
on isAppNameRunning(targetAppName)
tell application "System Events"
set runningProcesses to processes whose name is targetAppName
end tell
set answer to ((count of runningProcesses) is greater than 0)
return answer
end isAppNameRunning
on isAppBundleIdentifierRunning(targetBundleIdentifier)
tell application "System Events"
set runningProcesses to processes whose bundle identifier is targetBundleIdentifier
end tell
set answer to ((count of runningProcesses) is greater than 0)
return answer
end isAppBundleIdentifierRunning
(*
If possible, use one of the equivalent handlers quitAppBundleIdentifierIfRunning() or quitAppIfRunningBundleIdentifier() instead, because this handler hangs for 20 seconds if the given app is not running.
The following one-liners, though commonly used,
quit application "MyApp"
tell application "MyApp" to quit
have a couple of annoying behaviors:
1. If MyApp is not installed, the stupid thing will churn for about 20 seconds, then put up a dialog "Where is MyApp". That happens even if enclosed in try/end try.
2. They return before the app is quit. (See waitUntilDone, below).
The handler quitAppIfRunning was written to fix these issues.
howSave should be: 'yes', 'no' or 'ask', withOUT the quotes.
waitUntilDone should be 'true' or 'false', withOUT the quotes. This sets whether or not this handler should wait until the app quits before returning.
(Use 'true' if you want to immediately relaunch the application. Otherwise, you'll get a "Connection is invalid" because it will connect to a dying app.)
aTimeout is the maximum time in seconds that it will waitUntilDone. You need this in case the app will not quit, which ^will^ happen if a dirty document is open, howSave is 'ask', and the user clicks "Cancel". The aTimeout does ^not^ affect how long the user gets to respond to the Save/Don't dialog, which is infinite.
Returns true if the app is not running.
Example: quitAppIfRunning("Bookdog", ask, true, 4.5)
*)
on quitAppNameIfRunning(targetAppName, howSave, waitUntilDone, aTimeout)
set succeeded to true
try
-- id of app "Chrome" will show the EXTREMELY ANNOYING "Where is 'Chrome'" dialog if Chrome is not running. To avoid that, use System Events. Unfortunately, the this takes 20 seconds if targetAppName is not running.
tell application "System Events" to set targetBundleIdentifier to (bundle identifier of process targetAppName)
-- THERE MAY BE A FASTER METHOD, USING BASH SHELL. The following was taken from http://superuser.com/questions/346369/getting-the-bundle-identifier-of-an-os-x-application-in-a-shell-script
(*
$ bundle=$(mdfind -onlyin / kMDItemKind==Application | grep -i "/Whatever.app$" | head -1)
$ defaults read "$bundle/Contents/Info" CFBundleIdentifier
com.apple.finder
*)
-- If targetAppName is not running, will error out of the try here
-- If we made it to here, targetAppName is probably running
set isRunning to isAppBundleIdentifierRunning(targetBundleIdentifier)
on error
set isRunning to false
end try
if isRunning is true then
set succeeded to quitAppBundleIdentifierIfRunning(targetBundleIdentifier)
end if
return succeeded
end quitAppNameIfRunning
on quitAppBundleIdentifierIfRunning(targetBundleIdentifier, howSave, waitUntilDone, aTimeout)
set succeeded to true
try
set isRunning to isAppBundleIdentifierRunning(targetBundleIdentifier)
on error
set isRunning to false
end try
if isRunning is true then
set succeeded to false
try
set answer to quit application id bundleIdentifier saving howSave
end try
tell me to set timeoutTime to ((time of (current date)) + aTimeout) mod (24 * 60 * 60)
if (waitUntilDone) then
repeat
if (isAppBundleIdentifierRunning(targetBundleIdentifier) is false) then
set succeeded to true
exit repeat
end if
if (time of (current date) is less than timeoutTime) then
exit repeat
end if
delay 1
log "waiting for " & targetBundleIdentifier & " to quit"
end repeat
end if
end if
return succeeded
end quitAppBundleIdentifierIfRunning
-- This handler does not launch the target app if it is not running
on quitAppIfRunningBundleIdentifier(bi)
tell application "System Events"
set runCount to count (every process whose bundle identifier is bi)
end tell
if runCount is greater than 0 then
tell application id bi
close windows
quit
end tell
end if
end quitAppIfRunningBundleIdentifier
on killAppNamed(appName)
set cmdResult to -100
tell application "System Events"
set pid to 0
with timeout of 10 seconds
try
set pid to unix id of process appName
on error errMsg number errNumber
set cmdResult to errNumber
end try
end timeout
if pid is not 0 then
set cmdResult to do shell script "/bin/kill " & pid
end if
end tell
return cmdResult
end killAppNamed
-- Doesn't work because "No user interaction allowed". Oh, well.
on displayDialogAsync(msg)
set asCmd to "display dialog " & "\"" & msg & "\" buttons {} giving up after 5"
set shellCmd to "osascript -e " & quoted form of asCmd
log shellCmd
do shell script shellCmd
end displayDialogAsync
on meName()
set pathToMe to ((POSIX path of (path to me)) as string)
set filename to getLastPathComponent(pathToMe)
set aName to removeFilenameExtension(filename)
return aName
end meName
(* Logs a message to the system log (which you can monitor in Console.app). The msg is tagged with the name of this script. *)
on syslog1(msg)
if (length of msg is greater than 1500) then
set msg to (text 1 thru 1500 of msg) & " <snip> *** Sorry, Message > 1500 chars will not be reliably logged by BSD's 'logger'."
end if
set scriptName to meName()
set cmd to "logger -t " & quoted form of scriptName & " " & quoted form of msg
do shell script cmd
end syslog1
-- Simply logs a message to the system console
on syslog(msg)
set cmd to "logger " & quoted form of msg
do shell script cmd
end syslog
(* Returns true if aString has prefix, no otherwise. Case sensitive. Note: For case-insensitive compare, use the AppleScript term 'begins with' *)
on hasPrefix(prefix, aString)
if length of prefix is 0 then
return false
end if
if length of aString is less than length of prefix then
return false
end if
set prefixChars to characters of prefix
set stringChars to characters of aString
set i to 1
repeat with prefixChar in prefixChars
set stringChar to (item i of stringChars)
-- In AppleScript, "id" is the "identifier
-- For characters, it is the Unicode code point
-- See http://www.apple.com/applescript/features/unicode.html
if id of stringChar is not id of prefixChar then
return false
end if
set i to i + 1
end repeat
return true
end hasPrefix
(* Copies a file using /bin/cp, returns true if successful, otherwise false *)
on copyPath(src, dst)
set ok to true
try
set cmd to "/bin/cp \"" & src & "\" \"" & dst & "\""
do shell script cmd
on error
set ok to false
end try
return ok
end copyPath
(* Removes (unlinks) a given posix path, fails silently. Overwrites any existing path in trash with same name. Quotes the path, so you path cannot include a glob. Fails silently. *)
on removePath(aPath)
set target to quoted form of aPath
set cmd to "/bin/rm -Rf " & target
try
do shell script cmd
end try
end removePath
(* Removes (unlinks) a given posix path, fails silently. Overwrites any existing path in trash with same name. Does not quote the path, so path may be a glob. Fails silently. *)
on removePathGlob(aPath)
set cmd to "/bin/rm -Rf " & aPath
try
do shell script cmd
end try
end removePathGlob
(* Trashes a file given a posix path, fails silently. Finder makes a noise when trashing a file. *)
on trashPathUsingFinder(aPath)
try
tell application "Finder" to move (POSIX file aPath) as alias to trash
end try
end trashPathUsingFinder
(* If a directory does not exist at a given path, creates it, also creating any intermediate ancestor directories which do not exist. If given path already exists, does nothing. Works with or without a trailing slash on the given path. *)
on ensurePathExists(path)
set fragment to removeTrailingSlash(path)
set missingComponents to {}
set done to false
repeat while done is false
set cmd to "stat " & quoted form of fragment
try
do shell script cmd
exit repeat
on error
set lastPathComponent to getLastPathComponent(fragment)
set beginning of missingComponents to lastPathComponent
set fragment to removeLastPathComponent(fragment, true)
end try
log "fragment: " & fragment
-- In case someone passes a completely bogus path
if (length of fragment is less than 2) then
set done to true
end if
end repeat
log ("frg = " & fragment)
log ("mcs = " & missingComponents)
repeat with component in missingComponents
set fragment to fragment & "/" & component
set cmd to "mkdir " & quoted form of fragment
do shell script cmd
end repeat
end ensurePathExists
(* Closes a window identified by the name in its title bar, if such a window exists *)
on closeFinderWindowWithTitle(targetName)
tell application "Finder"
set openWindows to windows
repeat with aWindow in openWindows
set thisName to name of aWindow
log "window name: " & thisName
if thisName is targetName then
close aWindow
end if
end repeat
end tell
end closeFinderWindowWithTitle
(* If aPath begins with "/", the first item in the returned list will be an empty string *)
on pathComponents(aPath)
set aPath to trim(aPath, " ", 2)
set oldastid to AppleScript's text item delimiters
set AppleScript's text item delimiters to the "/"
set components to every text item of aPath
set AppleScript's text item delimiters to oldastid
return components
end pathComponents
(* Gets the part of a filename after the last slash *)
on getLastPathComponent(aPath)
set components to pathComponents(aPath)
return last item of components as string
end getLastPathComponent
(* removeTrailingSlash indicates whether or not trailing slash should be removed too *)
on removeLastPathComponent(aPath, removeTrailingSlash)
if aPath is missing value then
return missing value
end if
set oldastid to AppleScript's text item delimiters
set AppleScript's text item delimiters to the "/"
set the item_list to every text item of aPath
set lastItem to last item of item_list
set offsetForTrailingSlash to 0
if (count of lastItem) is 0 then
-- aPath has a trailing slash
set item_list to items 1 thru -2 of item_list
set offsetForTrailingSlash to 1
end if
set lastItem to last item of item_list
set cutLength to ((count of lastItem) as string) + offsetForTrailingSlash
set wholeLength to length of aPath
set newLength to wholeLength - cutLength
if removeTrailingSlash is true then
set newLength to newLength - 1
end if
set AppleScript's text item delimiters to oldastid
set answer to (characters 1 thru newLength of aPath) as string
return answer
end removeLastPathComponent
(* It seems to be not possible to remove a trailing colon from an alias. If an alias is to a directory, it will have a colon at the end. To remove it, I tried to convert it to a string, remove the colon, then convert it back to an alias. But upon coverting the string with no colon back to an alias, the colon reapppears. *)
on removeLastAliasComponent(aAlias)
if aAlias is missing value then
return missing value
end if
set aString to aAlias as string
set oldastid to AppleScript's text item delimiters
set AppleScript's text item delimiters to the ":"
set the pathComps to every text item of aString
set lastItem to last item of pathComps
set lengthOfLastItem to (count of lastItem)
if lengthOfLastItem is 0 then
-- Alias ends in a colon. We need to cut off the second-last item.
set secondLastItem to item ((count of pathComps) - 1) of pathComps
set cutLength to (count of secondLastItem) + 1
-- We added +1 for the colon at the end
else
set cutLength to lengthOfLastItem
end if
-- Also cut the colon between the last two nonzero pathComps
set cutLength to cutLength + 1
set wholeLength to length of aString
set newLength to wholeLength - cutLength
set AppleScript's text item delimiters to oldastid
set aString to (characters 1 thru newLength of aString) as string
set answer to aString as alias
return answer
end removeLastAliasComponent
on getFilenameExtension(aPath)
if aPath contains "." then
set aPath to ¬
(the reverse of every character of aPath) as string
set x to the offset of "." in aPath
set aPath to (text 1 thru (x - 1) of aPath)
set aPath to (the reverse of every character of aPath) as string
end if
return aPath
end getFilenameExtension
(* Removes from a list the item at a given index and returns the new list *)
on removeItemFromListByIndex(aList, index)
if index is greater than (count of aList) then
return aList
end if
if index is less than 1 then
return aList
end if
if index is greater than 1 then
set beforeItems to items 1 thru (index - 1) of aList
else
set beforeItems to {}
end if
if index is less than (count of aList) then
set afterItems to items (index + 1) thru end of aList
else
set afterItems to {}
end if
return beforeItems & afterItems
end removeItemFromListByIndex
-- This handler uses Finder, which has two effects:
-- * Should ask if authentication is required
-- * Gives the "trashed" sound effect
-- Returns true if requested path was found and deleted
-- Returns false if file could not be found or could not be deleted
to deletePosixFilePath(aPath)
set ok to true
tell application "Finder"
try
delete (POSIX file aPath) as alias
on error
set ok to false
end try
end tell
return ok
end deletePosixFilePath
on deleteDuplicates(aList)
set list2 to {}
repeat with x from 1 to count of items of aList
set n to item x of aList
if n is not in list2 then set end of list2 to n
end repeat
return list2
end deleteDuplicates
-- Returns 'missing value' if targetString is not in aList
-- Case-sensitive
on indexOfStringInList(targetItem, aList)
set i to 1
repeat with aItem in aList
considering case
set compareResult to (aItem as string = targetItem as string)
end considering
if compareResult is true then
return i
end if
set i to i + 1
end repeat
return missing value
end indexOfStringInList
-- AppleScript does not provide time with milliseconds, but unix does
on timeWithMilliseconds()
try
-- Will log an error since there is no such domain
do shell script "defaults read noSuchDomain"
on error errorText
-- The first 23 chars of the error message will be the time
text 1 thru 23 of errorText
end try
end timeWithMilliseconds
on sort(my_list)
set the index_list to {}
set the sorted_list to {}
repeat (the number of items in my_list) times
set the low_item to ""
repeat with i from 1 to (number of items in my_list)
if i is not in the index_list then
set this_item to item i of my_list as text
if the low_item is "" then
set the low_item to this_item
set the low_item_index to i
else if this_item comes before the low_item then
set the low_item to this_item
set the low_item_index to i
end if
end if
end repeat
set the end of sorted_list to the low_item
set the end of the index_list to the low_item_index
end repeat
return the sorted_list
end sort
on latestFilenames(glob, limit)
set byteCount to 0
set cmd to "/bin/ls -ltww " & glob
set lsResult to missing value
try
set lsResults to do shell script cmd
set fileStrings to split(lsResults, return)
set results to {}
repeat with fileString in fileStrings
set fileString to coalesceTabsAndSpaces(fileString)
set fields to split(fileString, " ")
set fileSize to item 5 of fields
set byteCount to (byteCount + fileSize)
if byteCount is less than limit then
set filePath to last item of fields
set pathComps to split(filePath, "/")
set filename to last item of pathComps
set end of results to filename
end if
end repeat
on error
set results to missing value
end try
return results
end latestFilenames
(* This method was written by Luther Fuller and posted in applescript-users@lists.apple.com on 20120325 *)
on getInstallHistory(leaders)
set filePath to ((path to library folder from local domain) as text) & "Receipts:InstallHistory.plist"
try
filePath as alias
on error
return "The file " & filePath & " does not exist." & return & "It is available only in Snow Leopard." & return & return
end try
tell application "System Events" to set installList to value of property list file filePath -- a list
set historyText to "Install History (./Library/Receipts/InstallHistory.plist)" & return
repeat with i from 1 to (count items of installList)
set installItem to (item i of installList)
set itemName to (displayName of installItem) as text
--
set itemDate to (|date| of installItem)
set dateText to (text 1 thru 3 of ((month of itemDate) as text))
set dateText to (((day of itemDate) as text) & space & dateText & space & (year of itemDate))
--
set spaceLen to (lineLength - (length of itemName) - (length of dateText) - 2)
set spacers to (space & (text 1 thru spaceLen of leaders) & space)
set historyText to (historyText & itemName & spacers & dateText & return)
end repeat
"" & return
repeat lineLength times
the result & "_"
end repeat
set historyText to (historyText & the result)
return historyText & return & return
end getInstallHistory
on narrateDurationOfProcess(processNameFragment, displayName)
try
set theLine to do shell script "ps -eo etime,%cpu,args | grep " & processNameFragment & " | grep -v grep"
-- The "grep -v grep" is to exclude the previous grep process from the result
log (theLine)
set theChar to item 3 of characters in theLine
set nDays to text 1 thru 2 of theLine
set nHours to text 4 thru 5 of theLine
set nMinutes to text 7 thru 8 of theLine
set nSeconds to text 10 thru 11 of theLine
set narrative to displayName & " has been running for " & nDays & " days " & nHours & " hours " & nMinutes & " minutes " & nSeconds & " seconds."
on error
set narrative to displayName & " is not running."
end try
return narrative & return & return
end narrateDurationOfProcess
(* Makes a lineage of folders; OK if some of the lineage already exists
* parameter 'root' is an alias to the parent of the lineage
* paramenter 'lineage' is a list of folder names which are desired to be created as necessary underneath root.
Returns an alias to the last folder in the lineage
Example: Create lineage AA ▸ BB ▸ CC on the Desktop
tell application "Finder" to set myRoot to the desktop
set myLineage to {"AA", "BB", "CC"}
set lastFolder to makeFolders(myRoot, myLineage)
log "path: " & (POSIX path of (lastFolder as alias))
*)
on makeFolders(root, lineage)
tell application "Finder"
set currFolder to root
repeat with aFolder in lineage
try
set nextFolder to make new folder at currFolder with properties {name:"" & aFolder}
on error
-- Assume that error occurred because folder already exists
set nextFolder to folder aFolder of currFolder
end try
set currFolder to nextFolder
end repeat
end tell
return currFolder
end makeFolders
on quickLookPath(path)
set aAlias to (POSIX file path) -- as alias -- caused error
tell application "Finder"
reveal aAlias
activate
tell application "System Events"
delay 1.0 -- threshold for working is 0.45 seconds
tell process "Finder"
keystroke space
end tell
end tell
end tell
end quickLookPath
-- Activates Finder and types a space character, which will toggle the show/hide state of Finder's QuickLook window
on toggleFinderQuickLookWindow()
tell application "Finder"
activate
tell application "System Events"
delay 1.0 -- threshold for working is ??
tell process "Finder"
keystroke space
end tell
end tell
end tell
end toggleFinderQuickLookWindow
(* Here's a universal handler to include in all of your GUI Scripting scripts so they will work in the new Mavericks world and the old world. This is included with the current version of my UI Browser product to help you write GUI Scripting scripts <http://pfiddlesoft.com/uibrowser>. Bill Cheeseman.
*)
on enabledGUIScripting(flag)
get system attribute "sysv"
if result is less than 4240 then -- 4240 is OS X 10.9.0 Mavericks
-- In OS X 10.8 Mountain Lion and older, enable GUI Scripting globally by calling this handler and passing 'true' in the flag parameter before your script executes any GUI Scripting commands, or pass 'false' to disable GUI Scripting. Authentication is required only if the value of the 'UI elements enabled' property will be changed. Returns the final setting of 'UI elements enabled' even if unchanged.
tell application "System Events"
activate -- brings System Events authentication dialog to front
set UI elements enabled to flag
return UI elements enabled
end tell
else
-- In OS X 10.9 Mavericks, global access is no longer available and GUI Scripting can only be enabled manually on a per-application basis. Pass true to present an alert with a button to open System Preferences and telling the user to select the current application (the application running the script) in the Accessibility list in the Security & Privacy preference's Privacy pane. Authentication is required to unlock the preference. Returns the current setting of 'UI elements enabled' asynchronously, without waiting for System Preferences to open, and tells the user to run the script again.
tell application "System Events" to set GUIScriptingEnabled to UI elements enabled -- read-only in OS X 10.9 Mavericks
if flag is true then
if not GUIScriptingEnabled then
activate
set scriptRunner to name of current application
display alert "GUI Scripting is not enabled for " & scriptRunner & "." message "Open System Preferences, unlock the Security & Privacy preference, select " & scriptRunner & " in the Privacy Pane's Accessibility list, and then run this script again." buttons {"Open System Preferences", "Cancel"} default button "Cancel"
if button returned of result is "Open System Preferences" then
tell application "System Preferences"
tell pane id "com.apple.preference.security" to reveal anchor "Privacy_Accessibility"
activate
end tell
end if
end if
end if
return GUIScriptingEnabled
end if
end enabledGUIScripting
-- Using a handler in a .scpt library
tell application "Finder"
set homeAlias to home
set scriptFile to file "JerryLib.scptd" of folder "AppleScripts" of folder "Documents" of home
set scriptHfsPath to scriptFile as string
end tell
set myLibrary to (load script file scriptHfsPath)
-- Test it
tell myLibrary to set newString to searchAndReplace("I am old", "old", "new")
-- Specifying an application by path. This may be necessary if more than one instance of an app is installed. Note that the following will also LAUNCH the application if it if not launched. Interestingly, though, if the path does not exist, the following will NOT make an error.
set appSpecifiedByPath to application "Users/jk/Documents/Programming/Builds/Debug/Bookmarksman.app"
-- To "save as" in an application. It depends on the class
tell application "TextEdit" to save aDocument in myAlias
tell application "TextEdit" to save aDocument in file myHFSPathAsString
-- The class of an alias is 'furl'
-- The class of a string is 'text'
-- To determine the AppleScript class of a variable
class of someVariable as string
-------------------
-- POSIX/HFS/ALIAS CONVERSIONS
-- POSIX to HFS
set theUnixPath to "/Users/Shared/"
(POSIX file theUnixPath) as string
-- POSIX to ALIAS
set theUnixPath to "/Users/Shared/"
(POSIX file theUnixPath) as alias
-- Doing the above inside of a tell application "Finder" block will fail!!
-- ALIAS to HFS
tell application "Finder" to set aAlias to folder "Safari" of folder "Preferences" of folder "Library" of home
set hfsPath to (aAlias as string)
-- ALIAS to POSIX (note that this is same as HFS to POSIX)
set aAlias to choose file with prompt "Choose the application, workflow application, or AppleScript application bundle to be scheduled." of type "com.apple.application" default location myAppSupport
POSIX path of aAlias
-- HFS to POSIX (note that this is same as ALIAS to POSIX)
set hfsPath to "Macintosh HD:Users:Shared:"
POSIX path of hfsPath
--> "/Users/Shared/"
-------------------
-- Case-Sensitive string compare
considering case
set result1 to "LOG" = "log" --> Returns: false
end considering
-- Case-Insensitive string compare
ignoring case
set result2 to "LOG" = "log" --> Returns: true
end ignoring
-- See http://docs.info.apple.com/article.html?path=AppleScript/2.1/en/as189.html ...
-- Path and version of application
-- The following WILL NOT LAUNCH the application. Thanks to Joseph Weaks for this one!
set targetAppBundleID to "com.sheepsystems.Bookdog"
tell application "Finder"
set targetAppAlias to (application file id targetAppBundleID)
set targetAppName to displayed name of targetAppAlias
set targetAppPath to POSIX path of (targetAppAlias as string)
set targetAppVersion to version of targetAppAlias
end tell
-- The following WILL LAUNCH the application
set targetAppPathHFS to (path to application targetAppName)
set v to get version of application "Safari"
set v to get version of application id "com.apple.Safari"
set pathToMe to ((POSIX path of (path to me)) as string)
set toolPath to quoted form of (pathToMe & "Contents/MacOS/SomeTool")
-- The following does not work when run from Automator, because the current working directory is /Applications
set aliasPathToMe to path to me
set myParent to missing value
tell application "Finder"
set myParent to parent of aliasPathToMe
end tell
set myParentPathHFS to (myParent as string)
set myParentPosixPath to POSIX path of myParentPathHFS
-- Path to another file in same folder as this script
tell application "Finder" to set myPath to folder of (path to me) as string
set otherScript to myPath & "OtherScript.scptd"
-- POSIX Desktop
set home_path_desktop to POSIX path of (path to desktop)
log home_path_desktop
-- HFS Home, the BEST way
set homeHFS to path to home folder
-- POSIX Home, the BEST WAY
set posixHome to POSIX path of (path to home folder)
-- For more named standard files, folders, disks:
-- http://docs.info.apple.com/article.html?path=AppleScript/2.1/en/as130.html
-- Appending to a list
set aList to {"one", "two"}
set end of aList to "shoe" -- {"one", "two", "shoe"}
-- To get stderr from do shell script, or error from any command:
try
set ffPlacesPosixPath to do shell script toolCmd
on error errMsg number errNumber
set msg to "shell script returned Error " & errNumber & return & return & errMsg & return & return & "Will abort to avoid possible data loss."
display dialog msg buttons {"Cancel", "Copy to Clipboard"} default button "Copy To Clipboard"
if button returned of result is "Copy to Clipboard" then
set the clipboard to msg
end if
return
end try
-- To activate the application using it's PID try this.
--(Use $! in bash to get pid of newest process.)
set appID to 37146
tell application "System Events" to set frontmost of (every process whose unix id is appID) to true
set wealthOfInformation to system info
-- result: {AppleScript version:"2.0.1", AppleScript Studio version:"1.5", system version:"10.5.6", short user name:"jk", long user name:"Jerry", user ID:501, user locale:"en_US", home directory:alias "JMiniHD:Users:jk:", boot volume:"JMiniHD", computer name:"Jerry’s Mac Mini", host name:"Jerrys-Mac-Mini.local", IPv4 address:"10.0.1.205", primary Ethernet address:"00:16:cb:a3:72:ac", CPU type:"Intel 80486", CPU speed:1660, physical memory:2048}
-- To extract one of them (parentheses are required):
set userShortName to short user name of (system info)
-- This isn't exactly a One Liner, but it's not a handler either
set daPath to "/Applications/Firefox.app"
tell application "System Events"
set targetProcess to missing value
set targetAlias to (POSIX file daPath) as alias
repeat with appProcess in application processes
set appFile to missing value
set appFile to application file of appProcess
-- We need a 'try' block here, because there is what I would call a bug in System Events, that my printer process, i.e. "Macintosh HD:Users:jk:Library:Printers:Laserjet 2100.app:" returns *undefined* as its application file. For more explanation of *undefined* AppleScript variables see pg. 103 of "AppleScript: the definitive Guide" by Matt Neuberg, 2nd edition.
try
if appFile is targetAlias then
set targetProcess to appProcess
end if
end try
end repeat
log (short name of targetProcess as Unicode text)
return targetProcess
end tell
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment