62 changes: 62 additions & 0 deletions src/Cloud/Azum.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#ifndef AZUM_H
#define AZUM_H

#include "CloudService.h"
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QImage>

class Azum : public CloudService {

Q_OBJECT

public:

Azum(Context *context);
CloudService *clone(Context *context) { return new Azum(context); }
~Azum();

QString id() const { return "Azum"; }
QString uiName() const { return tr("Azum"); }
QString description() const { return (tr("Sync with new and unique coaching platform from Switzerland.")); }
QImage logo() const { return QImage(":images/services/azum.png"); }

int capabilities() const { return OAuth | Download | Query; }

// open/connect and close/disconnect
bool open(QStringList &errors);
bool close();

// home directory
QString home();

// create a folder
bool createFolder(QString);

// read a file
bool readFile(QByteArray *data, QString remotename, QString remoteid);

// athlete selection
QList<CloudServiceAthlete> listAthletes();
bool selectAthlete(CloudServiceAthlete);

// dirent style api
CloudServiceEntry *root() { return root_; }
QList<CloudServiceEntry*> readdir(QString path, QStringList &errors, QDateTime from, QDateTime to);

public slots:
void readyRead();
void readFileCompleted();

private:
Context *context;
QNetworkAccessManager *nam;
QNetworkReply *reply;
CloudServiceEntry *root_;
QMap<QNetworkReply*, QByteArray*> buffers;

private slots:
void onSslErrors(QNetworkReply *reply, const QList<QSslError>&error);
};

#endif
28 changes: 25 additions & 3 deletions src/Cloud/OAuthDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ OAuthDialog::OAuthDialog(Context *context, OAuthSite site, CloudService *service
if (service->id() == "SportTracks.mobi") site = this->site = SPORTTRACKS;
if (service->id() == "Xert") site = this->site = XERT;
if (service->id() == "RideWithGPS") site = this->site = RIDEWITHGPS;
if (service->id() == "Azum") site = this->site = AZUM;
}

// check if SSL is available - if not - message and end
Expand Down Expand Up @@ -162,15 +163,21 @@ OAuthDialog::OAuthDialog(Context *context, OAuthSite site, CloudService *service
urlChanged(QUrl("http://www.goldencheetah.org/?code=0"));
} else if (site == RIDEWITHGPS) {
urlChanged(QUrl("http://www.goldencheetah.org/?code=0"));
} else if (site == AZUM) {
if (baseURL=="") baseURL=service->getSetting(GC_AZUM_URL, "https://training.azum.com").toString();
urlstr = QString("%1/oauth/authorize/?").arg(baseURL);

urlstr.append("redirect_uri=http://www.goldencheetah.org/&");
urlstr.append("response_type=code&");
urlstr.append("client_id=").append(GC_AZUM_CLIENT_ID);
}

