Weather Grabber 
Monday, July 4, 2011, 12:11
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.

Comments

Add Comment
Fill out the form below to add your own comments.









Insert Special:






Moderation is turned on for this blog. Your comment will require the administrators approval before it will be visible.