Monday, July 4, 2011, 12:11
Posted by Administrator
For the last couple of days I have been working the chat server and client that I made last semester. Adding additional features to it has been slow but satisfying work.
A weather function has been at the top of my list for things I wanted to see myself implement, so last night I decided to get to working on making something to retrieve the weather.
I've been using the
bash script below to get weather information for months now:
#!/bin/bash
var_url="http://www.google.com/ig/api?weather=72959&hl=en"
var_weather_wget=`wget -q $var_url -O -`
var_weather_xml=`echo "$var_weather_wget" | sed 's/<forecast_conditions>.*//'`
var_weather=`echo "$var_weather_xml" | sed 's/></>\n</g'`
var_date=`echo "$var_weather" | grep -e '<forecast_date' | \
sed -e 's/<forecast_date data="//' -e 's/"\/>//'`
var_city=`echo "$var_weather" | grep -e '<city' | \
sed -e 's/<city data="//' -e 's/"\/>//'`
var_condition=`echo "$var_weather" | grep -e '<condition' | \
sed -e 's/<condition data="//' -e 's/"\/>//'`
var_temp_f=`echo "$var_weather" | grep -e '<temp_f' | \
sed -e 's/<temp_f data="//' -e 's/"\/>//'`
var_temp_c=`echo "$var_weather" | grep -e '<temp_c' | \
sed -e 's/<temp_c data="//' -e 's/"\/>//'`
var_humidity=`echo "$var_weather" | grep -e '<humidity' | \
sed -e 's/<humidity data="//' -e 's/"\/>//'`
var_wind=`echo "$var_weather" | grep -e '<wind' | \
sed -e 's/<wind_condition data="//' -e 's/"\/>//'`
echo "Date: $var_date - City: $var_city"
echo "Condition: $var_condition"
echo "Temp: $var_temp_c C"
echo "$var_humidity"
echo "$var_wind"
This has been working well, but I wanted to make something more extensible with Java that I could add to my chatserver and run with any zipcode instead of just having it set to one location.
After finagling around a little I was able to come up with something I'm liking pretty well that fit great into the server I'm putting together:
This has been working well, but I wanted to make something more extensible with Java that I could add to my chatserver and run with any zipcode instead of just having it set to one location.
After finagling around a little I was able to come up with something I'm liking pretty well that fit great into the server I'm putting together:
/* < < Current Weather > > |
Forecast from Google's API |
Spike Snell |
2011 |
----------------------------------*/
import java.io.*;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class weather {
public static void main(String[] args) throws Exception {
if (args.length > 0)
System.out.println(toString(args[0]));
else
System.out.println("Please enter a valid 5 digit zipcode. Example: java weather 72701");
}
public static BufferedReader read(String url) throws Exception {
return new BufferedReader(new InputStreamReader(new URL(url).openStream()));
}
public static String toString(String zip) throws Exception {
// variables to hold the weather
String date = null;
String city = null;
String condition = null;
String tempC = null;
String humidity = null;
String wind = null;
// declare the pattern and matcher
Pattern p;
Matcher m;
// check to make sure the string is the right number of characters
if (zip.length() != 5)
return "Please enter the correct number of digits.";
// and make sure all 5 of the characters are numbers
p = Pattern.compile("\\d{5}");
m = p.matcher(zip);
if (m.find() == false)
return "Please enter a valid 5 digit zipcode.";
// open up a connection to google's weather API
BufferedReader reader = read("http://www.google.com/ig/api?weather="+ zip);
String page = reader.readLine();
// get the date
p = Pattern.compile("<forecast_date data=\"(.*?)\"/>");
m = p.matcher(page);
if (m.find() == true)
date = m.group(1);
// get the city
p = Pattern.compile("<city data=\"(.*?)\"/>");
m = p.matcher(page);
if (m.find() == true)
city = m.group(1);
// get the condition
p = Pattern.compile("<condition data=\"(.*?)\"/>");
m = p.matcher(page);
if (m.find() == true)
condition = m.group(1);
// get the temperature in C
p = Pattern.compile("<temp_c data=\"(.*?)\"/>");
m = p.matcher(page);
if (m.find() == true)
tempC = m.group(1);
// get the humidity
p = Pattern.compile("<humidity data=\"(.*?)\"/>");
m = p.matcher(page);
if (m.find() == true)
humidity = m.group(1);
// get the humidity
p = Pattern.compile("<wind_condition data=\"(.*?)\"/>");
m = p.matcher(page);
if (m.find() == true)
wind = m.group(1);
// if the date is still null there was a problem
if (date == null) {
return "There was a problem retrieving the weather.";
}
else {
// return the forecast
return city + " - " + date +
"\nCondition: " +
condition+ "\nTemp: " +
tempC + " *C\n" +
humidity + "\n" +
wind;
}
}
}
What it does is taken in a command line argument for the zipcode and after a bit of error checking (Making sure the zipcode is actually 5 numbers) it grabs the data from
google's weather API, runs it through some regexes to grab the data I want and then returns everything as a string.
Here is an example of it in use:
nrg@AKIRA ~/Desktop $ java weather 72701
Fayetteville, AR - 2011-07-04
Condition: Mostly Cloudy
Temp: 27 *C
Humidity: 74%
Wind: S at 5 mph
Any feedback on improving this code or any other comments about it would be much appreciated.