AppleScript subroutine: is there an updated version of script on server?

By • Published: January 13, 2010 • Last updated: January 17, 2010 • Filed in: Tips & tricks

EmailShare

While working on my better multi-country support AppleScript plug-in for Address Book, I was thinking of a way to check with a server to see if there was an updated version of the script.

The requirements:

  • make it optional: let the user decide if they want to switch it on;
  • make it privacy friendly: don’t use it to collect user information;
  • do it quick, don’t slow down the script too much.

Read on for the result I came up with.

The key part is that I am using a shell command to run curl, which is available on all systems:

set myoutput to do shell script "/usr/bin/curl --fail --max-time 3 --output - " & myurl & " 2> /dev/null"

–max-time 3: abort if it takes more than 3 seconds; –fail: no error messages if something fails; the content of the file is set to the AppleScript variable myoutput. All that is stored in the log file of the server: IP address and the user’s current version number of the script.

The server has a small text file, that looks like:

1.2.3|2010/01/12|here is a short description of what is new

The subroutine is relying in AppleScript’s clever evaluation of version numbers, e.g. it knows 1.1.1 < 1.2 .

I am sure there are dozens of other ways of doing it. And I am sure an AppleScript expert can come up with cleverer/cleaner code.
Interested in hearing from you!

property current_version : "1.1"
property check_for_updates : true -- optional: will check to see if there is an updated version of the script

if check_for_updates then
   set lets_get_new_version to check_latest_version(current_version) -- will show popup if there is a newer version
   if lets_get_new_version then return -- let's stop if the user wanted to open the browser to download the latest version
end if

-- rest of script
...

on check_latest_version(current_version)
   -- will only return "true" if the user decides to open the browser to download the new version
   set myurl to "http://.../latest_version_of_my_script.txt?" & current_version
   -- try to get the url with built in curl command, spend a maximum of 3 seconds to get it
   set mycmd to "/usr/bin/curl --fail --max-time 3 --output - " & myurl & " 2> /dev/null"
   set myloc to "http://.../home_page_of_my_script"
   try
       set myoutput to do shell script mycmd
   on error
       -- could not check the latest version, will skip and go back to regular programme...
       return false
   end try
   set {latest_version, version_date, version_description} to parse_version_output(myoutput)
   
   if (current_version < latest_version) then
       try
           set open_site to display dialog "New version available: " & latest_version & ¬
               " (" & version_date & ")" & return & "You have version: " & current_version & return & return & ¬
               "New in this release: " & version_description & return & return & "Go to site?" buttons {"Skip", "Yes"} ¬
               default button "Yes" giving up after 20 with title "New version of plug-in available"
       on error
           return false -- user pressed Skip
       end try
       if button returned of open_site is "Yes" then
           try
               tell application "System Events" to open location myloc -- open in default browser
           on error
               return false
           end try
           return true -- if we arrive here: we opened the browser, user is going to download
       end if
   end if -- compare current_version to latest_version
   return false -- if we arrive here: we already have latest version
end check_latest_version

on parse_version_output(output)
   set savedDelimiters to AppleScript's text item delimiters
   try
       set AppleScript's text item delimiters to {"|"} -- output looks like "1.2.3|2010/01/12|what is new"
       set {myversion, mydate, mydesc} to text items of output
   on error
       set AppleScript's text item delimiters to savedDelimiters
   end try
   set AppleScript's text item delimiters to savedDelimiters -- reset the delimiter to the original state
   return {myversion, mydate, mydesc}
end parse_version_output
EmailShare

Leave a Reply

« | Home | »