Skip to content

Instantly share code, notes, and snippets.

@bob-sims
Created November 28, 2011 22:28
Show Gist options
  • Save bob-sims/1402379 to your computer and use it in GitHub Desktop.
Save bob-sims/1402379 to your computer and use it in GitHub Desktop.
CommonJS module to pull XML response from from (undocumented) Google Weather API, for use with Titanium Mobile
// console dump of sample returned object
I/TiAPI ( 244): (kroll$4: app://app.js) [797,3312] Object
I/TiAPI ( 244): {
I/TiAPI ( 244): weatherData => Object
I/TiAPI ( 244): {
I/TiAPI ( 244): forecastInfo => Object
I/TiAPI ( 244): {
I/TiAPI ( 244): city => 'Bydgoszcz, Kuyavian-Pomeranian Voivodeship',
I/TiAPI ( 244): forecast_date => '2012-01-01'
I/TiAPI ( 244): },
I/TiAPI ( 244): currentConditions => Object
I/TiAPI ( 244): {
I/TiAPI ( 244): condition => 'Rain',
I/TiAPI ( 244): temp_f => '32',
I/TiAPI ( 244): temp_c => '0',
I/TiAPI ( 244): humidity => 'Humidity: 88%',
I/TiAPI ( 244): icon => '/ig/images/weather/rain.gif',
I/TiAPI ( 244): wind_condition => 'Wind: SE at 4 mph'
I/TiAPI ( 244): },
I/TiAPI ( 244): forecastConditions => Array
I/TiAPI ( 244): [
I/TiAPI ( 244): 0 => Object
I/TiAPI ( 244): {
I/TiAPI ( 244): day_of_week => 'Sun',
I/TiAPI ( 244): low => '43',
I/TiAPI ( 244): high => '45',
I/TiAPI ( 244): icon => '/ig/images/weather/chance_of_rain.gif',
I/TiAPI ( 244): condition => 'Chance of Rain'
I/TiAPI ( 244): },
I/TiAPI ( 244): 1 => Object
I/TiAPI ( 244): {
I/TiAPI ( 244): day_of_week => 'Mon',
I/TiAPI ( 244): low => '39',
I/TiAPI ( 244): high => '48',
I/TiAPI ( 244): icon => '/ig/images/weather/fog.gif',
I/TiAPI ( 244): condition => 'Fog'
I/TiAPI ( 244): },
I/TiAPI ( 244): 2 => Object
I/TiAPI ( 244): {
I/TiAPI ( 244): day_of_week => 'Tue',
I/TiAPI ( 244): low => '39',
I/TiAPI ( 244): high => '41',
I/TiAPI ( 244): icon => '/ig/images/weather/mostly_sunny.gif',
I/TiAPI ( 244): condition => 'Partly Sunny'
I/TiAPI ( 244): },
I/TiAPI ( 244): 3 => Object
I/TiAPI ( 244): {
I/TiAPI ( 244): day_of_week => 'Wed',
I/TiAPI ( 244): low => '34',
I/TiAPI ( 244): high => '45',
I/TiAPI ( 244): icon => '/ig/images/weather/mostly_sunny.gif',
I/TiAPI ( 244): condition => 'Mostly Sunny'
I/TiAPI ( 244): }
I/TiAPI ( 244): ]
I/TiAPI ( 244): },
I/TiAPI ( 244): type => 'net:weatherDataReturned',
I/TiAPI ( 244): source => [Ti.App]
I/TiAPI ( 244): }
// Sample app.js
// attempting to follow CommonJS pattern
// googleWeather.js fires a single app-level event that returns
// a single array of javascript objects.
// Normally 1st object will be current conditions, then next 4 objects
// will each be next days' forecasts
// remember 'require' statement does not need .js suffix to filename
require('googleWeather').fetchWeatherData('bydgoszcz,poland')
// set up an event listener to populate data when it's available from the network
Ti.App.addEventListener('net:weatherDataReturned', function(e){
Ti.API.info(JSON.stringify(e.forecastInfo));
Ti.API.info(JSON.stringify(e.currentConditions));
for (var i=0;i<items.length;i++) {
Ti.API.info(JSON.stringify(e.forecastConditions[i]));
};
});
// maybe add some cache features? ex: http://pastie.org/1541768
// cache ex: http://pastebin.com/Eq1DLsdP
// modeled after RSSReader demo by @skypanther
// 01-01-2012: refactored arrays and objects; added localization (I think!)
exports.fetchWeatherData = function(location) {
// attempt at localization using Google results, not tested enough!
var googleCountryArray = ["af","sq","sm","ar","az","eu","be","bn","bh","bs","bg","ca",
"zh-CN","zh-TW","hr","cs","da","nl","en","en-uk","eo","et","fo","fi","fr","fy","gl",
"ka","de","el","gu","iw","hi","hu","is","id","ia","ga","it","ja","jw","kn","ko","la",
"lv","lt","mk","ms","ml","mt","mr","ne","no","nn","oc","fa","pl","pt-BR","pt-PT","pa",
"ro","ru","gd","sr","si","sk","sl","es","su","sw","sv","tl","ta","te","th","ti","tr",
"uk","ur","uz","vi","cy","xh","zu"];
var googleCountryString = googleCountryArray.toString();
var languageCode = 'en'; // default language if device language not found
// test to see if platform locale is supported by Google API codes
if (googleCountryString.indexOf(Ti.Locale.currentCountry.toLowerCase())) {
languageCode = Ti.Locale.currentCountry.toLowerCase();
};
if (googleCountryString.indexOf(Ti.Locale.currentLanguage.toLowerCase())) {
languageCode = Ti.Locale.currentLanguage.toLowerCase();
};
Ti.API.info('locale: '+languageCode);
// Pulls the weather feed data and returns it to caller
var xhr = Titanium.Network.createHTTPClient();
// default weather location feed url
location = (location) ? location : "bydgoszcz,poland";
xhr.open('GET','http://www.google.com/ig/api?hl='+languageCode+'&oe=utf8&weather='+location);
xhr.setRequestHeader('User-Agent', 'mobile agent');
xhr.send();
xhr.onload = function() {
// Data is returned from weather API, start parsing
Ti.API.info('Got data!');
Ti.API.info('header: '+this.getResponseHeader('Content-Type'));
var xml = this.responseXML;
var forecastInfo = xml.documentElement.getElementsByTagName("forecast_information");
var currentConditions = xml.documentElement.getElementsByTagName("current_conditions");
var data = {};
// test to see if valid weather data returned
if(forecastInfo.length>0) {
data.forecastInfo = {
city: forecastInfo.item(0).getElementsByTagName("city").item(0).getAttribute("data"),
forecast_date: forecastInfo.item(0).getElementsByTagName("forecast_date").item(0).getAttribute("data")
};
data.currentConditions = {
condition: currentConditions.item(0).getElementsByTagName("condition").item(0).getAttribute("data"),
temp_f: currentConditions.item(0).getElementsByTagName("temp_f").item(0).getAttribute("data"),
temp_c: currentConditions.item(0).getElementsByTagName("temp_c").item(0).getAttribute("data"),
humidity: currentConditions.item(0).getElementsByTagName("humidity").item(0).getAttribute("data"),
icon: currentConditions.item(0).getElementsByTagName("icon").item(0).getAttribute("data"),
//wind_condition: currentConditions.item(0).getElementsByTagName("wind_condition").item(0).getAttribute("data"),
};
//hmmm... sometimes wind information is not returned...
if (currentConditions.item(0).getElementsByTagName("wind_condition").length>0) {
data.currentConditions.wind_condition = currentConditions.item(0).getElementsByTagName("wind_condition").item(0).getAttribute("data");
} else {
data.currentConditions.wind_condition = '';
}
var forecastConditions = xml.documentElement.getElementsByTagName("forecast_conditions");
data.forecastConditions = [];
for (var i=0;i<forecastConditions.length;i++) {
data.forecastConditions.push({
day_of_week: forecastConditions.item(i).getElementsByTagName("day_of_week").item(0).getAttribute("data"),
low: forecastConditions.item(i).getElementsByTagName("low").item(0).getAttribute("data"),
high: forecastConditions.item(i).getElementsByTagName("high").item(0).getAttribute("data"),
icon: forecastConditions.item(i).getElementsByTagName("icon").item(0).getAttribute("data"),
condition: forecastConditions.item(i).getElementsByTagName("condition").item(0).getAttribute("data"),
})
}
}
else {
Titanium.API.info('oops, error!');
};
// fire an app-level event to notify the UI that the weather data is available
Ti.App.fireEvent('net:weatherDataReturned',{
weatherData: data
});
}; //end onload
xhr.onerror = function(e) {
// should do something more robust
Titanium.API.info(e.error);
};
}; // end fetchWeatherData()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment