File indexing completed on 2024-04-14 05:43:44

0001 /*
0002  * SPDX-FileCopyrightText: 2020 Dimitris Kardarakos <dimkard@posteo.net>
0003  *
0004  * SPDX-License-Identifier: GPL-3.0-or-later
0005  */
0006 
0007 #include "conferencecontroller.h"
0008 #include "settingscontroller.h"
0009 #include "conference.h"
0010 #include <QDebug>
0011 #include <QDir>
0012 #include <QJsonDocument>
0013 #include <QJsonArray>
0014 #include <QNetworkRequest>
0015 #include <QNetworkReply>
0016 #include <KSharedConfig>
0017 #include <KConfigGroup>
0018 
0019 class ConferenceController::Private
0020 {
0021 public:
0022     Private() : config {"kongressrc"}
0023     {};
0024     KConfig config;
0025     QNetworkAccessManager *nam = nullptr;
0026 };
0027 
0028 ConferenceController::ConferenceController(QObject *parent) : QObject {parent}, m_active_conference {nullptr}, m_conferences_file {new QFile {}}, d {new Private}
0029 {
0030     connect(this, &ConferenceController::conferencesLoaded, [this]() {
0031         activateDefaultConference();
0032     });
0033 }
0034 
0035 void ConferenceController::setNetworkAccessManager(QNetworkAccessManager *nam)
0036 {
0037     d->nam = nam;
0038     if (!defaultConferenceId().isEmpty()) {
0039         loadConferences();
0040     }
0041 }
0042 
0043 QVector<Conference *> ConferenceController::conferences() const
0044 {
0045     return m_conferences;
0046 }
0047 
0048 void ConferenceController::loadConferences()
0049 {
0050     if (!m_conferences.isEmpty()) {
0051         qDeleteAll(m_conferences.begin(), m_conferences.end());
0052         m_conferences.clear();
0053     }
0054 
0055     Q_EMIT downlading(true);
0056 
0057     const auto dir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
0058     QDir().mkpath(dir);
0059 
0060     QLatin1String fileName {"/conference-data.json"};
0061     m_conferences_file = new QFile {dir + fileName};
0062 
0063     const QUrl conferencesUrl {QStringLiteral("https://autoconfig.kde.org/kongress") + fileName};
0064     QNetworkRequest request {conferencesUrl};
0065     auto reply = d->nam->get(request);
0066 
0067     connect(reply, &QNetworkReply::finished, [this, reply]() {
0068         if (reply->error() == QNetworkReply::NoError) {
0069             if (m_conferences_file == nullptr || !m_conferences_file->open(QIODevice::WriteOnly)) {
0070                 qDebug() << "Cannot open conferences file" << m_conferences_file->errorString();
0071             } else {
0072                 m_conferences_file->write(reply->readAll());
0073                 m_conferences_file->close();
0074             }
0075         }
0076         reply->deleteLater();
0077         Q_EMIT downlading(false);
0078         loadConferencesFromFile(*m_conferences_file);
0079     });
0080 }
0081 
0082 void ConferenceController::loadConferencesFromFile(QFile &jsonFile)
0083 {
0084     if (!jsonFile.exists()) {
0085         return;
0086     }
0087 
0088     QString data;
0089 
0090     if (jsonFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
0091         data = jsonFile.readAll();
0092         jsonFile.close();
0093     }
0094 
0095     auto jsonDoc = QJsonDocument::fromJson(data.toUtf8());
0096     QVariantList jsonVarList;
0097 
0098     if (!jsonDoc.isEmpty() && jsonDoc.isArray()) {
0099         auto jsonArray = jsonDoc.array();
0100         jsonVarList = jsonArray.toVariantList();
0101     }
0102 
0103     for (const QVariant &jsonVar : std::as_const(jsonVarList)) {
0104         loadConference(jsonVar.toJsonObject());
0105     }
0106 
0107     Q_EMIT conferencesLoaded();
0108 }
0109 
0110 void ConferenceController::loadConference(const QJsonObject &jsonObj)
0111 {
0112     auto conferenceId = jsonObj["id"].toString();
0113 
0114     for (const auto cf : std::as_const(m_conferences)) {
0115         if (cf->id() == conferenceId) {
0116             qDebug() << "Conference already loaded";
0117             return;
0118         }
0119     }
0120 
0121     auto conference = new Conference {this};
0122     conference->setId(conferenceId);
0123     conference->setName(jsonObj["name"].toString());
0124     conference->setDescription(jsonObj["description"].toString());
0125     conference->setIcalUrl(jsonObj["icalUrl"].toString());
0126     auto jsonDays = jsonObj["days"].toVariant();
0127     conference->setDays(jsonDays.toStringList());
0128     conference->setVenueImageUrl(jsonObj["venueImageUrl"].toString());
0129     conference->setVenueLatitude(jsonObj["venueLatitude"].toString());
0130     conference->setVenueLongitude(jsonObj["venueLongitude"].toString());
0131     conference->setVenueOsmUrl(jsonObj["venueOsmUrl"].toString());
0132     conference->setTimeZoneId(jsonObj["timeZoneId"].toString());
0133 
0134     m_conferences << conference;
0135 }
0136 
0137 Conference *ConferenceController::activeConference() const
0138 {
0139     return m_active_conference;
0140 }
0141 
0142 void ConferenceController::activateConference(const QString &conferenceId)
0143 {
0144     if (conferenceId.isEmpty()) {
0145         return;
0146     }
0147 
0148     for (const auto cf : std::as_const(m_conferences)) {
0149         if (cf->id() == conferenceId) {
0150 
0151             m_active_conference = cf;
0152             qDebug() << "activateConference: conference " << conferenceId << " activated";
0153 
0154             setDefaultConferenceId(conferenceId);
0155 
0156             Q_EMIT activeConferenceChanged();
0157 
0158             return;
0159         }
0160     }
0161 }
0162 
0163 void ConferenceController::activateDefaultConference()
0164 {
0165     activateConference(defaultConferenceId());
0166 }
0167 
0168 QString ConferenceController::defaultConferenceId() const
0169 {
0170     auto confId = d->config.group("general").readEntry("defaultConferenceId", QString {});
0171     d->config.sync();
0172 
0173     return confId;
0174 }
0175 
0176 void ConferenceController::setDefaultConferenceId(const QString &confId)
0177 {
0178     d->config.group("general").writeEntry("defaultConferenceId", confId);
0179     d->config.sync();
0180 
0181     Q_EMIT defaultConferenceIdChanged();
0182 }
0183 
0184 void ConferenceController::clearActiveConference()
0185 {
0186     m_active_conference = nullptr;
0187     setDefaultConferenceId(QString {});
0188     Q_EMIT activeConferenceChanged();
0189 }
0190 
0191 #include "moc_conferencecontroller.cpp"