summaryrefslogtreecommitdiffstats
path: root/weather/src/yahooweatherresponse.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'weather/src/yahooweatherresponse.cpp')
-rw-r--r--weather/src/yahooweatherresponse.cpp165
1 files changed, 165 insertions, 0 deletions
diff --git a/weather/src/yahooweatherresponse.cpp b/weather/src/yahooweatherresponse.cpp
new file mode 100644
index 0000000..652d2c8
--- /dev/null
+++ b/weather/src/yahooweatherresponse.cpp
@@ -0,0 +1,165 @@
+#include "yahooweatherresponse.h"
+#include <QDebug>
+
+static inline int strToInt(const QString &str, int defaultValue)
+{
+ bool ok;
+ int result = str.toInt(&ok);
+ return ok ? result : defaultValue;
+}
+
+static inline float strToFloat(const QString &str, qreal defaultValue)
+{
+ bool ok;
+ float result = str.toFloat(&ok);
+ return ok ? result : defaultValue;
+}
+
+static inline YahooWeatherResponse::PressureState readPressure(const QString &str)
+{
+ switch (strToInt(str, 0)) {
+ case 1: return YahooWeatherResponse::Rising;
+ case 2: return YahooWeatherResponse::Falling;
+ default: return YahooWeatherResponse::Steady;
+ }
+}
+
+static inline QString getNodeContentText(QDomNode node)
+{
+ if (node.childNodes().count() == 0 || !node.childNodes().at(0).isText())
+ return QString();
+ return node.childNodes().at(0).nodeValue();
+}
+
+static const QDateTime readDateTime(const QString &str)
+{
+ QString text = str.right(str.length() - str.indexOf(',') - 1);
+ int len = text.indexOf("am", 15);
+ len = len < 0 ? text.indexOf("pm", 15) : len;
+ text = text.left(len + 2).trimmed();
+ return QDateTime::fromString(text, "dd MMM yyyy h:mm ap");
+}
+
+YahooWeatherResponse::Location::Location(QDomElement element)
+ : m_city(element.attribute("city"))
+ , m_region(element.attribute("region"))
+ , m_country(element.attribute("country"))
+{}
+
+YahooWeatherResponse::Units::Units(QDomElement element)
+ : m_temperature(element.attribute("temperature") == "f" ? Fahrenheit : Celsius)
+ , m_distance(element.attribute("distance") == "mi" ? Miles : Kilometers)
+ , m_pressure(element.attribute("pressure") == "in" ? PoundsPerSquare : Millibars)
+ , m_speed(element.attribute("speed") == "mph" ? MilesPerHour : KilometersPerHour)
+{}
+
+YahooWeatherResponse::Wind::Wind(QDomElement element)
+ : m_chill(strToInt(element.attribute("chill"), 0))
+ , m_direction(strToInt(element.attribute("direction"), 0))
+ , m_speed(strToInt(element.attribute("speed"), 0))
+{}
+
+YahooWeatherResponse::Atmosphere::Atmosphere(QDomElement element)
+ : m_humidity(strToInt(element.attribute("humidity"), 0))
+ , m_visibility(strToFloat(element.attribute("visibility"), 0.0) * 100)
+ , m_pressure(strToFloat(element.attribute("pressure"), 0.0))
+ , m_pressureState(readPressure(element.attribute("rising")))
+{}
+
+YahooWeatherResponse::Astronomy::Astronomy(QDomElement element)
+ : m_sunrise(QTime::fromString(element.attribute("sunrise"), "h:mm ap"))
+ , m_sunset(QTime::fromString(element.attribute("sunset"), "h:mm ap"))
+{}
+
+YahooWeatherResponse::Condition::Condition(QDomElement element)
+ : m_text(element.attribute("text"))
+ , m_code(strToInt(element.attribute("code"), 3200))
+ , m_temperature(strToInt(element.attribute("temp"), 0))
+ , m_date(readDateTime(element.attribute("date")))
+{}
+
+YahooWeatherResponse::Forecast::Forecast(QDomElement element)
+ : m_date(QDate::fromString(element.attribute("date"), "dd MMM yyyy"))
+ , m_low(strToInt(element.attribute("low"), 0))
+ , m_high(strToInt(element.attribute("high"), 0))
+ , m_text(element.attribute("text"))
+ , m_code(strToInt(element.attribute("code"), 3200))
+{}
+
+void YahooWeatherResponse::readItem(QDomElement item)
+{
+ int idx = 0;
+ for (int i = 0; i < item.childNodes().count(); ++i) {
+ QDomNode node = item.childNodes().at(i);
+ if (node.nodeName() == "geo:lat")
+ m_latitude = strToFloat(getNodeContentText(node), 0.0);
+ if (node.nodeName() == "geo:long")
+ m_longitude = strToFloat(getNodeContentText(node), 0.0);
+ if (node.nodeName() == "pubDate")
+ m_pubDate = readDateTime(getNodeContentText(node));
+ if (node.nodeName() == "yweather:condition")
+ m_condition = Condition(node.toElement());
+ if (node.nodeName() == "yweather:forecast")
+ m_forecast[idx++] = Forecast(node.toElement());
+ idx = idx > 1 ? 0 : idx;
+ }
+}
+
+YahooWeatherResponse::YahooWeatherResponse(const QString &locationCode, QDomElement element)
+ : m_locationCode(locationCode)
+{
+ QDomNodeList channels = element.elementsByTagName("channel");
+ if (channels.count() == 0)
+ return;
+ QDomElement channel = channels.item(0).toElement();
+ for (int i = 0; i < channel.childNodes().count(); ++i) {
+ QDomNode node = channel.childNodes().at(i);
+
+ if (node.nodeName() == "lastBuildDate")
+ m_buildDate = readDateTime(getNodeContentText(node));
+
+ if (node.nodeName() == "ttl")
+ m_timeToLive = strToInt(getNodeContentText(node), 30);
+
+ if (node.nodeName() == "yweather:location")
+ m_location = Location(node.toElement());
+
+ if (node.nodeName() == "yweather:units")
+ m_units = Units(node.toElement());
+
+ if (node.nodeName() == "yweather:wind")
+ m_wind = Wind(node.toElement());
+
+ if (node.nodeName() == "yweather:atmosphere")
+ m_atmosphere = Atmosphere(node.toElement());
+
+ if (node.nodeName() == "yweather:astronomy")
+ m_astronomy = Astronomy(node.toElement());
+
+ if (node.nodeName() == "item")
+ readItem(node.toElement());
+
+ }
+}
+
+void YahooWeatherResponse::print()
+{
+ /*
+ qDebug() << "location code" << m_locationCode;
+ qDebug() << "buildDate" << m_buildDate;
+ qDebug() << "timeToLive" << m_timeToLive;
+
+ qDebug() << "latitude" << m_latitude;
+ qDebug() << "longitude" << m_longitude;
+ qDebug() << "pubDate" << m_pubDate;
+
+ qDebug() << "astronomy" << m_astronomy.sunrise() << m_astronomy.sunset();
+ qDebug() << "atmosphere" << m_atmosphere.humidity() << m_atmosphere.visibility() << m_atmosphere.pressure() << m_atmosphere.pressureState();
+ qDebug() << "condition" << m_condition.text() << m_condition.code() << m_condition.temperature() << m_condition.date();
+ qDebug() << "forecast" << m_forecast[0].text() << m_forecast[0].code() << m_forecast[0].low() << m_forecast[0].high() << m_forecast[0].date();
+ qDebug() << "forecast" << m_forecast[1].text() << m_forecast[1].code() << m_forecast[1].low() << m_forecast[1].high() << m_forecast[1].date();
+ qDebug() << "location" << m_location.city() << m_location.region() << m_location.country();
+ qDebug() << "units" << m_units.distance() << m_units.pressure() << m_units.speed() << m_units.temperature();
+ qDebug() << "wind" << m_wind.chill() << m_wind.direction() << m_wind.speed();
+ */
+}