#include "../headers/brproviderdr.h" BRProviderDr::BRProviderDr(QObject *parent) : BRProvider(parent) { // leagues source: // - https://github.com/ralfbecker/ranking/blob/master/sitemgr/digitalrock/dav_calendar.php // - https://github.com/ralfbecker/ranking/blob/master/sitemgr/digitalrock/sac_calendar.php this->leagues.insert( BRWidget::DAV, { { {"id", 0}, {"name", "Deutsche Meisterschaft"}, {"color", "#A8F0A8"}, {"leagueIDs", QVariantList({59, 57, 60})} }, { {"id", 1}, {"name", "Deutscher Jugendcup"}, {"color", "#D8FFD8"}, {"leagueIDs", QVariantList({58})} }, { {"id", 2}, {"name", "Landesmeisterschaft"}, {"color", "#F0F0F0"}, {"leagueIDs", QVariantList({61, 56})} } }); this->leagues.insert( BRWidget::SAC, { { {"id", 0}, {"name", "Erwachsene"}, {"color", "#A8F0A8"}, {"leagueIDs", QVariantList({57, 59, 60})} }, { {"id", 1}, {"name", "Jugend"}, {"color", "#D8FFD8"}, {"leagueIDs", QVariantList({65})} }, { {"id", 2}, {"name", "RegioCups"}, {"color", "#F0F0F0"}, {"leagueIDs", QVariantList({64})} }, { {"id", 3}, {"name", "Iceclimbing"}, {"color", "#F0F0F0"}, {"leagueIDs", QVariantList({84})} } }); } BRWidget::BRWidgetStatusCode BRProviderDr::getWidgetData(BRCalendar::BRCalendarData* calendarData) { // load some data QString nationStr = calendarData->calendar->getFederation() == BRWidget::SAC ? "SUI":"GER"; qDebug() << "Nation str: " << nationStr << " federation: " << calendarData->calendar->getFederation(); int year = QDate::currentDate().year(); QString requestUrl = "https://www.digitalrock.de/egroupware/ranking/json.php?nation=" + nationStr + "&year=" + QString::number(year); QVariantMap ret = this->serverRequest(QUrl(requestUrl)); if(ret["status"] != 200){ // request was a failure return BRWidget::BRWidgetStatusCode(ret["status"].toInt()); } QVariantMap data = QJsonDocument::fromJson(ret["text"].toString().toUtf8()).toVariant().toMap(); data.insert("year", year); data.insert("federation", calendarData->calendar->getFederation()); // create seasons QVariantList seasons = data["years"].toList(); for(QVariant seasonVar : seasons) { int seasonId = seasonVar.toString().toInt(); BRSeason* season = this->getSeason( calendarData->calendar->getFederation(), seasonId, this->parseSeasonData(seasonId, data) ); calendarData->seasons.append(season); if(seasonId == year) calendarData->currentSeason = season; } return BRWidget::Success; } BRWidget::BRWidgetStatusCode BRProviderDr::getWidgetData(BRSeason::BRSeasonData* seasonData) { if(seasonData->season->getLeagues().length() > 0) { // leagues are already loaded // load some data QString nationStr = seasonData->season->getFederation() == BRWidget::SAC ? "SUI":"GER"; qDebug() << "Nation str: " << nationStr << " federation: " << seasonData->season->getFederation(); int year = seasonData->season->getYear(); QString requestUrl = "https://www.digitalrock.de/egroupware/ranking/json.php?nation=" + nationStr + "&year=" + QString::number(year); QVariantMap ret = this->serverRequest(QUrl(requestUrl)); if(ret["status"] != 200){ // request was a failure return BRWidget::BRWidgetStatusCode(ret["status"].toInt()); } QVariantMap data = QJsonDocument::fromJson(ret["text"].toString().toUtf8()).toVariant().toMap(); data.insert("year", year); data.insert("federation", seasonData->season->getFederation()); // populate season QVariantList seasons = data["years"].toList(); this->parseSeasonData(seasonData, year, data); return BRWidget::Success; } else { // should never happen return BRWidget::NotImplementedError; } } BRSeason::BRSeasonData BRProviderDr::parseSeasonData(int id, QVariantMap rawData) { BRSeason::BRSeasonData data; this->parseSeasonData(&data, id, rawData); return data; } void BRProviderDr::parseSeasonData(BRSeason::BRSeasonData* seasonData, int id, QVariantMap rawData) { seasonData->year = id; seasonData->nativeMultiLeagueSupport = true; seasonData->name = QString::number(id); qDebug() << "Parsing season: " << seasonData->name; BRWidget::BRFederation federation = BRWidget::BRFederation(rawData["federation"].toInt(0)); // insert the leagues if the season is the current one if(seasonData->name == rawData["year"].toString()) for(QVariantMap leagueVar : this->leagues[federation]) { BRLeague* league = this->getLeague(federation, leagueVar["id"].toInt(), this->parseLeagueData(leagueVar, rawData)); seasonData->leagues.append(league); } } BRWidget::BRWidgetStatusCode BRProviderDr::getWidgetData(BRLeague::BRLeagueData* leagueData) { Q_UNUSED(leagueData) return BRWidget::NotImplementedError; } BRLeague::BRLeagueData BRProviderDr::parseLeagueData(QVariantMap leagueProperties, QVariantMap rawData) { BRLeague::BRLeagueData data; BRWidget::BRFederation federation = BRWidget::BRFederation(rawData["federation"].toInt(0)); data.name = leagueProperties["name"].toString(); data.color = QColor(leagueProperties["color"].toString()); data.enabled = true; qDebug() << "- Parsing league: " << data.name; // parse competitions QVariantList competitionsVar = rawData["competitions"].toList(); // TODO: make more efficient for(QVariant competitionVar : competitionsVar) { QVariantMap competitionMap = competitionVar.toMap(); // check if this competition is part of this league if(leagueProperties["leagueIDs"].toList().contains(competitionMap["cat_id"].toInt())) { BRCompetition* competition = this->getCompetition(federation, competitionVar.toMap()["WetId"].toInt(), this->parseCompetitionData(competitionMap, rawData["cats"].toList(), federation)); data.competitions.append(competition); } } // if this is league with id 0 if(leagueProperties["id"].toInt() == 0) { // parse cups QVariantList cupsVar = rawData["cups"].toList(); for(QVariant cupVar : cupsVar) { QVariantMap cupMap = cupVar.toMap(); BRCup* cup = this->getCup(federation, cupMap["SerId"].toInt(), this->parseCupData(rawData["cats"].toList(), cupMap, federation)); data.cups.append(cup); } } return data; } BRWidget::BRWidgetStatusCode BRProviderDr::getWidgetData(BRCompetition::BRCompetitionData* competitionData) { if(competitionData->competition->getCurrentCategory() == nullptr) return BRWidget::OpeationNotSupportedError; // reload all data BRCategory* currentCategory = competitionData->competition->getCurrentCategory(); // load category data QString competitionId = QString::number(currentCategory->getCompetition()->getId()); QString categoryId = QString::number(currentCategory->getId()); QString requestUrl = "https://www.digitalrock.de/egroupware/ranking/json.php?comp=" + competitionId + "&cat=" + categoryId; if(currentCategory->getCurrentRound() != nullptr && currentCategory->getCurrentRound()->getId() >= 0) requestUrl += "&route=" + QString::number(currentCategory->getCurrentRound()->getId()); QVariantMap ret = this->serverRequest(QUrl(requestUrl)); if(ret["status"] != 200){ // request was a failure return BRWidget::BRWidgetStatusCode(ret["status"].toInt()); } QVariantMap data = QJsonDocument::fromJson(ret["text"].toString().toUtf8()).toVariant().toMap(); this->parseCompetitionData(competitionData, data, competitionData->competition->getFederation()); return BRWidget::Success; } BRCompetition::BRCompetitionData BRProviderDr::parseCompetitionData(QVariantMap rawData, QVariantList globalCategoriesList, BRWidget::BRFederation federation) { // Load competition data from calendar BRCompetition::BRCompetitionData data; data.name = rawData["name"].toString(); qDebug() << "-- Parsing competition: " << data.name; if(rawData.contains("date")) data.startDate = QDate::fromString(rawData["date"].toString(), "yyyy-MM-dd"); if(rawData.contains("date_end")) data.endDate = QDate::fromString(rawData["date_end"].toString(), "yyyy-MM-dd"); if(rawData.contains("homepage")) data.eventWebsiteUrl = rawData["homepage"].toString(); // load infosheet URLs for(int i = 0; i < 2; i++) { QString infosheetName = QStringList({"info", "info2"})[i]; if(rawData.contains(infosheetName)) { QString url = rawData[infosheetName].toString(); if(federation == BRWidget::DAV) url = "http://ranking.alpenverein.de/" + QString::number(data.startDate.year()) + "/GER/" + rawData["rkey"].toString() + ".pdf"; data.infosheetUrls.append(url); } } // load categories QVariantList categoriesList = rawData["cats"].toList(); data.categories.clear(); for(QVariant categoryVar : categoriesList) { QVariantMap categoryMap = categoryVar.toMap(); // parse discipline QString discipline; if(rawData.contains("discipline")) // all categories have the same discipline discipline = rawData["discipline"].toString(); else // categories discipline may differ // search category in global categories list for(QVariant globalCategoryVar : globalCategoriesList) { QVariantMap globalCategoryMap = globalCategoryVar.toMap(); if(categoryMap["GrpId"].toInt() == globalCategoryMap["GrpId"].toInt()) { // TODO: sex / gender discipline = globalCategoryMap["discipline"].toString(); break; } } categoryMap.insert("discipline", discipline); BRCategory* category = this->getCategory(federation, categoryMap["GrpId"].toInt(), this->parseCategoryData(categoryMap)); data.categories.append(category); } data.currentCategory = nullptr; return data; } void BRProviderDr::parseCompetitionData(BRCompetition::BRCompetitionData* competitionData, QVariantMap rawData, BRWidget::BRFederation federation) { // load competition data from category page (?comp=X&cat=Y) competitionData->name = rawData["comp_name"].toString(); // reload categories // As digitalrock does not allow to get rounds in the competiton calendar // we need to populate all categories with their rounds when the first category is loaded. // for that, all categories are recreated QVariantList categoriesList = rawData["categorys"].toList(); // store old categories QMap oldCategories; for(BRCategory* category : competitionData->categories) if(!oldCategories.contains(category->getId())) oldCategories.insert(category->getId(), category); competitionData->categories.clear(); for(QVariant categoryVar : categoriesList) { QVariantMap categoryMap = categoryVar.toMap(); int categoryId = categoryMap["GrpId"].toInt(); BRCategory::BRCategoryData categoryData; categoryData.name = categoryMap["name"].toString(); // restore data that is not available in competition view of the API if(oldCategories.contains(categoryId)) { categoryData.status = oldCategories[categoryId]->getStatus(); categoryData.discipline = oldCategories[categoryId]->getDiscipline(); } categoryData.currentRound = nullptr; qDebug() << "Loading category: " << categoryData.name << " with discipline: " << categoryData.discipline; QVariantMap roundList; // check if route_names are given: if(rawData.contains("route_names")) roundList = rawData["route_names"].toMap(); else // if they are not -> insert Qualification roundList.insert("-1", "Qualifikation"); // load rounds for(QString roundId : roundList.keys()) { if(roundId.toInt() > categoryMap["route_order"].toInt()) continue; BRRound::BRRoundData roundData; roundData.name = roundList[roundId].toString(); BRRound* round = this->getRound(competitionData->competition->getFederation(), roundId.toInt(), roundData); categoryData.rounds.append(round); // if this was the previous round -> restore it! if(round->getId() == rawData["route_order"].toInt()) categoryData.currentRound = round; } // set default round if it was not restored if(categoryData.currentRound == nullptr && categoryData.rounds.length() > 0) categoryData.currentRound = categoryData.rounds[0]; BRCategory* category = this->getCategory(federation, categoryId, categoryData); competitionData->categories.append(category); // restore current category and load its reults if(category->getId() == rawData["GrpId"]) { competitionData->currentCategory = category; if(categoryData.currentRound != nullptr) { BRRound::BRRoundData roundData = categoryData.currentRound->getData(); roundData.results = {}; // load results QVariantList resultList = rawData["participants"].toList(); for(QVariant resultVar : resultList) { QVariantMap resultMap = resultVar.toMap(); // load athlete BRAthlete::BRAthleteData athleteData; // TODO: start number athleteData.firstName = resultMap["firstname"].toString(); athleteData.lastName = resultMap["lastname"].toString(); athleteData.federation = resultMap["federation"].toString(); athleteData.federationUrl = resultMap["fed_url"].toUrl(); athleteData.nation = resultMap["nation"].toString(); athleteData.city = resultMap["city"].toString(); athleteData.yearOfBirth = resultMap["birthyear"].toInt(); qDebug() << "--- Adding athlete: " << athleteData.firstName << " " << athleteData.lastName; BRAthlete* athlete = this->getAthlete(BRWidget::IFSC, resultMap["athlete_id"].toInt(), athleteData); // load result QString resultNumber = categoryData.currentRound->getId() < 0 ? "":QString::number(categoryData.currentRound->getId()); BRResult::BRResultData resultData; resultData.rank = resultMap["result_rank"].toInt(); resultData.athlete = athlete; BRResult* result = this->getResult(federation, -1, resultData); roundData.results.append(result); } this->setRoundData(categoryData.currentRound, roundData); } } // delete old categories for(int categoryId : oldCategories.keys()) { oldCategories[categoryId]->deleteLater(); } } } BRCup::BRCupData BRProviderDr::parseCupData(QVariantList categoriesList, QVariantMap rawData, BRWidget::BRFederation federation) { BRCup::BRCupData data; data.name = rawData["name"].toString(); qDebug() << "- Parsing Cup: " << data.name; // parse categories for(QVariant categoryName : rawData["cats"].toList()) { // find category name in cats: for(QVariant categoryVar : categoriesList) { QVariantMap categoryMap = categoryVar.toMap(); if(categoryMap["rkey"].toString() == categoryName.toString()) { BRCategory* category = this->getCategory(federation, rawData["GrpId"].toInt(), this->parseCategoryData(categoryMap)); data.categories.append(category); break; } } } return data; } BRCategory::BRCategoryData BRProviderDr::parseCategoryData(QVariantMap rawData) { BRCategory::BRCategoryData data; // TODO: gender data.name = rawData["name"].toString(); data.currentRound = nullptr; QMap statusTranslations = { {4, BRCategory::Registration}, {2, BRCategory::Startlist}, {1, BRCategory::Result}, {0, BRCategory::Result} }; QMap disciplineTranslations = { {"boulder", BRCategory::Boulder}, {"lead", BRCategory::Lead}, {"speed", BRCategory::Speed} }; if(disciplineTranslations.contains(rawData["discipline"].toString())) data.discipline = disciplineTranslations[rawData["discipline"].toString()]; else data.discipline = BRCategory::UnknownDiscipline; // parse status if(rawData.contains("status") && statusTranslations.contains(rawData["status"].toInt())) data.status = statusTranslations[rawData["status"].toInt()]; else data.status = BRCategory::UnknownStatus; qDebug() << "-- Parsing category: " << data.name << " with discipline: " << data.discipline << " and status: " << data.status; return data; } void BRProviderDr::parseCategoryData(BRCategory::BRCategoryData* categoryData, QVariantMap rawData) { // category is already set-up -> only load rounds! }