File indexing completed on 2024-05-12 04:42:47

0001 /*
0002     SPDX-FileCopyrightText: 2020 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #ifndef KPUBLICTRANSPORT_GBFSJOB_H
0008 #define KPUBLICTRANSPORT_GBFSJOB_H
0009 
0010 #include "kpublictransport_export.h"
0011 #include "gbfsservice.h"
0012 #include "gbfsstore.h"
0013 
0014 #include <QJsonArray>
0015 #include <QJsonDocument>
0016 #include <QObject>
0017 #include <QRectF>
0018 #include <QUrl>
0019 
0020 class QNetworkAccessManager;
0021 class QNetworkReply;
0022 
0023 namespace KPublicTransport {
0024 
0025 /** GBFS fetch job.
0026  *  @internal exported for testing only
0027  *  @see https://github.com/NABSA/gbfs/blob/master/gbfs.md
0028  */
0029 class KPUBLICTRANSPORT_EXPORT GBFSJob : public QObject
0030 {
0031     Q_OBJECT
0032 public:
0033     explicit GBFSJob(QNetworkAccessManager *nam, QObject *parent = nullptr);
0034     ~GBFSJob() override;
0035 
0036     /** Perform GBFS auto-discovery based on the given @p url and update the local state as far as necessary. */
0037     void discoverAndUpdate(const GBFSService &service);
0038 
0039     /** Define which data elements to fetch. */
0040     void setRequestedData(std::vector<GBFS::FileType> &&fileTypes);
0041 
0042     /** The service that is updated, or which has been discovered. */
0043     GBFSService service() const;
0044 
0045     enum Error {
0046         NoError,
0047         NetworkError,
0048         TooManyRequestsError, ///< API endpoint call limit, try again later
0049         DataError,
0050     };
0051     Error error() const;
0052     QString errorMessage() const;
0053 
0054 Q_SIGNALS:
0055     /** Emitted when the discovery and/or update process has finished.
0056      *  This can be immediately (if everything is still up to date).
0057      */
0058     void finished();
0059 
0060 private:
0061     void discoverFinished(QNetworkReply *reply);
0062     void parseDiscoverData();
0063     void processFeeds();
0064     void fetchFinished(QNetworkReply *reply, GBFS::FileType type);
0065     void handleNetworkError(QNetworkReply *reply);
0066     void parseData(const QJsonDocument &doc, GBFS::FileType type);
0067     void parseSystemInformation(const QJsonDocument &doc);
0068     void parseStationInformation(const QJsonDocument &doc);
0069     void parseFreeBikeStatus(const QJsonDocument &doc);
0070     void collectCoordinates(const QJsonArray &array);
0071     void parseVersionData(const QJsonDocument &doc);
0072     void parseGeofencingZones(const QJsonDocument &doc);
0073     void finalize();
0074     bool shouldFetchFile(GBFS::FileType fileType) const;
0075 
0076     enum class State {
0077         Discover,
0078         Version,
0079         DiscoverRestart,
0080         SystemInformation,
0081         Data
0082     };
0083     State m_state = State::Discover;
0084 
0085     QNetworkAccessManager *m_nam = nullptr;
0086     GBFSService m_service;
0087     QUrl m_previousDiscoveryUrl;
0088     GBFSStore m_store;
0089     QJsonDocument m_discoverDoc;
0090     QJsonDocument m_versionDoc;
0091     QJsonArray m_feeds;
0092 
0093     std::vector<GBFS::FileType> m_fileTypes;
0094 
0095     std::vector<double> m_latitudes;
0096     std::vector<double> m_longitudes;
0097 
0098     QString m_errorMsg;
0099     Error m_error = NoError;
0100     int m_pendingJobs = 0;
0101 };
0102 
0103 }
0104 
0105 #endif // KPUBLICTRANSPORT_GBFSJOB_H