Hi.
Any curl gurus out there? After fooling around with Dylan’s weather script the other day, I decided to do a version for my own use to work with AccuWeather.com’s UK/Ireland pages. These don’t change as radically throughout the day as the US pages and in fact it’s possible to get all the relevant information from the 5-day forecasts alone.
I’ve been trying to get the script to accept either a postcode or a place name as an input parameter. AccuWeather’s UK/Ireland URLs are based on postcodes. If you enter a place name, say “London”, into the site’s search field in a browser, a query is fired off in the form:
The site then returns a relative URL containing a postcode near the centre of the location and the browser redirects to that.
Using curl in the script, I’ve been able to isolate the returned postcode and redirect to the relevant 5-day forecast. But there’s a problem with non-unique place names. For instance, there’s a York in Yorkshire, which everyone knows, and a York in Lancashire, which is unbelievable, given the history of the two counties. When the query URL is entered into a browser .
. the browser redirects to a page asking you to choose between the two Yorks. The curl command, however, given the same URL, simply hangs and I have to force-quit AppleScript Editor to release it. Can anyone guide me to a solution or to the correct curl syntax? The problem area’s marked near the top of the displayWeather() handler.
property returnTab : return & tab
property twoReturns : return & return
on findNreplace(txt, find, replace)
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to find
set txt to txt's text items
set AppleScript's text item delimiters to replace
set txt to txt as text
set AppleScript's text item delimiters to astid
return txt
end findNreplace
on displayWeather(locationInput) -- locationInput is a record: either {postcode:"xxx xxx"} or {location:"Place Name"}
set {postcode:postcode, location:location} to locationInput & {postcode:"", location:""}
set astid to AppleScript's text item delimiters
if ((count postcode) > 0) then -- Postcode supplied.
set postcode to findNreplace(postcode, space, "%20")
else if ((count location) > 0) then -- Place name supplied.
(* Problem here with non-unique place names. 'curl' never returns. *)
set redirectData to (do shell script ("curl " & quoted form of "http://www.accuweather.com/ukie/uk-city-list.asp?partner=accuweather&postalcode=" & findNreplace(location, space, "%20") & "&submit=GO&u=1&partner=accuweather"))
if (redirectData begins with "<head><title>Object moved</title></head>") then
set AppleScript's text item delimiters to quote
set postcode to text item 2 of redirectData
set AppleScript's text item delimiters to "="
set postcode to text item -1 of postcode
else
set AppleScript's text item delimiters to astid
-- The server's returned something else.
end if
else
-- Input parameter problem.
end if
display dialog "Loading Weather Forecast; may be a few seconds!" buttons {"OK"} default button 1 giving up after 2
set fiveDayData to do shell script "curl " & space & quoted form of ("http://www.accuweather.com/ukie/forecast.asp?partner=accuweather&traveler=0&postalcode=" & postcode & "&metric=1")
-- Location.
set AppleScript's text item delimiters to "<div id=\"fcst_title\">"
set fiveDayData to text from text item 2 to -1 of fiveDayData
set AppleScript's text item delimiters to "</div>"
set city to text item 1 of fiveDayData
-- Local date and time.
set AppleScript's text item delimiters to "<span class=\"textsmallbold\">"
set fiveDayData to text from text item 2 to -1 of fiveDayData
set {m, d, y} to words 2 thru 4 of fiveDayData
set today to (date "Monday 1 January 1000 00:00:00")
set today's year to y
set today's month to (offset of (text 1 thru 3 of m) in "JanFebMarAprMayJunJulAugSepOctNovDec") div 3 + 1
set today's day to d
set AppleScript's text item delimiters to ">Currently</a> at "
set fiveDayData to text from text item 2 to -1 of fiveDayData
set AppleScript's text item delimiters to "</div>"
set t to text item 1 of fiveDayData
tell t to set today's time to ((word 1) mod 12 + ((word 3 is "PM") as integer) * 12) * hours + (word 2) * minutes
-- Data for now, today, and tomorrow.
set dayAfterTomorrow to today + 2 * days
set AppleScript's text item delimiters to "class=\"textsmall\">" & (dayAfterTomorrow's weekday) & "</a>, " & text 1 thru 3 of (dayAfterTomorrow's month as text) & " " & (dayAfterTomorrow's day) & "</div>"
set twoDayData to text item 1 of fiveDayData
-- Current, high, low, and feel temperatures. Only the first "feel" temperature is currently used.
set AppleScript's text item delimiters to {" °C", " °C", "°C"}
set {feelNow, temperatureNow, todayHighFeel, todayHigh, todayLowFeel, todayLow, tomorrowHighFeel, tomorrowHigh, tomorrowLowFeel, tomorrowLow} to text items 1 thru 10 of twoDayData
set AppleScript's text item delimiters to {"Temp: ", "Temp: "}
set temperatureNow to text item 2 of temperatureNow & "ºC"
set AppleScript's text item delimiters to {">Realfeel®:"}
set feelNow to text item 2 of feelNow & "ºC"
set AppleScript's text item delimiters to {"High: ", "High: "}
set todayHigh to text item 2 of todayHigh & "ºC"
set tomorrowHigh to text item 2 of tomorrowHigh & "ºC"
set AppleScript's text item delimiters to {"Low: ", "Low: "}
set todayLow to text item 2 of todayLow & "ºC"
set tomorrowLow to text item 2 of tomorrowLow & "ºC"
-- Descriptions.
set AppleScript's text item delimiters to "<div class=\"fcstTextBox\">"
set {nowdescription, todayDescription, tonightDescription, tomorrowDescription} to text items 2 thru 5 of twoDayData
set AppleScript's text item delimiters to "</div>"
set nowdescription to text 6 thru -1 of text item 1 of nowdescription
set todayDescription to text item 1 of todayDescription
set tonightDescription to text item 1 of tonightDescription
set tomorrowDescription to text item 1 of tomorrowDescription
-- Dialog text.
set nowText to "Currently" & returnTab & nowdescription & returnTab & "Temperature: " & temperatureNow & returnTab & "Feels like: " & feelNow & twoReturns
set todayText to "Today" & returnTab & todayDescription & returnTab & "High: " & todayHigh & twoReturns
set tonightText to "Tonight" & returnTab & tonightDescription & returnTab & "Low: " & todayLow & twoReturns
set tomorrowText to "Tomorrow" & returnTab & tomorrowDescription & returnTab & "High: " & tomorrowHigh & returnTab & "Low: " & tomorrowLow
set dialog to "Weather for " & city & return & today & twoReturns & nowText & todayText & tonightText & tomorrowText
set AppleScript's text item delimiters to ". "
set dialog to dialog's text items
set AppleScript's text item delimiters to returnTab
set dialog to dialog as text
set AppleScript's text item delimiters to astid
-----------------------------------------------------------------------------------------
display dialog dialog buttons {"OK"} default button 1 with title "Weather"
end displayWeather
displayWeather({location:"York"})