summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSteru <jerrydream111@gmail.com>2024-08-03 20:19:05 +0200
committerSteru <jerrydream111@gmail.com>2024-08-03 20:19:05 +0200
commitd399c562f5fad76ed8018c712a635f49715a8fed (patch)
treeae54011fe27a607d43329ee4e9be98ad3a8fe770 /src
parenta767d83d81755710fc760a6d3dc040b4a379c16a (diff)
Added another filter and sort functions. Also using mock data to test.
Diffstat (limited to 'src')
-rw-r--r--src/api/OlympicsAPI.cpp60
-rw-r--r--src/api/OlympicsAPI.h13
-rw-r--r--src/discipline/Sport.cpp84
-rw-r--r--src/discipline/Sport.h36
4 files changed, 155 insertions, 38 deletions
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);
+
};