#include "yahooweatherresponse.h" #include 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(); */ }