diff --git a/src/publictransport/CMakeLists.txt b/src/publictransport/CMakeLists.txt index be149ca..b848a88 100644 --- a/src/publictransport/CMakeLists.txt +++ b/src/publictransport/CMakeLists.txt @@ -1,44 +1,51 @@ set(kpublictransport_srcs + manager.cpp + journeyreply.cpp + journeyrequest.cpp + backends/navitiaclient.cpp backends/navitiaparser.cpp datatypes/journey.cpp datatypes/line.cpp datatypes/location.cpp ) ecm_qt_declare_logging_category(kpublictransport_srcs HEADER logging.h IDENTIFIER KPublicTransport::Log CATEGORY_NAME org.kde.kpublictransport) add_library(KPublicTransport STATIC ${kpublictransport_srcs}) target_include_directories(KPublicTransport PUBLIC "$") target_link_libraries(KPublicTransport PUBLIC Qt5::Gui PRIVATE Qt5::Network ) -# ecm_generate_headers(KPublicTransport_FORWARDING_HEADERS -# HEADER_NAMES -# PREFIX KPublicTransport -# REQUIRED_HEADERS KPublicTransport_HEADERS -# ) -# ### for testing only +ecm_generate_headers(KPublicTransport_FORWARDING_HEADERS + HEADER_NAMES + JourneyReply + JourneyRequest + Manager + PREFIX KPublicTransport + REQUIRED_HEADERS KPublicTransport_HEADERS +) +# # ### for testing only ecm_generate_headers(KPublicTransport_Backends_FORWARDING_HEADERS HEADER_NAMES NavitiaClient NavitiaParser PREFIX KPublicTransport REQUIRED_HEADERS KPublicTransport_Backends_HEADERS RELATIVE backends ) ecm_generate_headers(KPublicTransport_Datatypes_FORWARDING_HEADERS HEADER_NAMES Datatypes Journey Line Location PREFIX KPublicTransport REQUIRED_HEADERS KPublicTransport_Datatypes_HEADERS RELATIVE datatypes ) diff --git a/src/publictransport/journeyreply.cpp b/src/publictransport/journeyreply.cpp new file mode 100644 index 0000000..5a2efdb --- /dev/null +++ b/src/publictransport/journeyreply.cpp @@ -0,0 +1,62 @@ +/* + Copyright (C) 2018 Volker Krause + + 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 . +*/ + +#include "journeyreply.h" +#include "journeyrequest.h" + +#include "backends/navitiaclient.h" +#include "backends/navitiaparser.h" + +#include +#include + +#include +#include + +using namespace KPublicTransport; + +namespace KPublicTransport { +class JourneyReplyPrivate { +public: + std::vector journeys; +}; +} + +JourneyReply::JourneyReply(const JourneyRequest &req, QNetworkAccessManager *nam) + : d(new JourneyReplyPrivate) +{ + auto reply = NavitiaClient::findJourney(req.from(), req.to(), QDateTime::currentDateTime(), nam); + connect(reply, &QNetworkReply::finished, [reply, this] { + if (reply->error() != QNetworkReply::NoError) { + qDebug() << reply->errorString(); + // TODO + } else { + d->journeys = NavitiaParser::parseJourneys(reply->readAll()); + } + + emit finished(); + deleteLater(); + }); +} + +JourneyReply::~JourneyReply() = default; + +std::vector JourneyReply::journeys() const +{ + // TODO avoid the copy here + return d->journeys; +} diff --git a/src/publictransport/journeyreply.h b/src/publictransport/journeyreply.h new file mode 100644 index 0000000..cfe7186 --- /dev/null +++ b/src/publictransport/journeyreply.h @@ -0,0 +1,57 @@ +/* + Copyright (C) 2018 Volker Krause + + 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 . +*/ + +#ifndef KPUBLICTRANSPORT_JOURNEYREPLY_H +#define KPUBLICTRANSPORT_JOURNEYREPLY_H + +#include + +#include +#include + +class QNetworkAccessManager; + +namespace KPublicTransport { + +class Journey; +class JourneyReplyPrivate; +class JourneyRequest; + +/** Journey query response. */ +class JourneyReply : public QObject +{ + Q_OBJECT +public: + ~JourneyReply(); + + /** Returns the found journeys. */ + std::vector journeys() const; + + // TODO error messages +Q_SIGNALS: + /** Emitted whenever the journey search has been completed. */ + void finished(); + +private: + friend class Manager; + explicit JourneyReply(const JourneyRequest &req, QNetworkAccessManager *nam); + std::unique_ptr d; +}; + +} + +#endif // KPUBLICTRANSPORT_JOURNEYREPLY_H diff --git a/src/publictransport/journeyrequest.cpp b/src/publictransport/journeyrequest.cpp new file mode 100644 index 0000000..2455aeb --- /dev/null +++ b/src/publictransport/journeyrequest.cpp @@ -0,0 +1,59 @@ +/* + Copyright (C) 2018 Volker Krause + + 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 . +*/ + +#include "journeyrequest.h" + +#include + +#include + +using namespace KPublicTransport; + +namespace KPublicTransport { +class JourneyRequestPrivate : public QSharedData { +public: + Location from; + Location to; +}; +} + +JourneyRequest::JourneyRequest() : + d(new JourneyRequestPrivate) +{ +} + +JourneyRequest::JourneyRequest(const Location &from, const Location &to) + : d(new JourneyRequestPrivate) +{ + d->from = from; + d->to = to; +} + +JourneyRequest::JourneyRequest(JourneyRequest&&) noexcept = default; +JourneyRequest::JourneyRequest(const JourneyRequest&) = default; +JourneyRequest::~JourneyRequest() = default; +JourneyRequest& JourneyRequest::operator=(const JourneyRequest&) = default; + +Location JourneyRequest::from() const +{ + return d->from; +} + +Location JourneyRequest::to() const +{ + return d->to; +} diff --git a/src/publictransport/journeyrequest.h b/src/publictransport/journeyrequest.h new file mode 100644 index 0000000..29f38bc --- /dev/null +++ b/src/publictransport/journeyrequest.h @@ -0,0 +1,50 @@ +/* + Copyright (C) 2018 Volker Krause + + 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 . +*/ + +#ifndef KPUBLICTRANSPORT_JOURNEYREQUEST_H +#define KPUBLICTRANSPORT_JOURNEYREQUEST_H + +#include + +namespace KPublicTransport { + +class JourneyRequestPrivate; +class Location; + +/** Descripes a journey search. */ +class JourneyRequest +{ +public: + JourneyRequest(); + JourneyRequest(const Location &from, const Location &to); + JourneyRequest(JourneyRequest&&) noexcept; + JourneyRequest(const JourneyRequest &); + ~JourneyRequest(); + JourneyRequest& operator=(const JourneyRequest&); + + Location from() const; + Location to() const; + + // TODO departure/arrival time settings + +private: + QExplicitlySharedDataPointer d; +}; + +} + +#endif // KPUBLICTRANSPORT_JOURNEYREQUEST_H diff --git a/src/publictransport/manager.cpp b/src/publictransport/manager.cpp new file mode 100644 index 0000000..567d215 --- /dev/null +++ b/src/publictransport/manager.cpp @@ -0,0 +1,60 @@ +/* + Copyright (C) 2018 Volker Krause + + 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 . +*/ + +#include "manager.h" +#include "journeyreply.h" + +#include + +using namespace KPublicTransport; + +namespace KPublicTransport { +class ManagerPrivate { +public: + QNetworkAccessManager* nam(); + + QNetworkAccessManager *m_nam = nullptr; +}; +} + +QNetworkAccessManager* ManagerPrivate::nam() +{ + if (!m_nam) { + m_nam = new QNetworkAccessManager; + } + return m_nam; +} + + +Manager::Manager() : + d(new ManagerPrivate) +{ +} + +Manager::Manager(Manager&&) noexcept = default; +Manager::~Manager() = default; + +void Manager::setNetworkAccessManager(QNetworkAccessManager *nam) +{ + // TODO delete d->nam if we created it ourselves + d->m_nam = nam; +} + +JourneyReply* Manager::findJourney(const JourneyRequest &req) const +{ + return new JourneyReply(req, d->nam()); +} diff --git a/src/publictransport/manager.h b/src/publictransport/manager.h new file mode 100644 index 0000000..c9de002 --- /dev/null +++ b/src/publictransport/manager.h @@ -0,0 +1,54 @@ +/* + Copyright (C) 2018 Volker Krause + + 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 . +*/ + +#ifndef KPUBLICTRANSPORT_MANAGER_H +#define KPUBLICTRANSPORT_MANAGER_H + +#include + +class QNetworkAccessManager; + +namespace KPublicTransport { + +class JourneyReply; +class JourneyRequest; +class ManagerPrivate; + +/** Entry point for starting public transport queries. */ +class Manager +{ +public: + Manager(); + Manager(Manager&&) noexcept; + Manager(const Manager&) = delete; + ~Manager(); + + /** Set the network access manager to use for network operations. + * If not set, an instance is created internally. + */ + void setNetworkAccessManager(QNetworkAccessManager *nam); + + /** Query a journey. */ + JourneyReply* findJourney(const JourneyRequest &req) const; + +private: + std::unique_ptr d; +}; + +} + +#endif // KPUBLICTRANSPORT_MANAGER_H diff --git a/tests/journeyquery.cpp b/tests/journeyquery.cpp index cd0c94c..77b4283 100644 --- a/tests/journeyquery.cpp +++ b/tests/journeyquery.cpp @@ -1,84 +1,80 @@ /* Copyright (C) 2018 Volker Krause 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 . */ #include +#include +#include #include #include -#include -#include +#include #include #include #include #include #include #include -#include #include using namespace KPublicTransport; int main(int argc, char **argv) { QCoreApplication::setApplicationName(QStringLiteral("journeyquery")); QCoreApplication::setOrganizationName(QStringLiteral("KDE")); QCoreApplication::setOrganizationDomain(QStringLiteral("kde.org")); QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); QGuiApplication app(argc, argv); qmlRegisterUncreatableType("org.kde.kpublictransport", 1, 0, "Line", {}); qmlRegisterUncreatableType("org.kde.kpublictransport", 1, 0, "JourneySection", {}); QQmlApplicationEngine engine; engine.load(QStringLiteral("qrc:/journeyquery.qml")); QNetworkAccessManager nam; + Manager ptMgr; + ptMgr.setNetworkAccessManager(&nam); Location from; from.setCoordinate(2.57110, 49.00406); Location to; to.setCoordinate(2.37708, 48.84388); - auto reply = NavitiaClient::findJourney(from, to, QDateTime::currentDateTime(), &nam); - QObject::connect(reply, &QNetworkReply::finished, [reply, &app, &engine]{ - if (reply->error() != QNetworkReply::NoError) { - qDebug() << reply->errorString(); - app.exit(); - } else { - qDebug() << "Success!"; - auto res = NavitiaParser::parseJourneys(reply->readAll()); - QVariantList l; - l.reserve(res.size()); - std::transform(res.begin(), res.end(), std::back_inserter(l), [](const auto &journey) { return QVariant::fromValue(journey); }); - engine.rootContext()->setContextProperty(QStringLiteral("_journeys"), l); - - for (const auto &journey : res) { - qDebug() << journey.sections().size(); - for (const auto §ion : journey.sections()) { - qDebug() << " From" << section.from().name() << section.departureTime(); - qDebug() << " Mode" << section.mode() << section.route().line().name() << section.route().direction() << section.route().line().modeString(); - qDebug() << " To" << section.to().name() << section.arrivalTime(); - } + auto reply = ptMgr.findJourney({from, to}); + QObject::connect(reply, &JourneyReply::finished, [reply, &app, &engine]{ + const auto res = reply->journeys(); + QVariantList l; + l.reserve(res.size()); + std::transform(res.begin(), res.end(), std::back_inserter(l), [](const auto &journey) { return QVariant::fromValue(journey); }); + engine.rootContext()->setContextProperty(QStringLiteral("_journeys"), l); + + for (const auto &journey : res) { + qDebug() << journey.sections().size(); + for (const auto §ion : journey.sections()) { + qDebug() << " From" << section.from().name() << section.departureTime(); + qDebug() << " Mode" << section.mode() << section.route().line().name() << section.route().direction() << section.route().line().modeString(); + qDebug() << " To" << section.to().name() << section.arrivalTime(); } } }); return app.exec(); }