USERS  
  Log-In  
  Register  
  Members  

Daniel A. Shockley - AppleScript Handler Code-bits

Useful AppleScript Handler Code-bits

Here are some useful bits of AppleScript Handler code I've whipped up. I avoided using the line-continue character, since that makes copy-and-paste fail, so you'll see a variable set, and then added to on separate lines when it could have all been done on one line. (URLAS = URL Access Scripting)

simpleFTPupload

The is a simple curl replacement for the URL Access Scripting FTP upload capability.
-- SAMPLE USAGE 1 - upload file to the default ftp directory on the server
simpleFtpUpload("ftp://ftp.SOMEWHERE.com/", "DriveX:Users:YOU:Desktop:TEMP:some'dir:person's ploy", "testme", "testing12")

-- SAMPLE USAGE 2 - upload file to a specific directory on the server
simpleFtpUpload("ftp://ftp.SOMEWHERE.com/files/july/", "DriveX:Users:YOU:Desktop:TEMP:some'dir:person's ploy", "testme", "testing12")


on simpleFtpUpload(remoteURL, macFilePath, userName, userPasswd)
	-- version 1.2, Dan Shockley (http://www.danshockley.com)
	-- uses curl to do the upload
	-- remoteURL is the complete ftp url to the remote destination directory
	try
		if userName is "" then
			set userName to "anonymous"
			set userPasswd to "devnull@devnull.null"
			-- no email address, change if desired
		end if
		
		-- get parentFolder
		if (macFilePath as string) ends with ":" then -- it is a folder itself
			set {od, AppleScript's text item delimiters} to {AppleScript's text item delimiters, ":"}
			set parentFolder to (text items 1 thru -3 of (macFilePath as string)) as string
			set AppleScript's text item delimiters to od
		else -- it is just a file
			set {od, AppleScript's text item delimiters} to {AppleScript's text item delimiters, ":"}
			set parentFolder to (text items 1 thru -2 of (macFilePath as string)) as string
			set AppleScript's text item delimiters to od
		end if
		
		set localPosixPath to quoted form of POSIX path of alias macFilePath
		
		set uploadFileName to do shell script "basename " & localPosixPath
		set uploadDirectory to quoted form of POSIX path of parentFolder
		
		-- curl --upload-file SOMEFILE ftp://SERVER.com --user MYUSER:THEPASSWD
		-- must be IN the directory of the file you want to upload
		set myCommand to "cd " & uploadDirectory & ";" & "curl --upload-file "
		set myCommand to myCommand & quoted form of uploadFileName
		set myCommand to myCommand & " " & remoteURL
		set myCommand to myCommand & " --user " & userName & ":" & userPasswd
		set myCommand to myCommand & " " & "--write-out " & "%{size_upload}"
		set myCommand to myCommand & " --quote -quit"
		
		-- output is the 'size_upload' result from curl
		
		set uploadResult to do shell script myCommand
		
		return uploadResult -- size uploaded in kilobytes
	on error errMsg number errNum
		error "simpleFtpUpload FAILED: " & errMsg number errNum
	end try
end simpleFtpUpload

curlSimpleDownload

This is a simple replacement for the URL Access Scripting download capability. One of the many nice things about curl is that you can get the result directly into a string, rather than having to save a file. Set destExpected to "" to get a string back.
-- SAMPLE USAGE
set actionURL to "http://www.macslash.org"
set testFormInfo to ""
set saveFilePath to ""

curlSimpleDownload(actionURL, saveFilePath, testFormInfo)

on curlSimpleDownload(downloadURL, destExpected, theFormInfo)
	-- version 1.2, Daniel A. Shockley - public domain
	-- downloadURL is STRING
	-- saves to destExpected (Mac path as STRING, FILE SPEC, or ALIAS), if given
	-- if destExpected is "", returns source result directly as string
	-- optional form data for POST - use "" for no form data
	try
		-- basic download to standard output
		set curlCode to "curl '" & downloadURL & "'"
		
		if (length of theFormInfo) > 0 then
			set curlCode to curlCode & " -d \"" & theFormInfo & "\""
		end if
		
		-- now, add on the desired file location, if there is one given
		if destExpected is not "" then
			set unixDestExpected to quoted form of POSIX path of (destExpected as string)
			set curlCode to curlCode & " --output " & unixDestExpected & " --write-out \"%{http_code}\""
		else -- result as string
			set curlCode to curlCode & " | vis" -- pipe into vis to strip nonprintable characters
		end if
		
		set curlResponse to do shell script curlCode
		
		return curlResponse
		(*
		curlResponse will be the http success code ("200"), or an error code.
		If no destination was given, curlResponse will be the source 
		returned, and no file will be saved
	*)
	on error errMsg number errNum
		error "curlSimpleDownload FAILED: " & errMsg number errNum
	end try
end curlSimpleDownload


dateAsCustomString

This handler allows you to format a date in almost any desired form.
--SAMPLE USAGE
dateAsCustomString("12/25/2002 1:30 PM", "YYYY MM DD hh mm ss ap")
--> "2002 12 25 01 30 00 pm"

dateAsCustomString("1/6/2003 9:23:21 AM", "YYYY-MM-DD hh-mm-ss AP")
--> "2003-01-06 09-23-21 AM"

on dateAsCustomString(incomingDate, stringFormat)
	-- version 1.2, Daniel A. Shockley http://www.danshockley.com
	-- 1.2 added am/pm option, and date class checking, with a nod to Arthur J. Knapp
	-- NEEDS simpleReplace() handler
	
	-- takes any form of MM, DD, YYYY, YY
	-- AND any form of hh, mm, ss 
	--  (optional ap or AP, which gives am/pm or AM/PM)
	-- leaving off am/pm option coerces to military time
	-- MUST USE LOWER-CASE for TIME!!!! (avoids month/minute conflict)
	
	-- use single letters to allow single digits, where applicable
	
	-- textVars are each always 2 digits, whereas month and day 
	-- may be 1 digit, and year will normally be 4 digit
	
	if class of incomingDate is not date then
		try
			set incomingDate to date incomingDate
		on error
			set incomingDate to (current date)
		end try
	end if
	
	set numHours to (time of incomingDate) div hours
	set textHours to text -2 through -1 of ("0" & (numHours as string))
	
	set numMinutes to (time of incomingDate) mod hours div minutes
	set textMinutes to text -2 through -1 of ("0" & (numMinutes as string))
	
	set numSeconds to (time of incomingDate) mod minutes
	set textSeconds to text -2 through -1 of ("0" & (numSeconds as string))
	
	set numDay to day of incomingDate as number
	set textDay to text -2 through -1 of ("0" & (numDay as string))
	
	set numYear to year of incomingDate as number
	set textYear to text -2 through -1 of (numYear as string)
	
	-- Emmanuel Levy's Plain Vanilla get month number function
	copy incomingDate to b
	set the month of b to January
	set numMonth to (1 + (incomingDate - b + 1314864) div 2629728)
	set textMonth to text -2 through -1 of ("0" & (numMonth as string))
	
	set customDateString to stringFormat
	
	if numHours > 12 and (customDateString contains "ap" or customDateString contains "AP") then
		-- (afternoon) and requested am/pm
		set numHours to numHours - 12 -- pull off the military 12 hours for pm hours
		set textHours to text -2 through -1 of ("0" & (numHours as string))
	end if
	
	set customDateString to simpleReplace(customDateString, "MM", textMonth)
	set customDateString to simpleReplace(customDateString, "DD", textDay)
	set customDateString to simpleReplace(customDateString, "YYYY", numYear as string)
	set customDateString to simpleReplace(customDateString, "hh", textHours)
	
	set customDateString to simpleReplace(customDateString, "mm", textMinutes)
	set customDateString to simpleReplace(customDateString, "ss", textSeconds)
	
	
	-- shorter options
	set customDateString to simpleReplace(customDateString, "M", numMonth)
	set customDateString to simpleReplace(customDateString, "D", numDay)
	set customDateString to simpleReplace(customDateString, "YY", textYear)
	set customDateString to simpleReplace(customDateString, "h", numHours)
	set customDateString to simpleReplace(customDateString, "m", numMinutes)
	set customDateString to simpleReplace(customDateString, "s", numSeconds)
	
	-- AM/PM MUST be after Minutes/Month done, since it adds an M
	if (time of incomingDate) > (12 * hours) then
		-- afternoon
		set customDateString to simpleReplace(customDateString, "ap", "pm")
		set customDateString to simpleReplace(customDateString, "AP", "PM")
	else
		set customDateString to simpleReplace(customDateString, "ap", "am")
		set customDateString to simpleReplace(customDateString, "AP", "AM")
	end if
	
	return customDateString
	
end dateAsCustomString


on simpleReplace(thisText, oldChars, newChars)
	-- version 1.1
	
	-- 1.1 coerces the newChars to a STRING, since other data types do not always coerce
	--     (example, replacing "nine" with 9 as number replaces with "")
	set oldDelims to AppleScript's text item delimiters
	set AppleScript's text item delimiters to the oldChars
	set the parsedList to every text item of thisText
	set AppleScript's text item delimiters to the {(newChars as string)}
	set the newText to the parsedList as string
	set AppleScript's text item delimiters to oldDelims
	return newText
	
end simpleReplace


Multiple Messages (in Eudora)

This script will take your front-most message in Eudora and send it separately to everyone selected in your Mac OS X Address book (who has an email address), using the personality/From address marked for that message.
(*
Multiple Messages
version 2.0, Dan Shockley (http://www.danshockley.com)
This script will take your front-most message in Eudora and send it separately to 
everyone selected in your Mac OS X Address book (who has an email address), 
using the personality/From address marked for that message.
*)

on run
	tell application "Eudora"
		activate
		set frontWin to a reference to window 1
		set frontID to id of frontWin
		set {msgText, msgBody, msgSubject, msgPersonality, msgFrom, msgSig} to ¬
			{whole text, body, subject, personality, field "FROM", signature} of message frontID
		set sendDialog to (display dialog "This script will take your front-most message (subject: " & msgSubject & ") " & ¬
			"and send it separately to everyone selected in your Mac OS X Address book (who has an email address), " & ¬
			"using the personality/From address marked for that message. Send immediately, or Queue outgoing " & ¬
			"messages?" buttons {"Cancel", "Send", "Queue"} default button "Queue")
	end tell
	
	set fromAddress to my replaceSimple(msgFrom, "From: ", "")
	
	tell application "Address Book"
		set selectedContacts to selection
		set toList to {}
		repeat with oneSelected in selectedContacts
			if (count of emails of oneSelected) is greater than 0 then
				set oneEmail to get value of first email of oneSelected
				set oneFirst to get first name of oneSelected
				set oneMid to get middle name of oneSelected
				set oneLast to get last name of oneSelected
				set fullName to ""
				if oneFirst is not missing value then set fullName to my addWithDelim(fullName, space, oneFirst)
				if oneMid is not missing value then set fullName to my addWithDelim(fullName, space, oneMid)
				if oneLast is not missing value then set fullName to my addWithDelim(fullName, space, oneLast)
				if length of fullName is not 0 then
					set emailLine to "\"" & fullName & "\" <" & oneEmail & ">"
				else
					set emailLine to "<" & oneEmail & ">"
				end if
				copy emailLine to end of toList
			end if
		end repeat
	end tell
	
	repeat with oneAddress in toList
		tell application "Eudora"
			make message at end of mailbox "out"
			
			-- 0 is the current message
			set field "from" of message 0 to "dan@danshockley.com"
			set field "to" of message 0 to oneAddress
			set field "subject" of message 0 to msgSubject
			set body of message 0 to msgBody
			set personality of message 0 to msgPersonality
			set signature of message 0 to msgSig
			
			queue message 0
			if button returned of sendDialog is "Send" then
				connect with sending without checking
			end if
		end tell
	end repeat
end run

on addWithDelim(oldString, delim, newPart)
	if length of oldString is 0 then
		return newPart
	else
		return oldString & delim & newPart
		
	end if
end addWithDelim

on parseChars(thisText, parseString)
	-- version 1.2, Daniel A. Shockley, http://www.danshockley.com
	
	set oldDelims to AppleScript's text item delimiters
	try
		set AppleScript's text item delimiters to the {parseString as string}
		set the parsedList to every text item of thisText
		set AppleScript's text item delimiters to oldDelims
		return parsedList
	on error errMsg number errNum
		try
			set AppleScript's text item delimiters to oldDelims
		end try
		error "ERROR: parseChars() handler: " & errMsg number errNum
	end try
end parseChars

on replaceSimple(thisText, oldChars, newChars)
	-- version 1.1, Daniel A. Shockley http://www.danshockley.com
	
	-- 1.1 coerces the newChars to a STRING, since other data types do not always coerce
	--     (example, replacing "nine" with 9 as number replaces with "")
	set oldDelims to AppleScript's text item delimiters
	set AppleScript's text item delimiters to the oldChars
	set the parsedList to every text item of thisText
	set AppleScript's text item delimiters to the {(newChars as string)}
	set the newText to the parsedList as string
	set AppleScript's text item delimiters to oldDelims
	return newText
	
end replaceSimple

For more information, please

Return to my main page