Imported from archive.
* Initial release 1.0.
This commit is contained in:
39
INSTALL
Normal file
39
INSTALL
Normal 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
22
LICENSE
Normal 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
31
weather
Executable 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
87
weather.1
Normal 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
170
weather.py
Normal 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
15
weatherrc
Normal 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
72
weatherrc.5
Normal 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>.
|
||||
Reference in New Issue
Block a user