Mercurial > pycweather
changeset 3:a754b01955c7
1st stage of work for final 0.2.0
| author | Vlad Glagolev <enqlave@gmail.com> |
|---|---|
| date | Mon, 27 Jul 2009 00:02:10 +0400 |
| parents | bf34534a0acd |
| children | fd9d81f66ff7 |
| files | ChangeLog LICENSE pycweather/__init__.py pycweather/dmanager.py pycweather/template.py pycweather/weather.py setup.py share/template.xsl |
| diffstat | 8 files changed, 223 insertions(+), 169 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Thu Nov 06 23:02:41 2008 +0300 +++ b/ChangeLog Mon Jul 27 00:02:10 2009 +0400 @@ -1,3 +1,9 @@ +2009-07-26 Vlad Glagolev <enqlave@gmail.com> + * version 0.2.0 + * fixed max-day limit to 5 as supported by weather.com + * added missing parameters in request (needed since 2009-07-07) + * rewritten the engine in OOP + 2008-11-06 Vlad Glagolev <enqlave@gmail.com> * bump to 0.1.2 * removed useless installation of text files for now
--- a/LICENSE Thu Nov 06 23:02:41 2008 +0300 +++ b/LICENSE Mon Jul 27 00:02:10 2009 +0400 @@ -1,4 +1,5 @@ -Copyright (c) 2008 Vlad Glagolev <enqlave@gmail.com>. All rights reserved. +Copyright (c) 2008-2009 Vlad Glagolev <enqlave@gmail.com> +All rights reserved. Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above
--- a/pycweather/__init__.py Thu Nov 06 23:02:41 2008 +0300 +++ b/pycweather/__init__.py Mon Jul 27 00:02:10 2009 +0400 @@ -2,7 +2,8 @@ # # This file is part of PycWeather # -# Copyright (c) 2008 Vlad Glagolev <enqlave@gmail.com>. All rights reserved. +# Copyright (c) 2008-2009 Vlad Glagolev <enqlave@gmail.com> +# All rights reserved. # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -18,4 +19,4 @@ """ pycweather/__init__.py: initialization script """ -__version__ = "0.1.2" +__version__ = "0.2.0"
--- a/pycweather/dmanager.py Thu Nov 06 23:02:41 2008 +0300 +++ b/pycweather/dmanager.py Mon Jul 27 00:02:10 2009 +0400 @@ -2,7 +2,8 @@ # # This file is part of PycWeather # -# Copyright (c) 2008 Vlad Glagolev <enqlave@gmail.com>. All rights reserved. +# Copyright (c) 2008-2009 Vlad Glagolev <enqlave@gmail.com> +# All rights reserved. # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -18,38 +19,33 @@ """ pycweather/dmanager.py: weather display manager """ -from cStringIO import StringIO import getopt import os import sys -import urllib2 - -from lxml.etree import parse, tostring, fromstring, XMLSyntaxError from pycweather import __version__ -from pycweather.template import XSL +from pycweather import weather -# correct url to the XOAP service -XOAP_URL = "http://xoap.weather.com/" - -# default values stay for Moscow (RU) location, 0 days to display (means only +# default values stay for Moscow (RU) location, 1 days to display (means only # current day), metric measurement system and internal XSL stylesheet usage _CODE = "RSXX0063" _DAYS = 1 _UNIT = "m" -_XSL = None + +# TODO: default XSL template +_TEMPLATE = os.path.join(os.path.dirname(__file__), "template.xsl") def usage(): print """Usage: %s [options]\n -h, --help show this help -v, --version version information + -a, --auth <id:key> authority data in format: partner-id:license-key -c, --code <code> location ID code (default is %s) - -d, --days <days> number of days to display [1-10] (default is %d) + -d, --days <days> number of days to display [1-5] (default is %d) -u, --unit <unit> measurement system [m]etric|[i]mperial (default is %s) -s, --search <word> search for the specified location (city, state, etc.) - -i, --int dump internal XSL stylesheet to stdout -x, --xsl <file> custom XSL file\n""" % (sys.argv[0], _CODE, _DAYS, _UNIT) @@ -61,59 +57,26 @@ exit(0) -def search(location): - data = urllib2.urlopen(XOAP_URL + "search/search?where=%s" % location) - - tree = data.read() - - try: - xml = fromstring(tree) - except XMLSyntaxError: - print "XML syntax error occured while parsing content: ", tree - exit(2) - - if not xml.getchildren(): - print "No location has been found!" - elif xml.tag == "error": - print "Error: %s" % xml.getchildren()[0].text - else: - print "Code | Location\n--------+----------" - for loc in xml.xpath("loc"): - print loc.get("id") + ": " + loc.text - - print "--\nTo catch weather information use: %s -c <code>" % sys.argv[0] - - exit(0) - - -def preview(xml, xsl): - try: - xsl_file = parse(xsl) if xsl else fromstring(XSL) - except XMLSyntaxError: - print "XML syntax error occured while parsing XSL stylesheet" - exit(2) - - document = parse(StringIO(tostring(xml))) - - print document.xslt(xsl_file) - - def main(): try: - opts, args = getopt.getopt(sys.argv[1:], "hvc:d:u:s:ix:", ["help", \ - "version", "code=", "days=", "unit=", \ - "search=", "int", "xsl="]) + opts, args = getopt.getopt(sys.argv[1:], "hva:c:d:u:s:x:", ["help", \ + "version", "auth=", "code=", "days=", \ + "unit=", "search=", "xsl="]) except getopt.error, msg: print msg usage() exit(2) + forecast = weather.Weather() + for o, a in opts: if o in ("-h", "--help"): usage() exit(0) elif o in ("-v", "--version"): version() + elif o in ("-a", "--auth"): + forecast.auth(a) elif o in ("-c", "--code"): code = a elif o in ("-d", "--days"): @@ -121,9 +84,7 @@ elif o in ("-u", "--unit"): unit = a elif o in ("-s", "--search"): - search(a) - elif o in ("-i", "--int"): - print XSL + forecast.search(a) exit(0) elif o in ("-x", "--xsl"): xsl = a @@ -145,30 +106,12 @@ try: xsl + except NameError: + xsl = _TEMPLATE - if not os.access(xsl, os.R_OK): - print "Error reading custom XSL file, using internal stylesheet..." - xsl = _XSL - except NameError: - xsl = _XSL + forecast.load(xsl) - try: - data = urllib2.urlopen(XOAP_URL + \ - "weather/local/%s?cc=*&dayf=%d&unit=%s" % (code, - days, unit)) - except: - print "Unable to connect to %s" % XOAP_URL - exit(2) - - tree = data.read() - - try: - xml = fromstring(tree) - except XMLSyntaxError: - print "XML syntax error occured while parsing content: ", tree - exit(2) - - if xml.tag == "error": - print "Error: %s" % xml.xpath("err")[0].text + if forecast.id and forecast.key: + forecast.preview(code, days, unit) else: - preview(xml, xsl) + print "Look at http://registration.weather.com/ursa/xmloap/step1"
--- a/pycweather/template.py Thu Nov 06 23:02:41 2008 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +0,0 @@ -# -*- coding: utf-8 -*- -# -# This file is part of PycWeather -# -# Copyright (c) 2008 Vlad Glagolev <enqlave@gmail.com>. All rights reserved. -# -# Permission to use, copy, modify, and distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -""" pycweather/template.py: XSL stylesheet for displaying weather """ - -from pycweather import __version__ - - -XSL = """<xsl:stylesheet xmlns="http://www.w3.org/1999/xhtml" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> - <xsl:output method="text" disable-output-escaping="yes"/> - <xsl:variable name="nl"> - <xsl:text> </xsl:text> - </xsl:variable> - <xsl:template match="weather"> - <xsl:apply-templates select="cc"/> - <xsl:apply-templates select="dayf"/> - <xsl:comment>PycWeather %s</xsl:comment> - </xsl:template> - <xsl:template match="cc"> - <xsl:text>Location: </xsl:text><xsl:value-of select="obst"/><xsl:text> (</xsl:text><xsl:value-of select="../loc/lat"/><xsl:text>, </xsl:text><xsl:value-of select="../loc/lon"/><xsl:text>)</xsl:text><xsl:value-of select="$nl"/> - <xsl:text>Temperature: </xsl:text><xsl:value-of select="tmp"/>°<xsl:value-of select="../head/ut"/><xsl:value-of select="$nl"/> - <xsl:if test="tmp != flik"> - <xsl:text>Windchill: </xsl:text><xsl:value-of select="flik"/>°<xsl:value-of select="../head/ut"/><xsl:value-of select="$nl"/> - </xsl:if> - <xsl:text>Conditions: </xsl:text><xsl:value-of select="t"/><xsl:value-of select="$nl"/> - <xsl:text>Wind: </xsl:text> - <xsl:choose> - <xsl:when test="wind/s = 'calm'"> - <xsl:text>0</xsl:text> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="wind/s"/> - </xsl:otherwise> - </xsl:choose> - <xsl:value-of select="../head/us"/> - <xsl:text> (</xsl:text><xsl:value-of select="wind/t"/><xsl:text>)</xsl:text> - </xsl:template> - <!-- MULTIPLE DAYS DISPLAY --> - <xsl:template match="dayf"> - <!-- don't repeat the first one --> - <xsl:apply-templates select="child::day[position() > 1]"/> - </xsl:template> - <xsl:template match="day"> - <xsl:value-of select="$nl"/> - <xsl:value-of select="@dt"/><xsl:text>, </xsl:text><xsl:value-of select="@t"/> - <xsl:if test="@d = 1"> - <xsl:text> (Tomorrow)</xsl:text> - </xsl:if> - <xsl:text>: </xsl:text> - <xsl:apply-templates select="part"/> - </xsl:template> - <xsl:template match="part"> - <xsl:choose> - <xsl:when test="@p = 'd'"> - <xsl:text>Day (</xsl:text> - <xsl:value-of select="../hi"/>°<xsl:value-of select="../../../head/ut"/> - </xsl:when> - <xsl:otherwise> - <xsl:text>Night (</xsl:text> - <xsl:value-of select="../low"/>°<xsl:value-of select="../../../head/ut"/> - </xsl:otherwise> - </xsl:choose> - <xsl:text>, </xsl:text> - <xsl:apply-templates select="t"/> - <xsl:text>)</xsl:text> - <xsl:if test="@p = 'd'"> - <xsl:text>; </xsl:text> - </xsl:if> - </xsl:template> -</xsl:stylesheet>""" % __version__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pycweather/weather.py Mon Jul 27 00:02:10 2009 +0400 @@ -0,0 +1,104 @@ +# -*- coding: utf-8 -*- +# +# This file is part of PycWeather +# +# Copyright (c) 2009 Vlad Glagolev <enqlave@gmail.com> +# All rights reserved. +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +""" pycweather/weather.py: Weather class """ + +from cStringIO import StringIO +from urllib2 import urlopen + +from lxml.etree import parse, tostring, fromstring, XMLSyntaxError + +from pycweather import __version__ + + +# correct url to the XOAP service +XOAP_URL = "http://xoap.weather.com/" + + +class Weather: + + def __init__(self): + self.xsl = None + self.id = None + self.key = None + + def auth(self, credentials): + try: + self.id, self.key = credentials.split(":") + except: + print "Invalid credentials" + + def search(self, location): + data = urlopen(XOAP_URL + "search/search?where=%s" % location) + + tree = data.read() + + try: + xml = fromstring(tree) + except XMLSyntaxError: + print "XML syntax error occured while parsing content: ", tree + + return -1 + + if not xml.getchildren(): + print "No location has been found!" + elif xml.tag == "error": + print "Error: %s" % xml.getchildren()[0].text + else: + print "Code | Location\n--------+----------" + for loc in xml.xpath("loc"): + print loc.get("id") + ": " + loc.text + + print "--\nTo catch weather information use: pycweather -c <code>" + + def load(self, xsl_file): + try: + self.xsl = parse(xsl_file) + except XMLSyntaxError: + print "XML syntax error occured while parsing XSL stylesheet" + except: + print "Unable to read XSL file" + + def preview(self, code, days, unit): + try: + data = urlopen(XOAP_URL + \ + "weather/local/%s?cc=*&dayf=%d&unit=%s&par=%s&key=%s" % \ + (code, days, unit, self.id, self.key)) + except: + print "Unable to connect to %s" % XOAP_URL + + return -1 + + tree = data.read() + + try: + xml = fromstring(tree) + except XMLSyntaxError: + print "XML syntax error occured while parsing content: ", tree + + return -1 + + if xml.tag == "error": + print "Error: %s" % xml.xpath("err")[0].text + + return -1 + else: + document = parse(StringIO(tostring(xml))) + + print document.xslt(self.xsl)
--- a/setup.py Thu Nov 06 23:02:41 2008 +0300 +++ b/setup.py Mon Jul 27 00:02:10 2009 +0400 @@ -3,7 +3,8 @@ # # This file is part of PycWeather # -# Copyright (c) 2008 Vlad Glagolev <enqlave@gmail.com>. All rights reserved. +# Copyright (c) 2008-2009 Vlad Glagolev <enqlave@gmail.com> +# All rights reserved. # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -32,6 +33,7 @@ author_email = "enqlave@gmail.com", packages = ["pycweather"], scripts = ["bin/pycweather"], + data_files = [('share/pycweather', ["share/template.xsl"])], description = "Weather display manager for conky", platforms = ["Linux", "Unix"], long_description = "PycWeather is pure-pythonic weather display manager \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/template.xsl Mon Jul 27 00:02:10 2009 +0400 @@ -0,0 +1,82 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- pycweather/template.xsl: XSL stylesheet for displaying weather + +This file is part of PycWeather + +Copyright (c) 2009 Vlad Glagolev <enqlave@gmail.com>. All rights reserved. + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +--> +<xsl:stylesheet xmlns="http://www.w3.org/1999/xhtml" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> + <xsl:output method="text" disable-output-escaping="yes"/> + <xsl:variable name="nl"> + <xsl:text> </xsl:text> + </xsl:variable> + <xsl:template match="weather"> + <xsl:apply-templates select="cc"/> + <xsl:apply-templates select="dayf"/> + <xsl:comment>PycWeather</xsl:comment> + </xsl:template> + <xsl:template match="cc"> + <xsl:text>Location: </xsl:text><xsl:value-of select="obst"/><xsl:text> (</xsl:text><xsl:value-of select="../loc/lat"/><xsl:text>, </xsl:text><xsl:value-of select="../loc/lon"/><xsl:text>)</xsl:text><xsl:value-of select="$nl"/> + <xsl:text>Temperature: </xsl:text><xsl:value-of select="tmp"/>°<xsl:value-of select="../head/ut"/><xsl:value-of select="$nl"/> + <xsl:if test="tmp != flik"> + <xsl:text>Windchill: </xsl:text><xsl:value-of select="flik"/>°<xsl:value-of select="../head/ut"/><xsl:value-of select="$nl"/> + </xsl:if> + <xsl:text>Conditions: </xsl:text><xsl:value-of select="t"/><xsl:value-of select="$nl"/> + <xsl:text>Wind: </xsl:text> + <xsl:choose> + <xsl:when test="wind/s = 'calm'"> + <xsl:text>0</xsl:text> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="wind/s"/> + </xsl:otherwise> + </xsl:choose> + <xsl:value-of select="../head/us"/> + <xsl:text> (</xsl:text><xsl:value-of select="wind/t"/><xsl:text>)</xsl:text> + </xsl:template> + <!-- MULTIPLE DAYS DISPLAY --> + <xsl:template match="dayf"> + <!-- don't repeat the first one --> + <xsl:apply-templates select="child::day[position() > 1]"/> + </xsl:template> + <xsl:template match="day"> + <xsl:value-of select="$nl"/> + <xsl:value-of select="@dt"/><xsl:text>, </xsl:text><xsl:value-of select="@t"/> + <xsl:if test="@d = 1"> + <xsl:text> (Tomorrow)</xsl:text> + </xsl:if> + <xsl:text>: </xsl:text> + <xsl:apply-templates select="part"/> + </xsl:template> + <xsl:template match="part"> + <xsl:choose> + <xsl:when test="@p = 'd'"> + <xsl:text>Day (</xsl:text> + <xsl:value-of select="../hi"/>°<xsl:value-of select="../../../head/ut"/> + </xsl:when> + <xsl:otherwise> + <xsl:text>Night (</xsl:text> + <xsl:value-of select="../low"/>°<xsl:value-of select="../../../head/ut"/> + </xsl:otherwise> + </xsl:choose> + <xsl:text>, </xsl:text> + <xsl:apply-templates select="t"/> + <xsl:text>)</xsl:text> + <xsl:if test="@p = 'd'"> + <xsl:text>; </xsl:text> + </xsl:if> + </xsl:template> +</xsl:stylesheet>
