Imported from archive.

* Initial release 1.0.
This commit is contained in:
Jeremy Stanley
2006-03-26 17:08:52 +00:00
commit 155d8574df
7 changed files with 436 additions and 0 deletions

39
INSTALL Normal file
View File

@@ -0,0 +1,39 @@
BASIC UNIX INSTALLATION INSTRUCTIONS FOR THE WEATHER UTILITY
PREREQUISITES
You need the Python interpreter installed somewhere in your path
(most modern UNIX derivatives come with one already). The weather
executable assumes your Python interpreter is /usr/bin/python so you
may need to edit the #! line if that is not the case. If you need
Python for some reason, it can be obtained from
http://www.python.org/ (but chances are your operating system at
least provides some sort of native package for it, which you should
probably install in whatever means is recommended by your OS
vendor/distributor).
INSTALLING THE UTILITY
The file named weather should be made executable and put somewhere
in your path (/usr/local/bin/ or ~/bin/ for example). Similarly,
weather.py needs to be somewhere in Python's include path. You can
see your Python interpreter's default include path by running:
python -c "import sys ; print sys.path"
CONFIGURATION
The weatherrc file should go in /etc/ or you can save it in your
home directory as a dotfile (~/.weatherrc) to support user-specific
alias configuration and overrides of the global /etc/weatherrc file.
MANUALS
Optionally, the weather.1 and weatherrc.5 files can be placed in
sane locations for TROFF/NROFF manual files on your system (for
example, /usr/local/share/man/ or ~/man/).

22
LICENSE Normal file
View File

@@ -0,0 +1,22 @@
Copyright (c) 2006 Jeremy Stanley <fungi@yuggoth.org>, all rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

31
weather Executable file
View File

@@ -0,0 +1,31 @@
#!/usr/bin/python
# Copyright (c) 2006 Jeremy Stanley <fungi@yuggoth.org>, all rights reserved.
# Licensed per terms in the LICENSE file distributed with this software.
import weather
# initialize options and configs
selections = weather.Selections()
get = selections.get
get_boolean = selections.get_boolean
# this mode just lists the aliases defined in the config
if get_boolean("list"): print weather.list_aliases(selections.config)
# normal operation
else:
for argument in selections.arguments:
if get_boolean("conditions", argument):
print weather.get_metar(
get("id", argument),
get_boolean("verbose", argument)
)
if not get_boolean("conditions", argument) \
or get_boolean("forecast", argument):
print weather.get_forecast(
get("city", argument),
get("st", argument),
get_boolean("verbose", argument)
)

87
weather.1 Normal file
View File

@@ -0,0 +1,87 @@
.TH WEATHER 1 "March 26, 2006"
.SH NAME
weather \- command\-line tool to obtain weather conditions and forecasts
.SH SYNOPSIS
.B weather [ options ] [ alias [ alias [...] ] ]
.SH DESCRIPTION
This utility is intended to provide quick access to current weather
conditions and forecasts. Presently, it is capable of providing data for
localities throughout the United States of America by retrieving and
processing METAR data from the National Oceanic and Atmospheric
Administration and forecasts from the National Weather Service. Behavior
can be determined by command\-line options and specification of zero or
more aliases. Aliases are defined in weatherrc files, as a convenient
means of grouping option combinations together using a short name.
Specifying multiple aliases on the command line causes the utility to
output data for each, as if it had been invoked multiple times. If no
alias is specified, then an alias of "default" is used (assuming it has
been defined) or the built\-in default values are chosen (if it has not).
.SH OPTIONS
A summary of options is included below.
.TP
.B \-\-version
show program's version number and exit
.TP
.B \-h, \-\-help
show a help message and exit
.TP
.B \-cCITY, \-\-city=CITY
the city name (ex: "Raleigh Durham")
.TP
.B \-f, \-\-forecast
include a local forecast
.TP
.B \-iID, \-\-id=ID
the METAR station ID (ex: KRDU)
.TP
.B \-l, \-\-list
print a list of configured aliases
.TP
.B \-n, \-\-no\-conditions
disable output of current conditions (implies \-\-forecast)
.TP
.B \-sST, \-\-st=ST
the state abbreviation (ex: NC)
.TP
.B \-v, \-\-verbose
show full decoded feeds
.SH FILES
.B weather
may additionally obtain configuration data from a system\-wide
configuration file, a per\-user configuration file, and a local
directory configuration file. The file format and configuration options
are described in
.BR weatherrc (5) .
They are aggregated in the following order:
.TP
.B /etc/weatherrc
the system\-wide configuration
.TP
.B ~/.weatherrc
the per\-user configuration (can be used to override the above)
.TP
.B ./.weatherrc
the local directory configuration (can be used to override the above)
.SH EXAMPLES
.TP
.B weather
View output for the defined default alias, or the built-in default values
if there is no default alias defined in the configuration files.
.TP
.B weather -i kavl
Display current conditions at the KAVL METAR station.
.TP
.B weather -n -c asheville -s nc
See a forecast for the Asheville, NC area.
.TP
.B weather -fv gso
Get the full decoded METAR for the station associated with the gso alias,
and the forecast data for the City/State associated with the gso alias,
without filtering or fancy formatting.
.TP
.B weather home work
Show current conditions for both the home and work aliases in that order.
.SH SEE ALSO
.BR weatherrc (5)
.SH AUTHOR
Utility and manual written by Jeremy Stanley <fungi@yuggoth.org>.

