File indexing completed on 2024-05-05 05:01:22

0001 // SPDX-FileCopyrightText: 2024 Tobias Fella <tobias.fella@kde.org>
0002 // SPDX-License-Identifier: LGPL-2.0-or-later
0003 
0004 #include "itinerarymodel.h"
0005 
0006 #include <QProcess>
0007 
0008 #include "config-neochat.h"
0009 
0010 #ifndef Q_OS_ANDROID
0011 #include <KIO/ApplicationLauncherJob>
0012 #endif
0013 
0014 ItineraryModel::ItineraryModel(QObject *parent)
0015     : QAbstractListModel(parent)
0016 {
0017 }
0018 
0019 void ItineraryModel::setConnection(NeoChatConnection *connection)
0020 {
0021     if (m_connection == connection) {
0022         return;
0023     }
0024     m_connection = connection;
0025     Q_EMIT connectionChanged();
0026 }
0027 
0028 NeoChatConnection *ItineraryModel::connection() const
0029 {
0030     return m_connection;
0031 }
0032 
0033 QVariant ItineraryModel::data(const QModelIndex &index, int role) const
0034 {
0035     if (!index.isValid()) {
0036         return {};
0037     }
0038     auto row = index.row();
0039     auto data = m_data[row];
0040     if (role == NameRole) {
0041         if (data[QStringLiteral("@type")] == QStringLiteral("TrainReservation")) {
0042             return data[QStringLiteral("reservationFor")][QStringLiteral("trainNumber")];
0043         }
0044         if (data[QStringLiteral("@type")] == QStringLiteral("LodgingReservation")) {
0045             return data[QStringLiteral("reservationFor")][QStringLiteral("name")];
0046         }
0047     }
0048     if (role == TypeRole) {
0049         return data[QStringLiteral("@type")];
0050     }
0051     if (role == DepartureStationRole) {
0052         return data[QStringLiteral("reservationFor")][QStringLiteral("departureStation")][QStringLiteral("name")];
0053     }
0054     if (role == ArrivalStationRole) {
0055         return data[QStringLiteral("reservationFor")][QStringLiteral("arrivalStation")][QStringLiteral("name")];
0056     }
0057     if (role == DepartureTimeRole) {
0058         const auto &time = data[QStringLiteral("reservationFor")][QStringLiteral("departureTime")];
0059         auto dateTime = (time.isString() ? time : time[QStringLiteral("@value")]).toVariant().toDateTime();
0060         if (const auto &timeZone = time[QStringLiteral("timezone")].toString(); timeZone.length() > 0) {
0061             dateTime.setTimeZone(QTimeZone(timeZone.toLatin1().data()));
0062         }
0063         return dateTime.toString(QLocale::system().dateTimeFormat(QLocale::ShortFormat));
0064     }
0065     if (role == ArrivalTimeRole) {
0066         const auto &time = data[QStringLiteral("reservationFor")][QStringLiteral("arrivalTime")];
0067         auto dateTime = (time.isString() ? time : time[QStringLiteral("@value")]).toVariant().toDateTime();
0068         if (const auto &timeZone = time[QStringLiteral("timezone")].toString(); timeZone.length() > 0) {
0069             dateTime.setTimeZone(QTimeZone(timeZone.toLatin1().data()));
0070         }
0071         return dateTime.toString(QLocale::system().dateTimeFormat(QLocale::ShortFormat));
0072     }
0073     if (role == AddressRole) {
0074         const auto &addressData = data[QStringLiteral("reservationFor")][QStringLiteral("address")];
0075         return QStringLiteral("%1 - %2 %3 %4")
0076             .arg(addressData[QStringLiteral("streetAddress")].toString(),
0077                  addressData[QStringLiteral("postalCode")].toString(),
0078                  addressData[QStringLiteral("addressLocality")].toString(),
0079                  addressData[QStringLiteral("addressCountry")].toString());
0080     }
0081     if (role == StartTimeRole) {
0082         auto dateTime = data[QStringLiteral("checkinTime")][QStringLiteral("@value")].toVariant().toDateTime();
0083         return dateTime.toString(QLocale::system().dateTimeFormat(QLocale::ShortFormat));
0084     }
0085     if (role == EndTimeRole) {
0086         auto dateTime = data[QStringLiteral("checkoutTime")][QStringLiteral("@value")].toVariant().toDateTime();
0087         return dateTime.toString(QLocale::system().dateTimeFormat(QLocale::ShortFormat));
0088     }
0089     if (role == DeparturePlatformRole) {
0090         return data[QStringLiteral("reservationFor")][QStringLiteral("departurePlatform")];
0091     }
0092     if (role == ArrivalPlatformRole) {
0093         return data[QStringLiteral("reservationFor")][QStringLiteral("arrivalPlatform")];
0094     }
0095     if (role == CoachRole) {
0096         return data[QStringLiteral("reservedTicket")][QStringLiteral("ticketedSeat")][QStringLiteral("seatSection")];
0097     }
0098     if (role == SeatRole) {
0099         return data[QStringLiteral("reservedTicket")][QStringLiteral("ticketedSeat")][QStringLiteral("seatNumber")];
0100     }
0101     return {};
0102 }
0103 
0104 int ItineraryModel::rowCount(const QModelIndex &parent) const
0105 {
0106     Q_UNUSED(parent);
0107     return m_data.size();
0108 }
0109 
0110 QHash<int, QByteArray> ItineraryModel::roleNames() const
0111 {
0112     return {
0113         {NameRole, "name"},
0114         {TypeRole, "type"},
0115         {DepartureStationRole, "departureStation"},
0116         {ArrivalStationRole, "arrivalStation"},
0117         {DepartureTimeRole, "departureTime"},
0118         {ArrivalTimeRole, "arrivalTime"},
0119         {AddressRole, "address"},
0120         {StartTimeRole, "startTime"},
0121         {EndTimeRole, "endTime"},
0122         {DeparturePlatformRole, "departurePlatform"},
0123         {ArrivalPlatformRole, "arrivalPlatform"},
0124         {CoachRole, "coach"},
0125         {SeatRole, "seat"},
0126     };
0127 }
0128 
0129 QString ItineraryModel::path() const
0130 {
0131     return m_path;
0132 }
0133 
0134 void ItineraryModel::setPath(const QString &path)
0135 {
0136     if (path == m_path) {
0137         return;
0138     }
0139     m_path = path;
0140     Q_EMIT pathChanged();
0141     loadData();
0142 }
0143 
0144 void ItineraryModel::loadData()
0145 {
0146     auto process = new QProcess(this);
0147     process->start(QLatin1String(CMAKE_INSTALL_FULL_LIBEXECDIR_KF6) + QLatin1String("/kitinerary-extractor"), {m_path.mid(7)});
0148     connect(process, &QProcess::finished, this, [this, process]() {
0149         auto data = process->readAllStandardOutput();
0150         beginResetModel();
0151         m_data = QJsonDocument::fromJson(data).array();
0152         endResetModel();
0153     });
0154 }
0155 
0156 void ItineraryModel::sendToItinerary()
0157 {
0158 #ifndef Q_OS_ANDROID
0159     auto job = new KIO::ApplicationLauncherJob(KService::serviceByDesktopName(QStringLiteral("org.kde.itinerary")));
0160     job->setUrls({QUrl::fromLocalFile(m_path.mid(7))});
0161     job->start();
0162 #endif
0163 }