diff options
Diffstat (limited to 'weather/src/yahooweatherresponse.cpp')
-rw-r--r-- | weather/src/yahooweatherresponse.cpp | 165 |
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(); + */ +} |