Source code for pyowm.weatherapi25.forecast
"""
Module containing weather forecast classes and data structures.
"""
import json
import xml.etree.ElementTree as ET
from pyowm.weatherapi25.xsd.xmlnsconfig import (
FORECAST_XMLNS_PREFIX, FORECAST_XMLNS_URL)
from pyowm.utils import timeutils, timeformatutils, xmlutils
[docs]class ForecastIterator(object):
"""
Iterator over the list of *Weather* objects encapsulated in a *Forecast*
class instance
:param obj: the iterable object
:type obj: object
:returns: a *ForecastIterator* instance
"""
def __init__(self, obj):
self._obj = obj
self._cnt = 0
[docs] def next(self):
"""
Compatibility for Python 2.x, delegates to function: `__next__()`
Returns the next *Weather* item
:returns: the next *Weather* item
"""
return self.__next__()
def __next__(self):
"""
Returns the next *Weather* item
:returns: the next *Weather* item
"""
try:
result = self._obj.get(self._cnt)
self._cnt += 1
return result
except IndexError:
raise StopIteration
[docs]class Forecast(object):
"""
A class encapsulating weather forecast data for a certain location and
relative to a specific time interval (forecast for every three hours or
for every day)
:param interval: the time granularity of the forecast. May be: *'3h'* for
three hours forecast or *'daily'* for daily ones
:type interval: str
:param reception_time: GMT UNIXtime of the forecast reception from the OWM
web API
:type reception_time: int
:param location: the *Location* object relative to the forecast
:type location: Location
:param weathers: the list of *Weather* objects composing the forecast
:type weathers: list
:returns: a *Forecast* instance
:raises: *ValueError* when negative values are provided
"""
def __init__(self, interval, reception_time, location, weathers):
self._interval = interval
if reception_time < 0:
raise ValueError("'reception_time' must be greater than 0")
self._reception_time = reception_time
self._location = location
self._weathers = weathers
def __iter__(self):
"""
Creates a *ForecastIterator* instance
:returns: a *ForecastIterator* instance
"""
return ForecastIterator(self)
[docs] def get(self, index):
"""
Lookups up into the *Weather* items list for the item at the specified
index
:param index: the index of the *Weather* object in the list
:type index: int
:returns: a *Weather* object
"""
return self._weathers[index]
[docs] def get_interval(self):
"""
Returns the time granularity of the forecast
:returns: str
"""
return self._interval
[docs] def set_interval(self, interval):
"""
Sets the time granularity of the forecast
:param interval: the time granularity of the forecast, may be "3h" or
"daily"
:type interval: str
"""
self._interval = interval
[docs] def get_reception_time(self, timeformat='unix'):
"""Returns the GMT time telling when the forecast was received
from the OWM Weather API
:param timeformat: the format for the time value. May be:
'*unix*' (default) for UNIX time
'*iso*' for ISO8601-formatted string in the format ``YYYY-MM-DD HH:MM:SS+00``
'*date* for ``datetime.datetime`` object instance
:type timeformat: str
:returns: an int or a str
:raises: ValueError
"""
return timeformatutils.timeformat(self._reception_time, timeformat)
[docs] def get_location(self):
"""
Returns the Location object relative to the forecast
:returns: a *Location* object
"""
return self._location
[docs] def get_weathers(self):
"""
Returns a copy of the *Weather* objects list composing the forecast
:returns: a list of *Weather* objects
"""
return list(self._weathers)
[docs] def count_weathers(self):
"""
Tells how many *Weather* items compose the forecast
:returns: the *Weather* objects total
"""
return len(self._weathers)
[docs] def actualize(self):
"""
Removes from this forecast all the *Weather* objects having a reference
timestamp in the past with respect to the current timestamp
"""
current_time = timeutils.now(timeformat='unix')
for w in self._weathers:
if w.get_reference_time(timeformat='unix') < current_time:
self._weathers.remove(w)
[docs] def to_JSON(self):
"""Dumps object fields into a JSON formatted string
:returns: the JSON string
"""
return json.dumps({"interval": self._interval,
"reception_time": self._reception_time,
"Location": json.loads(self._location.to_JSON()),
"weathers": json.loads("[" + \
",".join([w.to_JSON() for w in self]) + "]")
})
[docs] def to_XML(self, xml_declaration=True, xmlns=True):
"""
Dumps object fields to an XML-formatted string. The 'xml_declaration'
switch enables printing of a leading standard XML line containing XML
version and encoding. The 'xmlns' switch enables printing of qualified
XMLNS prefixes.
:param XML_declaration: if ``True`` (default) prints a leading XML
declaration line
:type XML_declaration: bool
:param xmlns: if ``True`` (default) prints full XMLNS prefixes
:type xmlns: bool
:returns: an XML-formatted string
"""
root_node = self._to_DOM()
if xmlns:
xmlutils.annotate_with_XMLNS(root_node,
FORECAST_XMLNS_PREFIX,
FORECAST_XMLNS_URL)
return xmlutils.DOM_node_to_XML(root_node, xml_declaration)
def _to_DOM(self):
"""
Dumps object data to a fully traversable DOM representation of the
object.
:returns: a ``xml.etree.Element`` object
"""
root_node = ET.Element("forecast")
interval_node = ET.SubElement(root_node, "interval")
interval_node.text = self._interval
reception_time_node = ET.SubElement(root_node, "reception_time")
reception_time_node.text = str(self._reception_time)
root_node.append(self._location._to_DOM())
weathers_node = ET.SubElement(root_node, "weathers")
for weather in self:
weathers_node.append(weather._to_DOM())
return root_node
def __len__(self):
"""Redefine __len__ hook"""
return self.count_weathers()
def __repr__(self):
return "<%s.%s - reception time=%s, interval=%s>" % (__name__, \
self.__class__.__name__, self.get_reception_time('iso'),
self._interval)