diff options
| author | Steru <jerrydream111@gmail.com> | 2024-08-03 20:19:05 +0200 | 
|---|---|---|
| committer | Steru <jerrydream111@gmail.com> | 2024-08-03 20:19:05 +0200 | 
| commit | d399c562f5fad76ed8018c712a635f49715a8fed (patch) | |
| tree | ae54011fe27a607d43329ee4e9be98ad3a8fe770 | |
| parent | a767d83d81755710fc760a6d3dc040b4a379c16a (diff) | |
Added another filter and sort functions. Also using mock data to test.
| -rw-r--r-- | res/mock/ARC.json (renamed from res/archery/archery.json) | 0 | ||||
| -rw-r--r-- | src/api/OlympicsAPI.cpp | 60 | ||||
| -rw-r--r-- | src/api/OlympicsAPI.h | 13 | ||||
| -rw-r--r-- | src/discipline/Sport.cpp | 84 | ||||
| -rw-r--r-- | src/discipline/Sport.h | 36 | 
5 files changed, 155 insertions, 38 deletions
| diff --git a/res/archery/archery.json b/res/mock/ARC.json index fcc93f2..fcc93f2 100644 --- a/res/archery/archery.json +++ b/res/mock/ARC.json diff --git a/src/api/OlympicsAPI.cpp b/src/api/OlympicsAPI.cpp index edcb021..4fe9701 100644 --- a/src/api/OlympicsAPI.cpp +++ b/src/api/OlympicsAPI.cpp @@ -12,6 +12,7 @@  #include <QUrlQuery>  // json parsing +#include <QFile>  #include <QJsonValue>  #include <QJsonDocument>  #include <QJsonObject> @@ -29,41 +30,54 @@ using namespace std;  QJsonObject OlympicsAPI::getSportData(OlympicsAPI::Disciplines sport) {      string shortName = this->getDisciplineShort(sport); -    // create custom temporary event loop on stack -    QEventLoop eventLoop; +    if (USE_API_REQUEST) { +        // create custom temporary event loop on stack +        QEventLoop eventLoop; -    // "quit()" the event-loop, when the network request "finished()" -    QNetworkAccessManager mgr; -    QObject::connect(&mgr, SIGNAL(finished(QNetworkReply*)), &eventLoop, SLOT(quit())); +        // "quit()" the event-loop, when the network request "finished()" +        QNetworkAccessManager mgr; +        QObject::connect(&mgr, SIGNAL(finished(QNetworkReply*)), &eventLoop, SLOT(quit())); -    QString endpoint = (API_LINK + shortName).c_str(); +        QString endpoint = (API_LINK + shortName).c_str(); -    // the HTTP request -    QNetworkRequest req( (QUrl( endpoint )) ); -    QNetworkReply *reply = mgr.get(req); -    eventLoop.exec(); // blocks stack until "finished()" has been called +        // the HTTP request +        QNetworkRequest req( (QUrl( endpoint )) ); +        QNetworkReply *reply = mgr.get(req); +        eventLoop.exec(); // blocks stack until "finished()" has been called -    if (reply->error() == QNetworkReply::NoError) { -        //success +        if (reply->error() == QNetworkReply::NoError) { +            //success -        QString strReply = (QString)reply->readAll(); +            QString strReply = (QString)reply->readAll(); -        //parse json -        QJsonDocument jsonResponse = QJsonDocument::fromJson(strReply.toUtf8()); +            //parse json +            QJsonDocument jsonResponse = QJsonDocument::fromJson(strReply.toUtf8()); -        QJsonObject jsonObj = jsonResponse.object(); +            QJsonObject jsonObj = jsonResponse.object(); -        delete reply; +            delete reply; -        return jsonObj; -    } -    else { -        //failure -        delete reply; +            return jsonObj; +        } +        else { +            //failure +            delete reply; -        throw invalid_argument("API request failed."); +            throw invalid_argument("API request failed."); +        }      } +    // if API is not used, open locally stored data +    QString filePath = ("../../res/mock/" + shortName + ".json").c_str(); +    QFile file( filePath ); + +    if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) { +        throw invalid_argument("Could not open file to read data of the given discipline."); +    } else { +        QString text = file.readAll(); +        file.close(); +        return (QJsonDocument::fromJson(text.toUtf8())).object(); +    }  }  /** diff --git a/src/api/OlympicsAPI.h b/src/api/OlympicsAPI.h index 8efaa26..f1168b6 100644 --- a/src/api/OlympicsAPI.h +++ b/src/api/OlympicsAPI.h @@ -8,17 +8,10 @@  #include <string>  #include <QJsonObject> -using namespace std; +// TODO: change this to true to use the olympics api, instead of the mock date in res/mock/ +#define USE_API_REQUEST false -/* - * TODO: - * Replace api request code snippet in main with: - * -    OlympicsAPI api; -    QJsonObject archery = api.getSportData(api.Archery); -    qDebug() << "Competitor:" << archery["units"][0]["competitors"][0]["name"].toString(); - * - */ +using namespace std;  class OlympicsAPI { diff --git a/src/discipline/Sport.cpp b/src/discipline/Sport.cpp index ed8331d..05ba95e 100644 --- a/src/discipline/Sport.cpp +++ b/src/discipline/Sport.cpp @@ -1,12 +1,34 @@  #include "Sport.h"  #include <set> +#include <algorithm>  #include <QJsonObject>  #include <QJsonArray>  #include <QJsonValueRef>  #include <QString> +// static compare function for specific attribute in competitors +function<bool (const QJsonValue &left, const QJsonValue &right)> genCompare(QString attribute) { +    return [attribute](const QJsonValue &left, const QJsonValue &right) { +        QString l = left.toObject()[attribute].toString(); +        QString r = right.toObject()[attribute].toString(); +        return l.compare(r) < 0; +    }; +} + +// static compare function for the results of a competitor in a specific competition (also called mark) +bool compareMark(const QJsonValue &left, const QJsonValue &right) { +    QJsonObject l = left.toObject(); +    if (!l.contains("results")) return true; +    QJsonObject r = right.toObject(); +    if (!r.contains("results")) return false; + +    float lMark = l["results"].toObject()["mark"].toString().toFloat(); +    float rMark = r["results"].toObject()["mark"].toString().toFloat(); +    return lMark < rMark; +} +  /**   * @brief Sport::getCategories Reads all possible categories (also called units). @@ -44,5 +66,65 @@ QJsonArray Sport::getCompetitorsByCategory(QString category) {          }      } -    return competitors; +    return QJsonArray(competitors); +} + +/** + * @brief Sport::filterByName Filter the competitors by name (case insensitive). + * @param competitors The competitors of one category. + * @param name The (part of the) name to search for. + */ +void Sport::filterByName(QJsonArray &competitors, QString name) { +    filterCompetitors(competitors, QString("name"), name); +} + +/** + * @brief Sport::filterByCountry Filter the competitors by their national olympics comittee (case insensitive, short form). + * @param competitors The competitors of one category. + * @param nocShort The (part of the) national olympics comittee short name to search for. + */ +void Sport::filterByCountry(QJsonArray &competitors, QString nocShort) { +    filterCompetitors(competitors, QString("noc"), nocShort); +} + +void Sport::filterCompetitors(QJsonArray &competitors, QString attribute, QString filter) { +    for (int i = 0; i < competitors.size(); i++) { + +        if (!competitors[i].toObject()[attribute].toString().contains(filter, Qt::CaseInsensitive)) { +            // remove the competitor, if the attribute does not fit the filter string +            competitors.removeAt(i); +            i--; +        } + +    } +} + +/** + * @brief Sport::sortByName Sort the competitors by their name (alphabetical, ascending). + * @param competitors The competitors of one category. + */ +void Sport::sortByName(QJsonArray &competitors) { +    sortCompetitors(competitors, genCompare( QString("name") ));  } + +/** + * @brief Sport::sortByCountry Sort the competitors by their national olympic comittee short name (alphabetical, ascending). + * @param competitors The competitors of one category. + */ +void Sport::sortByCountry(QJsonArray &competitors) { +    sortCompetitors(competitors, genCompare( QString("noc") )); +} + +/** + * @brief Sport::sortByResult Sort the competitors by their results in one specific category (numerical, ascending). + * @param competitors The competitors of one category. + */ +void Sport::sortByResult(QJsonArray &competitors) { +    sortCompetitors(competitors, compareMark); +} + +void Sport::sortCompetitors(QJsonArray &competitors, function<bool (const QJsonValue &left, const QJsonValue &right)> compare) { +    make_heap(competitors.begin(), competitors.end(), compare); +    sort_heap(competitors.begin(), competitors.end(), compare); +} + diff --git a/src/discipline/Sport.h b/src/discipline/Sport.h index 9c993fb..3b1c7f4 100644 --- a/src/discipline/Sport.h +++ b/src/discipline/Sport.h @@ -23,18 +23,46 @@ public:      set<QString> getCategories();      QJsonArray getCompetitorsByCategory(QString category); -    // chainable -    QJsonObject filterByName(QJsonObject discipline, QString name); -    QJsonObject filterByCountry(QJsonObject discipline, QString name); +    // filter to change the current competitor array +    void filterByName(QJsonArray& competitors, QString name); +    void filterByCountry(QJsonArray& competitors, QString nocShort); + +    // sort functions to change the order of the current competitor array +    void sortByName(QJsonArray &competitors); +    void sortByCountry(QJsonArray &competitors); +    void sortByResult(QJsonArray &competitors);      void setDiscipline(QJsonObject discipline) { -        this->discipline = discipline; +        this->discipline = QJsonObject(discipline);      }  private: +    /* +     * Analysis of provided competitor objects: +     * +     * Attributes: +     * - code +     * - noc (national olympics comittee) +     * - name (sometimes the country name? mostly the competitors name) +     * - order +     * [- results] (only if the results are out!) +     * +     * +     * Analysis of provided result objects: +     * +     * Attributes: +     * - position +     * - mark +     * - medalType +     * - irk +     * [- winnerLoserTie] (only if provided in the discipline?) +     */      QJsonObject discipline; +    void filterCompetitors(QJsonArray& competitors, QString attribute, QString filter); +    void sortCompetitors(QJsonArray &competitors,  function<bool (const QJsonValue &left, const QJsonValue &right)> compare); +  }; | 
