diff --git a/NewStructure.md b/NewStructure.md index 6991f6f..fb70f03 100644 --- a/NewStructure.md +++ b/NewStructure.md @@ -25,3 +25,16 @@ # layer 4 - QML - Will call functions from Layer 2 and get Objects from Layer 3 + + +# Season and Leagues handling +1. Calendar loads +-> Calendar gets available seasons (which get available leagues) +-> Data loader decides on default season and default league(s) +-> Data loader loads default competitions +2. Calendar displays competitions +3. Current season is changed: +-> calendar reloads +-> Data loader sees that the availableSeasons are already +4. Current League is changed: +-> calendar reloads diff --git a/blueROCK.pro b/blueROCK.pro index df09f3f..1d66de9 100644 --- a/blueROCK.pro +++ b/blueROCK.pro @@ -25,6 +25,7 @@ DEFINES += QT_DEPRECATED_WARNINGS #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ + sources/brleague.cpp \ sources/appsettings.cpp \ sources/brcalendar.cpp \ sources/brcategory.cpp \ @@ -33,12 +34,15 @@ SOURCES += \ sources/brcup.cpp \ sources/brprovider.cpp \ sources/brproviderdr.cpp \ + sources/brprovidervl.cpp \ + sources/brseason.cpp \ sources/brserverconnector.cpp \ sources/brwidget.cpp \ sources/main.cpp HEADERS += \ + headers/brleague.h \ headers/appsettings.h \ headers/brcalendar.h \ headers/brcategory.h \ @@ -47,6 +51,8 @@ HEADERS += \ headers/brcup.h \ headers/brprovider.h \ headers/brproviderdr.h \ + headers/brprovidervl.h \ + headers/brseason.h \ headers/brserverconnector.h \ headers/brwidget.h diff --git a/headers/brcalendar.h b/headers/brcalendar.h index 9880dd5..b48ff74 100644 --- a/headers/brcalendar.h +++ b/headers/brcalendar.h @@ -3,38 +3,46 @@ #include -#include "brcompetition.h" #include "brwidget.h" +#include "brseason.h" +#include "brcompetition.h" #include "brcategory.h" #include "brcup.h" -class BRProvider; - class BRCalendar : public BRWidget { Q_OBJECT + Q_PROPERTY(QString title READ getTitle NOTIFY titleChanged) + Q_PROPERTY(QList seasons READ getSeasonsQML NOTIFY seasonsChanged) + Q_PROPERTY(BRSeason* currentSeason READ getCurrentSeason WRITE setCurrentSeason NOTIFY currentSeasonChanged) + public: friend class BRProvider; - friend class BRProviderDr; - BRWidget::BRWidgetStatusCode load() override; + typedef struct { + BRCalendar* calendar; + BRSeason* currentSeason; + QList seasons; + } BRCalendarData; - Q_INVOKABLE int getYear(); - int getLeague(); - QList getCompetitions(); - QList getCompetitionsQML(); + Q_INVOKABLE BRWidget::BRWidgetStatusCode load() override; + + Q_INVOKABLE QString getTitle(); + Q_INVOKABLE QList getSeasonsQML(); + Q_INVOKABLE BRSeason* getCurrentSeason(); + Q_INVOKABLE void setCurrentSeason(BRSeason* season); private: - explicit BRCalendar(BRProvider* provider, BRFederation federation, int year, int league); + explicit BRCalendar(BRProvider* provider, BRFederation federation); + void setData(BRCalendarData data); - int year; - int league; - QList competitions; - QList categories; - QList cups; + QList seasons; + BRSeason* currentSeason; signals: - + void titleChanged(); + void seasonsChanged(); + void currentSeasonChanged(); }; #endif // BRCALENDAR_H diff --git a/headers/brcategory.h b/headers/brcategory.h index 4b76732..f794c19 100644 --- a/headers/brcategory.h +++ b/headers/brcategory.h @@ -3,13 +3,33 @@ #include -class BRCategory : public QObject +#include "brwidget.h" + +class BRCategory : public BRWidget { Q_OBJECT + Q_PROPERTY(QString name READ getName NOTIFY metadataChanged) public: - explicit BRCategory(QObject *parent = nullptr); + friend class BRProvider; + + typedef struct { + const BRCategory* category; + QString name; + } BRCategoryData; + + Q_INVOKABLE BRWidget::BRWidgetStatusCode load() override; + + Q_INVOKABLE QString getName(); + +private: + BRCategory(BRProvider* provider, BRWidget::BRFederation federation, int id, BRCategoryData initialData); + void setData(BRCategoryData data); + + const int id; + QString name; signals: + void metadataChanged(); }; diff --git a/headers/brcompetition.h b/headers/brcompetition.h index ffb9b34..07c6eb8 100644 --- a/headers/brcompetition.h +++ b/headers/brcompetition.h @@ -3,37 +3,88 @@ #include #include +#include +#include + #include "brwidget.h" #include "brcategory.h" +class BRLeague; + class BRCompetition : public BRWidget { Q_OBJECT + Q_PROPERTY(QString name READ getName NOTIFY metadataChanged) + Q_PROPERTY(QString discipline READ getDiscipline NOTIFY metadataChanged) + Q_PROPERTY(QDate startDate READ getStartDate NOTIFY metadataChanged) + Q_PROPERTY(QDate endDate READ getEndDate NOTIFY metadataChanged) + Q_PROPERTY(QString dateSpan READ getDateSpan NOTIFY metadataChanged) + Q_PROPERTY(BRLeague* league READ getLeague NOTIFY metadataChanged) + Q_PROPERTY(QUrl eventWebsiteUrl READ getEventWebsiteUrl NOTIFY metadataChanged) + Q_PROPERTY(QList infosheetUrls READ getInfosheetUrls NOTIFY metadataChanged) + Q_PROPERTY(QList categories READ getCategoriesQML NOTIFY categoriesChanged) + public: friend class BRProvider; - friend class BRProviderDr; - - Q_INVOKABLE QString getName(); - - BRWidget::BRWidgetStatusCode load() override; -private: - explicit BRCompetition(BRProvider* provider, BRWidget::BRFederation federation, int id); + friend class BRLeague; enum BRDiscipline { + Unknown = -1, Boulder, Lead, Speed }; + Q_ENUM(BRDiscipline) - int id; + typedef struct BRCompetitionData { + const BRCompetition* competition; + QString name; + BRDiscipline discipline; + QDate startDate; + QDate endDate; + QUrl eventWebsiteUrl; + QList infosheetUrls; + + QList categories; + } BRCompetitionData; + + Q_INVOKABLE BRWidget::BRWidgetStatusCode load() override; + + Q_INVOKABLE QString getName(); + Q_INVOKABLE BRDiscipline getDiscipline(); + Q_INVOKABLE QDate getStartDate(); + Q_INVOKABLE QDate getEndDate(); + Q_INVOKABLE QString getDateSpan(); + Q_INVOKABLE BRLeague* getLeague(); + Q_INVOKABLE QUrl getEventWebsiteUrl(); + Q_INVOKABLE QList getInfosheetUrls(); + Q_INVOKABLE QList getCategoriesQML(); + + static bool lessThan(BRCompetition* competition1, BRCompetition* competition2); + +private: + explicit BRCompetition(BRProvider* provider, BRWidget::BRFederation federation, int id, BRCompetitionData initialData); + + void setLeague(BRLeague* league); + + // metadata + const int id; QString name; BRDiscipline discipline; QDate startDate; QDate endDate; + BRLeague* league; + QUrl eventWebsiteUrl; + QList infosheetUrls; + // data QList categories; + void setData(BRCompetitionData data); + signals: + void metadataChanged(); + void categoriesChanged(); }; diff --git a/headers/brcontroller.h b/headers/brcontroller.h index 2e0681e..4ba3ec7 100644 --- a/headers/brcontroller.h +++ b/headers/brcontroller.h @@ -4,6 +4,7 @@ #include #include "brproviderdr.h" +#include "brprovidervl.h" #include "brwidget.h" class BRCalendar; @@ -14,10 +15,11 @@ class BRController : public QObject public: explicit BRController(QObject *parent = nullptr); - Q_INVOKABLE BRCalendar* getCalendar(BRWidget::BRFederation federation, int year, int league = 0); + Q_INVOKABLE BRCalendar* getCalendar(BRWidget::BRFederation federation); private: BRProvider* providerDr; + BRProvider* providerVl; signals: diff --git a/headers/brcup.h b/headers/brcup.h index ccd9632..097dd55 100644 --- a/headers/brcup.h +++ b/headers/brcup.h @@ -2,13 +2,42 @@ #define BRCUP_H #include +#include + #include "brwidget.h" +#include "brcategory.h" class BRCup : public BRWidget { Q_OBJECT + Q_PROPERTY(QString name READ getName NOTIFY metadataChanged) + Q_PROPERTY(QList categories READ getCategoriesQML NOTIFY categoriesChanged) + public: - BRCup(BRProvider* provider, BRWidget::BRFederation federation); + friend class BRProvider; + + typedef struct { + const BRCup* cup; + QString name; + QList categories; + } BRCupData; + + Q_INVOKABLE BRWidget::BRWidgetStatusCode load() override; + + Q_INVOKABLE QString getName(); + Q_INVOKABLE QList getCategoriesQML(); + +private: + BRCup(BRProvider* provider, BRWidget::BRFederation federation, int id, BRCupData initialData); + void setData(BRCupData data); + + const int id; + QString name; + QList categories; + +signals: + void metadataChanged(); + void categoriesChanged(); }; #endif // BRCUP_H diff --git a/headers/brleague.h b/headers/brleague.h new file mode 100644 index 0000000..419a682 --- /dev/null +++ b/headers/brleague.h @@ -0,0 +1,59 @@ +#ifndef BRLEAGUE_H +#define BRLEAGUE_H + +#include +#include + +#include "brwidget.h" +#include "brcompetition.h" +#include "brcategory.h" +#include "brcup.h" + +class BRLeague : public BRWidget +{ + Q_OBJECT + Q_PROPERTY(QString name READ getName NOTIFY metadataChanged) + Q_PROPERTY(QColor color READ getColor NOTIFY metadataChanged) + Q_PROPERTY(QList competitions READ getCompetitionsQML NOTIFY competitionsChanged) + Q_PROPERTY(QList cups READ getCupsQML NOTIFY cupsChanged) +public: + friend class BRProvider; + + typedef struct { + const BRLeague* league; + + QString name; + QColor color; + + QList competitions; + QList cups; + } BRLeagueData; + + BRWidget::BRWidgetStatusCode load() override; + + int getId() const; + Q_INVOKABLE QString getName(); + Q_INVOKABLE QColor getColor(); + Q_INVOKABLE QList getCompetitions(); + Q_INVOKABLE QList getCompetitionsQML(); + Q_INVOKABLE QList getCupsQML(); + +private: + BRLeague(BRProvider* provider, BRWidget::BRFederation federation, int id, BRLeagueData initialData); + void setData(BRLeagueData data); + + const int id; + + QString name; + QColor color; + + QList competitions; + QList cups; + +signals: + void metadataChanged(); + void competitionsChanged(); + void cupsChanged(); +}; + +#endif // BRLEAGUE_H diff --git a/headers/brprovider.h b/headers/brprovider.h index 9bf7a5c..14477a6 100644 --- a/headers/brprovider.h +++ b/headers/brprovider.h @@ -9,8 +9,9 @@ #include "brwidget.h" #include "brcalendar.h" +#include "brseason.h" +#include "brleague.h" #include "brcompetition.h" -#include "brcategory.h" #include "brcup.h" class BRProvider : public QObject @@ -19,13 +20,27 @@ class BRProvider : public QObject public: explicit BRProvider(QObject *parent = nullptr); + friend class BRController; friend class BRCalendar; + friend class BRSeason; + friend class BRLeague; + friend class BRCompetition; - BRCalendar* getCalendar(BRWidget::BRFederation federation, int year, int league); protected: - QVariantMap serverRequest(QUrl serviceUrl, QUrlQuery pdata = QUrlQuery()); + QVariantMap serverRequest(QUrl serviceUrl, QList additionalHeaders = {}, QUrlQuery postData = QUrlQuery()); + + virtual BRCalendar* getCalendar(BRWidget::BRFederation federation) final; + virtual BRSeason* getSeason(BRWidget::BRFederation federation, int id, BRSeason::BRSeasonData initialData) final; + virtual BRLeague* getLeague(BRWidget::BRFederation federation, int id, BRLeague::BRLeagueData initialData) final; + virtual BRCompetition* getCompetition(BRWidget::BRFederation federation, int id, BRCompetition::BRCompetitionData initialData) final; + virtual BRCup* getCup(BRWidget::BRFederation federation, int id, BRCup::BRCupData initialData) final; + virtual BRCategory* getCategory(BRWidget::BRFederation federation, int id, BRCategory::BRCategoryData initialData) final; + + virtual BRWidget::BRWidgetStatusCode getWidgetData(BRCalendar::BRCalendarData* calendarData) = 0; + virtual BRWidget::BRWidgetStatusCode getWidgetData(BRSeason::BRSeasonData* seasonData) = 0; + virtual BRWidget::BRWidgetStatusCode getWidgetData(BRLeague::BRLeagueData* leagueData) = 0; + virtual BRWidget::BRWidgetStatusCode getWidgetData(BRCompetition::BRCompetitionData* competitionData) = 0; - virtual BRWidget::BRWidgetStatusCode loadCalendarData(BRCalendar* calendar) = 0; signals: diff --git a/headers/brproviderdr.h b/headers/brproviderdr.h index 2eb8bdc..bbad631 100644 --- a/headers/brproviderdr.h +++ b/headers/brproviderdr.h @@ -4,8 +4,6 @@ #include #include "brprovider.h" -#include "brcalendar.h" -#include "brcompetition.h" class BRProviderDr : public BRProvider { @@ -14,11 +12,24 @@ public: explicit BRProviderDr(QObject *parent = nullptr); protected: - BRWidget::BRWidgetStatusCode loadCalendarData(BRCalendar* calendar); + BRWidget::BRWidgetStatusCode getWidgetData(BRCalendar::BRCalendarData* calendarData) override; - BRWidget::BRWidgetStatusCode loadCompetitionData(BRCompetition* competition, QVariantMap data); + BRWidget::BRWidgetStatusCode getWidgetData(BRSeason::BRSeasonData* seasonData) override; + BRSeason::BRSeasonData parseSeasonData(int id, QVariantMap rawData); + void parseSeasonData(BRSeason::BRSeasonData* seasonData, int id, QVariantMap rawData); + + BRWidget::BRWidgetStatusCode getWidgetData(BRLeague::BRLeagueData* leagueData) override; + BRLeague::BRLeagueData parseLeagueData(QVariantMap leagueProperties, QVariantMap rawData); + + BRWidget::BRWidgetStatusCode getWidgetData(BRCompetition::BRCompetitionData* competitionData) override; + BRCompetition::BRCompetitionData parseCompetitionData(QVariantMap rawData, BRWidget::BRFederation federation); + + BRCup::BRCupData parseCupData(QVariantList categoriesList, QVariantMap rawData, BRWidget::BRFederation federation); + + BRCategory::BRCategoryData parseCategoryData(QVariantMap rawData); private: + QMap> leagues; }; diff --git a/headers/brprovidervl.h b/headers/brprovidervl.h new file mode 100644 index 0000000..d0cddf2 --- /dev/null +++ b/headers/brprovidervl.h @@ -0,0 +1,35 @@ +#ifndef BRPROVIDERVL_H +#define BRPROVIDERVL_H + +#include + +#include "brprovider.h" + +class BRProviderVl : public BRProvider +{ + Q_OBJECT +public: + explicit BRProviderVl(QObject *parent = nullptr); + +protected: + BRWidget::BRWidgetStatusCode getWidgetData(BRCalendar::BRCalendarData* calendarData) override; + + BRWidget::BRWidgetStatusCode getWidgetData(BRSeason::BRSeasonData* seasonData) override; + BRSeason::BRSeasonData parseSeasonData(QVariantMap rawData); + + BRWidget::BRWidgetStatusCode getWidgetData(BRLeague::BRLeagueData* leagueData) override; + void parseLeagueData(BRLeague::BRLeagueData* leagueData, QVariantMap rawData); + + BRWidget::BRWidgetStatusCode getWidgetData(BRCompetition::BRCompetitionData* competitionData) override; + BRCompetition::BRCompetitionData parseCompetitionData(QVariantMap rawData, BRWidget::BRFederation federation); + + BRCup::BRCupData parseCupData(QVariantMap rawData); + + BRCategory::BRCategoryData parseCategoryData(QVariantMap rawData); + +private: + QMap> leagues; + +}; + +#endif // BRPROVIDERVL_H diff --git a/headers/brseason.h b/headers/brseason.h new file mode 100644 index 0000000..e134698 --- /dev/null +++ b/headers/brseason.h @@ -0,0 +1,61 @@ +#ifndef BRSEASON_H +#define BRSEASON_H + +#include + +#include "brwidget.h" +#include "brleague.h" + +class BRSeason : public BRWidget +{ + Q_OBJECT + Q_PROPERTY(int year READ getYear NOTIFY metadataChanged) + Q_PROPERTY(QString name READ getName NOTIFY metadataChanged) + Q_PROPERTY(QList leagues READ getLeaguesQML NOTIFY leaguesChanged) + Q_PROPERTY(QList competitions READ getCompetitionsQML NOTIFY competitionsChanged) + Q_PROPERTY(QList cups READ getCupsQML NOTIFY cupsChanged) + + +public: + friend class BRProvider; + + typedef struct { + const BRSeason* season; + + int year; + QString name; + bool nativeMultiLeagueSupport; + + QList leagues; + } BRSeasonData; + + BRWidget::BRWidgetStatusCode load() override; + + Q_INVOKABLE int getYear() const; + Q_INVOKABLE QString getName(); + Q_INVOKABLE QList getLeaguesQML(); + QList getLeagues() const; + Q_INVOKABLE QList getCompetitionsQML(); + Q_INVOKABLE QList getCupsQML(); + + +private: + explicit BRSeason(BRProvider* provider, BRWidget::BRFederation federation, int id, BRSeasonData initialData); + void setData(BRSeasonData data); + + const int id; + int year; + QString name; + bool multiLeagueSupport; + + QList leagues; + +signals: + void metadataChanged(); + void leaguesChanged(); + void competitionsChanged(); + void cupsChanged(); + +}; + +#endif // BRSEASON_H diff --git a/headers/brwidget.h b/headers/brwidget.h index 81ae8aa..0316962 100644 --- a/headers/brwidget.h +++ b/headers/brwidget.h @@ -19,21 +19,33 @@ public: enum BRWidgetStatusCode { Success = 200, - NoProviderError = 510 + InternalError = 900, + NoProviderError = 901, + NotImplementedError = 902 }; Q_ENUM(BRWidgetStatusCode) - explicit BRWidget(BRProvider* provider, BRFederation federation); - Q_INVOKABLE virtual BRWidget::BRWidgetStatusCode load() = 0; - BRFederation getFederation(); + + Q_INVOKABLE BRFederation getFederation() const; protected: + explicit BRWidget(BRProvider* provider, BRFederation federation); BRProvider* getProvider(); + template + QList listToQmlList(QList list) { + QList tmpList; + + for(T* item : list) + tmpList.append(static_cast(item)); + + return tmpList; + }; + private: BRProvider* provider; - BRFederation federation; + const BRFederation federation; signals: diff --git a/resources/qml/Pages/BRWidgetPage.qml b/resources/qml/Pages/BRWidgetPage.qml index 4882561..be1bad5 100644 --- a/resources/qml/Pages/BRWidgetPage.qml +++ b/resources/qml/Pages/BRWidgetPage.qml @@ -31,6 +31,7 @@ Page { property BRWidget data property Component headerComponent + property alias selector: selectorPu property string subTitle property bool titleIsPageTitle: true @@ -38,9 +39,17 @@ Page { property int status: -1 property bool ready: false + signal loadingFinished() + signal selectionFinished(int index, var data) + Component.onCompleted: { - data.load() + var status = data.load() + if(status !== BRWidget.Success) + ready = false + else + ready = true + loadingFinished() } function loadData(params) { @@ -88,8 +97,6 @@ Page { property var dataObj property string subTitle: "" - signal selectionFinished(int index, var data) - x: 0 //root.width / 2 - width / 2 y: root.height - selectorPu.height * 0.7//root.height - height //root.height / 2 - height / 2 @@ -210,7 +217,7 @@ Page { onClicked: { selectorPu.close() - selectorPu.selectionFinished(index, selectorPu.dataObj[index].data) + control.selectionFinished(index, selectorPu.dataObj[index].data) } } } diff --git a/resources/qml/Pages/CalendarPage.qml b/resources/qml/Pages/CalendarPage.qml index 277ee9d..661af46 100644 --- a/resources/qml/Pages/CalendarPage.qml +++ b/resources/qml/Pages/CalendarPage.qml @@ -27,7 +27,7 @@ import "../Components" BRWidgetPage { id: control - title: "New Calendar"//(params.nation === "ICC" ? "IFSC":params.nation === "GER" ? "DAV":"SAC") + " " + qsTr("calendar") + " " + control.year + title: control.data.title headerComponent: RowLayout { height: parent.height @@ -38,9 +38,7 @@ BRWidgetPage { ToolButton { id:yearToolBt - onClicked: { - control.changeYear() - } + onClicked: control.changeSeason() icon.name: "year" } @@ -48,27 +46,7 @@ BRWidgetPage { ToolButton { id: filterToolBt - onClicked: { - var obj = app.compCats - var compCats = new Array - - for(var prop in obj) { - // go through the whole array and search for data keys - if (obj.hasOwnProperty(prop) && obj[prop]["nation"] === params.nation) { - //console.log("found cat: " + obj[prop]['label']) - - compCats.push( {"text": obj[prop]['label'], "data": obj[prop]} ) - } - } - - compCats.push( {"text": qsTr("Pinned"), "data": {"sort_rank":0, "cat_id":[-1]}} ) - - compCats.sort(function(a, b) { - return a['data']['sort_rank'] - b['data']['sort_rank']; - }); - - filterSelectPu.appear(compCats, qsTr("Select Filters"), "") - } + onClicked: control.changeLeagues() icon.name: "filter" } @@ -76,31 +54,126 @@ BRWidgetPage { ToolButton { id: cupToolBt - onClicked: { - control.openCup() - } + onClicked: control.openCup() icon.name: "cup" } } + onLoadingFinished: { + calendarLv.autoScroll() + } + + onSelectionFinished: { + if(data.task === "competition"){ + app.openWidget({comp: data.comp, cat: data.cat, type:data.status === 4 ? 'starters':''}) + } + else if(data.task === "season"){ + loadingDl.open() + control.data.currentSeason = data.season + loadingDl.close() + } + else if(data.task === "cup1"){ + control.openCup(data) + } + else if(data.task === "cup2"){ + app.openWidget({cup: data.cup, cat: data.cat}) + } + } + + function changeSeason(){ + var selectOptions = [] + + for(var i = 0; i < control.data.seasons.length; i++){ + selectOptions.push({text: control.data.seasons[i].name, data:{task: "season", season: control.data.seasons[i]}}) + } + + selector.appear(selectOptions, qsTr("select season")) + } + + function openCompetition(competition){ + var selectOptions = [] + var categories = competition.categories + for(var i = 0; i < categories.length; i++){ + selectOptions.push({text: categories[i].name, data:{task: "competition", cat: categories[i], comp: competition, status:categories.status}}) + } + + var infoUrls = competition.infosheetUrls + var infosheet = ""; + if(infoUrls.length >= 1) + infosheet += ("" + qsTr('infosheet') + "") + if(infoUrls.length === 2) + infosheet += (", " + qsTr('further infos') + "") + + var eventWebsite = competition.eventWebsiteUrl.toString() !== "" ? ("" + qsTr('Event Website') + ""):"" + + selector.appear(selectOptions, competition.name, eventWebsite + ((eventWebsite !== "" && infosheet !== "") ? ", ":"") + infosheet ) + } + + function openCup(data) { + + var cups = control.data.currentSeason.cups + + var prop + var selectOptions = [] + var selectTitle = "" + + if(data === undefined){ + // opened for the first time -> select cup + selectTitle = qsTr("select cup") + + for(var i = 0; i < cups.length; i++){ + selectOptions.push({text: cups[i].name, data:{task: "cup1", cup: cups[i]}}) + } + } + else if(data.task === "cup1"){ + // opened for the second time -> select cat + var cup = data.cup + + selectTitle = cup['name'] + ": " + qsTr("select category") + + for(var c = 0; c < cup.categories.length; c++){ + selectOptions.push({text: cup.categories[c].name, data:{task: "cup2", cup: data.cup, cat: cup.categories[c]}}) + } + } + + selector.appear(selectOptions, selectTitle) + } + + function changeLeagues() { + var leagues = control.data.currentSeason.leagues + var selectOptions = [] + + for(var i = 0; i < leagues.length; i++) { + //console.log("found cat: " + obj[prop]['label']) + + selectOptions.push( {text: leagues[i].name, data:{task:"leagues", league: selectOptions}} ) + } + + //compCats.push( {"text": qsTr("Pinned"), "data": {"sort_rank":0, "cat_id":[-1]}} ) + console.log("leagues: " + leagues) + filterSelectPu.appear(selectOptions, qsTr("Select Filters"), "") + } + DataListView { + id: calendarLv anchors.fill: parent //boundsBehavior: Flickable.StopAtBounds - model: widgetData["competitions"].length + model: control.data.currentSeason.competitions + //listData: widgetData['competitions'] onRefresh: { - updateData({}, false) + control.data.load() } Component.onCompleted: { //initFilters() //initFavorites() - if(model){ + /*if(model){ control.status = 200 control.ready = true } @@ -108,9 +181,7 @@ BRWidgetPage { control.ready = false control.status = 901 return - } - - autoScroll() + }*/ } /* onWidgetDataChanged: { @@ -122,38 +193,16 @@ BRWidgetPage { */ function autoScroll() { // function to scroll to the next competition that is not already over - var compList = control.widgetData["competitions"] + var compList = calendarLv.model - //console.log("scrolling") - - if(parseInt(control.year) === new Date().getFullYear()){ + if(control.data.currentSeason.year === new Date().getFullYear()){ + console.log("SCROLLING") for(var i = 0; i < compList.length; i ++){ - // get the start date of the competition - var startDate = Date.fromLocaleString(Qt.locale(), compList[i]["date"], "yyyy-MM-dd") - //control.widgetData["competitions"][i]["month"] = startDate.getMonth() - - //console.log("got date: " + startDate + " from string: " + compList[i]["date"] + " -> month is: " + compList[i]["month"]) - - // get the duration of the competition - var durationString = compList[i]["duration"] === undefined ? "1":compList[i]["duration"] - var days = parseInt(durationString.replace(/\D/g,'')) - // calculate the end date of the competition - var endDate = new Date(startDate.valueOf()) - endDate.setDate(endDate.getDate() + days); - - //console.log(compList[i]["date"] + ": " + startDate + " to " + endDate) - - if(endDate.getTime() < new Date().getTime()){ + if(compList[i].endDate.getTime() < new Date().getTime()){ // end date is already over -> move the list view down! - control.positionViewAtIndex(i, ListView.Top) - //console.log("moving down!") + calendarLv.positionViewAtIndex(i, ListView.Top) } } - - //control.widgetData = control.widgetData - } - else { - //console.log("not current year") } } @@ -169,130 +218,6 @@ BRWidgetPage { } } - function openComp(compIndex){ - var cats = control.widgetData["competitions"][compIndex]["cats"] - - cats.sort(function(a, b) { - return parseInt(a["GrpId"]) - parseInt(b["GrpId"]); - }); - - var selectOptions = [] - - for(var prop in cats){ - if (cats.hasOwnProperty(prop)) { - selectOptions.push({text: cats[prop]["name"], data:{cat: cats[prop]["GrpId"], comp: control.widgetData["competitions"][compIndex]["WetId"], status:cats[prop]["status"]}}) - } - } - - var infoUrls = getCompInfoUrls(compIndex) - var infosheet = ""; - if(infoUrls.length >= 1) - infosheet += ("" + qsTr('infosheet') + "") - if(infoUrls.length === 2) - infosheet += (", " + qsTr('further infos') + "") - - console.log("Infosheet: " + infosheet) - - var eventWebsite = control.widgetData["competitions"][compIndex]["homepage"] !== undefined ? ("" + qsTr('Event Website') + ""):"" - - selector.appear(selectOptions, control.widgetData["competitions"][compIndex]['name'], eventWebsite + ((eventWebsite !== "" && infosheet !== "") ? ", ":"") + infosheet ) - } - - function changeYear(){ - var years = control.widgetData["years"] - - var selectOptions = [] - - for(var prop in years){ - if (years.hasOwnProperty(prop)) { - selectOptions.push({text: years[prop], data:{year: years[prop]}}) - } - } - - selector.appear(selectOptions, qsTr("select year")) - } - - function openCup(state, data) { - var cups = control.widgetData["cups"] - - var prop - var selectOptions = [] - var selectTitle = "" - - if(state === undefined){ - // opened for the first time -> select cup - selectTitle = qsTr("select cup") - - cups.sort(function(a, b) { - return parseInt(b["SerId"]) - parseInt(a["SerId"]); - }); - - for(prop in cups){ - if (cups.hasOwnProperty(prop)) { - selectOptions.push({text: cups[prop]["name"], data:{cup: cups[prop]["SerId"]}}) - } - } - } - else if(state === 1){ - // opened for the second time -> select cat - var cup - - // find the selected cup - for(prop in cups){ - if (cups.hasOwnProperty(prop) && cups[prop]['SerId'] === data.cup) { - cup = cups[prop] - } - } - - if(cup === undefined){ - // cup was not found - return - } - - selectTitle = cup['name'] + ": " + qsTr("select category") - - // build a list with all cat in the cup out of the cat keys (rkey) given in the cup.cats - for(prop in cup['cats']){ - if (cup['cats'].hasOwnProperty(prop)) { - - // search the rkey in the cat list - for(var i = 0; i < control.widgetData["cats"].length; i ++ ){ - if(control.widgetData["cats"][i]["rkey"] === cup["cats"][prop] && control.widgetData["cats"][i]["sex"] !== undefined){ - // found it -> append it to the select list - var catName = control.widgetData["cats"][i]["name"] // name of cat - var catId = control.widgetData["cats"][i]["GrpId"] // id of cat - selectOptions.push({text: catName, data:{cup: data.cup, cat: catId}}) - } - } - } - } - } - - selector.appear(selectOptions, selectTitle) - - } - - function getCompInfoUrls(compIndex) { - - var urls = []; - - if(control.widgetData["competitions"][compIndex].hasOwnProperty("info")) { - if(params.nation === "GER") - urls.push("http://ranking.alpenverein.de/" + control.year + "/GER/" + control.widgetData["competitions"][compIndex]['rkey'] + ".pdf") - else - urls.push(control.widgetData["competitions"][compIndex]['info']) - } - - if(control.widgetData["competitions"][compIndex].hasOwnProperty("info2")) { - if(params.nation === "GER") - urls.push("http://ranking.alpenverein.de/" + control.year + "/GER/i" + control.widgetData["competitions"][compIndex]['rkey'] + ".pdf") - else - urls.push(control.widgetData["competitions"][compIndex]['info2']) - } - - return urls; - } - function filterCats(display, cats) { //console.log("filtering cats: " + cats + " displaying: " + display) for(var i = 0; i < cats.length; i ++){ @@ -361,26 +286,6 @@ BRWidgetPage { console.log(control.compFavorites) } - Connections { - target: parent.selector - onSelectionFinished: { - if(data.comp !== undefined){ - //console.log(data.status) - app.openWidget({comp: data.comp, cat: data.cat, type:data.status === 4 ? 'starters':''}) - } - else if(data.year !== undefined){ - updateData({year: data.year}, true) - control.year = data.year - } - else if(data.cup !== undefined && data.cat === undefined){ - control.openCup(1,data) - } - else if(data.cup !== undefined && data.cat !== undefined){ - app.openWidget({cup: data.cup, cat: data.cat}) - } - } - } - header: Item { id: topSpacerItm width: parent.width @@ -397,16 +302,16 @@ BRWidgetPage { id: competitionDel property bool over - property var thisData: control.widgetData["competitions"][index] + property var thisData: modelData - property string name: thisData["name"] - property string date: thisData["date_span"] + property string name: thisData.name + property string date: thisData.dateSpan //"test" // TODO thisData["date_span"] property var cats: thisData["cats"] property int catId: thisData["cat_id"] === undefined ? 0:thisData["cat_id"] - property bool thisIsFavored: control.compFavorites.indexOf(parseInt(thisData['WetId'])) >= 0 - property bool includedByFavorites: control.displayedCompCats.indexOf(-1) >= 0 && thisIsFavored - property bool includedByFilter: control.displayedCompCats.indexOf(parseInt(thisData['cat_id'])) >= 0 + property bool thisIsFavored: true //control.compFavorites.indexOf(parseInt(thisData['WetId'])) >= 0 + property bool includedByFavorites: true //control.displayedCompCats.indexOf(-1) >= 0 && thisIsFavored + property bool includedByFilter: true//control.displayedCompCats.indexOf(parseInt(thisData['cat_id'])) >= 0 property bool thisIsVisible: includedByFavorites || includedByFilter function updateVisibility() { @@ -418,7 +323,7 @@ BRWidgetPage { width: parent.width height: thisIsVisible ? compDelCol.height + 10 : 0 - enabled: ((thisData["cats"] !== undefined && thisData["cats"].length > 0) || competitionDel.thisData["homepage"] !== undefined || getCompInfoUrls(index).length > 0) && height > 0 + enabled: true//((thisData["cats"] !== undefined && thisData["cats"].length > 0) || competitionDel.thisData["homepage"] !== undefined || getCompInfoUrls(index).length > 0) && height > 0 //visible: includedByFilter opacity: 0 @@ -457,7 +362,7 @@ BRWidgetPage { } onClicked: { - control.openComp(index) + control.openCompetition(thisData) } ParallelAnimation { @@ -479,7 +384,7 @@ BRWidgetPage { opacity: 0.5 - color: control.getCompCatData(catId) === undefined ? "white":control.getCompCatData(catId)["bgcolor"] + color: competitionDel.thisData.league.color } Column { @@ -570,189 +475,190 @@ BRWidgetPage { width: parent.width text: section } + } - Dialog { - id: filterSelectPu + Dialog { + id: filterSelectPu - property var dataObj - property string subTitle: "" + property var dataObj + property string subTitle: "" - signal selectionFinished(int index, var data) + signal selectionFinished(int index, var data) - x: 0 - control.anchors.leftMargin //root.width / 2 - width / 2 - y: root.height - filterSelectPu.height * 0.7//root.height - height //root.height / 2 - height / 2 + x: 0 - control.anchors.leftMargin //root.width / 2 - width / 2 + y: control.height - filterSelectPu.height * 0.7//root.height - height //root.height / 2 - height / 2 - opacity: 0 + opacity: 0 - width: control.width + control.anchors.leftMargin + control.anchors.rightMargin - height: selectorLv.implicitHeight + width: control.width + control.anchors.leftMargin + control.anchors.rightMargin + height: selectorLv.implicitHeight - modal: true - focus: true + modal: true + focus: true - title: "" + title: "" - function appear(dataObj, title, subTitle) { - if(dataObj.length > 0){ - filterSelectPu.dataObj = dataObj - filterSelectPu.title = title - filterSelectPu.subTitle = subTitle === undefined ? "":subTitle - filterSelectPu.open() - } + function appear(dataObj, title, subTitle) { + if(dataObj.length > 0){ + filterSelectPu.dataObj = dataObj + filterSelectPu.title = title + filterSelectPu.subTitle = subTitle === undefined ? "":subTitle + filterSelectPu.open() } + } - header: Column { - id: filterSelectPuHeaderCol + header: Column { + id: filterSelectPuHeaderCol + + width: parent.width + + Label { + id: headerLa + + visible: filterSelectPu.title width: parent.width - Label { - id: headerLa - - visible: filterSelectPu.title - - width: parent.width - - elide: "ElideRight" - padding: 24 - bottomPadding: 0 - font.bold: true - font.pixelSize: 16 - background: Rectangle { - radius: 2 - //color: filterSelectPu.Material.dialogColor - clip: true - } - - text: filterSelectPu.title - - onLinkActivated: { - Qt.openUrlExternally(link) - } - + elide: "ElideRight" + padding: 24 + bottomPadding: 0 + font.bold: true + font.pixelSize: 16 + background: Rectangle { + radius: 2 + //color: filterSelectPu.Material.dialogColor + clip: true } - Label { - id: headerSubLa - visible: filterSelectPu.subTitle - - width: parent.width - - elide: "ElideRight" - padding: 24 - topPadding: 5 - bottomPadding: 0 - font.bold: true - font.pixelSize: 16 - background: Rectangle { - radius: 2 - //color: filterSelectPu.Material.dialogColor - clip: true - } - - text: filterSelectPu.subTitle - - onLinkActivated: { - Qt.openUrlExternally(link) - } + text: filterSelectPu.title + onLinkActivated: { + Qt.openUrlExternally(link) } + + } + Label { + id: headerSubLa + + visible: filterSelectPu.subTitle + + width: parent.width + + elide: "ElideRight" + padding: 24 + topPadding: 5 + bottomPadding: 0 + font.bold: true + font.pixelSize: 16 + background: Rectangle { + radius: 2 + //color: filterSelectPu.Material.dialogColor + clip: true + } + + text: filterSelectPu.subTitle + + onLinkActivated: { + Qt.openUrlExternally(link) + } + + } + } + + ListView { + id: selectorLv + + property int delegateHeight: 50 + + anchors.fill: parent + + implicitWidth: parent.width + implicitHeight: control.height * 0.7 < ( (delegateHeight + spacing) * model ) ? root.height * 0.7 : (delegateHeight + spacing) * model + 100 + + model: filterSelectPu.dataObj !== undefined ? filterSelectPu.dataObj.length:0 + + ScrollIndicator.vertical: ScrollIndicator { + parent: selectorLv.parent + anchors { + top: selectorLv.top + left: selectorLv.right + margins: 10 + leftMargin: 3 + bottom: selectorLv.bottom + } + } - ListView { - id: selectorLv + delegate: CheckDelegate { + id: catBt - property int delegateHeight: 50 + width: parent.width + height: text !== "" ? selectorLv.delegateHeight:0 - anchors.fill: parent + //flat: true - implicitWidth: parent.width - implicitHeight: root.height * 0.7 < ( (delegateHeight + spacing) * model ) ? root.height * 0.7 : (delegateHeight + spacing) * model + 100 - - model: filterSelectPu.dataObj !== undefined ? filterSelectPu.dataObj.length:0 - - ScrollIndicator.vertical: ScrollIndicator { - parent: selectorLv.parent - anchors { - top: selectorLv.top - left: selectorLv.right - margins: 10 - leftMargin: 3 - bottom: selectorLv.bottom - } + text: filterSelectPu.dataObj[index].text + Component.onCompleted: { + checked = getCheckedState() } - delegate: CheckDelegate { - id: catBt - - width: parent.width - height: text !== "" ? selectorLv.delegateHeight:0 - - //flat: true - - text: filterSelectPu.dataObj[index].text - - Component.onCompleted: { + Connections { + target: control + onDisplayedCompCatsChanged: { + //console.log("filters changed") + //competitionDel.visible = control.displayedCompCats.indexOf(parseInt(competitionDel.thisData['cat_id'])) >= 0 checked = getCheckedState() } + } - Connections { - target: control - onDisplayedCompCatsChanged: { - //console.log("filters changed") - //competitionDel.visible = control.displayedCompCats.indexOf(parseInt(competitionDel.thisData['cat_id'])) >= 0 - checked = getCheckedState() + function getCheckedState() { + for(var i = 0; i < filterSelectPu.dataObj[index].data.cat_id.length; i ++){ + + //console.log("checking cat " + filterSelectPu.dataObj[index].data.label ) + if(control.displayedCompCats.indexOf(filterSelectPu.dataObj[index].data.cat_id[i] ) >= 0){ + return true } } + return false + } - function getCheckedState() { - for(var i = 0; i < filterSelectPu.dataObj[index].data.cat_id.length; i ++){ - //console.log("checking cat " + filterSelectPu.dataObj[index].data.label ) - if(control.displayedCompCats.indexOf(filterSelectPu.dataObj[index].data.cat_id[i] ) >= 0){ - return true - } - } - return false + onClicked: { + control.filterCats(checked, filterSelectPu.dataObj[index].data.cat_id) + if(control.displayedCompCats.length === 0){ + control.filterCats(true, filterSelectPu.dataObj[index].data.cat_id) + checked = true } - - - onClicked: { - control.filterCats(checked, filterSelectPu.dataObj[index].data.cat_id) - if(control.displayedCompCats.length == 0){ - control.filterCats(true, filterSelectPu.dataObj[index].data.cat_id) - checked = true - } - } - } - } - - enter: Transition { - NumberAnimation { - property: "opacity"; - //from: 0.0; - to: 1.0 - } - NumberAnimation { - property: "y" - //from: root.height - filterSelectPu.height * 0.7 - to: root.height - filterSelectPu.height - } - } - - exit: Transition { - NumberAnimation { - property: "opacity"; - //from: 1.0; - to: 0.0 - } - NumberAnimation { - property: "y" - //from: root.height - filterSelectPu.height - to: root.height - filterSelectPu.height * 0.7 } } } + + enter: Transition { + NumberAnimation { + property: "opacity"; + //from: 0.0; + to: 1.0 + } + NumberAnimation { + property: "y" + //from: root.height - filterSelectPu.height * 0.7 + to: control.height - filterSelectPu.height + } + } + + exit: Transition { + NumberAnimation { + property: "opacity"; + //from: 1.0; + to: 0.0 + } + NumberAnimation { + property: "y" + //from: root.height - filterSelectPu.height + to: control.height - filterSelectPu.height * 0.7 + } + } } + } diff --git a/resources/qml/Pages/StartPage.qml b/resources/qml/Pages/StartPage.qml index 29268a6..7c4435b 100644 --- a/resources/qml/Pages/StartPage.qml +++ b/resources/qml/Pages/StartPage.qml @@ -61,10 +61,7 @@ Page { image: "qrc:/icons/ifsc.png" - onClicked: { - app.openWidget({nation:"ICC"}) - } - + onClicked: app.openCalendar(BRWidget.IFSC) } FancyButton { @@ -75,10 +72,7 @@ Page { image: "qrc:/icons/dav.png" - onClicked: { - app.openCalendar(BRWidget.DAV, 2020, -1) - } - + onClicked: app.openCalendar(BRWidget.DAV) } FancyButton { @@ -89,10 +83,7 @@ Page { image: "qrc:/icons/sac.png" - onClicked: { - app.openWidget({nation:"SUI"}) - } - + onClicked: app.openCalendar(BRWidget.SAC) } } diff --git a/resources/qml/main.qml b/resources/qml/main.qml index 610127f..2c5327e 100644 --- a/resources/qml/main.qml +++ b/resources/qml/main.qml @@ -39,174 +39,6 @@ Window { property int errorCode: -1 - // comp cats source: - // - https://github.com/ralfbecker/ranking/blob/master/sitemgr/digitalrock/icc_calendar.php - // - https://github.com/ralfbecker/ranking/blob/master/sitemgr/digitalrock/dav_calendar.php - // - https://github.com/ralfbecker/ranking/blob/master/sitemgr/digitalrock/sac_calendar.php - - property var compCats: { - - // --- ICC --- - - /*'int' : { - 'label' : 'International', - 'nation' : 'ICC', - 'wettk_reg' : '^[0-9]{2,2}[_^E]{1}[^YJ]{1,1}.*', - 'serie_reg' : '^[0-9]{2,2}_(WC|TR){1,1}.*', - 'rang_title': 'CUWR continuously updated WORLDRANKING', - 'bgcolor' : '#B8C8FF', - 'nat_team_ranking' : '', - 'cat_id' : [68,86]//[68,69,70,86,259] - },*/ - 'worldcup': { - 'label' : 'World Cups', - 'nation' : 'ICC', - 'bgcolor' : '#B8C8FF', - 'sort_rank': 1, - 'cat_id' : [69] - }, - 'youth' : { - 'label' : 'Youth Events', - 'nation' : 'ICC', - 'wettk_reg' : '^[0-9]{2,2}(EYC|_J|_Y){1,1}.*', - 'serie_reg' : '^[0-9]{2,2}_EYC', - 'rang_title': '', - 'bgcolor' : '#D8E8FF', - 'sort_rank': 2, - 'cat_id' : [71,258] - }, - 'cont': { - 'label' : 'Continental Events', - 'nation' : 'ICC', - 'bgcolor' : '#B8C8FF', - 'sort_rank': 3, - 'cat_id' : [262] - }, - 'masters' : { - 'label' : 'Masters and Promo Events', - 'nation' : 'ICC', - 'wettk_reg' : '^[0-9]{2,2}_[^PWERASL]{1}.*', - // 'serie_reg' : '^[0-9]{2,2}_(WC|TR){1,1}.*', - // 'rang_title': 'CUWR continuously updated WORLDRANKING', - 'bgcolor' : '#F0F0F0', - 'sort_rank': 4, - 'cat_id' : [70] - }, - 'para' : { - 'label' : 'Paraclimbing Events', - 'nation' : 'ICC', - 'wettk_reg' : '^[0-9]{2,2}_PE.*', - 'bgcolor' : '#F0F0F0', - 'sort_rank': 5, - 'cat_id' : [256,259] - }, - 'games': { - 'label': 'Games', - 'nation': 'ICC', - 'bgcolor' : '#B8C8FF', - 'sort_rank': 6, - 'cat_id': [68,86] - }, - - // --- GER --- - - /*'ger_boulder' : { - 'label' : 'Bouldern', - 'nation' : 'GER', - 'wettk_reg' : '^[0-9]{2,2}_B+.*', - 'serie_reg' : '^[0-9]{2,2}_BC', - 'bgcolor' : '#FFDBA8', //'#f59d30' - 'cat_id' : [59] - }, - 'ger' : { - 'label' : 'Lead', - 'nation' : 'GER', - 'wettk_reg' : '^[0-9]{2,2}[_J]{1,1}[^WLJ]+.*', - 'serie_reg' : '^[0-9]{2,2}_DC', - 'bgcolor' : '#A8F0A8', //'#69b9a9' - 'cat_id' : [57] - }, - 'ger_speed' : { - 'label' : 'Speed', - 'nation' : 'GER', - 'wettk_reg' : '^[0-9]{2,2}[_J]{1,1}[^WLJ]+.*', - 'serie_reg' : '', - 'rang_title': '', - 'bgcolor' : '#A8F0A8', //'#e72e5d' - 'cat_id' : [60] - },*/ - - 'ger_meisterschaft' : { - 'label' : 'Deutsche Meisterschaft', - 'nation' : 'GER', - 'bgcolor' : '#A8F0A8', - 'sort_rank': 1, - 'cat_id' : [57, 59, 60] - }, - - 'ger_jugend' : { - 'label' : 'Deutscher Jugendcup', - 'nation' : 'GER', - 'wettk_reg' : '^[0-9]{2,2}[_J]{1,1}[^WL]+.*', - 'serie_reg' : '^[0-9]{2,2}_JC', - // 'rang_title': 'Deutsche Jugend RANGLISTE', - 'bgcolor' : '#D8FFD8', - 'sort_rank': 2, - 'cat_id' : [58] - }, - 'ger_state' : { - 'label' : 'Landesmeisterschaft', - 'nation' : 'GER', - 'wettk_reg' : '^[0-9]{2,2}[_J]{1,1}LM.*', - 'serie_reg' : '^[0-9]{2,2}[_J]{1,1}LM.*', - 'rang_title': '', - 'bgcolor' : '#F0F0F0', - 'sort_rank': 3, - 'cat_id' : [61,56] - }, - - // --- SUI --- - - 'sui' : { - 'label' : 'Erwachsene', - 'nation' : 'SUI', - 'wettk_reg' : '^[0-9]{2,2}_[^R].*', - 'serie_reg' : '.*', - 'rang_title': 'SWISS RANKING', - 'bgcolor' : '#A8F0A8', - 'sort_rank': 1, - 'cat_id' : [62,63] - }, - 'sui_jugend' : { - 'label' : 'Jugend', - 'nation' : 'SUI', - 'wettk_reg' : '^[0-9]{2,2}_[^R].*', - 'serie_reg' : '.*', - 'rang_title': 'SWISS RANKING', - 'bgcolor' : '#D8FFD8', - 'sort_rank': 2, - 'cat_id' : [65] - }, - 'sui_local' : { - 'label' : 'RegioCups', - 'nation' : 'SUI', - 'wettk_reg' : '^[0-9]{2,2}_RG_.*', - 'rang_title': '', - 'bgcolor' : '#F0F0F0', - 'sort_rank': 3, - 'cat_id' : [64] - }, - 'sui_ice' : { - 'label' : 'Iceclimbing', - 'nation' : 'SUI', - 'wettk_reg' : '^[0-9]{2,2}_RC_.*', - 'rang_title': '', - 'bgcolor' : '#F0F0F0', - 'sort_rank': 4, - 'cat_id' : [84] - } - } - anchors.fill: parent Component.onCompleted: { @@ -613,13 +445,13 @@ Window { loadingDl.close() } - function openCalendar(federation, year, season) { + function openCalendar(federation) { loadingDl.open() - var newPageComp = Qt.createComponent("qrc:/Pages/CalendarPage.qml").createObject(null, {"data": brController.getCalendar(BRWidget.DAV, year, season)}) + var newPageComp = Qt.createComponent("qrc:/Pages/CalendarPage.qml").createObject(null, {"data": brController.getCalendar(federation)}) app.errorCode = newPageComp.status - if(calComp.ready){ + if(newPageComp.ready){ mainStack.push(newPageComp) } else { diff --git a/sources/brcalendar.cpp b/sources/brcalendar.cpp index 2e7f237..5c4f3a6 100644 --- a/sources/brcalendar.cpp +++ b/sources/brcalendar.cpp @@ -1,32 +1,40 @@ #include "../headers/brcalendar.h" #include "headers/brprovider.h" -BRCalendar::BRCalendar(BRProvider* provider, BRFederation federation, int year, int league) : BRWidget(provider, federation) +BRCalendar::BRCalendar(BRProvider* provider, BRFederation federation) : BRWidget(provider, federation) { - this->year = year; - this->league = league; + this->currentSeason = nullptr; + this->seasons = {}; + + connect(this, &BRCalendar::currentSeasonChanged, this, &BRCalendar::titleChanged); + connect(this, &BRCalendar::seasonsChanged, this, &BRCalendar::titleChanged); +} + +QString BRCalendar::getTitle() { + QString title = QStringList({"IFSC", "DAV", "SAC"})[this->getFederation()] + " " + tr("calendar"); + + if(this->currentSeason != nullptr) + title += " " + this->currentSeason->getName(); + + return title; +} + +QList BRCalendar::getSeasonsQML() { + return this->listToQmlList(this->seasons); } -int BRCalendar::getYear() { - return this->year; +BRSeason* BRCalendar::getCurrentSeason() { + return this->currentSeason; } -int BRCalendar::getLeague() { - return this->league; -} +void BRCalendar::setCurrentSeason(BRSeason* season) { + if(!this->seasons.contains(season)) + return; -QList BRCalendar::getCompetitions() { - return this->competitions; -} - -QList BRCalendar::getCompetitionsQML() { - QList tmpCompetitions; - - for(BRCompetition* competition : this->competitions) - tmpCompetitions.append(competition); - - return tmpCompetitions; + this->currentSeason = season; + this->currentSeason->load(); + emit this->currentSeasonChanged(); } BRWidget::BRWidgetStatusCode BRCalendar::load() { @@ -34,11 +42,29 @@ BRWidget::BRWidgetStatusCode BRCalendar::load() { return BRWidget::NoProviderError; // reload all comp data using our providers - this->competitions.clear(); - this->categories.clear(); - this->cups.clear(); - // TODO: handle changes dynamically + BRCalendarData newData { + this, + this->currentSeason, + this->seasons + }; - return this->getProvider()->loadCalendarData(this); + BRWidget::BRWidgetStatusCode statusCode = this->getProvider()->getWidgetData(&newData); + + if(statusCode != BRWidget::Success) + return statusCode; + + if(this->seasons != newData.seasons) { + this->seasons.clear(); + this->seasons = newData.seasons; + emit this->seasonsChanged(); + } + + if(this->currentSeason != newData.currentSeason) { + this->currentSeason = newData.currentSeason; + emit this->currentSeasonChanged(); + } + + + return statusCode; } diff --git a/sources/brcategory.cpp b/sources/brcategory.cpp index 45c4927..3166c5b 100644 --- a/sources/brcategory.cpp +++ b/sources/brcategory.cpp @@ -1,6 +1,20 @@ #include "../headers/brcategory.h" -BRCategory::BRCategory(QObject *parent) : QObject(parent) +BRCategory::BRCategory(BRProvider* provider, BRWidget::BRFederation federation, int id, BRCategoryData initialData) : BRWidget(provider, federation), id(id) { - + this->setData(initialData); +} + +QString BRCategory::getName() { + return this->name; +} + +void BRCategory::setData(BRCategoryData data) { + this->name = data.name; + emit this->metadataChanged(); +} + + +BRWidget::BRWidgetStatusCode BRCategory::load() { + // TODO } diff --git a/sources/brcompetition.cpp b/sources/brcompetition.cpp index 42c08da..18d7999 100644 --- a/sources/brcompetition.cpp +++ b/sources/brcompetition.cpp @@ -1,14 +1,79 @@ -#include "../headers/brcompetition.h" +#include "headers/brcompetition.h" +#include "headers/brleague.h" -BRCompetition::BRCompetition(BRProvider* provider, BRWidget::BRFederation federation, int id) : BRWidget(provider, federation) -{ - this->id = id; +BRCompetition::BRCompetition(BRProvider* provider, BRWidget::BRFederation federation, int id, BRCompetitionData initialData) : BRWidget(provider, federation), id(id) { + this->setData(initialData); +} + +void BRCompetition::setLeague(BRLeague* league) { + if(league == nullptr) + return; + + this->league = league; + emit this->metadataChanged(); } QString BRCompetition::getName() { return this->name; } +BRCompetition::BRDiscipline BRCompetition::getDiscipline() { + return this->discipline; +} + +QDate BRCompetition::getStartDate() { + return this->startDate; +} + +QDate BRCompetition::getEndDate() { + return this->endDate; +} + +QString BRCompetition::getDateSpan() { + if(this->startDate == this->endDate) + return this->startDate.toString("d MMMM yyyy"); + else + return this->startDate.toString("d MMMM yyyy") + " - " + this->endDate.toString("d MMMM yyyy"); +} + +BRLeague* BRCompetition::getLeague() { + return this->league; +} + +QUrl BRCompetition::getEventWebsiteUrl() { + return this->eventWebsiteUrl; +} + +QList BRCompetition::getInfosheetUrls() { + return this->infosheetUrls; +} + +QList BRCompetition::getCategoriesQML() { + return this->listToQmlList(this->categories); +} + BRWidget::BRWidgetStatusCode BRCompetition::load() { } + +void BRCompetition::setData(BRCompetition::BRCompetitionData data) { + this->name = data.name; + this->discipline = data.discipline; + this->startDate = data.startDate; + this->endDate = data.endDate; + this->eventWebsiteUrl = data.eventWebsiteUrl; + this->infosheetUrls = data.infosheetUrls; + emit this->metadataChanged(); + + if(this->categories != data.categories) { + this->categories.clear(); + this->categories = data.categories; + emit this->categoriesChanged(); + } + +} + + +bool BRCompetition::lessThan(BRCompetition* competition1, BRCompetition* competition2) { + return competition1->startDate < competition2->startDate; +} diff --git a/sources/brcontroller.cpp b/sources/brcontroller.cpp index ad274ac..9c3d21e 100644 --- a/sources/brcontroller.cpp +++ b/sources/brcontroller.cpp @@ -3,9 +3,13 @@ BRController::BRController(QObject *parent) : QObject(parent) { this->providerDr = new BRProviderDr(this); + this->providerVl = new BRProviderVl(this); } -BRCalendar* BRController::getCalendar(BRWidget::BRFederation federation, int year, int league) { - return this->providerDr->getCalendar(federation, year, -1); +BRCalendar* BRController::getCalendar(BRWidget::BRFederation federation) { + if(federation == BRWidget::IFSC) + return this->providerVl->getCalendar(federation); + else + return this->providerDr->getCalendar(federation); } diff --git a/sources/brcup.cpp b/sources/brcup.cpp index 4ead14b..d321cae 100644 --- a/sources/brcup.cpp +++ b/sources/brcup.cpp @@ -1,6 +1,31 @@ #include "../headers/brcup.h" -BRCup::BRCup(BRProvider* provider, BRFederation federation) : BRWidget(provider, federation) +BRCup::BRCup(BRProvider* provider, BRWidget::BRFederation federation, int id, BRCupData initialData) : BRWidget(provider, federation), id(id) { - + this->categories = {}; + this->setData(initialData); +} + +QString BRCup::getName() { + return this->name; +} + +QList BRCup::getCategoriesQML() { + return this->listToQmlList(this->categories); +} + +void BRCup::setData(BRCupData data) { + this->name = data.name; + emit this->metadataChanged(); + + if(this->categories != data.categories) { + this->categories.clear(); + this->categories = data.categories; + emit this->categoriesChanged(); + } +} + + +BRWidget::BRWidgetStatusCode BRCup::load() { + // TODO } diff --git a/sources/brleague.cpp b/sources/brleague.cpp new file mode 100644 index 0000000..da8f29b --- /dev/null +++ b/sources/brleague.cpp @@ -0,0 +1,83 @@ +#include "headers/brleague.h" +#include "headers/brprovider.h" + +BRLeague::BRLeague(BRProvider* provider, BRWidget::BRFederation federation, int id, BRLeagueData initialData) : BRWidget(provider, federation), id(id) +{ + this->competitions = {}; + this->competitions = {}; + this->setData(initialData); +} + +int BRLeague::getId() const { + return this->id; +} + +QString BRLeague::getName() { + return this->name; +} + +QColor BRLeague::getColor() { + return this->color; +} + +QList BRLeague::getCompetitions() { + return this->competitions; +} + +QList BRLeague::getCompetitionsQML() { + return this->listToQmlList(this->competitions); +} + +QList BRLeague::getCupsQML() { + return this->listToQmlList(this->cups); +} + +void BRLeague::setData(BRLeagueData data) { + + this->name = data.name; + this->color = data.color; + emit this->metadataChanged(); + + if(this->competitions != data.competitions) { + this->competitions.clear(); + this->competitions = data.competitions; + + for(BRCompetition* competition : this->competitions) + competition->setLeague(this); + + emit this->competitionsChanged(); + } + + if(this->cups != data.cups) { + this->cups.clear(); + this->cups = data.cups; + emit this->cupsChanged(); + } +} + + +BRWidget::BRWidgetStatusCode BRLeague::load() { + if(this->getProvider() == nullptr) + return BRWidget::NoProviderError; + + // reload all comp data using our providers + + BRLeagueData newData { + this, + this->name, + this->color, + this->competitions, + this->cups + }; + + BRWidget::BRWidgetStatusCode statusCode = this->getProvider()->getWidgetData(&newData); + + if(statusCode != BRWidget::Success) + return statusCode; + + qDebug() << "new Data: " << newData.competitions; + + this->setData(newData); + + return statusCode; +} diff --git a/sources/brprovider.cpp b/sources/brprovider.cpp index 27e46f0..ade7aa3 100644 --- a/sources/brprovider.cpp +++ b/sources/brprovider.cpp @@ -5,11 +5,32 @@ BRProvider::BRProvider(QObject *parent) : QObject(parent) } -BRCalendar* BRProvider::getCalendar(BRWidget::BRFederation federation, int year, int league) { - return new BRCalendar(this, federation, year, league); +BRCalendar* BRProvider::getCalendar(BRWidget::BRFederation federation) { + return new BRCalendar(this, federation); } -QVariantMap BRProvider::serverRequest(QUrl serviceUrl, QUrlQuery pdata) +BRSeason* BRProvider::getSeason(BRWidget::BRFederation federation, int id, BRSeason::BRSeasonData initialData) { + return new BRSeason(this, federation, id, initialData); +} + +BRLeague* BRProvider::getLeague(BRWidget::BRFederation federation, int id, BRLeague::BRLeagueData initialData) { + return new BRLeague(this, federation, id, initialData); +} + +BRCompetition* BRProvider::getCompetition(BRWidget::BRFederation federation, int id, BRCompetition::BRCompetitionData initialData) { + return new BRCompetition(this, federation, id, initialData); +} + + +BRCup* BRProvider::getCup(BRWidget::BRFederation federation, int id, BRCup::BRCupData initialData) { + return new BRCup(this, federation, id, initialData); +} + +BRCategory* BRProvider::getCategory(BRWidget::BRFederation federation, int id, BRCategory::BRCategoryData initialData) { + return new BRCategory(this, federation, id, initialData); +} + +QVariantMap BRProvider::serverRequest(QUrl serviceUrl, QList additionalHeaders, QUrlQuery postData) { qDebug() << "requesting: " << serviceUrl; @@ -20,8 +41,13 @@ QVariantMap BRProvider::serverRequest(QUrl serviceUrl, QUrlQuery pdata) // Create network request QNetworkRequest request(serviceUrl); - request.setHeader(QNetworkRequest::ContentTypeHeader, - "application/x-www-form-urlencoded"); + + // insert additional headers + for(QStringList additionalHeader : additionalHeaders) { + if(additionalHeader.length() == 2) + request.setRawHeader(additionalHeader[0].toUtf8(), additionalHeader[1].toUtf8()); + } + //QSslConfiguration config = QSslConfiguration::defaultConfiguration(); //config.setProtocol(QSsl::TlsV1_2); @@ -31,13 +57,13 @@ QVariantMap BRProvider::serverRequest(QUrl serviceUrl, QUrlQuery pdata) QNetworkReply *reply; - if(pdata.isEmpty()){ + if(postData.isEmpty()){ // if no post data is given -> send a GET request reply = networkManager->get(request); } else { // if post data is given -> send POST request - reply = networkManager->post(request, pdata.toString(QUrl::FullyEncoded).toUtf8()); + reply = networkManager->post(request, postData.toString(QUrl::FullyEncoded).toUtf8()); } // loop to wait until the request has finished before processing the data @@ -58,6 +84,8 @@ QVariantMap BRProvider::serverRequest(QUrl serviceUrl, QUrlQuery pdata) //get the status code QVariant status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute); + qDebug() << "Finished: " << status_code; + ret.insert("status", status_code.toInt()); //get the full text response diff --git a/sources/brproviderdr.cpp b/sources/brproviderdr.cpp index 2a53a96..2cc51f6 100644 --- a/sources/brproviderdr.cpp +++ b/sources/brproviderdr.cpp @@ -2,14 +2,71 @@ 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::loadCalendarData(BRCalendar* calendar) +BRWidget::BRWidgetStatusCode BRProviderDr::getWidgetData(BRCalendar::BRCalendarData* calendarData) { // load some data - QString nationStr = calendar->getFederation() == BRWidget::SAC ? "SUI":"GER"; - QVariantMap ret = this->serverRequest(QUrl("https://www.digitalrock.de/egroupware/ranking/json.php?nation=" + nationStr)); + 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 @@ -17,28 +74,138 @@ BRWidget::BRWidgetStatusCode BRProviderDr::loadCalendarData(BRCalendar* calendar } QVariantMap data = QJsonDocument::fromJson(ret["text"].toString().toUtf8()).toVariant().toMap(); + data.insert("year", year); + data.insert("federation", calendarData->calendar->getFederation()); - // parse competitions - QVariantList competitions = data["competitions"].toList(); - QList tmpCompetitions; + // create seasons + QVariantList seasons = data["years"].toList(); - for(QVariant competitionVar : competitions) { - BRCompetition* competition = new BRCompetition(this, calendar->getFederation(), competitionVar.toMap()["WetId"].toInt()); - this->loadCompetitionData(competition, competitionVar.toMap()); - tmpCompetitions.append(competition); + 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; } - if(calendar->competitions != tmpCompetitions) - calendar->competitions = tmpCompetitions; - return BRWidget::Success; } -BRWidget::BRWidgetStatusCode BRProviderDr::loadCompetitionData(BRCompetition* competition, QVariantMap data) { - // load basic properties - competition->name = data["name"].toString(); +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); + + BRWidget::BRFederation federation = BRWidget::BRFederation(rawData["federation"].toInt(0)); + + // insert the leagues + 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()); + + qDebug() << "Adding 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, federation)); + data.competitions.append(competition); + qDebug() << "- Adding competition: " << competition->getName(); + } + } + + // 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) { + + +} + +BRCompetition::BRCompetitionData BRProviderDr::parseCompetitionData(QVariantMap rawData, BRWidget::BRFederation federation) { QMap disciplineTranslations = { {"boulder", BRCompetition::Boulder}, @@ -46,14 +213,69 @@ BRWidget::BRWidgetStatusCode BRProviderDr::loadCompetitionData(BRCompetition* co {"speed", BRCompetition::Speed} }; - if(disciplineTranslations.contains(data["discipline"].toString())) - competition->discipline = disciplineTranslations[data["discipline"].toString()]; + BRCompetition::BRCompetitionData data; - competition->startDate = QDate::fromString(data["date"].toString()); - competition->endDate = QDate::fromString(data["date_end"].toString()); + data.name = rawData["name"].toString(); - // TODO load categories - //competition->categories.clear(); + if(disciplineTranslations.contains(rawData["discipline"].toString())) + data.discipline = disciplineTranslations[rawData["discipline"].toString()]; + + data.startDate = QDate::fromString(rawData["date"].toString(), "yyyy-MM-dd"); + data.endDate = QDate::fromString(rawData["date_end"].toString(), "yyyy-MM-dd"); + + data.eventWebsiteUrl = rawData["homepage"].toString(); + + 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); + } + } + + QVariantList categoriesList = rawData["cats"].toList(); + for(QVariant categoryVar : categoriesList) { + QVariantMap categoryMap = categoryVar.toMap(); + BRCategory* category = this->getCategory(federation, rawData["GrpId"].toInt(), this->parseCategoryData(categoryMap)); + data.categories.append(category); + } // TODO load results + return data; +} + + +BRCup::BRCupData BRProviderDr::parseCupData(QVariantList categoriesList, QVariantMap rawData, BRWidget::BRFederation federation) { + BRCup::BRCupData data; + + data.name = rawData["name"].toString(); + + // 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) { + // TODO: status + // TODO: sex + BRCategory::BRCategoryData data; + data.name = rawData["name"].toString(); + return data; } diff --git a/sources/brprovidervl.cpp b/sources/brprovidervl.cpp new file mode 100644 index 0000000..e836d75 --- /dev/null +++ b/sources/brprovidervl.cpp @@ -0,0 +1,199 @@ +#include "headers/brprovidervl.h" + +BRProviderVl::BRProviderVl(QObject *parent) : BRProvider(parent) +{ +} + +BRWidget::BRWidgetStatusCode BRProviderVl::getWidgetData(BRCalendar::BRCalendarData* calendarData) +{ + // load some data + QString requestUrl = "https://ifsc.results.info/api/v1/"; + QVariantMap ret = this->serverRequest(QUrl(requestUrl), {{"x-auth-token", "cc7375f680648e7e6171e035e70351eb"}}); + + if(ret["status"] != 200){ + // request was a failure + return BRWidget::BRWidgetStatusCode(ret["status"].toInt()); + } + + QVariantMap data = QJsonDocument::fromJson(ret["text"].toString().toUtf8()).toVariant().toMap(); + + // create seasons + QVariantList seasons = data["seasons"].toList(); + + for(QVariant seasonVar : seasons) { + QVariantMap seasonMap = seasonVar.toMap(); + int seasonId = seasonMap["name"].toInt(); + BRSeason* season = this->getSeason( + calendarData->calendar->getFederation(), + seasonId, + this->parseSeasonData(seasonMap) + ); + + calendarData->seasons.append(season); + qDebug() << "Inserted season:" << season->getName(); + + if(seasonId == data["current"].toMap()["season"].toInt()) + calendarData->currentSeason = season; + } + + // load default league of current season + calendarData->currentSeason->getLeagues()[0]->load(); + + return BRWidget::Success; +} + + + +BRWidget::BRWidgetStatusCode BRProviderVl::getWidgetData(BRSeason::BRSeasonData* seasonData) { + if(seasonData->season->getLeagues().length() > 0) { + // leagues are already loaded + + // load default league + seasonData->season->getLeagues()[0]->load(); + + return BRWidget::Success; + } + else { + // should never happen + return BRWidget::NotImplementedError; + } +} + +BRSeason::BRSeasonData BRProviderVl::parseSeasonData(QVariantMap rawData) { + BRSeason::BRSeasonData data; + data.year = rawData["name"].toInt(); + data.name = rawData["name"].toString(); + data.nativeMultiLeagueSupport = false; + + // insert the leagues + for(QVariant leagueVar : rawData["leagues"].toList()) { + QVariantMap leagueMap = leagueVar.toMap(); + + BRLeague::BRLeagueData leagueData; + leagueData.name = leagueMap["name"].toString(); + int leagueId = leagueMap["url"].toString().split("/").last().toInt(); + + BRLeague* league = this->getLeague(BRWidget::IFSC, leagueId, leagueData); + data.leagues.append(league); + } + + return data; +} + +BRWidget::BRWidgetStatusCode BRProviderVl::getWidgetData(BRLeague::BRLeagueData* leagueData) { + // load some data + QString requestUrl = "https://ifsc.results.info/api/v1/season_leagues/" + QString::number(leagueData->league->getId()); + QVariantMap ret = this->serverRequest(QUrl(requestUrl), {{"x-auth-token", "cc7375f680648e7e6171e035e70351eb"}}); + + 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->parseLeagueData(leagueData, data); + + return BRWidget::Success; +} + +void BRProviderVl::parseLeagueData(BRLeague::BRLeagueData* data, QVariantMap rawData) { + + BRWidget::BRFederation federation = BRWidget::BRFederation(rawData["federation"].toInt(0)); + + data->name = rawData["league"].toString(); + data->color = QColor("#ffffff"); // TODO + + qDebug() << "Adding league: " << data->name; + + // parse competitions + QVariantList competitionsVar = rawData["events"].toList(); + + for(QVariant competitionVar : competitionsVar) { + QVariantMap competitionMap = competitionVar.toMap(); + + BRCompetition* competition = this->getCompetition(federation, competitionVar.toMap()["event_id"].toInt(), this->parseCompetitionData(competitionMap, federation)); + data->competitions.append(competition); + qDebug() << "- Adding competition: " << competition->getName(); + } + + // parse cups + QVariantList cupsVar = rawData["cups"].toList(); + + for(QVariant cupVar : cupsVar) { + QVariantMap cupMap = cupVar.toMap(); + BRCup* cup = this->getCup(federation, cupMap["cup_id"].toInt(), this->parseCupData(cupMap)); + data->cups.append(cup); + } +} + + +BRWidget::BRWidgetStatusCode BRProviderVl::getWidgetData(BRCompetition::BRCompetitionData* competitionData) { + + +} + +BRCompetition::BRCompetitionData BRProviderVl::parseCompetitionData(QVariantMap rawData, BRWidget::BRFederation federation) { + + QMap disciplineTranslations = { + {"boulder", BRCompetition::Boulder}, + {"lead", BRCompetition::Lead}, + {"speed", BRCompetition::Speed} + }; + + BRCompetition::BRCompetitionData data; + + data.name = rawData["event"].toString(); + data.discipline = BRCompetition::Unknown; + + data.startDate = QDate::fromString(rawData["starts_at"].toString().split(" ")[0], "yyyy-MM-dd"); + data.endDate = QDate::fromString(rawData["ends_at"].toString().split(" ")[0], "yyyy-MM-dd"); + + data.eventWebsiteUrl = ""; + + for(int i = 0; i < 2; i++) { + QString infosheetName = QStringList({"infosheet_url", "additional_info_url"})[i]; + if(rawData.contains(infosheetName) && !rawData[infosheetName].isNull()) { + data.infosheetUrls.append(rawData[infosheetName].toString()); + } + } + + QVariantList categoriesList = rawData["d_cats"].toList(); + for(QVariant categoryVar : categoriesList) { + QVariantMap categoryMap = categoryVar.toMap(); + BRCategory* category = this->getCategory(federation, rawData["id"].toInt(), this->parseCategoryData(categoryMap)); + data.categories.append(category); + } + + // TODO load results + return data; +} + + +BRCup::BRCupData BRProviderVl::parseCupData(QVariantMap rawData) { + BRCup::BRCupData data; + + data.name = rawData["cup"].toString(); + + // parse categories + for(QVariant categoryVar : rawData["d_cats"].toList()) { + // find category name in cats: + + QVariantMap categoryMap = categoryVar.toMap(); + + int categoryId = categoryMap["ranking_url"].toString().split("/").last().toInt(); + BRCategory* category = this->getCategory(BRWidget::IFSC, categoryId, this->parseCategoryData(categoryMap)); + data.categories.append(category); + + } + + return data; +} + +BRCategory::BRCategoryData BRProviderVl::parseCategoryData(QVariantMap rawData) { + // TODO: status + // TODO: sex + BRCategory::BRCategoryData data; + data.name = rawData["name"].toString(); + return data; +} diff --git a/sources/brseason.cpp b/sources/brseason.cpp new file mode 100644 index 0000000..4354c6d --- /dev/null +++ b/sources/brseason.cpp @@ -0,0 +1,93 @@ +#include "headers/brseason.h" +#include "headers/brprovider.h" + +using namespace std; + +BRSeason::BRSeason(BRProvider* provider, BRWidget::BRFederation federation, int id, BRSeasonData initialData) : BRWidget(provider, federation), id(id) +{ + connect(this, &BRSeason::leaguesChanged, this, &BRSeason::competitionsChanged); + connect(this, &BRSeason::leaguesChanged, this, &BRSeason::cupsChanged); + this->setData(initialData); +} + +int BRSeason::getYear() const { + return this->year; +} + +QString BRSeason::getName() { + return this->name; +} + +QList BRSeason::getLeaguesQML() { + return this->listToQmlList(this->leagues); +} + +QList BRSeason::getLeagues() const { + return this->leagues; +} + +QList BRSeason::getCompetitionsQML() { + QList allCompetitions; + + for(BRLeague* league : this->leagues) { + allCompetitions.append(league->getCompetitions()); + } + + std::sort(allCompetitions.begin(), allCompetitions.end(), BRCompetition::lessThan); + + qDebug() << "competitions: " << allCompetitions; + + return this->listToQmlList(allCompetitions); +} + +QList BRSeason::getCupsQML() { + QList allCups; + + for(BRLeague* league : this->leagues) { + allCups.append(league->getCupsQML()); + } + + return this->listToQmlList(allCups); +} + +void BRSeason::setData(BRSeasonData data) { + this->year = data.year; + this->name = data.name; + this->multiLeagueSupport = data.nativeMultiLeagueSupport; + emit this->metadataChanged(); + + if(this->leagues != data.leagues) { + this->leagues.clear(); + this->leagues = data.leagues; + emit this->leaguesChanged(); + + for(BRLeague* league : this->leagues) { + connect(league, &BRLeague::competitionsChanged, this, &BRSeason::competitionsChanged); + connect(league, &BRLeague::cupsChanged, this, &BRSeason::cupsChanged); + } + } +} + +BRWidget::BRWidgetStatusCode BRSeason::load() { + if(this->getProvider() == nullptr) + return BRWidget::NoProviderError; + + // reload all comp data using our providers + + BRSeasonData newData { + this, + this->year, + this->name, + this->multiLeagueSupport, + this->leagues + }; + + BRWidget::BRWidgetStatusCode statusCode = this->getProvider()->getWidgetData(&newData); + + if(statusCode != BRWidget::Success) + return statusCode; + + this->setData(newData); + + return statusCode; +} diff --git a/sources/brwidget.cpp b/sources/brwidget.cpp index 235f5c4..0b4cc61 100644 --- a/sources/brwidget.cpp +++ b/sources/brwidget.cpp @@ -2,13 +2,11 @@ #include "headers/brprovider.h" -BRWidget::BRWidget(BRProvider* provider, BRFederation federation) : QObject(provider) +BRWidget::BRWidget(BRProvider* provider, BRFederation federation) : QObject(provider), provider(provider), federation(federation) { - this->provider = provider; - this->federation = federation; } -BRWidget::BRFederation BRWidget::getFederation() { +BRWidget::BRFederation BRWidget::getFederation() const { return this->federation; } diff --git a/sources/main.cpp b/sources/main.cpp index f60f1ea..351df81 100644 --- a/sources/main.cpp +++ b/sources/main.cpp @@ -44,8 +44,14 @@ int main(int argc, char *argv[]) qmlRegisterType("de.itsblue.blueRock", 2, 0, "BRController"); qmlRegisterUncreatableType("de.itsblue.blueRock", 2, 0, "BRCalendar", "BRCalendar is not creatable"); + qmlRegisterUncreatableType("de.itsblue.blueRock", 2, 0, "BRSeason", "BRSeason is not creatable"); + qmlRegisterUncreatableType("de.itsblue.blueRock", 2, 0, "BRLeague", "BRLeague is not creatable"); + qmlRegisterUncreatableType("de.itsblue.blueRock", 2, 0, "BRCompetition", "BRCompetition is not creatable"); + qmlRegisterUncreatableType("de.itsblue.blueRock", 2, 0, "BRCup", "BRCup is not creatable"); + qmlRegisterUncreatableType("de.itsblue.blueRock", 2, 0, "BRCategory", "BRCategory is not creatable"); qmlRegisterUncreatableType("de.itsblue.blueRock", 2, 0, "BRWidget", "BRWidget is not creatable"); qRegisterMetaType("BRWidget::BRFederation"); + qRegisterMetaType("BRWidget::BRWidgetStatusCode"); //qmlRegisterType("de.itsblue.blueRock", 2, 0, "BRController"); QQmlApplicationEngine engine;