170
weather.py Normal file
View File

@@ -0,0 +1,170 @@
# Copyright (c) 2006 Jeremy Stanley <fungi@yuggoth.org>, all rights reserved.
# Licensed per terms in the LICENSE file distributed with this software.
version = "1.0"
class Selections:
"""An object to contain selection data."""
def __init__(self):
"""Store the config, options and arguments."""
self.config = get_config()
self.options, self.arguments = get_options()
if self.arguments:
self.arguments = [(x.lower()) for x in self.arguments]
else: self.arguments = [ None ]
def get(self, option, argument=None):
"""Retrieve data from the config or options."""
if not argument: argument = "default"
if self.config.has_option(argument, option):
return self.config.get(argument, option)
else: return self.options.__dict__[option]
def get_boolean(self, option, argument=None):
"""Get data and coerce to a boolean if necessary."""
data = self.get(option, argument)
if type(data) is str:
if eval(data): return True
else: return False
else:
if data: return True
else: return False
def quote(words):
"""Wrap a string in quotes if it contains spaces."""
if words.find(" ") != -1: words = "\"" + words + "\""
return words
def sorted(data):
"""Return a sorted copy of a list."""
new_copy = data[:]
new_copy.sort()
return new_copy
def get_url(url):
"""Return a string containing the results of a URL GET."""
import urllib
return urllib.urlopen(url).read()
def get_metar(id, verbose=False):
"""Return a summarized METAR for the specified station."""
metar = get_url(
"http://weather.noaa.gov/pub/data/observations/metar/decoded/" \
+ id.upper() + ".TXT")
if verbose: return metar
else:
lines = metar.split("\n")
headings = [
"Relative Humidity",
"Precipitation last hour",
"Sky conditions",
"Temperature",
"Weather",
"Wind"
]
output = []
output.append("Current conditions at " \
+ lines[0].split(", ")[1] + " (" \
+ id.upper() +")")
output.append("Last updated " + lines[1])
for line in lines:
for heading in headings:
if line.startswith(heading + ":"):
output.append(" " + line)
return "\n".join(output)
def get_forecast(city, st, verbose=False):
"""Return the forecast for a specified city/st combination."""
forecast = get_url("http://weather.noaa.gov/pub/data/forecasts/city/" \
+ st.lower() + "/" + city.lower().replace(" ", "_") \
+ ".txt")
if verbose: return forecast
else:
lines = forecast.split("\n")
output = []
output.append(lines[2])
output.append(lines[3])
for line in lines:
if line.startswith("."):
output.append(line.replace(".", " ", 1))
return "\n".join(output)
def get_options():
"""Parse the options passed on the command line."""
import optparse
usage = "usage: %prog [ options ] [ alias [ alias [...] ] ]"
verstring = "%prog " + version
option_parser = optparse.OptionParser(usage=usage, version=verstring)
option_parser.add_option("-c", "--city",
dest="city",
default="Raleigh Durham",
help="the city name (ex: \"Raleigh Durham\")")
option_parser.add_option("-f", "--forecast",
dest="forecast",
action="store_true",
default=False,
help="include forecast (needs -c and -s)")
option_parser.add_option("-i", "--id",
dest="id",
default="KRDU",
help="the METAR station ID (ex: KRDU)")
option_parser.add_option("-l", "--list",
dest="list",
action="store_true",
default=False,
help="print a list of configured aliases")
option_parser.add_option("-n", "--no-conditions",
dest="conditions",
action="store_false",
default=True,
help="disable output of current conditions (implies --forecast)")
option_parser.add_option("-s", "--st",
dest="st",
default="NC",
help="the state abbreviation (ex: NC)")
option_parser.add_option("-v", "--verbose",
dest="verbose",
action="store_true",
default=False,
help="show full decoded feeds")
options, arguments = option_parser.parse_args()
return options, arguments
def get_config():
"""Parse the aliases and configuration."""
import ConfigParser
config = ConfigParser.ConfigParser()
import os.path
rcfiles = [
".weatherrc",
os.path.expanduser("~/.weatherrc"),
"/etc/weatherrc"
]
import os
for rcfile in rcfiles:
if os.access(rcfile, os.R_OK): config.read(rcfile)
for section in config.sections():
if section != section.lower():
if config.has_section(section.lower()):
config.remove_section(section.lower())
config.add_section(section.lower())
for option,value in config.items(section):
config.set(section.lower(), option, value)
return config
def list_aliases(config):
"""Return a formatted list of aliases defined in the config."""
sections = []
for section in config.sections():
if section.lower() not in sections and section != "default":
sections.append(section.lower())
output = "configured aliases..."
for section in sorted(sections):
output += "\n " \
+ section \
+ ": --id=" \
+ quote(config.get(section, "id")) \
+ " --city=" \
+ quote(config.get(section, "city")) \
+ " --st=" \
+ quote(config.get(section, "st"))
return output

