From 620c4bd1e3a98c008b269cfde68dd0e0363a6092 Mon Sep 17 00:00:00 2001 From: arcan1s Date: Thu, 2 Jun 2016 11:09:02 +0300 Subject: [PATCH] Return to owm weather provider Since yahoo support already exists, so I've added new option X-AW-Provider (apiver 3). Added tests for these cases --- sources/awesomewidgets/abstractextitem.cpp | 4 +- .../awesomewidgets/abstractweatherprovider.h | 47 ++++++ .../awesomewidgets-extweather-ids.json | 131 +++++++++++++++- sources/awesomewidgets/extscript.h | 7 +- sources/awesomewidgets/extweather.cpp | 144 +++++++++--------- sources/awesomewidgets/extweather.h | 19 ++- sources/awesomewidgets/extweather.ui | 42 ++++- sources/awesomewidgets/graphicalitem.cpp | 3 +- sources/awesomewidgets/graphicalitem.h | 8 +- sources/awesomewidgets/owmweatherprovider.cpp | 112 ++++++++++++++ sources/awesomewidgets/owmweatherprovider.h | 43 ++++++ sources/awesomewidgets/weather/01d.png | Bin 0 -> 2859 bytes sources/awesomewidgets/weather/02d.png | Bin 0 -> 2969 bytes sources/awesomewidgets/weather/03d.png | Bin 0 -> 2565 bytes sources/awesomewidgets/weather/04d.png | Bin 0 -> 2773 bytes sources/awesomewidgets/weather/09d.png | Bin 0 -> 3818 bytes sources/awesomewidgets/weather/10d.png | Bin 0 -> 3793 bytes sources/awesomewidgets/weather/11d.png | Bin 0 -> 3777 bytes sources/awesomewidgets/weather/13d.png | Bin 0 -> 3901 bytes sources/awesomewidgets/weather/50d.png | Bin 0 -> 3328 bytes sources/awesomewidgets/weather/london.desktop | 3 +- .../awesomewidgets/yahooweatherprovider.cpp | 126 +++++++++++++++ sources/awesomewidgets/yahooweatherprovider.h | 47 ++++++ sources/test/testextweather.cpp | 90 +++++------ sources/test/testextweather.h | 4 +- sources/version.h.in | 5 +- 26 files changed, 704 insertions(+), 131 deletions(-) create mode 100644 sources/awesomewidgets/abstractweatherprovider.h create mode 100644 sources/awesomewidgets/owmweatherprovider.cpp create mode 100644 sources/awesomewidgets/owmweatherprovider.h create mode 100644 sources/awesomewidgets/weather/01d.png create mode 100644 sources/awesomewidgets/weather/02d.png create mode 100644 sources/awesomewidgets/weather/03d.png create mode 100644 sources/awesomewidgets/weather/04d.png create mode 100644 sources/awesomewidgets/weather/09d.png create mode 100644 sources/awesomewidgets/weather/10d.png create mode 100644 sources/awesomewidgets/weather/11d.png create mode 100644 sources/awesomewidgets/weather/13d.png create mode 100644 sources/awesomewidgets/weather/50d.png create mode 100644 sources/awesomewidgets/yahooweatherprovider.cpp create mode 100644 sources/awesomewidgets/yahooweatherprovider.h diff --git a/sources/awesomewidgets/abstractextitem.cpp b/sources/awesomewidgets/abstractextitem.cpp index 62e0e09..787acc0 100644 --- a/sources/awesomewidgets/abstractextitem.cpp +++ b/sources/awesomewidgets/abstractextitem.cpp @@ -178,7 +178,7 @@ void AbstractExtItem::setName(const QString _name) void AbstractExtItem::setNumber(int _number) { qCDebug(LOG_LIB) << "Number" << _number; - if (_number == -1) + if (_number == -1) { _number = []() { qCWarning(LOG_LIB) << "Number is empty, generate new one"; qsrand(QTime::currentTime().msec()); @@ -186,6 +186,8 @@ void AbstractExtItem::setNumber(int _number) qCInfo(LOG_LIB) << "Generated number is" << n; return n; }(); + writeConfiguration(); + } m_number = _number; } diff --git a/sources/awesomewidgets/abstractweatherprovider.h b/sources/awesomewidgets/abstractweatherprovider.h new file mode 100644 index 0000000..9582cac --- /dev/null +++ b/sources/awesomewidgets/abstractweatherprovider.h @@ -0,0 +1,47 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +#ifndef ABSTRACTWEATHERPROVIDER_H +#define ABSTRACTWEATHERPROVIDER_H + +#include +#include + + +class AbstractWeatherProvider : public QObject +{ + Q_OBJECT + Q_PROPERTY(int number READ number) + +public: + explicit AbstractWeatherProvider(QObject *parent, const int number) + : QObject(parent) + , m_number(number){}; + virtual ~AbstractWeatherProvider(){}; + virtual void initUrl(const QString city, const QString country, + const int ts) + = 0; + virtual QVariantHash parse(const QVariantMap &json) const = 0; + virtual QUrl url() const = 0; + int number() const { return m_number; }; + +private: + int m_number; +}; + + +#endif /* ABSTRACTWEATHERPROVIDER_H */ diff --git a/sources/awesomewidgets/awesomewidgets-extweather-ids.json b/sources/awesomewidgets/awesomewidgets-extweather-ids.json index 69f9085..e8ec649 100644 --- a/sources/awesomewidgets/awesomewidgets-extweather-ids.json +++ b/sources/awesomewidgets/awesomewidgets-extweather-ids.json @@ -1,11 +1,75 @@ { - "__url": "https://developer.yahoo.com/weather/documentation.html", + "__url-yahoo": "https://developer.yahoo.com/weather/documentation.html", + "__url-owm": "http://openweathermap.org/weather-conditions", "image": { "__comment": "should be described as html image with full path inside", "default": "", + "800": "", + + "801": "", + + "802": "", + "803": "", + + "804": "", + + "300": "", + "301": "", + "302": "", + "310": "", + "311": "", + "312": "", + "313": "", + "314": "", + "321": "", + "520": "", + "521": "", + "522": "", + "531": "", + + "500": "", + "501": "", + "502": "", + "503": "", + "504": "", + + "200": "", + "201": "", + "202": "", + "210": "", + "211": "", + "212": "", + "221": "", + "230": "", + "231": "", + "232": "", + + "511": "", + "600": "", + "601": "", + "602": "", + "611": "", + "612": "", + "615": "", + "616": "", + "620": "", + "621": "", + "622": "", + + "701": "", + "711": "", + "721": "", + "731": "", + "741": "", + "751": "", + "761": "", + "762": "", + "771": "", + "781": "", + "0": "", "1": "", "2": "", @@ -59,8 +123,71 @@ "text": { "default": "\u2604", - "3200": "\u2604", + "800": "\u2600", + + "801": "\u26C5", + + "802": "\u2601", + "803": "\u2601", + + "804": "\u2601", + + "300": "\u2602", + "301": "\u2602", + "302": "\u2602", + "310": "\u2602", + "311": "\u2602", + "312": "\u2602", + "313": "\u2602", + "314": "\u2602", + "321": "\u2602", + "520": "\u2602", + "521": "\u2602", + "522": "\u2602", + "531": "\u2602", + + "500": "\u2614", + "501": "\u2614", + "502": "\u2614", + "503": "\u2614", + "504": "\u2614", + + "200": "\u2608", + "201": "\u2608", + "202": "\u2608", + "210": "\u2608", + "211": "\u2608", + "212": "\u2608", + "221": "\u2608", + "230": "\u2608", + "231": "\u2608", + "232": "\u2608", + + "511": "\u2603", + "600": "\u2603", + "601": "\u2603", + "602": "\u2603", + "611": "\u2603", + "612": "\u2603", + "615": "\u2603", + "616": "\u2603", + "620": "\u2603", + "621": "\u2603", + "622": "\u2603", + + "701": "\u26C5", + "711": "\u26C5", + "721": "\u26C5", + "731": "\u26C5", + "741": "\u26C5", + "751": "\u26C5", + "761": "\u26C5", + "762": "\u26C5", + "771": "\u26C5", + "781": "\u26C5", + + "3200": "\u2604", "0": "\u2604", "1": "\u2604", "2": "\u2604", diff --git a/sources/awesomewidgets/extscript.h b/sources/awesomewidgets/extscript.h index 1dca548..5189a63 100644 --- a/sources/awesomewidgets/extscript.h +++ b/sources/awesomewidgets/extscript.h @@ -37,7 +37,12 @@ class ExtScript : public AbstractExtItem Q_PROPERTY(Redirect redirect READ redirect WRITE setRedirect) public: - enum class Redirect { stdout2stderr = 0, nothing = 1, stderr2stdout = 2, swap = 3 }; + enum class Redirect { + stdout2stderr = 0, + nothing = 1, + stderr2stdout = 2, + swap = 3 + }; explicit ExtScript(QWidget *parent, const QString filePath = QString()); virtual ~ExtScript(); diff --git a/sources/awesomewidgets/extweather.cpp b/sources/awesomewidgets/extweather.cpp index 0aabd44..456d893 100644 --- a/sources/awesomewidgets/extweather.cpp +++ b/sources/awesomewidgets/extweather.cpp @@ -27,11 +27,12 @@ #include #include #include -#include #include #include "awdebug.h" +#include "owmweatherprovider.h" +#include "yahooweatherprovider.h" ExtWeather::ExtWeather(QWidget *parent, const QString filePath) @@ -68,6 +69,7 @@ ExtWeather::~ExtWeather() SLOT(weatherReplyReceived(QNetworkReply *))); m_manager->deleteLater(); + delete m_providerObject; delete ui; } @@ -83,6 +85,7 @@ ExtWeather *ExtWeather::copy(const QString _fileName, const int _number) item->setCountry(country()); item->setImage(image()); item->setNumber(_number); + item->setProvider(provider()); item->setTs(ts()); return item; @@ -117,6 +120,28 @@ bool ExtWeather::image() const } +ExtWeather::Provider ExtWeather::provider() const +{ + return m_provider; +} + + +QString ExtWeather::strProvider() const +{ + QString value; + switch (m_provider) { + case Provider::OWM: + value = QString("OWM"); + break; + case Provider::Yahoo: + value = QString("Yahoo"); + break; + } + + return value; +} + + int ExtWeather::ts() const { return m_ts; @@ -134,7 +159,7 @@ void ExtWeather::setCity(const QString _city) qCDebug(LOG_LIB) << "City" << _city; m_city = _city; - initUrl(); + initProvider(); } @@ -143,7 +168,7 @@ void ExtWeather::setCountry(const QString _country) qCDebug(LOG_LIB) << "Country" << _country; m_country = _country; - initUrl(); + initProvider(); } @@ -155,11 +180,32 @@ void ExtWeather::setImage(const bool _image) } +void ExtWeather::setProvider(const Provider _provider) +{ + qCDebug(LOG_LIB) << "Provider" << static_cast(_provider); + + m_provider = _provider; + initProvider(); +} + + +void ExtWeather::setStrProvider(const QString _provider) +{ + qCDebug(LOG_LIB) << "Provider" << _provider; + + if (_provider == QString("Yahoo")) + setProvider(Provider::Yahoo); + else + setProvider(Provider::OWM); +} + + void ExtWeather::setTs(const int _ts) { qCDebug(LOG_LIB) << "Timestamp" << _ts; m_ts = _ts; + initProvider(); } @@ -176,16 +222,11 @@ void ExtWeather::readConfiguration() // api == 2 setImage(settings.value(QString("X-AW-Image"), QVariant(m_image)).toString() == QString("true")); + // api == 3 + setStrProvider( + settings.value(QString("X-AW-Provider"), strProvider()).toString()); settings.endGroup(); - // update for current API - if ((apiVersion() > 0) && (apiVersion() < AWEWAPI)) { - qCWarning(LOG_LIB) << "Bump API version from" << apiVersion() << "to" - << AWEWAPI; - setApiVersion(AWEWAPI); - writeConfiguration(); - } - bumpApi(AWEWAPI); } @@ -224,7 +265,8 @@ QVariantHash ExtWeather::run() if (times == 1) { qCInfo(LOG_LIB) << "Send request"; isRunning = true; - QNetworkReply *reply = m_manager->get(QNetworkRequest(m_url)); + QNetworkReply *reply + = m_manager->get(QNetworkRequest(m_providerObject->url())); new QReplyTimeout(reply, REQUEST_TIMEOUT); } @@ -244,6 +286,7 @@ int ExtWeather::showConfiguration(const QVariant args) ui->lineEdit_name->setText(name()); ui->lineEdit_comment->setText(comment()); ui->label_numberValue->setText(QString("%1").arg(number())); + ui->comboBox_provider->setCurrentIndex(static_cast(m_provider)); ui->lineEdit_city->setText(m_city); ui->lineEdit_country->setText(m_country); ui->spinBox_timestamp->setValue(m_ts); @@ -261,6 +304,7 @@ int ExtWeather::showConfiguration(const QVariant args) setApiVersion(AWEWAPI); setCity(ui->lineEdit_city->text()); setCountry(ui->lineEdit_country->text()); + setProvider(static_cast(ui->comboBox_provider->currentIndex())); setTs(ui->spinBox_timestamp->value()); setImage(ui->checkBox_image->checkState() == Qt::Checked); setActive(ui->checkBox_active->checkState() == Qt::Checked); @@ -282,6 +326,7 @@ void ExtWeather::writeConfiguration() const settings.setValue(QString("X-AW-City"), m_city); settings.setValue(QString("X-AW-Country"), m_country); settings.setValue(QString("X-AW-Image"), m_image); + settings.setValue(QString("X-AW-Provider"), strProvider()); settings.setValue(QString("X-AW-TS"), m_ts); settings.endGroup(); @@ -304,69 +349,31 @@ void ExtWeather::weatherReplyReceived(QNetworkReply *reply) return; } - // convert to map - QVariantMap json = jsonDoc.toVariant().toMap()[QString("query")].toMap(); - if (json[QString("count")].toInt() != 1) { - qCWarning(LOG_LIB) << "Found data count" - << json[QString("count")].toInt() << "is not 1"; + QVariantHash data = m_providerObject->parse(jsonDoc.toVariant().toMap()); + if (data.isEmpty()) return; - } - QVariantMap results - = json[QString("results")].toMap()[QString("channel")].toMap(); - QVariantMap item = results[QString("item")].toMap(); - - if (m_ts == 0) { - // current weather - int id = item[QString("condition")].toMap()[QString("code")].toInt(); - values[tag(QString("weatherId"))] = id; - values[tag(QString("weather"))] = weatherFromInt(id); - values[tag(QString("temperature"))] - = item[QString("condition")].toMap()[QString("temp")].toInt(); - values[tag(QString("timestamp"))] - = item[QString("condition")].toMap()[QString("date")].toString(); - values[tag(QString("humidity"))] = results[QString("atmosphere")] - .toMap()[QString("humidity")] - .toInt(); - values[tag(QString("pressure"))] - = static_cast(results[QString("atmosphere")] - .toMap()[QString("pressure")] - .toFloat()); - } else { - // forecast weather - QVariantList weatherList = item[QString("forecast")].toList(); - QVariantMap weatherMap = weatherList.count() < m_ts - ? weatherList.last().toMap() - : weatherList.at(m_ts).toMap(); - int id = weatherMap[QString("code")].toInt(); - values[tag(QString("weatherId"))] = id; - values[tag(QString("weather"))] = weatherFromInt(id); - values[tag(QString("timestamp"))] - = weatherMap[QString("date")].toString(); - // yahoo provides high and low temperatures. Lets calculate average one - values[tag(QString("temperature"))] - = (weatherMap[QString("high")].toFloat() - + weatherMap[QString("low")].toFloat()) - / 2.0; - // ... and no forecast data for humidity and pressure - values[tag(QString("humidity"))] = 0; - values[tag(QString("pressure"))] = 0.0; - } + values = data; + values[tag(QString("weather"))] + = weatherFromInt(values[tag(QString("weatherId"))].toInt()); emit(dataReceived(values)); } -void ExtWeather::initUrl() +void ExtWeather::initProvider() { - // init query - m_url = QUrl(YAHOO_WEATHER_URL); - QUrlQuery params; - params.addQueryItem(QString("format"), QString("json")); - params.addQueryItem(QString("env"), - QString("store://datatables.org/alltableswithkeys")); - params.addQueryItem(QString("q"), - QString(YAHOO_WEATHER_QUERY).arg(m_city, m_country)); - m_url.setQuery(params); + delete m_providerObject; + + switch (m_provider) { + case Provider::OWM: + m_providerObject = new OWMWeatherProvider(this, number()); + break; + case Provider::Yahoo: + m_providerObject = new YahooWeatherProvider(this, number()); + break; + } + + return m_providerObject->initUrl(m_city, m_country, m_ts); } @@ -375,6 +382,7 @@ void ExtWeather::translate() ui->label_name->setText(i18n("Name")); ui->label_comment->setText(i18n("Comment")); ui->label_number->setText(i18n("Tag")); + ui->label_provider->setText(i18n("Provider")); ui->label_city->setText(i18n("City")); ui->label_country->setText(i18n("Country")); ui->label_timestamp->setText(i18n("Timestamp")); diff --git a/sources/awesomewidgets/extweather.h b/sources/awesomewidgets/extweather.h index 6b60583..8ee174c 100644 --- a/sources/awesomewidgets/extweather.h +++ b/sources/awesomewidgets/extweather.h @@ -22,12 +22,8 @@ #include "abstractextitem.h" -#define YAHOO_WEATHER_URL "https://query.yahooapis.com/v1/public/yql" -#define YAHOO_WEATHER_QUERY \ - "select * from weather.forecast where u='c' and woeid in (select woeid " \ - "from geo.places(1) where text='%1, %2')" - +class AbstractWeatherProvider; namespace Ui { class ExtWeather; @@ -39,9 +35,13 @@ class ExtWeather : public AbstractExtItem Q_PROPERTY(QString city READ city WRITE setCity) Q_PROPERTY(QString country READ country WRITE setCountry) Q_PROPERTY(bool image READ image WRITE setImage) + Q_PROPERTY(Provider povider READ provider WRITE setProvider) + Q_PROPERTY(QString strPovider READ strProvider WRITE setStrProvider) Q_PROPERTY(int ts READ ts WRITE setTs) public: + enum class Provider { OWM = 0, Yahoo = 1 }; + explicit ExtWeather(QWidget *parent, const QString filePath = QString()); virtual ~ExtWeather(); ExtWeather *copy(const QString _fileName, const int _number); @@ -50,12 +50,16 @@ public: QString city() const; QString country() const; bool image() const; + Provider provider() const; + QString strProvider() const; int ts() const; QString uniq() const; // set methods void setCity(const QString _city = QString("London")); void setCountry(const QString _country = QString("uk")); void setImage(const bool _image = false); + void setProvider(const Provider _provider = Provider::OWM); + void setStrProvider(const QString _provider = QString("OWM")); void setTs(const int _ts = 0); public slots: @@ -70,15 +74,16 @@ private slots: private: QNetworkAccessManager *m_manager = nullptr; - QUrl m_url; + AbstractWeatherProvider *m_providerObject = nullptr; bool isRunning = false; Ui::ExtWeather *ui = nullptr; - void initUrl(); + void initProvider(); void translate(); // properties QString m_city = QString("London"); QString m_country = QString("uk"); bool m_image = false; + Provider m_provider = Provider::OWM; int m_ts = 0; QVariantMap m_jsonMap = QVariantMap(); // values diff --git a/sources/awesomewidgets/extweather.ui b/sources/awesomewidgets/extweather.ui index 5015643..0b5bb43 100644 --- a/sources/awesomewidgets/extweather.ui +++ b/sources/awesomewidgets/extweather.ui @@ -7,7 +7,7 @@ 0 0 420 - 301 + 333 @@ -81,6 +81,46 @@ + + + + + + + 0 + 0 + + + + Provider + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + OWM + + + + + Yahoo + + + + + + diff --git a/sources/awesomewidgets/graphicalitem.cpp b/sources/awesomewidgets/graphicalitem.cpp index 313f022..d236cdc 100644 --- a/sources/awesomewidgets/graphicalitem.cpp +++ b/sources/awesomewidgets/graphicalitem.cpp @@ -514,7 +514,8 @@ int GraphicalItem::showConfiguration(const QVariant args) setActiveColor(ui->lineEdit_activeColor->text()); setInactiveColor(ui->lineEdit_inactiveColor->text()); setType(static_cast(ui->comboBox_type->currentIndex())); - setDirection(static_cast(ui->comboBox_direction->currentIndex())); + setDirection( + static_cast(ui->comboBox_direction->currentIndex())); setItemHeight(ui->spinBox_height->value()); setItemWidth(ui->spinBox_width->value()); diff --git a/sources/awesomewidgets/graphicalitem.h b/sources/awesomewidgets/graphicalitem.h index b7bc656..cbfe3a2 100644 --- a/sources/awesomewidgets/graphicalitem.h +++ b/sources/awesomewidgets/graphicalitem.h @@ -50,7 +50,13 @@ class GraphicalItem : public AbstractExtItem public: enum class Direction { LeftToRight = 0, RightToLeft = 1 }; - enum class Type { Horizontal = 0, Vertical = 1, Circle = 2, Graph = 3, Bars = 4 }; + enum class Type { + Horizontal = 0, + Vertical = 1, + Circle = 2, + Graph = 3, + Bars = 4 + }; explicit GraphicalItem(QWidget *parent, const QString filePath = QString()); virtual ~GraphicalItem(); diff --git a/sources/awesomewidgets/owmweatherprovider.cpp b/sources/awesomewidgets/owmweatherprovider.cpp new file mode 100644 index 0000000..f3057b9 --- /dev/null +++ b/sources/awesomewidgets/owmweatherprovider.cpp @@ -0,0 +1,112 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +#include "owmweatherprovider.h" + +#include +#include + +#include "awdebug.h" + + +OWMWeatherProvider::OWMWeatherProvider(QObject *parent, const int number) + : AbstractWeatherProvider(parent, number) +{ + qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; +} + + +OWMWeatherProvider::~OWMWeatherProvider() +{ + qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; +} + + +void OWMWeatherProvider::initUrl(const QString city, const QString country, + const int ts) +{ + qCDebug(LOG_LIB) << "Init query for" << city << country << "with ts" << ts; + + m_ts = ts; + + if (m_ts == 0) + m_url = QUrl(OWM_WEATHER_URL); + else + m_url = QUrl(OWM_FORECAST_URL); + QUrlQuery params; + params.addQueryItem(QString("q"), QString("%1,%2").arg(city, country)); + params.addQueryItem(QString("units"), QString("metric")); + m_url.setQuery(params); +} + + +QVariantHash OWMWeatherProvider::parse(const QVariantMap &json) const +{ + qCDebug(LOG_LIB) << "Parse json" << json; + + if (json[QString("cod")].toInt() != 200) { + qCWarning(LOG_LIB) << "Invalid OpenWeatherMap return code" + << json[QString("cod")].toInt(); + return QVariantHash(); + } + + if (m_ts == 0) { + return parseSingleJson(json); + } else { + QVariantList list = json[QString("list")].toList(); + return parseSingleJson(list.count() <= m_ts ? list.at(m_ts - 1).toMap() + : list.last().toMap()); + } +} + + +QUrl OWMWeatherProvider::url() const +{ + return m_url; +} + + +QVariantHash OWMWeatherProvider::parseSingleJson(const QVariantMap &json) const +{ + qCDebug(LOG_LIB) << "Single json data" << json; + + QVariantHash output; + + // weather status + QVariantList weather = json[QString("weather")].toList(); + if (!weather.isEmpty()) { + int id = weather.first().toMap()[QString("id")].toInt(); + output[QString("weatherId%1").arg(number())] = id; + } + + // main data + QVariantMap mainWeather = json[QString("main")].toMap(); + if (!weather.isEmpty()) { + output[QString("humidity%1").arg(number())] + = mainWeather[QString("humidity")].toFloat(); + output[QString("pressure%1").arg(number())] + = mainWeather[QString("pressure")].toFloat(); + output[QString("temperature%1").arg(number())] + = mainWeather[QString("temp")].toFloat(); + } + + // timestamp + output[QString("timestamp%1").arg(number())] + = QDateTime::fromTime_t(json[QString("dt")].toUInt()).toUTC(); + + return output; +} diff --git a/sources/awesomewidgets/owmweatherprovider.h b/sources/awesomewidgets/owmweatherprovider.h new file mode 100644 index 0000000..6f8b639 --- /dev/null +++ b/sources/awesomewidgets/owmweatherprovider.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +#ifndef OWMWEATHERPROVIDER_H +#define OWMWEATHERPROVIDER_H + +#include "abstractweatherprovider.h" + +#define OWM_WEATHER_URL "http://arcanis.me/weather" +#define OWM_FORECAST_URL "http://arcanis.me/forecast" + + +class OWMWeatherProvider : public AbstractWeatherProvider +{ +public: + explicit OWMWeatherProvider(QObject *parent, const int number); + virtual ~OWMWeatherProvider(); + void initUrl(const QString city, const QString country, const int); + QVariantHash parse(const QVariantMap &json) const; + QUrl url() const; + +private: + QVariantHash parseSingleJson(const QVariantMap &json) const; + int m_ts = 0; + QUrl m_url; +}; + + +#endif /* OWMWEATHERPROVIDER_H */ diff --git a/sources/awesomewidgets/weather/01d.png b/sources/awesomewidgets/weather/01d.png new file mode 100644 index 0000000000000000000000000000000000000000..7d2f792c324408eaccb8a13e0cd16fd502dd51cf GIT binary patch literal 2859 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 literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/03d.png b/sources/awesomewidgets/weather/03d.png new file mode 100644 index 0000000000000000000000000000000000000000..8a4a8e9fa75b5b860ff33f84cd6bf65a9ad04e54 GIT binary patch literal 2565 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nC-&H|6fVg?3oVGw3ym^DX&fq~U0 zGbExU!q>+tIX_n~F(p4KRj(qq0H~UQ!KT6r$jnVGNmQuF&B-gas<2f8tFQvHLBje< z3ScEA*|tg%z5xo(`9-M;rh0~YMoM;E3JMA~MJZ`kK`w4k?LeNbQbtKhft9{~d3m{B zxv^e;QM$gNrKP35fswwEkuFe$ZgFK^Nn(X=Ua>O75STeGsl~}fnFS@8`FRQ;a}$&D zOG|8(lt3220o0wj1#pYv;5=hU{aFdS+1b8CnV*`x_BM_jXmG!D8x zRw`Az%UZayTWQM$*YHIwE*yEH7h^R&7Oqp7-Ozo>EAy?B$R$2Eb=9LsQWl;~ne#pE z-u~w{dp*S-SLeSwb6DtJ>&)_<_V;b?|2${;y{PZ;gufSl{B>ZmbaDBY@8#Cz($(^$ zQDci!k&bcB5{}KUoo?;O7ZKe3Kq0TR^lNa%=D8bnt8bNch;(=EmuxGZE%3R2;zYr< z-044@3g+5K&A0jaJVWVNyqL?wB`ThUr?+)JzR~iWHEGter#H^kCRvJmA6|ODR`+EA zqw&P4Q>VV1A+mq&xi4ZD+4>&eo5j?hDSaYhnrlU$`l?lV=3AeIA3l88zBFU?^D;Fh z0WbN^JwLkVO!Yp{(6Q)&kfYHGgMT>z#|?PO_bfE~XRQ1A$b$zDlKr!-W~7{*nE!N6 zjMHJoB^?THgdC$Mu>32KQR;c}X=lvdxc}=mMOdoKiP^Jl^>PSmSo-?$ZN_j%WrUkDLhHDTTB^`*Z5xjAZ-x{_pyIyAbHBDa;M zW@o>?_T)Q+wFX7{8-Q8`odn%YJUTv83SPWmAQ!`Hx;$?AkEN z>C=shMs=nyroQU6wLg>BpIBXNP;+%|$`9@(CoWwIGP^nXkK?&i|F2(EVnj3Iwp6RB zwuJIN;yP{OV6kLj=K0rKZ;6C#fBrV<(JzOt6PZ7Q_UYGiy}IbqD(YtzLmaT&YHJ}=F!w>LHWw(IJ@y~+DrR$aYi{&7bMufBN> zn@Z;PjsWKg9C3>#H0LP>NNWkS7;^02wJ0QO>)V^1ot^F_wX4^^Uo3df*WG|;!<9#g zb)5HJ3G6rQdma;WMw};JrDeL#wh%4TB87=N0wZI3svrJ%#-Z{wnB_qCd4m#j$Gr^J za~D5sJIe6eYD%`I*#Df}{~vfB*!SD6CSK`k)>pZfAltcq%Qu7^QhiqSzP4d*-({so z`}j7jVpM$NJ?X-iL*G=5OiV)J;^Ou(Z<_C_P{Fcm-Y2HF$7F;K&1cZhJZy43^lId% zLtj;yX20FKbt|_+0#C#84~iappRwNQwLIf~Mx5hywz0AC>$n;FLc8yu4fI#zZBZIPPNqB_1>Gr5@}PN&FZ!qgu)J&=)=KZ~FqD@Jdej{z~6x Rf*Poy=IQF^vd$@?2>@Ou)Or8_ literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/04d.png b/sources/awesomewidgets/weather/04d.png new file mode 100644 index 0000000000000000000000000000000000000000..4677b8596acb4bed4fc8c62633e673567e8af6db GIT binary patch literal 2773 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 literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/10d.png b/sources/awesomewidgets/weather/10d.png new file mode 100644 index 0000000000000000000000000000000000000000..b1e1f8305ef7558bad0ab12e5298db59229d69a3 GIT binary patch literal 3793 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 literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/13d.png b/sources/awesomewidgets/weather/13d.png new file mode 100644 index 0000000000000000000000000000000000000000..7b64a6cfd080465634c92f56e1eba8a5a3166c4f GIT binary patch literal 3901 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 V(K#=GDl30*9c^83SFQ2K{sUPJTaN$$ literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/50d.png b/sources/awesomewidgets/weather/50d.png new file mode 100644 index 0000000000000000000000000000000000000000..18afb341e1f8f91119d249434cf170be5e686715 GIT binary patch literal 3328 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 AO#lD@ literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/london.desktop b/sources/awesomewidgets/weather/london.desktop index c89d790..cddbedc 100644 --- a/sources/awesomewidgets/weather/london.desktop +++ b/sources/awesomewidgets/weather/london.desktop @@ -3,10 +3,11 @@ Comment=London current weather Encoding=UTF-8 Name=London current X-AW-Active=false -X-AW-ApiVersion=2 +X-AW-ApiVersion=3 X-AW-City=London X-AW-Country=uk X-AW-Image=false X-AW-Interval=3600 X-AW-Number=0 +X-AW-Provider=OWM X-AW-TS=0 diff --git a/sources/awesomewidgets/yahooweatherprovider.cpp b/sources/awesomewidgets/yahooweatherprovider.cpp new file mode 100644 index 0000000..569a269 --- /dev/null +++ b/sources/awesomewidgets/yahooweatherprovider.cpp @@ -0,0 +1,126 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +#include "yahooweatherprovider.h" + +#include + +#include "awdebug.h" + + +YahooWeatherProvider::YahooWeatherProvider(QObject *parent, const int number) + : AbstractWeatherProvider(parent, number) +{ + qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; +} + + +YahooWeatherProvider::~YahooWeatherProvider() +{ + qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; +} + + +void YahooWeatherProvider::initUrl(const QString city, const QString country, + const int ts) +{ + qCDebug(LOG_LIB) << "Init query for" << city << country << "with ts" << ts; + + m_ts = ts; + + m_url = QUrl(YAHOO_WEATHER_URL); + QUrlQuery params; + params.addQueryItem(QString("format"), QString("json")); + params.addQueryItem(QString("env"), + QString("store://datatables.org/alltableswithkeys")); + params.addQueryItem(QString("q"), + QString(YAHOO_WEATHER_QUERY).arg(city, country)); + m_url.setQuery(params); +} + + +QVariantHash YahooWeatherProvider::parse(const QVariantMap &json) const +{ + qCDebug(LOG_LIB) << "Parse json" << json; + + QVariantMap jsonMap = json[QString("query")].toMap(); + if (jsonMap[QString("count")].toInt() != 1) { + qCWarning(LOG_LIB) << "Found data count" + << json[QString("count")].toInt() << "is not 1"; + return QVariantHash(); + } + QVariantMap results + = jsonMap[QString("results")].toMap()[QString("channel")].toMap(); + QVariantMap item = results[QString("item")].toMap(); + QVariantMap atmosphere = results[QString("atmosphere")].toMap(); + + return m_ts == 0 ? parseCurrent(item, atmosphere) : parseForecast(item); +} + + +QUrl YahooWeatherProvider::url() const +{ + return m_url; +} + + +QVariantHash +YahooWeatherProvider::parseCurrent(const QVariantMap &json, + const QVariantMap &atmosphere) const +{ + qCDebug(LOG_LIB) << "Parse current weather from" << json; + + QVariantHash values; + int id = json[QString("condition")].toMap()[QString("code")].toInt(); + values[QString("weatherId%1").arg(number())] = id; + values[QString("temperature%1").arg(number())] + = json[QString("condition")].toMap()[QString("temp")].toInt(); + values[QString("timestamp%1").arg(number())] + = json[QString("condition")].toMap()[QString("date")].toString(); + values[QString("humidity%1").arg(number())] + = atmosphere[QString("humidity")].toInt(); + values[QString("pressure%1").arg(number())] + = static_cast(atmosphere[QString("pressure")].toFloat()); + + return values; +} + + +QVariantHash YahooWeatherProvider::parseForecast(const QVariantMap &json) const +{ + qCDebug(LOG_LIB) << "Parse forecast from" << json; + + QVariantHash values; + QVariantList weatherList = json[QString("forecast")].toList(); + QVariantMap weatherMap = weatherList.count() < m_ts + ? weatherList.last().toMap() + : weatherList.at(m_ts).toMap(); + int id = weatherMap[QString("code")].toInt(); + values[QString("weatherId%1").arg(number())] = id; + values[QString("timestamp%1").arg(number())] + = weatherMap[QString("date")].toString(); + // yahoo provides high and low temperatures. Lets calculate average one + values[QString("temperature%1").arg(number())] + = (weatherMap[QString("high")].toFloat() + + weatherMap[QString("low")].toFloat()) + / 2.0; + // ... and no forecast data for humidity and pressure + values[QString("humidity%1").arg(number())] = 0; + values[QString("pressure%1").arg(number())] = 0.0; + + return values; +} diff --git a/sources/awesomewidgets/yahooweatherprovider.h b/sources/awesomewidgets/yahooweatherprovider.h new file mode 100644 index 0000000..d5c997f --- /dev/null +++ b/sources/awesomewidgets/yahooweatherprovider.h @@ -0,0 +1,47 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +#ifndef YAHOOWEATHERPROVIDER_H +#define YAHOOWEATHERPROVIDER_H + +#include "abstractweatherprovider.h" + +#define YAHOO_WEATHER_URL "https://query.yahooapis.com/v1/public/yql" +#define YAHOO_WEATHER_QUERY \ + "select * from weather.forecast where u='c' and woeid in (select woeid " \ + "from geo.places(1) where text='%1, %2')" + + +class YahooWeatherProvider : public AbstractWeatherProvider +{ +public: + explicit YahooWeatherProvider(QObject *parent, const int number); + virtual ~YahooWeatherProvider(); + void initUrl(const QString city, const QString country, const int); + QVariantHash parse(const QVariantMap &json) const; + QUrl url() const; + +private: + QVariantHash parseCurrent(const QVariantMap &json, + const QVariantMap &atmosphere) const; + QVariantHash parseForecast(const QVariantMap &json) const; + int m_ts = 0; + QUrl m_url; +}; + + +#endif /* YAHOOWEATHERPROVIDER_H */ diff --git a/sources/test/testextweather.cpp b/sources/test/testextweather.cpp index bf41746..d1d38d9 100644 --- a/sources/test/testextweather.cpp +++ b/sources/test/testextweather.cpp @@ -30,6 +30,7 @@ void TestExtWeather::initTestCase() extWeather->setCity(city); extWeather->setCountry(country); extWeather->setNumber(0); + extWeather->setProvider(ExtWeather::Provider::OWM); extWeather->run(); } @@ -47,62 +48,28 @@ void TestExtWeather::test_values() QCOMPARE(extWeather->number(), 0); QCOMPARE(extWeather->city(), city); QCOMPARE(extWeather->country(), country); + QCOMPARE(extWeather->provider(), ExtWeather::Provider::OWM); } -void TestExtWeather::test_run() +void TestExtWeather::test_runOWM() { - // init spy - QSignalSpy spy(extWeather, SIGNAL(dataReceived(const QVariantHash &))); - QVariantHash firstValue = extWeather->run(); + run(); +} - // check values - QVERIFY(spy.wait(5000)); - QVariantHash arguments = spy.takeFirst().at(0).toHash(); - QEXPECT_FAIL("", "WeatherID should not be 0", Continue); - QCOMPARE(arguments[extWeather->tag(QString("weatherId"))].toInt(), 0); - QVERIFY((arguments[extWeather->tag(QString("humidity"))].toInt() - > humidity.first) - && (arguments[extWeather->tag(QString("humidity"))].toInt() - < humidity.second)); - QEXPECT_FAIL("", "https://yahoo.uservoice.com/forums/207813-us-weather/" - "suggestions/14209233-invalid-pressure-calculation", - Continue); - QVERIFY((arguments[extWeather->tag(QString("pressure"))].toFloat() - > pressure.first) - && (arguments[extWeather->tag(QString("pressure"))].toInt() - < pressure.second)); - QVERIFY((arguments[extWeather->tag(QString("temperature"))].toFloat() - > temp.first) - && (arguments[extWeather->tag(QString("temperature"))].toInt() - < temp.second)); - // image should be only one symbol here - QCOMPARE(arguments[extWeather->tag(QString("weather"))].toString().count(), - 1); + +void TestExtWeather::test_runYahoo() +{ + extWeather->setProvider(ExtWeather::Provider::Yahoo); + run(); + extWeather->setProvider(ExtWeather::Provider::OWM); } void TestExtWeather::test_ts() { extWeather->setTs(1); - // init spy - QSignalSpy spy(extWeather, SIGNAL(dataReceived(const QVariantHash &))); - QVariantHash firstValue = extWeather->run(); - - // check values - QVERIFY(spy.wait(5000)); - QVariantHash arguments = spy.takeFirst().at(0).toHash(); - QEXPECT_FAIL("", "WeatherID should not be 0", Continue); - QCOMPARE(arguments[extWeather->tag(QString("weatherId"))].toInt(), 0); - QCOMPARE(arguments[extWeather->tag(QString("humidity"))].toInt(), 0); - QCOMPARE(arguments[extWeather->tag(QString("pressure"))].toFloat(), 0.0f); - QVERIFY((arguments[extWeather->tag(QString("temperature"))].toFloat() - > temp.first) - && (arguments[extWeather->tag(QString("temperature"))].toInt() - < temp.second)); - // image should be only one symbol here - QCOMPARE(arguments[extWeather->tag(QString("weather"))].toString().count(), - 1); + run(); } @@ -131,10 +98,43 @@ void TestExtWeather::test_copy() QCOMPARE(newExtWeather->country(), extWeather->country()); QCOMPARE(newExtWeather->ts(), extWeather->ts()); QCOMPARE(newExtWeather->image(), extWeather->image()); + QCOMPARE(newExtWeather->provider(), extWeather->provider()); QCOMPARE(newExtWeather->number(), 1); delete newExtWeather; } +void TestExtWeather::run() +{ + // init spy + QSignalSpy spy(extWeather, SIGNAL(dataReceived(const QVariantHash &))); + QVariantHash firstValue = extWeather->run(); + + // check values + QVERIFY(spy.wait(5000)); + QVariantHash arguments = spy.takeFirst().at(0).toHash(); + QEXPECT_FAIL("", "WeatherID should not be 0", Continue); + QCOMPARE(arguments[extWeather->tag(QString("weatherId"))].toInt(), 0); + QVERIFY((arguments[extWeather->tag(QString("humidity"))].toInt() + >= humidity.first) + && (arguments[extWeather->tag(QString("humidity"))].toInt() + <= humidity.second)); + QWARN("May fail here for Yahoo! Weather, see " + "https://yahoo.uservoice.com/forums/207813-us-weather/suggestions/" + "14209233-invalid-pressure-calculation"); + QVERIFY((arguments[extWeather->tag(QString("pressure"))].toFloat() + > pressure.first) + && (arguments[extWeather->tag(QString("pressure"))].toInt() + < pressure.second)); + QVERIFY((arguments[extWeather->tag(QString("temperature"))].toFloat() + > temp.first) + && (arguments[extWeather->tag(QString("temperature"))].toInt() + < temp.second)); + // image should be only one symbol here + QCOMPARE(arguments[extWeather->tag(QString("weather"))].toString().count(), + 1); +} + + QTEST_MAIN(TestExtWeather); diff --git a/sources/test/testextweather.h b/sources/test/testextweather.h index 8e28e05..e06cae2 100644 --- a/sources/test/testextweather.h +++ b/sources/test/testextweather.h @@ -34,12 +34,14 @@ private slots: void cleanupTestCase(); // test void test_values(); - void test_run(); + void test_runOWM(); + void test_runYahoo(); void test_ts(); void test_image(); void test_copy(); private: + void run(); ExtWeather *extWeather = nullptr; QString city = QString("London"); QString country = QString("uk"); diff --git a/sources/version.h.in b/sources/version.h.in index 5803bec..4c89f7b 100644 --- a/sources/version.h.in +++ b/sources/version.h.in @@ -19,7 +19,8 @@ "qnetworkreply-network-reply-timeout-helper" #define SPECIAL_THANKS \ "Yahoo! Finance,https://finance.yahoo.com/;Yahoo! " \ - "Weather,https://weather.yahoo.com/;JetBrains,https://www.jetbrains.com/" + "Weather,https://weather.yahoo.com/;JetBrains,https://www.jetbrains.com/" \ + ";OpenWeatherMap,http://openweathermap.org/" #define CHANGELOG "@PROJECT_CHANGELOG@" // configuraion @@ -32,7 +33,7 @@ // extupgrade api version #define AWEUAPI 3 // extweather api version -#define AWEWAPI 2 +#define AWEWAPI 3 // formatter api version #define AWEFAPI 1 // network requests timeout, ms