Commit 5c78fe6c authored by Volker Krause's avatar Volker Krause

Add infrastructure for supporting multiple backends

parent 7fa7ea4a
......@@ -6,6 +6,8 @@ set(kpublictransport_srcs
manager.cpp
reply.cpp
backends/abstractbackend.cpp
backends/navitiabackend.cpp
backends/navitiaclient.cpp
backends/navitiaparser.cpp
......@@ -13,6 +15,8 @@ set(kpublictransport_srcs
datatypes/journey.cpp
datatypes/line.cpp
datatypes/location.cpp
networks/networks.qrc
)
ecm_qt_declare_logging_category(kpublictransport_srcs HEADER logging.h IDENTIFIER KPublicTransport::Log CATEGORY_NAME org.kde.kpublictransport)
......
/*
Copyright (C) 2018 Volker Krause <vkrause@kde.org>
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This program 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 Library General Public
License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "abstractbackend.h"
using namespace KPublicTransport;
AbstractBackend::AbstractBackend() = default;
AbstractBackend::~AbstractBackend() = default;
bool AbstractBackend::queryDeparture(DepartureReply *reply, QNetworkAccessManager *nam)
{
Q_UNUSED(reply);
Q_UNUSED(nam);
return false;
}
bool AbstractBackend::queryJourney(JourneyReply *reply, QNetworkAccessManager *nam)
{
Q_UNUSED(reply);
Q_UNUSED(nam);
return false;
}
/*
Copyright (C) 2018 Volker Krause <vkrause@kde.org>
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This program 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 Library General Public
License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef KPUBLICTRANSPORT_ABSTRACTBACKEND_H
#define KPUBLICTRANSPORT_ABSTRACTBACKEND_H
#include <qobjectdefs.h>
class QNetworkAccessManager;
namespace KPublicTransport {
class DepartureReply;
class JourneyReply;
/** Abstract base class for transport provider backends. */
class AbstractBackend
{
Q_GADGET
public:
AbstractBackend();
virtual ~AbstractBackend();
/** Perform a journey query.
* @return @c true if performing an async operation, @c false otherwise.
*/
virtual bool queryJourney(JourneyReply *reply, QNetworkAccessManager *nam);
/** Perform a departure query.
* @return @c true if performing an async operation, @c false otherwise.
*/
virtual bool queryDeparture(DepartureReply *reply, QNetworkAccessManager *nam);
private:
Q_DISABLE_COPY(AbstractBackend)
};
}
#endif // KPUBLICTRANSPORT_ABSTRACTBACKEND_H
/*
Copyright (C) 2018 Volker Krause <vkrause@kde.org>
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This program 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 Library General Public
License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "navitiabackend.h"
using namespace KPublicTransport;
NavitiaBackend::NavitiaBackend() = default;
bool NavitiaBackend::queryDeparture(DepartureReply *reply, QNetworkAccessManager *nam)
{
return true;
}
bool NavitiaBackend::queryJourney(JourneyReply *reply, QNetworkAccessManager *nam)
{
return true;
}
/*
Copyright (C) 2018 Volker Krause <vkrause@kde.org>
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This program 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 Library General Public
License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef KPUBLICTRANSPORT_NAVITIABACKEND_H
#define KPUBLICTRANSPORT_NAVITIABACKEND_H
#include "abstractbackend.h"
#include <QString>
namespace KPublicTransport {
/** Backend for Navitia-based providers. */
class NavitiaBackend : public AbstractBackend
{
Q_GADGET
Q_PROPERTY(QString endpoint MEMBER m_endpoint)
Q_PROPERTY(QString coverage MEMBER m_coverage)
Q_PROPERTY(QString authorization MEMBER m_auth)
public:
NavitiaBackend();
bool queryJourney(JourneyReply *reply, QNetworkAccessManager *nam) override;
bool queryDeparture(DepartureReply *reply, QNetworkAccessManager *nam) override;
private:
QString m_endpoint;
QString m_coverage;
QString m_auth;
};
}
#endif // KPUBLICTRANSPORT_NAVITIABACKEND_H
......@@ -18,17 +18,32 @@
#include "manager.h"
#include "departurereply.h"
#include "journeyreply.h"
#include "logging.h"
#include "backends/navitiabackend.h"
#include <QDirIterator>
#include <QJsonDocument>
#include <QJsonObject>
#include <QMetaProperty>
#include <QNetworkAccessManager>
using namespace KPublicTransport;
static inline void initResources() {
Q_INIT_RESOURCE(networks);
}
namespace KPublicTransport {
class ManagerPrivate {
public:
QNetworkAccessManager* nam();
void loadNetworks();
std::unique_ptr<AbstractBackend> loadNetwork(const QJsonObject &obj);
template <typename T> std::unique_ptr<AbstractBackend> loadNetwork(const QJsonObject &obj);
QNetworkAccessManager *m_nam = nullptr;
std::vector<std::unique_ptr<AbstractBackend>> m_backends;
};
}
......@@ -40,10 +55,58 @@ QNetworkAccessManager* ManagerPrivate::nam()
return m_nam;
}
void ManagerPrivate::loadNetworks()
{
QDirIterator it(QStringLiteral(":/org.kde.pim/kpublictransport/networks"));
while (it.hasNext()) {
QFile f(it.next());
if (!f.open(QFile::ReadOnly)) {
qCWarning(Log) << "Failed to open public transport network configuration:" << f.errorString();
continue;
}
const auto doc = QJsonDocument::fromJson(f.readAll());
auto net = loadNetwork(doc.object());
if (net) {
m_backends.push_back(std::move(net));
}
}
qCDebug(Log) << m_backends.size() << "public transport network configurations loaded";
}
std::unique_ptr<AbstractBackend> ManagerPrivate::loadNetwork(const QJsonObject &obj)
{
const auto type = obj.value(QLatin1String("type")).toString();
if (type == QLatin1String("navitia")) {
return loadNetwork<NavitiaBackend>(obj);
}
return {};
}
static void applyBackendOptions(void *backend, const QMetaObject *mo, const QJsonObject &obj)
{
const auto opts = obj.value(QLatin1String("options")).toObject();
for (auto it = opts.begin(); it != opts.end(); ++it) {
const auto idx = mo->indexOfProperty(it.key().toUtf8());
const auto mp = mo->property(idx);
mp.writeOnGadget(backend, it.value().toVariant());
}
}
template<typename T> std::unique_ptr<AbstractBackend> ManagerPrivate::loadNetwork(const QJsonObject &obj)
{
std::unique_ptr<AbstractBackend> backend(new T);
applyBackendOptions(backend.get(), &T::staticMetaObject, obj);
return backend;
}
Manager::Manager() :
d(new ManagerPrivate)
{
initResources();
d->loadNetworks();
}
Manager::Manager(Manager&&) noexcept = default;
......
{
"type": "navitia",
"options": {
"endpoint": "api.navitia.io",
"authorization": "48ed1733-d3f0-445a-9210-9fb36e20a8a3"
}
}
<RCC>
<qresource prefix="/org.kde.pim/kpublictransport/networks">
<file>navitia.json</file>
<file>sncf.json</file>
</qresource>
</RCC>
{
"type": "navitia",
"options": {
"endpoint": "api.sncf.com",
"coverage": "sncf",
"authorization": "f0f7fc73-c7f6-4f1d-8ae0-fd1e7bd20271"
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment