diff --git a/src/blackcore/pluginmanagerweatherdata.cpp b/src/blackcore/pluginmanagerweatherdata.cpp new file mode 100644 index 000000000..108e56cd9 --- /dev/null +++ b/src/blackcore/pluginmanagerweatherdata.cpp @@ -0,0 +1,69 @@ +/* Copyright (C) 2016 + * swift Project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +#include "pluginmanagerweatherdata.h" +#include "weatherdata.h" +#include +#include + +namespace BlackCore +{ + + using namespace BlackMisc; + + CPluginManagerWeatherData::CPluginManagerWeatherData(QObject *parent) : IPluginManager(parent) + { + } + + IWeatherDataFactory *CPluginManagerWeatherData::getFactory(const QString &pluginId) + { + return getPluginById(pluginId); + } + + Weather::CWeatherDataPluginInfoList CPluginManagerWeatherData::getAvailableWeatherDataPlugins() const + { + BlackMisc::Weather::CWeatherDataPluginInfoList list; + for (const auto &i : m_plugins.values()) + { + list.push_back(i.info); + } + return list; + } + + void CPluginManagerWeatherData::collectPlugins() + { + IPluginManager::collectPlugins(); + + const CSequence &plugins = getPlugins(); + for (const QJsonObject &json : plugins) + { + QString iid = json["IID"].toString(); + if (iid == QStringLiteral("org.swift-project.blackcore.weatherdata")) + { + // PluginExtended() instead of {} to silence wrong warning for gcc < 5.X + auto it = m_plugins.insert(pluginIdentifier(json), PluginExtended()); + it->info.convertFromJson(json); + } + } + } + + BlackMisc::CSequence CPluginManagerWeatherData::acceptedIids() const + { + return + { + QStringLiteral("org.swift-project.blackcore.weatherdata") + }; + } + + QString CPluginManagerWeatherData::pluginDirectory() const + { + return qApp->applicationDirPath() % QStringLiteral("/plugins/weatherdata"); + } + +} diff --git a/src/blackcore/pluginmanagerweatherdata.h b/src/blackcore/pluginmanagerweatherdata.h new file mode 100644 index 000000000..960ce2dda --- /dev/null +++ b/src/blackcore/pluginmanagerweatherdata.h @@ -0,0 +1,66 @@ +/* Copyright (C) 2016 + * swift Project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +//! \file + +#ifndef BLACKCORE_PLUGINMANAGERWEATHERDATA_H +#define BLACKCORE_PLUGINMANAGERWEATHERDATA_H + +#include "blackcoreexport.h" +#include "pluginmanager.h" +#include "blackmisc/weather/weatherdataplugininfolist.h" +#include + +namespace BlackCore +{ + class IWeatherDataFactory; + class IWeatherData; + + /*! + * Manages plugins of type WeatherData. + */ + class BLACKCORE_EXPORT CPluginManagerWeatherData : + public BlackCore::IPluginManager + { + Q_OBJECT + + public: + //! Ctor + CPluginManagerWeatherData(QObject *parent = nullptr); + + //! Get weatherdata factory from the plugin + IWeatherDataFactory *getFactory(const QString &pluginId); + + //! Get all weather data plugins + BlackMisc::Weather::CWeatherDataPluginInfoList getAvailableWeatherDataPlugins() const; + + //! \copydoc BlackCore::IPluginManager::collectPlugins() + virtual void collectPlugins() override; + + protected: + //! \copydoc BlackCore::IPluginManager::acceptedIids() + virtual BlackMisc::CSequence acceptedIids() const override; + + //! \copydoc BlackCore::IPluginManager::pluginDirectory() + virtual QString pluginDirectory() const override; + + private: + //! Extended data for plugin + struct PluginExtended + { + BlackMisc::Weather::CWeatherDataPluginInfo info; + QHash storage; //!< Permanent plugin storage - data stored here will be kept even when plugin is unloaded + }; + + QMap m_plugins; //!< Id <-> extended data pairs + }; + +} // namespace + +#endif // guard diff --git a/src/blackcore/weatherdata.cpp b/src/blackcore/weatherdata.cpp new file mode 100644 index 000000000..f08b730a1 --- /dev/null +++ b/src/blackcore/weatherdata.cpp @@ -0,0 +1,15 @@ +/* Copyright (C) 2016 + * swift Project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +#include "weatherdata.h" + +namespace BlackCore +{ + +} // namespace diff --git a/src/blackcore/weatherdata.h b/src/blackcore/weatherdata.h new file mode 100644 index 000000000..ec59da503 --- /dev/null +++ b/src/blackcore/weatherdata.h @@ -0,0 +1,67 @@ +/* Copyright (C) 2016 + * swift Project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +//! \file + +#ifndef BLACKCORE_WEATHERDATA_H +#define BLACKCORE_WEATHERDATA_H + +#include "blackcoreexport.h" +#include "blackmisc/geo/latitude.h" +#include "blackmisc/geo/longitude.h" +#include "blackmisc/weather/gridpoint.h" +#include "blackmisc/weather/weathergrid.h" +#include + +namespace BlackCore +{ + + /*! + * Interface to weather data + */ + class BLACKCORE_EXPORT IWeatherData : public QObject + { + Q_OBJECT + + public: + //! Destructor + virtual ~IWeatherData() {} + + //! Fetch new weather data + virtual void fetchWeatherData(const BlackMisc::Geo::CLatitude &latitude, const BlackMisc::Geo::CLongitude &longitude, double maxDistance = -1) = 0; + + //! Get fetched weather data + virtual BlackMisc::Weather::CWeatherGrid getWeatherData() const = 0; + + signals: + //! Finished fetching data + void fetchingFinished(); + + protected: + //! Default constructor + IWeatherData(QObject *parent = nullptr) : QObject(parent) {} + }; + + /*! + * Factory pattern class to create instances of IWeatherData + */ + class BLACKCORE_EXPORT IWeatherDataFactory + { + public: + //! Virtual destructor + virtual ~IWeatherDataFactory() {} + + //! Create a new instance + virtual IWeatherData *create(QObject *parent = nullptr) = 0; + }; +} // namespace + +Q_DECLARE_INTERFACE(BlackCore::IWeatherDataFactory, "org.swift-project.blackcore.weatherdata") + +#endif // guard diff --git a/src/blackmisc/weather/weatherdataplugininfo.cpp b/src/blackmisc/weather/weatherdataplugininfo.cpp new file mode 100644 index 000000000..903022776 --- /dev/null +++ b/src/blackmisc/weather/weatherdataplugininfo.cpp @@ -0,0 +1,43 @@ +/* Copyright (C) 2016 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +#include "weatherdataplugininfo.h" + +using namespace BlackMisc; + +namespace BlackMisc +{ + namespace Weather + { + CWeatherDataPluginInfo::CWeatherDataPluginInfo(const QString &identifier, const QString &name, const QString &description, bool valid) : + m_identifier(identifier), m_name(name), m_description(description), m_valid(valid) + { } + + void CWeatherDataPluginInfo::convertFromJson(const QJsonObject &json) + { + if (json.contains("IID")) // comes from the plugin + { + // json data is already validated by CPluginManagerWeatherData + CValueObject::convertFromJson(json["MetaData"].toObject()); + m_valid = true; + } + else + { + CValueObject::convertFromJson(json); + } + } + + QString CWeatherDataPluginInfo::convertToQString(bool i18n) const + { + Q_UNUSED(i18n); + return QString("%1 (%2)").arg(m_name, m_identifier); + } + + } // ns +} // ns diff --git a/src/blackmisc/weather/weatherdataplugininfo.h b/src/blackmisc/weather/weatherdataplugininfo.h new file mode 100644 index 000000000..136bb919e --- /dev/null +++ b/src/blackmisc/weather/weatherdataplugininfo.h @@ -0,0 +1,72 @@ +/* Copyright (C) 2016 + * swift Project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +//! \file + +#ifndef BLACKMISC_WEATHER_WEATHERDATAPLUGININFO_H +#define BLACKMISC_WEATHER_WEATHERDATAPLUGININFO_H + +#include "blackmisc/blackmiscexport.h" +#include "blackmisc/valueobject.h" + +namespace BlackMisc +{ + namespace Weather + { + //! Describing a weather data plugin + class BLACKMISC_EXPORT CWeatherDataPluginInfo : public BlackMisc::CValueObject + { + public: + //! Default constructor + CWeatherDataPluginInfo() = default; + + //! Constructor (used with unit tests) + CWeatherDataPluginInfo(const QString &identifier, const QString &name, + const QString &description, bool valid); + + //! \copydoc BlackMisc::CValueObject::convertFromJson + void convertFromJson(const QJsonObject &json); + + //! Check if the provided plugin metadata is valid. + //! Weather data plugin has to meet the following requirements: + //! * implements org.swift-project.blackcore.weatherdata; + //! * provides plugin name; + bool isValid() const { return m_valid; } + + //! Identifier + const QString &getIdentifier() const { return m_identifier; } + + //! Name + const QString &getName() const { return m_name; } + + //! Description + const QString &getDescription() const { return m_description; } + + //! \copydoc CValueObject::convertToQString + QString convertToQString(bool i18n = false) const; + + private: + BLACK_ENABLE_TUPLE_CONVERSION(CWeatherDataPluginInfo) + QString m_identifier; + QString m_name; + QString m_description; + bool m_valid { false }; + }; + } // ns +} // ns + +BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Weather::CWeatherDataPluginInfo, ( + attr(o.m_identifier, flags ()), + attr(o.m_name, flags < DisabledForComparison | DisabledForHashing > ()), + attr(o.m_description, flags < DisabledForComparison | DisabledForHashing > ()), + attr(o.m_valid, flags < DisabledForComparison | DisabledForHashing > ()) + )) +Q_DECLARE_METATYPE(BlackMisc::Weather::CWeatherDataPluginInfo) + +#endif // guard diff --git a/src/blackmisc/weather/weatherdataplugininfolist.cpp b/src/blackmisc/weather/weatherdataplugininfolist.cpp new file mode 100644 index 000000000..bbe4cf7aa --- /dev/null +++ b/src/blackmisc/weather/weatherdataplugininfolist.cpp @@ -0,0 +1,25 @@ +/* Copyright (C) 2016 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +#include "weatherdataplugininfolist.h" + +namespace BlackMisc +{ + namespace Weather + { + + CWeatherDataPluginInfoList::CWeatherDataPluginInfoList() { } + + QStringList CWeatherDataPluginInfoList::toStringList(bool i18n) const + { + return this->transform([i18n](const CWeatherDataPluginInfo & info) { return info.toQString(i18n); }); + } + + } // namespace +} // namespace diff --git a/src/blackmisc/weather/weatherdataplugininfolist.h b/src/blackmisc/weather/weatherdataplugininfolist.h new file mode 100644 index 000000000..874087ed6 --- /dev/null +++ b/src/blackmisc/weather/weatherdataplugininfolist.h @@ -0,0 +1,50 @@ +/* Copyright (C) 2016 + * swift Project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +//! \file + +#ifndef BLACKMISC_WEATHER_WEATHERDATAPLUGININFOLIST_H +#define BLACKMISC_WEATHER_WEATHERDATAPLUGININFOLIST_H + +#include "weatherdataplugininfo.h" +#include "blackmisc/blackmiscexport.h" +#include "blackmisc/sequence.h" +#include "blackmisc/collection.h" +#include + +namespace BlackMisc +{ + namespace Weather + { + //! Value object encapsulating a list of CWeatherDataPluginInfo objects. + class BLACKMISC_EXPORT CWeatherDataPluginInfoList : + public BlackMisc::CSequence, + public BlackMisc::Mixin::MetaType + { + public: + BLACKMISC_DECLARE_USING_MIXIN_METATYPE(CWeatherDataPluginInfoList) + + //! Default constructor + CWeatherDataPluginInfoList(); + + //! Construct from a base class object. + CWeatherDataPluginInfoList(const CSequence &other); + + //! String list with meaningful representations + QStringList toStringList(bool i18n = false) const; + + }; + } // ns +} // ns + +Q_DECLARE_METATYPE(BlackMisc::Weather::CWeatherDataPluginInfoList) +Q_DECLARE_METATYPE(BlackMisc::CCollection) +Q_DECLARE_METATYPE(BlackMisc::CSequence) + +#endif // guard