15
weatherrc Normal file
View File

@@ -0,0 +1,15 @@
[AVL]
City = Asheville
ID = KAVL
St = NC
[GSO]
City = Greensboro
ID = KGSO
St = NC
[RDU]
City = Raleigh Durham
ID = KRDU
St = NC

72
weatherrc.5 Normal file
View File

@@ -0,0 +1,72 @@
.TH WEATHERRC 5 "March 26, 2006"
.SH NAME
weatherrc \- configuration file format for the
.BR weather (1)
utility
.SH DESCRIPTION
The weatherrc file format is intended to specify a set of macros
by which to group a METAR station ID for current conditions data with a
city/state combination for a forecast, but many of the other
command\-line options/flags for the weather utility can be specified as
well. The file is organized as an INI-format config, with the alias name
in [] brackets and the associated parameter/value pairs on following
lines. Parameters and their values as separated by = or : characters.
Multi-word values do not need quoting.
.SH PARAMETERS
These parameters are supported...
.TP
.B city
the city name (ex: Raleigh Durham)
.TP
.B forecast
include a local forecast (possible values are False and True or 0 and 1)
.TP
.B id
the METAR station ID (ex: KRDU)
.TP
.B conditions
output current conditions (possible values are False and True or 0 and 1)
.TP
.B st
the state abbreviation (ex: NC)
.TP
.B verbose
show full decoded feeds (possible values are False and True or 0 and 1)
.SH EXAMPLES
Following is an example
.B ~/.weatherrc
defining the default settings to be used when running the utility with no
aliases specified, and a couple definitions for aliases named home and
work...
.P
.RS
[default]
.br
City = Asheville
.br
Forecast = True
.br
ID = KAVL
.br
St = NC
.P
[home]
.br
City = Raleigh Durham
.br
ID = KRDU
.br
St = NC
.P
[work]
.br
City = Greensboro
.br
ID = KGSO
.br
St = NC
.RE
.SH SEE ALSO
.BR weather (1)
.SH AUTHOR
Specification and manual written by Jeremy Stanley <fungi@yuggoth.org>.