//
// STEP 1: LOGIN AND AUTHORISE THE APPLICATION
//
if (site == NOLIO || site == DROPBOX || site == STRAVA || site == CYCLING_ANALYTICS || site == POLAR || site == SPORTTRACKS || site == TODAYSPLAN || site == WITHINGS) {
if (site == NOLIO || site == DROPBOX || site == STRAVA || site == CYCLING_ANALYTICS || site == POLAR || site == SPORTTRACKS || site == TODAYSPLAN || site == WITHINGS || site == AZUM) {
url = QUrl(urlstr);
view->setUrl(url);

// connects
connect(view, SIGNAL(urlChanged(const QUrl&)), this, SLOT(urlChanged(const QUrl&)));
}
Expand Down Expand Up @@ -204,7 +211,7 @@ OAuthDialog::urlChanged(const QUrl &url)
QString authheader;

// sites that use this scheme
if (site == NOLIO || site == DROPBOX || site == STRAVA || site == CYCLING_ANALYTICS || site == TODAYSPLAN || site == POLAR || site == SPORTTRACKS || site == XERT || site == RIDEWITHGPS || site == WITHINGS) {
if (site == NOLIO || site == DROPBOX || site == STRAVA || site == CYCLING_ANALYTICS || site == TODAYSPLAN || site == POLAR || site == SPORTTRACKS || site == XERT || site == RIDEWITHGPS || site == WITHINGS || site == AZUM) {

if (url.toString().startsWith("http://www.goldencheetah.org/?state=&code=") ||
url.toString().contains("blank.html?code=") ||
Expand Down Expand Up @@ -315,6 +322,14 @@ OAuthDialog::urlChanged(const QUrl &url)
params.addQueryItem("action", "requesttoken");
params.addQueryItem("grant_type", "authorization_code");

} else if (site == AZUM) {

if (baseURL=="") baseURL=service->getSetting(GC_AZUM_URL, "https://training.azum.com").toString();
urlstr = QString("%1/oauth/token/?").arg(baseURL);
params.addQueryItem("client_id", GC_AZUM_CLIENT_ID);
params.addQueryItem("client_secret", GC_AZUM_CLIENT_SECRET);
params.addQueryItem("redirect_uri","http://www.goldencheetah.org/");
params.addQueryItem("grant_type", "authorization_code");
}

// all services will need us to send the temporary code received
Expand Down Expand Up @@ -500,6 +515,13 @@ OAuthDialog::networkRequestFinished(QNetworkReply *reply)
QString info = QString(tr("Nolio authorization was successful."));
QMessageBox information(QMessageBox::Information, tr("Information"), info);
information.exec();
} else if (site == AZUM) {
service->setSetting(GC_AZUM_ACCESS_TOKEN, access_token);
service->setSetting(GC_AZUM_REFRESH_TOKEN, refresh_token);
QString info = QString(tr("Azum authorization was successful."));
QMessageBox information(QMessageBox::Information, tr("Information"), info);
information.exec();

}

} else {
Expand Down
3 changes: 2 additions & 1 deletion src/Cloud/OAuthDialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ class OAuthDialog : public QDialog
WITHINGS,
POLAR,
XERT,
RIDEWITHGPS
RIDEWITHGPS,
AZUM
} OAuthSite;

// will work with old config via site and new via cloudservice (which is null for calendar and withings for now)
Expand Down
4 changes: 4 additions & 0 deletions src/Core/Secrets.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@
#define GC_NOKIA_CLIENT_SECRET "__GC_NOKIA_CLIENT_SECRET__"
#endif

#ifndef GC_AZUM_CLIENT_SECRET
#define GC_AZUM_CLIENT_SECRET "__GC_AZUM_CLIENT_SECRET__"
#endif

#ifndef GC_DROPBOX_CLIENT_SECRET
#define GC_DROPBOX_CLIENT_SECRET "__GC_DROPBOX_CLIENT_SECRET__"
#endif
Expand Down
12 changes: 12 additions & 0 deletions src/Core/Settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@
#define GC_POLARFLOW_CLIENT_ID "Not defined"
#endif

// Xert
#ifndef GC_AZUM_CLIENT_ID
#define GC_AZUM_CLIENT_ID "vhNabGIWHbvl9lIy5XTAGOJ3Ypa7Qqg9cBrBloca"
#endif


// Xert
#ifndef GC_XERT_CLIENT_ID
#define GC_XERT_CLIENT_ID "xert_goldencheetah"
Expand Down Expand Up @@ -397,6 +403,12 @@
#define GC_SIXCYCLE_PASS "<athlete-private>sixcycle_pass"
#define GC_SIXCYCLE_URL "<athlete-private>sixcycle_url"

// Azum
#define GC_AZUM_ACCESS_TOKEN "<athlete-private>azum_access_token"
#define GC_AZUM_REFRESH_TOKEN "<athlete-private>azum_refresh_token"
#define GC_AZUM_URL "<athlete-private>azum_url"
#define GC_AZUM_ATHLETE_ID "<athlete-private>azum_athlete_id"

// Polar Flow
#define GC_POLARFLOW_TOKEN "<athlete-private>polarflow_token"
#define GC_POLARFLOW_USER_ID "<athlete-private>polarflow_user_id"
Expand Down
Binary file added src/Resources/images/services/azum.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 4 additions & 2 deletions src/src.pro
Original file line number Diff line number Diff line change
Expand Up @@ -703,7 +703,8 @@ HEADERS += Cloud/CalendarDownload.h Cloud/CloudService.h \
Cloud/LocalFileStore.h Cloud/OAuthDialog.h Cloud/TodaysPlanBodyMeasures.h \
Cloud/WithingsDownload.h Cloud/Strava.h Cloud/CyclingAnalytics.h Cloud/RideWithGPS.h \
Cloud/TrainingsTageBuch.h Cloud/Selfloops.h Cloud/Velohero.h Cloud/SportsPlusHealth.h \
Cloud/AddCloudWizard.h Cloud/Withings.h Cloud/MeasuresDownload.h Cloud/Xert.h
Cloud/AddCloudWizard.h Cloud/Withings.h Cloud/MeasuresDownload.h Cloud/Xert.h \
Cloud/Azum.h

# core data
HEADERS += Core/Athlete.h Core/Context.h Core/DataFilter.h Core/FreeSearch.h Core/GcCalendarModel.h Core/GcUpgrade.h \
Expand Down Expand Up @@ -805,7 +806,8 @@ SOURCES += Cloud/CalendarDownload.cpp Cloud/CloudService.cpp \
Cloud/LocalFileStore.cpp Cloud/OAuthDialog.cpp Cloud/TodaysPlanBodyMeasures.cpp \
Cloud/WithingsDownload.cpp Cloud/Strava.cpp Cloud/CyclingAnalytics.cpp Cloud/RideWithGPS.cpp \
Cloud/TrainingsTageBuch.cpp Cloud/Selfloops.cpp Cloud/Velohero.cpp Cloud/SportsPlusHealth.cpp \
Cloud/AddCloudWizard.cpp Cloud/Withings.cpp Cloud/MeasuresDownload.cpp Cloud/Xert.cpp
Cloud/AddCloudWizard.cpp Cloud/Withings.cpp Cloud/MeasuresDownload.cpp Cloud/Xert.cpp \
Cloud/Azum.cpp

## Core Data Structures
SOURCES += Core/Athlete.cpp Core/Context.cpp Core/DataFilter.cpp Core/FreeSearch.cpp Core/GcUpgrade.cpp Core/IdleTimer.cpp \
Expand Down