* Release 1.1.
* weather: Switched to "#!/usr/bin/env python" instead for
portability.
* weather.1, weather.5, weather.py: Implemented the --omit-forecast
option to cancel --forecast.
* weather.py: Calling with undefined aliases now throws an error and
exits. Aliases, options and default overrides operate more
logically. Upped the version to 1.1.
* weatherrc: Added 214 standard aliases.
--- /dev/null
+FREQUENTLY ASKED QUESTIONS ABOUT THE WEATHER UTILITY
+
+Copyright (c) 2006 Jeremy Stanley <fungi@yuggoth.org>, all rights reserved.
+Licensed per terms in the LICENSE file distributed with this software.
+
+
+1. Can I help?
+
+Sure! Bug reports and feature suggestions are always welcome, but
+fixes and patches are of course preferred. Contact
+fungi@yuggoth.org if desired, but please read this FAQ and the
+included manuals for weather(1) and weatherrc(5) before asking
+questions that might be answered therein. One big way anyone can
+help is to provide me with some additional mappings of METAR
+station ID, city name and state abbreviation for inclusion in the
+default /etc/weatherrc file.
+
+
+2. How do I figure out my local METAR station ID?
+
+The list of stations is found at
+http://weather.noaa.gov/data/nsd_cccc.gz (it's thousands of lines
+long, so I recommend keyword searching in your browser or using
+grep(1) to find what you're looking for).
+
+
+3. How do I figure out my local city name and state abbreviation?
+
+The forecasts can be located starting from
+http://weather.noaa.gov/pub/data/forecasts/city/ (choose the
+state abbreviation to get to a list of cities in that state).
+
+
+4. I live outside the USA--can this be made to work for me
+anyway?
+
+If you have any recommendations for similar forecast data in
+other countries, I will be happy to try and find a way to
+integrate it into the weather utility, but I suspect that some
+serious modification would be necessary given that the data is
+likely to be published in a non-English language, requiring some
+additional input from speakers of that language for how to handle
+filtering and formatting of the text.
+
+
+5. I get a warning when using apt-get to install on Debian Etch
+or later...
+
+If you're getting a warning from apt-get update like:
+
+ W: GPG error: http://fungi.yuggoth.org ./ Release: The
+ following signatures couldn't be verified because the
+ public key is not available: NO_PUBKEY 29ABF7441FB84657
+
+...it means my PGP key is not recognized by apt-get. Since this
+isn't an official Debian package repository, the Release.gpg
+file can't be signed by a key on the default keyring. To add my
+personal key to the list of trusted package repository Release
+signers, run (as root):
+
+ finger fungi@yuggoth.org | apt-key add -
+
+...or if you want to be a little paranoid, retrieve it from a
+public keyserver instead (all one line):
+
+ wget -O- "http://subkeys.pgp.net:11371/pks
+ /lookup?op=get&search=0x29ABF7441FB84657" | apt-key add -
+
+Though if you're really, truly paranoid, you'll re-write the
+program from scratch anyway, right?
+
BASIC UNIX INSTALLATION INSTRUCTIONS FOR THE WEATHER UTILITY
+Copyright (c) 2006 Jeremy Stanley <fungi@yuggoth.org>, all rights reserved.
+Licensed per terms in the LICENSE file distributed with this software.
+
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).
+(most modern UNIX derivatives come with one already). If you need to
+get Python, 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).
+
+
+RUNNING IN PLACE
+
+An easy way to try it out is to unpack the tarball and change to the
+resulting directory:
+
+ tar xzf weather-*.tar.gz
+ cd weather
+ ./weather --version
+ ./weather --help
+ man ./weather.1
+ man ./weatherrc.5
+ ./weather --forecast --no-conditions --city=charlotte --st=nc
+ ./weather ord sea
+
+...and so on. The weather utility, included Python module and
+documentation are all fully functional when kept together in one
+directory, if somewhat inconvenient.
INSTALLING THE UTILITY
--- /dev/null
+GENERAL INFORMATION ABOUT THE WEATHER UTILITY
+
+Copyright (c) 2006 Jeremy Stanley <fungi@yuggoth.org>, all rights reserved.
+Licensed per terms in the LICENSE file distributed with this software.
+
+
+WHAT?
+
+This command-line utility is intended to provide quick access to
+current weather conditions and forecasts. Presently, it is
+capable of returning data for localities throughout the USA by
+retrieving and formatting decoded METARs (Meteorological
+Aerodrome Reports) from NOAA (the National Oceanic and
+Atmospheric Administration) and forecasts from the NWS (National
+Weather Service). The tool is written to function in the same
+spirit as other command-line informational utilities like cal(1),
+calendar(1) and dict(1). It can retrieve arbitrary weather data
+via specific command-line switches (station ID, city, state), or
+aliases can be configured system wide and on a per-user basis. It
+can be freely used and redistributed under the terms of the BSD
+License.
+
+
+WHY?
+
+My girlfriend has a long commute to/from work and school, and
+often wants to check the weather both for home and her office.
+Unfortunately, starting a Web browser, pulling up a weather site,
+entering multiple ZIP codes and waiting for them to load is
+time-consuming for the marginally-impatient. Since she tends to
+stay logged into a shell server most of the time, I figured I'd
+install a quick command-line tool to retrieve weather info for
+her commute, but to my surprise, a quick search turned up little
+that met my basic requirements:
+
+ * retrieve current data on-demand
+ * provide both current conditions and short-term forecasts
+ * simple, human-readable output
+ * easy to configure and use
+ * flexible command-line switches and options
+
+
+WHERE?
+
+A tarball for the most recent version of the weather utility can
+be had here:
+
+ http://fungi.yuggoth.org/weather/src/
+
+Alternatively, Debian users can grab a pre-built DEB package
+here:
+
+ http://fungi.yuggoth.org/weather/debian/
+
+...or add these lines for binary and, optionally, source packages
+to /etc/apt/sources.list:
+
+ deb http://fungi.yuggoth.org/weather/debian ./
+ deb-src http://fungi.yuggoth.org/weather/debian ./
+
+...then 'apt-get update && apt-get install weather-util' as root
+to get the current package installed and working.
+
-#!/usr/bin/python
+#!/usr/bin/env python
+# weather version 1.1, http://fungi.yuggoth.org/weather/
# Copyright (c) 2006 Jeremy Stanley <fungi@yuggoth.org>, all rights reserved.
# Licensed per terms in the LICENSE file distributed with this software.
+"""Wrapper utility using the weather.py module."""
+
import weather
# initialize options and configs
selections = weather.Selections()
get = selections.get
-get_boolean = selections.get_boolean
+get_bool = selections.get_bool
# this mode just lists the aliases defined in the config
-if get_boolean("list"): print weather.list_aliases(selections.config)
+if get_bool("list"): print weather.list_aliases(selections.config)
# normal operation
else:
for argument in selections.arguments:
- if get_boolean("conditions", argument):
+ if get_bool("conditions", argument):
print weather.get_metar(
get("id", argument),
- get_boolean("verbose", argument)
+ get_bool("verbose", argument)
)
- if not get_boolean("conditions", argument) \
- or get_boolean("forecast", argument):
+ if not get_bool("conditions", argument) \
+ or get_bool("forecast", argument):
print weather.get_forecast(
get("city", argument),
get("st", argument),
- get_boolean("verbose", argument)
+ get_bool("verbose", argument)
)
-.TH WEATHER 1 "March 26, 2006"
+.TH WEATHER 1 "March 26, 2006" "" \" -*- nroff -*-
+\" Copyright (c) 2006 Jeremy Stanley <fungi@yuggoth.org>, all rights reserved.
+\" Licensed per terms in the LICENSE file distributed with this software.
.SH NAME
weather \- command\-line tool to obtain weather conditions and forecasts
.SH SYNOPSIS
print a list of configured aliases
.TP
.B \-n, \-\-no\-conditions
-disable output of current conditions (implies \-\-forecast)
+disable output of current conditions (forces \-f)
+.TP
+.B \-o, \-\-omit\-forecast
+omit the local forecast (cancels \-f)
.TP
.B \-sST, \-\-st=ST
the state abbreviation (ex: NC)
.B ~/.weatherrc
the per\-user configuration (can be used to override the above)
.TP
-.B ./.weatherrc
+.B ./weatherrc
the local directory configuration (can be used to override the above)
.SH EXAMPLES
.TP
.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,
+and the forecast data for the city/state associated with the gso alias,
without filtering or fancy formatting.
.TP
.B weather home work
+# weather.py version 1.1, http://fungi.yuggoth.org/weather/
# 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"
+"""Contains various object definitions needed by the weather utility."""
+
+version = "1.1"
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()
+ self.options, self.arguments = get_options(self.config)
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):
+ if not argument: return self.options.__dict__[option]
+ elif not self.config.has_section(argument):
+ import sys
+ sys.stderr.write("ERROR: no alias defined for " \
+ + argument + "\n")
+ sys.exit(1)
+ elif 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):
+ def get_bool(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
+ return bool(self.get(option, argument))
+
+def bool(data):
+ """Coerce data to a boolean value."""
+ 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."""
for line in lines:
for heading in headings:
if line.startswith(heading + ":"):
+ if line.endswith(":0"):
+ line = line[:-2]
output.append(" " + line)
return "\n".join(output)
output.append(line.replace(".", " ", 1))
return "\n".join(output)
-def get_options():
+def get_options(config):
"""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)
+ if config.has_option("default", "city"):
+ default_city = config.get("default", "city")
+ else: default_city = "Raleigh Durham"
option_parser.add_option("-c", "--city",
dest="city",
- default="Raleigh Durham",
+ default=default_city,
help="the city name (ex: \"Raleigh Durham\")")
+ if config.has_option("default", "forecast"):
+ default_forecast = bool(config.get("default", "forecast"))
+ else: default_forecast = False
option_parser.add_option("-f", "--forecast",
dest="forecast",
action="store_true",
- default=False,
- help="include forecast (needs -c and -s)")
+ default=default_forecast,
+ help="include a local forecast")
+ if config.has_option("default", "id"):
+ default_id = config.get("default", "id")
+ else: default_id = "KRDU"
option_parser.add_option("-i", "--id",
dest="id",
- default="KRDU",
+ default=default_id,
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")
+ if config.has_option("default", "conditions"):
+ default_conditions = bool(config.get("default", "conditions"))
+ else: default_conditions = True
option_parser.add_option("-n", "--no-conditions",
dest="conditions",
action="store_false",
- default=True,
- help="disable output of current conditions (implies --forecast)")
+ default=default_conditions,
+ help="disable output of current conditions (forces -f)")
+ option_parser.add_option("-o", "--omit-forecast",
+ dest="forecast",
+ action="store_false",
+ default=default_forecast,
+ help="omit the local forecast (cancels -f)")
+ if config.has_option("default", "st"):
+ default_st = config.get("default", "st")
+ else: default_st = "NC"
option_parser.add_option("-s", "--st",
dest="st",
- default="NC",
+ default=default_st,
help="the state abbreviation (ex: NC)")
+ if config.has_option("default", "verbose"):
+ default_verbose = bool(config.get("default", "verbose"))
+ else: default_verbose = False
option_parser.add_option("-v", "--verbose",
dest="verbose",
action="store_true",
- default=False,
+ default=default_verbose,
help="show full decoded feeds")
options, arguments = option_parser.parse_args()
return options, arguments
config = ConfigParser.ConfigParser()
import os.path
rcfiles = [
- ".weatherrc",
+ "/etc/weatherrc",
os.path.expanduser("~/.weatherrc"),
- "/etc/weatherrc"
+ "weatherrc"
]
import os
for rcfile in rcfiles:
def list_aliases(config):
"""Return a formatted list of aliases defined in the config."""
sections = []
- for section in config.sections():
+ for section in sorted(config.sections()):
if section.lower() not in sections and section != "default":
sections.append(section.lower())
output = "configured aliases..."
+[ABE]
+City = Allentown
+ID = KABE
+St = PA
+
+[ABI]
+City = Abilene
+ID = KABI
+St = TX
+
+[ABQ]
+City = Albuquerque
+ID = KABQ
+St = NM
+
+[ABR]
+City = Aberdeen
+ID = KABR
+St = SD
+
+[ABY]
+City = Albany
+ID = KABY
+St = GA
+
+[ACT]
+City = Waco
+ID = KACT
+St = TX
+
+[ACY]
+City = Atlantic City
+ID = KACY
+St = NJ
+
+[AED]
+City = Anchorage
+ID = PAED
+St = AK
+
+[AEI]
+City = Fairbanks
+ID = PAEI
+St = AK
+
+[AFA]
+City = Fairbanks
+ID = PAFA
+St = AK
+
+[AGS]
+City = Augusta
+ID = KAGS
+St = GA
+
+[AHN]
+City = Athens
+ID = KAHN
+St = GA
+
+[AJN]
+City = Juneau
+ID = PAJN
+St = AK
+
+[AKT]
+City = Ketchikan
+ID = PAKT
+St = AK
+
+[ALB]
+City = Albany
+ID = KALB
+St = NY
+
+[ALO]
+City = Waterloo
+ID = KALO
+St = IA
+
+[ALS]
+City = Alamosa
+ID = KALS
+St = CO
+
+[AMA]
+City = Amarillo
+ID = KAMA
+St = TX
+
+[ANC]
+City = Anchorage
+ID = PANC
+St = AK
+
+[AOM]
+City = Nome
+ID = PAOM
+St = AK
+
+[APN]
+City = Alpena
+ID = KAPN
+St = MI
+
+[ASI]
+City = Sitka
+ID = PASI
+St = AK
+
+[AST]
+City = Astoria
+ID = KAST
+St = OR
+
+[ATL]
+City = Atlanta
+ID = KATL
+St = GA
+
[AVL]
City = Asheville
ID = KAVL
St = NC
+[AYA]
+City = Yakutat
+ID = PAYA
+St = AK
+
+[BDL]
+City = Windsor Locks
+ID = KBDL
+St = CT
+
+[BDR]
+City = Bridgeport
+ID = KBDR
+St = CT
+
+[BFF]
+City = Scottsbluff
+ID = KBFF
+St = NE
+
+[BFL]
+City = Bakersfield
+ID = KBFL
+St = CA
+
+[BGM]
+City = Binghamton
+ID = KBGM
+St = NY
+
+[BHM]
+City = Birmingham
+ID = KBHM
+St = AL
+
+[BIH]
+City = Bishop
+ID = KBIH
+St = CA
+
+[BIL]
+City = Billings
+ID = KBIL
+St = MT
+
+[BIS]
+City = Bismarck
+ID = KBIS
+St = ND
+
+[BJI]
+City = Bemidji
+ID = KBJI
+St = MN
+
+[BJN]
+City = Las Vegas
+ID = KBJN
+St = NV
+
+[BKW]
+City = Beckley
+ID = KBKW
+St = WV
+
+[BML]
+City = Berlin
+ID = KBML
+St = NH
+
+[BNA]
+City = Nashville
+ID = KBNA
+St = TN
+
+[BNO]
+City = Burns
+ID = KBNO
+St = OR
+
+[BOI]
+City = Boise
+ID = KBOI
+St = ID
+
+[BOS]
+City = Boston
+ID = KBOS
+St = MA
+
+[BRO]
+City = Brownsville
+ID = KBRO
+St = TX
+
+[BTV]
+City = Burlington
+ID = KBTV
+St = VT
+
+[BUF]
+City = Buffalo
+ID = KBUF
+St = NY
+
+[CAE]
+City = Columbia
+ID = KCAE
+St = SC
+
+[CAK]
+City = Akron
+ID = KCAK
+St = OH
+
+[CAR]
+City = Caribou
+ID = KCAR
+St = ME
+
+[CHA]
+City = Chattanooga
+ID = KCHA
+St = TN
+
+[CHS]
+City = Charleston
+ID = KCHS
+St = SC
+
+[CLE]
+City = Cleveland
+ID = KCLE
+St = OH
+
+[CLT]
+City = Charlotte
+ID = KCLT
+St = NC
+
+[CMH]
+City = Columbus
+ID = KCMH
+St = OH
+
+[CMX]
+City = Hancock
+ID = KCMX
+St = MI
+
+[CNK]
+City = Concordia
+ID = KCNK
+St = KS
+
+[COD]
+City = Cody
+ID = KCOD
+St = WY
+
+[CON]
+City = Concord
+ID = KCON
+St = NH
+
+[COS]
+City = Colorado Springs
+ID = KCOS
+St = CO
+
+[COU]
+City = Columbia
+ID = KCOU
+St = MO
+
+[CPR]
+City = Casper
+ID = KCPR
+St = WY
+
+[CRP]
+City = Corpus Christi
+ID = KCRP
+St = TX
+
+[CRW]
+City = Charleston
+ID = KCRW
+St = WV
+
+[CTY]
+City = Cross City
+ID = KCTY
+St = FL
+
+[CYS]
+City = Cheyenne
+ID = KCYS
+St = WY
+
+[DAY]
+City = Dayton
+ID = KDAY
+St = OH
+
+[DBQ]
+City = Dubuque
+ID = KDBQ
+St = IA
+
+[DDC]
+City = Dodge City
+ID = KDDC
+St = KS
+
+[DEN]
+City = Denver
+ID = KDEN
+St = CO
+
+[DGW]
+City = Douglas
+ID = KDGW
+St = WY
+
+[DLH]
+City = Duluth
+ID = KDLH
+St = MN
+
+[DRT]
+City = Del Rio
+ID = KDRT
+St = TX
+
+[DSM]
+City = Des Moines
+ID = KDSM
+St = IA
+
+[DTW]
+City = Detroit
+ID = KDTW
+St = MI
+
+[EKN]
+City = Elkins
+ID = KEKN
+St = WV
+
+[ELP]
+City = El Paso
+ID = KELP
+St = TX
+
+[ELY]
+City = Ely
+ID = KELY
+St = NV
+
+[ERI]
+City = Erie
+ID = KERI
+St = PA
+
+[ESC]
+City = Escanaba
+ID = KESC
+St = MI
+
+[EUG]
+City = Eugene
+ID = KEUG
+St = OR
+
+[EVV]
+City = Evansville
+ID = KEVV
+St = IN
+
+[EWR]
+City = Newark
+ID = KEWR
+St = NJ
+
+[EYW]
+City = Key West
+ID = KEYW
+St = FL
+
+[FAR]
+City = Fargo
+ID = KFAR
+St = ND
+
+[FAT]
+City = Fresno
+ID = KFAT
+St = CA
+
+[FNT]
+City = Flint
+ID = KFNT
+St = MI
+
+[FOD]
+City = Fort Dodge
+ID = KFOD
+St = IA
+
+[FSD]
+City = Sioux Falls
+ID = KFSD
+St = SD
+
+[FSM]
+City = Fort Smith
+ID = KFSM
+St = AR
+
+[FWA]
+City = Fort Wayne
+ID = KFWA
+St = IN
+
+[GCC]
+City = Gillette
+ID = KGCC
+St = WY
+
+[GEG]
+City = Spokane
+ID = KGEG
+St = WA
+
+[GGG]
+City = Longview
+ID = KGGG
+St = TX
+
+[GJT]
+City = Grand Junction
+ID = KGJT
+St = CO
+
+[GLD]
+City = Goodland
+ID = KGLD
+St = KS
+
+[GLS]
+City = Galveston
+ID = KGLS
+St = TX
+
+[GPI]
+City = Kalispell
+ID = KGPI
+St = MT
+
+[GRB]
+City = Green Bay
+ID = KGRB
+St = WI
+
+[GRI]
+City = Grand Island
+ID = KGRI
+St = NE
+
+[GRR]
+City = Grand Rapids
+ID = KGRR
+St = MI
+
[GSO]
City = Greensboro
ID = KGSO
St = NC
+[GTF]
+City = Great Falls
+ID = KGTF
+St = MT
+
+[HLN]
+City = Helena
+ID = KHLN
+St = MT
+
+[HNL]
+City = Honolulu
+ID = PHNL
+St = HI
+
+[HON]
+City = Huron
+ID = KHON
+St = SD
+
+[HSV]
+City = Huntsville
+ID = KHSV
+St = AL
+
+[HTS]
+City = Huntington
+ID = KHTS
+St = WV
+
+[HVR]
+City = Havre
+ID = KHVR
+St = MT
+
+[IAH]
+City = Houston
+ID = KIAH
+St = TX
+
+[ICT]
+City = Wichita
+ID = KICT
+St = KS
+
+[IGM]
+City = Kingman
+ID = KIGM
+St = AZ
+
+[IND]
+City = Indianapolis
+ID = KIND
+St = IN
+
+[INL]
+City = International Falls
+ID = KINL
+St = MN
+
+[INW]
+City = Winslow
+ID = KINW
+St = AZ
+
+[IPT]
+City = Williamsport
+ID = KIPT
+St = PA
+
+[ISN]
+City = Williston
+ID = KISN
+St = ND
+
+[JAN]
+City = Jackson
+ID = KJAN
+St = MS
+
+[JAX]
+City = Jacksonville
+ID = KJAX
+St = FL
+
+[JCT]
+City = Junction
+ID = KJCT
+St = TX
+
+[JFK]
+City = New York
+ID = KJFK
+St = NY
+
+[LAN]
+City = Lansing
+ID = KLAN
+St = MI
+
+[LAS]
+City = Las Vegas
+ID = KLAS
+St = NV
+
+[LBB]
+City = Lubbock
+ID = KLBB
+St = TX
+
+[LBF]
+City = North Platte
+ID = KLBF
+St = NE
+
+[LCH]
+City = Lake Charles
+ID = KLCH
+St = LA
+
+[LEX]
+City = Lexington
+ID = KLEX
+St = KY
+
+[LGA]
+City = New York
+ID = KLGA
+St = NY
+
+[LND]
+City = Lander
+ID = KLND
+St = WY
+
+[LNK]
+City = Lincoln
+ID = KLNK
+St = NE
+
+[LRD]
+City = Laredo
+ID = KLRD
+St = TX
+
+[LSE]
+City = La Crosse
+ID = KLSE
+St = WI
+
+[LYH]
+City = Lynchburg
+ID = KLYH
+St = VA
+
+[MAF]
+City = Midland
+ID = KMAF
+St = TX
+
+[MCI]
+City = Kansas City
+ID = KMCI
+St = MO
+
+[MCN]
+City = Macon
+ID = KMCN
+St = GA
+
+[MCO]
+City = Orlando
+ID = KMCO
+St = FL
+
+[MDW]
+City = Chicago
+ID = KMDW
+St = IL
+
+[MEI]
+City = Meridian
+ID = KMEI
+St = MS
+
+[MEM]
+City = Memphis
+ID = KMEM
+St = TN
+
+[MFR]
+City = Medford
+ID = KMFR
+St = OR
+
+[MGM]
+City = Montgomery
+ID = KMGM
+St = AL
+
+[MIA]
+City = Miami
+ID = KMIA
+St = FL
+
+[MKE]
+City = Milwaukee
+ID = KMKE
+St = WI
+
+[MKG]
+City = Muskegon
+ID = KMKG
+St = MI
+
+[MLB]
+City = Melbourne
+ID = KMLB
+St = FL
+
+[MLI]
+City = Moline
+ID = KMLI
+St = IL
+
+[MLS]
+City = Miles City
+ID = KMLS
+St = MT
+
+[MOB]
+City = Mobile
+ID = KMOB
+St = AL
+
+[MQT]
+City = Marquette
+ID = KMQT
+St = MI
+
+[MRF]
+City = Marfa
+ID = KMRF
+St = TX
+
+[MSN]
+City = Madison
+ID = KMSN
+St = WI
+
+[MSO]
+City = Missoula
+ID = KMSO
+St = MT
+
+[MSP]
+City = Minneapolis
+ID = KMSP
+St = MN
+
+[MSY]
+City = New Orleans
+ID = KMSY
+St = LA
+
+[NKX]
+City = San Diego
+ID = KNKX
+St = CA
+
+[OKC]
+City = Oklahoma City
+ID = KOKC
+St = OK
+
+[OMA]
+City = Omaha
+ID = KOMA
+St = NE
+
+[ORD]
+City = Chicago
+ID = KORD
+St = IL
+
+[PAH]
+City = Paducah
+ID = KPAH
+St = KY
+
+[PBI]
+City = West Palm Beach
+ID = KPBI
+St = FL
+
+[PDT]
+City = Pendleton
+ID = KPDT
+St = OR
+
+[PDX]
+City = Portland
+ID = KPDX
+St = OR
+
+[PGA]
+City = Page
+ID = KPGA
+St = AZ
+
+[PHL]
+City = Philadelphia
+ID = KPHL
+St = PA
+
+[PHX]
+City = Phoenix
+ID = KPHX
+St = AZ
+
+[PIA]
+City = Peoria
+ID = KPIA
+St = IL
+
+[PIH]
+City = Pocatello
+ID = KPIH
+St = ID
+
+[PIT]
+City = Pittsburgh
+ID = KPIT
+St = PA
+
+[PQI]
+City = Presque Isle
+ID = KPQI
+St = ME
+
+[PUB]
+City = Pueblo
+ID = KPUB
+St = CO
+
+[PVD]
+City = Providence
+ID = KPVD
+St = RI
+
+[PWM]
+City = Portland
+ID = KPWM
+St = ME
+
+[RAP]
+City = Rapid City
+ID = KRAP
+St = SD
+
+[RBL]
+City = Red Bluff
+ID = KRBL
+St = CA
+
[RDU]
City = Raleigh Durham
ID = KRDU
St = NC
+[RFD]
+City = Rockford
+ID = KRFD
+St = IL
+
+[RIC]
+City = Richmond
+ID = KRIC
+St = VA
+
+[RIW]
+City = Riverton
+ID = KRIW
+St = WY
+
+[RKS]
+City = Rock Springs
+ID = KRKS
+St = WY
+
+[RMG]
+City = Rome
+ID = KRMG
+St = GA
+
+[RNO]
+City = Reno
+ID = KRNO
+St = NV
+
+[ROC]
+City = Rochester
+ID = KROC
+St = NY
+
+[RST]
+City = Rochester
+ID = KRST
+St = MN
+
+[RUE]
+City = Russellville
+ID = KRUE
+St = AR
+
+[SAC]
+City = Sacramento
+ID = KSAC
+St = CA
+
+[SAN]
+City = San Diego
+ID = KSAN
+St = CA
+
+[SAT]
+City = San Antonio
+ID = KSAT
+St = TX
+
+[SAV]
+City = Savannah
+ID = KSAV
+St = GA
+
+[SBN]
+City = South Bend
+ID = KSBN
+St = IN
+
+[SDF]
+City = Louisville
+ID = KSDF
+St = KY
+
+[SEA]
+City = Seattle
+ID = KSEA
+St = WA
+
+[SFO]
+City = San Francisco
+ID = KSFO
+St = CA
+
+[SGF]
+City = Springfield
+ID = KSGF
+St = MO
+
+[SHR]
+City = Sheridan
+ID = KSHR
+St = WY
+
+[SHV]
+City = Shreveport
+ID = KSHV
+St = LA
+
+[SJT]
+City = San Angelo
+ID = KSJT
+St = TX
+
+[SLC]
+City = Salt Lake City
+ID = KSLC
+St = UT
+
+[SLE]
+City = Salem
+ID = KSLE
+St = OR
+
+[SLO]
+City = Salem
+ID = KSLO
+St = IL
+
+[SNY]
+City = Sidney
+ID = KSNY
+St = NE
+
+[SPS]
+City = Wichita Falls
+ID = KSPS
+St = TX
+
+[SUX]
+City = Sioux City
+ID = KSUX
+St = IA
+
+[SYR]
+City = Syracuse
+ID = KSYR
+St = NY
+
+[TLH]
+City = Tallahassee
+ID = KTLH
+St = FL
+
+[TOL]
+City = Toledo
+ID = KTOL
+St = OH
+
+[TOP]
+City = Topeka
+ID = KTOP
+St = KS
+
+[TPA]
+City = Tampa
+ID = KTPA
+St = FL
+
+[TUL]
+City = Tulsa
+ID = KTUL
+St = OK
+
+[TUP]
+City = Tupelo
+ID = KTUP
+St = MS
+
+[TUS]
+City = Tucson
+ID = KTUS
+St = AZ
+
+[TYS]
+City = Knoxville
+ID = KTYS
+St = TN
+
+[VCT]
+City = Victoria
+ID = KVCT
+St = TX
+
+[VTN]
+City = Valentine
+ID = KVTN
+St = NE
+
+[WMC]
+City = Winnemucca
+ID = KWMC
+St = NV
+
+[WWR]
+City = Woodward
+ID = KWWR
+St = OK
+
+[YKM]
+City = Yakima
+ID = KYKM
+St = WA
+
+[YNG]
+City = Youngstown
+ID = KYNG
+St = OH
+
-.TH WEATHERRC 5 "March 26, 2006"
+.TH WEATHERRC 5 "March 26, 2006" "" \" -*- nroff -*-
+\" Copyright (c) 2006 Jeremy Stanley <fungi@yuggoth.org>, all rights reserved.
+\" Licensed per terms in the LICENSE file distributed with this software.
.SH NAME
weatherrc \- configuration file format for the
.BR weather (1)
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
+command\-line options and 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