summaryrefslogtreecommitdiff
path: root/src/model/Sport.cpp
diff options
context:
space:
mode:
authorSteru <jerrydream111@gmail.com>2024-08-16 16:58:31 +0200
committerSteru <jerrydream111@gmail.com>2024-08-16 16:58:31 +0200
commitb0063e96410ff0c407e2daead4cf53252568b542 (patch)
treef12989e92cebd09b13e93cedf440751c02a07a0d /src/model/Sport.cpp
parent884280076a50c2a2063dbfbf9390032d8b3df5c7 (diff)
Integrated Sport class into SportModel class.
Diffstat (limited to 'src/model/Sport.cpp')
-rw-r--r--src/model/Sport.cpp452
1 files changed, 0 insertions, 452 deletions
diff --git a/src/model/Sport.cpp b/src/model/Sport.cpp
deleted file mode 100644
index 9dd6c69..0000000
--- a/src/model/Sport.cpp
+++ /dev/null
@@ -1,452 +0,0 @@
-#include "Sport.h"
-#include "Competitor.h"
-
-// categories
-#include <QNetworkReply>
-#include <qlogging.h>
-#include <qobject.h>
-#include <set>
-
-// sorting and filtering
-#include <map>
-#include <algorithm>
-#include <regex>
-
-// float to string formatting
-#include <iostream>
-#include <iomanip>
-
-#include <QJsonObject>
-#include <QJsonArray>
-#include <QJsonValueRef>
-#include <QString>
-
-namespace {
- const QString &k_requestUrl = "https://sph-s-api.olympics.com/summer/schedules/api/ENG/schedule/discipline/";
-}
-
-SportModel::SportModel(QObject *parent) : QAbstractListModel(parent) {
-}
-
-int SportModel::rowCount(const QModelIndex &parent) const {
- Q_UNUSED(parent);
- return m_sportList.size();
-}
-
-QVariant SportModel::data(const QModelIndex &index, int role) const {
- if (index.isValid() && index.row() >= 0 && index.row() < m_sportList.size()) {
- EventInfo *event = m_sportList[index.row()];
-
- switch ((Role) role) {
- case EventName:
- return event->eventName();
-
- case Competitors:
- return event->competitors();
- }
- }
-
- return {};
-}
-
-
-QHash<int, QByteArray> SportModel::roleNames() const {
- QHash<int, QByteArray> names;
- names[EventName] = "eventName";
- names[Competitors] = "competitors";
-
- return names;
-}
-
-QString SportModel::discipline() const {
- return m_discipline;
-}
-
-void SportModel::setDiscipline(const QString &discipline) {
- m_discipline = discipline;
-}
-
-
-void SportModel::request(QString discipline) {
- m_discipline = discipline;
- m_reply = m_networkManager.get(QNetworkRequest( k_requestUrl + m_discipline));
- qDebug() << m_reply;
- connect(m_reply, &QNetworkReply::finished, this, &SportModel::parseData);
-}
-
-void SportModel::parseData() {
-
- if (m_reply->error() == QNetworkReply::NoError) {
- beginResetModel();
- qDeleteAll(m_sportList);
- m_sportList.clear();
-
-
-
- QByteArray strReply = m_reply->readAll();
-
- //parse json
- // qDebug() << "Response:" << strReply;
- QJsonDocument jsonDocument = QJsonDocument::fromJson(strReply);
-
- QJsonArray sports = jsonDocument["units"].toArray();
- for (const auto &sport : sports) {
- QJsonObject entry = sport.toObject();
-
- EventInfo *event = new EventInfo(this);
- event->setEventName(entry["eventUnitName"].toString());
-
- QList<QString> competitors;
- for (const auto &competitor : entry["competitors"].toArray()) {
- competitors << competitor.toObject()["name"].toString();
- }
- event->setCompetitors(competitors);
-
- qDebug() << entry["eventUnitName"].toString();
- m_sportList << event;
- }
- endResetModel();
- }
-}
-
-// QJsonArray filter function, provide with input array and evaluation function
-QJsonArray filter(QJsonArray input, function<bool (QJsonObject)> eval) {
- QJsonArray output;
-
- for (const QJsonValueRef &elemRef :input) {
- QJsonObject elem = elemRef.toObject();
- if(eval(elem)) {
- output.append(elem);
- }
- }
-
- return output;
-}
-
-/**
- * @brief Sport::lastName Reduce the full name to the part that is marked in capital letters (probably last name).
- * @param competitors The competitors of one category.
- */
-void Sport::lastName(QList<Competitor> &competitors) {
- // validate competitors
- if (competitors.isEmpty()) return;
-
- for (int i = 0; i < competitors.size(); i++) {
- Competitor comp = competitors.value(i);
- string fullName = comp.getName().toUtf8().constData();
-
- // regex to identify names, written in CAPS
- regex r("[A-Z']{2,}");
- smatch m;
-
- regex_search(fullName, m, r);
-
- // combine found names again
- string lastName = "";
- for (string s : m) lastName = lastName + s + " ";
-
- // remove last space
- QString name = QString(lastName.substr(0, lastName.size() - 1).c_str());
-
- // replace competitor name in list
- comp.setName(name);
- }
-}
-
-/**
- * @brief Sport::validateDiscipline Validates the discipline object. Checks for the units attribute.
- * @return True, if discipline contains units.
- */
-bool Sport::validateDiscipline() {
- return this->discipline.contains("units");
-}
-
-/**
- * @brief Sport::getCategories Reads all possible categories (also called units).
- * @return A set of all category names.
- */
-set<QString> Sport::getCategories() {
- set<QString> categoryNames;
-
- if (!validateDiscipline()) return categoryNames;
-
- // search in each unit for the category (named "eventUnitName")
- for (const QJsonValueRef &unitRef : this->discipline["units"].toArray()) {
- QJsonObject unit = unitRef.toObject();
-
- // validate unit
- if (!unit.contains("eventUnitName")) continue;
-
- categoryNames.insert(unit["eventUnitName"].toString());
- }
-
- return categoryNames;
-}
-
-/**
- * @brief Sport::getCompetitorsByCategory Searches for all competitors, who took part in the given category.
- * @param category The category to search in.
- * @return An QJsonArray with all competitors as QJsonValueRef, which can be casted to QJsonObject.
- */
-QList<CompetitorWithResults> Sport::getCompetitorsByCategory(QString category) {
- QList<CompetitorWithResults> competitors;
-
- if (!validateDiscipline()) return competitors;
-
- for (const QJsonValueRef &unitRef : this->discipline["units"].toArray()) {
- QJsonObject unit = unitRef.toObject();
-
- // validate unit
- if (!unit.contains("eventUnitName") || !unit.contains("competitors")) continue;
-
- // search all units with the same category
- if (unit["eventUnitName"].toString().compare(category, Qt::CaseSensitive) != 0) continue;
-
- // add all competitors from one unit
- for (const QJsonValueRef &compRef : unit["competitors"].toArray()) {
- CompetitorWithResults comp = new CompetitorWithResults(); // TODO declare comp
- comp.setCompetitorWithResults(compRef.toObject());
- competitors.push_back(comp);
- }
- }
-
- return competitors;
-}
-
-/**
- * @brief Sport::getCompetitorsWithMedal Filters all competitors, who have at least one medal. These objects are different from getCompetitorsByCategory !!!
- * @return All competitors, who won at least one medal. Structure of one competitor: {code, name, m_noc, medals{ME_GOLD, ME_SILVER, ME_BRONZE}}
- */
-QList<MedalWinner> Sport::getCompetitorsWithMedal() {
- map<QString, QJsonObject> competitors;
-
- if (!validateDiscipline()) return QList<MedalWinner>();
-
- // filter all units, which have medal events
- QJsonArray units = filter(this->discipline["units"].toArray(), [](QJsonObject unit){
- // search all units with Final, Gold or Bronze in their name, because these are the categories with the medal winners
- QString unitName = unit["eventUnitName"].toString();
- return unitName.contains("Bronze", Qt::CaseSensitive)
- || unitName.contains("Gold", Qt::CaseSensitive)
- || unitName.contains("Final", Qt::CaseSensitive);
- });
-
- for (const QJsonValueRef &unitRef : units) {
- QJsonObject unit = unitRef.toObject();
-
- // validate unit
- if (!unit.contains("competitors")) continue;
-
- // filter all competitors, who won medals
- QJsonArray medalComps = filter(unit["competitors"].toArray(), [](QJsonObject comp) {
- if (!comp.contains("results")) return false;
-
- QString medalType = comp["results"].toObject()["m_medalType"].toString();
- return !medalType.isEmpty();
- });
-
- for (const QJsonValueRef &medalCompRef : medalComps) {
- QJsonObject medalComp = medalCompRef.toObject();
-
- // validate competitor (with medal)
- if (!medalComp.contains("name")
- || !medalComp.contains("results")
- || !medalComp["results"].toObject().contains("m_medalType")) continue;
-
- QString name = medalComp["name"].toString();
- QString medalType = medalComp["results"].toObject()["m_medalType"].toString();
-
- // check if competitor has other medal(s)
- if (competitors.find(name) == competitors.end()) {
- competitors.insert({name, createCompetitorWithMedals(medalComp)});
- }
-
- // update the medal count
- QJsonObject updatedMedalCount = QJsonObject(competitors.find(name)->second["medals"].toObject());
-
- int amount = updatedMedalCount[medalType].toInt() + 1;
- updatedMedalCount.remove(medalType);
- updatedMedalCount.insert(medalType, amount);
-
- // create new medals QJsonObject and set it in the map
- competitors.find(name)->second["medals"] = updatedMedalCount;
- }
- }
-
- // convert map to QJsonArray
- QList<MedalWinner> output;
- for (const pair<QString, QJsonObject> &competitor : competitors) {
- MedalWinner comp = new MedalWinner(); // TODO declare comp
- comp.setMedalWinner(competitor.second);
- output.append(comp);
- }
-
- return output;
-}
-
-/**
- * @brief Sport::createCompetitorWithMedals Creates a competitor QJsonObject with the following attributes: code, name, m_noc, medals{ME_GOLD, ME_SILVER, ME_BRONZE}
- * @param comp The original competitor object.
- * @return A competitor object with medal counts.
- */
-QJsonObject Sport::createCompetitorWithMedals(QJsonObject comp) {
- // repair competitor if something is missing
- if (!comp.contains("code")) comp.insert("code", "0");
- if (!comp.contains("name")) comp.insert("code", "");
- if (!comp.contains("m_noc")) comp.insert("code", "");
-
- // create new competitor QJsonObject and add it to the competitor map
- QJsonObject medals {
- {"ME_GOLD", 0},
- {"ME_SILVER", 0},
- {"ME_BRONZE", 0}
- };
-
- QJsonObject medalComp {
- {"code", comp["code"].toString()},
- {"name", comp["name"].toString()},
- {"m_noc", comp["m_noc"].toString()},
- {"medals", medals}
- };
-
- return medalComp;
-}
-
-/**
- * @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(QList<Competitor> &competitors, QString name) {
- filterCompetitors(competitors, 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(QList<Competitor> &competitors, QString nocShort) {
- filterCompetitors(competitors, nocShort);
-}
-
-/**
- * @brief Sport::filterCompetitors Filters the given QJsonArray by comparing the value of a certain attribute with the given filter string.
- * @param competitors The competitors of one category.
- * @param attribute The attribute to filter by.
- * @param filter The string, which should be contained.
- */
-void Sport::filterCompetitors(QList<Competitor> &competitors, QString filter) {
- for (int i = 0; i < competitors.size(); i++) {
- if (!competitors.value(i).getNOC().contains(filter)) {
- competitors.remove(i);
- i--;
- }
- }
-}
-
-/**
- * @brief Sport::sortByName Sort the competitors by their name (alphabetical, ascending).
- * @param competitors The competitors of one category.
- */
-void Sport::sortByName(QList<Competitor> &competitors) {
- if (competitors.isEmpty()) return;
- sort(competitors.begin(), competitors.end(), Competitor::compareName);
-}
-
-/**
- * @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(QList<Competitor> &competitors) {
- if (competitors.isEmpty()) return;
- sort(competitors.begin(), competitors.end(), Competitor::compareNOC);
-}
-
-/**
- * @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(QList<CompetitorWithResults> &competitors) {
- if (competitors.isEmpty()) return;
- sort(competitors.begin(), competitors.end(), CompetitorWithResults::compare);
-}
-
-/**
- * @brief Sport::sortByMedals Sort the competitors by their medal amounts in one specific category (numerical, ascending).
- * @param competitors The competitors of one category.
- */
-void Sport::sortByMedals(QList<MedalWinner> &competitors) {
- if (competitors.isEmpty()) return;
- sort(competitors.begin(), competitors.end(), MedalWinner::compare);
-}
-
-/**
- * @brief Sport::reverseOrder Reverses the order of the competitors.
- * @param competitors The competitors of one category.
- */
-void Sport::reverseOrder(QList<Competitor> &competitors) {
- int iterations = competitors.size() / 2; // automatically rounds down
-
- for (int i = 0; i < iterations; i++) {
- Competitor left = Competitor(competitors.value(i));
- Competitor right = Competitor(competitors.value(competitors.size() - 1 - i));
-
- competitors.replace(i, right);
- competitors.replace(competitors.size() - 1 - i, left);
- }
-}
-
-/**
- * @brief Sport::addRelativeToFirst Adds a relative value to the result of all competitors. Relative to the first competitor in the QJsonArray.
- * Stores the m_statistic in obj->results->stat for each competitor.
- * @param competitors The competitors of one category.
- */
-void Sport::addRelativeToFirst(QList<CompetitorWithResults> &competitors) {
- if (competitors.isEmpty()) return;
-
- QString reference = competitors.value(0).getMark();
-
- for (CompetitorWithResults comp : competitors) {
- QString result = comp.getMark();
-
- // format relative float value to string with 2 digits after decimal point and sign
- stringstream sstream;
- sstream << fixed << setprecision(2) << calcRelativeStat(reference, result);
- QString stat(sstream.str().c_str());
- stat.append("%");
- if (stat.at(0).isNumber()) stat = QString("+").append(stat);
-
- comp.setStatistic(stat);
- }
-
-}
-
-/**
- * @brief Sport::calcRelativeStat Calculates the relative deviation of val from ref in percent.
- * @param ref The reference value.
- * @param val The value to calculate the deviation from.
- * @return The deviation from ref to val in percent.
- */
-float Sport::calcRelativeStat(QString ref, QString val) {
- // check if the value is not a time
- if (!ref.contains(":") && !val.contains(":")) {
- float fRef = ref.toFloat();
-
- if (fRef == 0) return 0.0;
- return ((val.toFloat() * 100)/ fRef) - 100;
- }
-
- regex r("\\d+");
- smatch mref, mval;
- string sref = ref.toUtf8().constData();
- string sval = val.toUtf8().constData();
-
- regex_search(sref, mref, r);
- regex_search(sval, mval, r);
-
- float timeRef = stof(mref.str(1)) * 60 * 100 + stof(mref.str(2)) * 100 + stof(mref.str(3));
- float timeVal = stof(mval.str(1)) * 60 * 100 + stof(mval.str(2)) * 100 + stof(mval.str(3));
-
- return ((timeVal * 100) / timeRef) - 100;
-}