File indexing completed on 2025-01-12 05:01:49

0001 /*
0002     SPDX-FileCopyrightText: 2007-2009 Shawn Starr <shawn.starr@rogers.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 /* Ion for BBC Weather from UKMET Office */
0008 
0009 #pragma once
0010 
0011 #include "../ion.h"
0012 
0013 #include <Plasma5Support/DataEngineConsumer>
0014 
0015 #include <QDateTime>
0016 #include <QList>
0017 
0018 class KJob;
0019 namespace KIO
0020 {
0021 class Job;
0022 class TransferJob;
0023 }
0024 class QXmlStreamReader;
0025 
0026 class WeatherData
0027 {
0028 public:
0029     WeatherData();
0030 
0031     QString place;
0032     QString stationName;
0033     double stationLatitude;
0034     double stationLongitude;
0035 
0036     // Current observation information.
0037     QString obsTime;
0038     QDateTime observationDateTime;
0039 
0040     QString condition;
0041     QString conditionIcon;
0042     float temperature_C;
0043     QString windDirection;
0044     float windSpeed_miles;
0045     float humidity;
0046     float pressure;
0047     QString pressureTendency;
0048     QString visibilityStr;
0049 
0050     QString solarDataTimeEngineSourceName;
0051     bool isNight = false;
0052     bool isSolarDataPending = false;
0053 
0054     // Five day forecast
0055     struct ForecastInfo {
0056         ForecastInfo();
0057         QString period;
0058         QString iconName;
0059         QString summary;
0060         float tempHigh;
0061         float tempLow;
0062         float windSpeed;
0063         QString windDirection;
0064     };
0065 
0066     // 5 day Forecast
0067     QList<WeatherData::ForecastInfo *> forecasts;
0068 
0069     bool isForecastsDataPending = false;
0070 };
0071 
0072 Q_DECLARE_TYPEINFO(WeatherData::ForecastInfo, Q_RELOCATABLE_TYPE);
0073 Q_DECLARE_TYPEINFO(WeatherData, Q_RELOCATABLE_TYPE);
0074 
0075 class Q_DECL_EXPORT UKMETIon : public IonInterface, public Plasma5Support::DataEngineConsumer
0076 {
0077     Q_OBJECT
0078 
0079 public:
0080     UKMETIon(QObject *parent);
0081     ~UKMETIon() override;
0082 
0083 public: // IonInterface API
0084     bool updateIonSource(const QString &source) override;
0085 
0086 public Q_SLOTS:
0087     // for solar data pushes from the time engine
0088     void dataUpdated(const QString &sourceName, const Plasma5Support::DataEngine::Data &data);
0089 
0090 protected: // IonInterface API
0091     void reset() override;
0092 
0093 private Q_SLOTS:
0094     void setup_slotDataArrived(KIO::Job *, const QByteArray &);
0095     void setup_slotJobFinished(KJob *, const QString &);
0096     // void setup_slotRedirected(KIO::Job *, const KUrl &url);
0097 
0098     void observation_slotDataArrived(KIO::Job *, const QByteArray &);
0099     void observation_slotJobFinished(KJob *);
0100 
0101     void forecast_slotDataArrived(KIO::Job *, const QByteArray &);
0102     void forecast_slotJobFinished(KJob *);
0103 
0104 private:
0105     void updateWeather(const QString &source);
0106 
0107     // bool night(const QString& source) const;
0108 
0109     /* UKMET Methods - Internal for Ion */
0110     QMap<QString, ConditionIcons> setupDayIconMappings() const;
0111     QMap<QString, ConditionIcons> setupNightIconMappings() const;
0112     QMap<QString, IonInterface::WindDirections> setupWindIconMappings() const;
0113 
0114     QMap<QString, ConditionIcons> const &nightIcons() const;
0115     QMap<QString, ConditionIcons> const &dayIcons() const;
0116     QMap<QString, IonInterface::WindDirections> const &windIcons() const;
0117 
0118     // Load and Parse the place search XML listings
0119     void findPlace(const QString &place, const QString &source);
0120     void validate(const QString &source); // Sync data source with Applet
0121     void getFiveDayForecast(const QString &source);
0122     void getXMLData(const QString &source);
0123     void readSearchHTMLData(const QString &source, const QList<QByteArray *> htmls);
0124     bool readFiveDayForecastXMLData(const QString &source, QXmlStreamReader &xml);
0125     void parseSearchLocations(const QString &source, QXmlStreamReader &xml);
0126 
0127     // Observation parsing methods
0128     bool readObservationXMLData(const QString &source, QXmlStreamReader &xml);
0129     void parsePlaceObservation(const QString &source, WeatherData &data, QXmlStreamReader &xml);
0130     void parseWeatherChannel(const QString &source, WeatherData &data, QXmlStreamReader &xml);
0131     void parseWeatherObservation(const QString &source, WeatherData &data, QXmlStreamReader &xml);
0132     void parseFiveDayForecast(const QString &source, QXmlStreamReader &xml);
0133     void parsePlaceForecast(const QString &source, QXmlStreamReader &xml);
0134     void parseWeatherForecast(const QString &source, QXmlStreamReader &xml);
0135     void parseUnknownElement(QXmlStreamReader &xml) const;
0136 
0137     void parseFloat(float &value, const QString &string);
0138 
0139     void deleteForecasts();
0140 
0141 private:
0142     struct XMLMapInfo {
0143         QString stationId;
0144         QString place;
0145         QString forecastHTMLUrl;
0146         QString sourceExtraArg;
0147     };
0148 
0149     // Key dicts
0150     QHash<QString, UKMETIon::XMLMapInfo> m_place;
0151     QList<QString> m_locations;
0152 
0153     // Weather information
0154     QHash<QString, WeatherData> m_weatherData;
0155 
0156     // Store KIO jobs - Search list
0157     QHash<KJob *, QByteArray *> m_jobHtml;
0158     QHash<KJob *, QString> m_jobList;
0159 
0160     bool m_normalSearchArrived = false;
0161     bool m_autoSearchArrived = false;
0162 
0163     QHash<KJob *, QXmlStreamReader *> m_obsJobXml;
0164     QHash<KJob *, QString> m_obsJobList;
0165 
0166     QHash<KJob *, QXmlStreamReader *> m_forecastJobXml;
0167     QHash<KJob *, QString> m_forecastJobList;
0168 
0169     QStringList m_sourcesToReset;
0170 };