##!/usr/bin/env python
# xmlweather.cgi is a python cgi script that parses National Weather Service XML weather data and displays it in a web page.
# Set the url variable with the weather station of your choice. I include this in webpages using server-side includes with the
# following statement: Notice also that you'll need to create a directory for the image
# cache and a file for the xml cache. Both need to be writable by apache.
# Enjoy. http://www.braggtown.com
## Import Python modules
import cgi, cgitb; cgitb.enable()
from urllib import urlopen, urlretrieve
from xml.dom import minidom
from sys import exit
import os
from os.path import exists, join, split
from time import time
## Set url variable. Get url from http://www.nws.noaa.gov/data/current_obs/
url = "http://www.nws.noaa.gov/data/current_obs/KRDU.xml"
## Set cache variable to True to use local cache, False to always retrieve newest file
useCache = True
## Set variable to location of locally cached xml file
cache = "/home/jtuttle/public_html/weather_cache.xml"
## Set image directory. This reduces network latency by utilizing local image directory. Set to False if no local images.
imgDir = "/home/jtuttle/public_html/images"
imgDirUrl = "http://www.prairienet.org/~jtuttle/images/weather_icons"
# Acquire, parse, and normalize xml from NWS. Return xml tree object
def getWebXML(url):
try:
content = urlopen(url).read()
xml = minidom.parseString(content)
xml.normalize()
return xml
except IOError:
print "Content-Type: text/html\n"
print " No valid data at ", url
exit()
# Acquire, parse, and normalize xml from local cached file. Return xml tree object
def getCacheXML(cache):
xml = minidom.parse(cache)
xml.normalize()
return xml
# Parse out selected elements and populate variables. Return variable dictionary
def getElements(xml):
root = xml.getElementsByTagName('current_observation')
imgroot = xml.getElementsByTagName('image')
location = (root[0].getElementsByTagName('location')[0]).childNodes[0].data.encode('iso-8859-1')
weather = (root[0].getElementsByTagName('weather')[0]).childNodes[0].data.encode('iso-8859-1')
temperature_string = (root[0].getElementsByTagName('temperature_string')[0]).childNodes[0].data.encode('iso-8859-1')
relative_humidity = (root[0].getElementsByTagName('relative_humidity')[0]).childNodes[0].data.encode('iso-8859-1')
wind_string = (root[0].getElementsByTagName('wind_string')[0]).childNodes[0].data.encode('iso-8859-1')
heat_index_string = (root[0].getElementsByTagName('heat_index_string')[0]).childNodes[0].data.encode('iso-8859-1')
observation_time = (root[0].getElementsByTagName('observation_time')[0]).childNodes[0].data.encode('iso-8859-1')
credit = (root[0].getElementsByTagName('credit')[0]).childNodes[0].data.encode('iso-8859-1')
credit_URL = (root[0].getElementsByTagName('credit_URL')[0]).childNodes[0].data.encode('iso-8859-1')
img_url = (imgroot[0].getElementsByTagName('url')[0]).childNodes[0].data.encode('iso-8859-1')
if (imgDir) and exists(imgDir):
img_url = cacheIcons(imgDir, img_url, imgDirUrl)
img_title = (imgroot[0].getElementsByTagName('title')[0]).childNodes[0].data.encode('iso-8859-1')
img_link = (imgroot[0].getElementsByTagName('link')[0]).childNodes[0].data.encode('iso-8859-1')
icon_url_base = (root[0].getElementsByTagName('icon_url_base')[0]).childNodes[0].data.encode('iso-8859-1')
icon_url_name = (root[0].getElementsByTagName('icon_url_name')[0]).childNodes[0].data.encode('iso-8859-1')
icon_url = join(icon_url_base, icon_url_name)
if (imgDir) and exists(imgDir):
icon_url = cacheIcons(imgDir, icon_url, imgDirUrl)
elDict = {'location': location, 'weather': weather, 'temperature_string': temperature_string, 'relative_humidity': relative_humidity,\
'wind_string': wind_string, 'heat_index_string': heat_index_string, 'observation_time': observation_time, 'credit': credit, \
'credit_URL': credit_URL, 'img_url': img_url, 'img_title': img_title, 'img_link': img_link, 'icon_url': icon_url}
return elDict
# Determine if local cache of icon exists. If not, copy to image cache directory
def cacheIcons(imgDir, url, imgDirUrl):
path, icon = split(url)
if not exists(join(imgDir,icon)):
urlretrieve(url, join(imgDir, icon))
return join(imgDirUrl, icon)
# Format results and xhtml in verbose fashion
def formatDataVerbose(elDict, url):
print "Content-Type: text/html\n"
print """
\n""" \
% (elDict["icon_url"])
print "