commit 32307b1c173206d9a6b91e49e233dbb195107c45
parent 3d4cf0da5a3b2556c8339116237fddbcc39a1188
Author: myadzel <myadzel@gmail.com>
Date: Thu, 18 Jun 2020 12:00:57 +0300
parse garmin connect routes and activities #398
Diffstat:
3 files changed, 92 insertions(+), 1 deletion(-)
diff --git a/src/lib/leaflet.control.track-list/lib/services/garmin.js b/src/lib/leaflet.control.track-list/lib/services/garmin.js
@@ -0,0 +1,88 @@
+import BaseService from './baseService';
+import urlViaCorsProxy from '~/lib/CORSProxy';
+
+class GarminBase extends BaseService {
+ isOurUrl() {
+ return this.urlRe.test(this.origUrl);
+ }
+}
+
+class GarminRoute extends GarminBase {
+ urlRe = /^https?:\/\/connect.garmin.com\/modern\/course\/(\d+)/u;
+
+ requestOptions() {
+ const m = this.urlRe.exec(this.origUrl);
+ const trackId = this.trackId = m[1];
+ return [{
+ url: urlViaCorsProxy(`https://connect.garmin.com/modern/proxy/course-service/course/${trackId}`),
+ options: {
+ responseType: 'json',
+ isResponseSuccess: (xhr) => xhr.status === 200 || xhr.status === 403 || xhr.status === 404
+ },
+ }];
+ }
+
+ parseResponse(responses) {
+ const response = responses[0];
+ if (response.status === 403) {
+ return [{error: 'Garmin Connect user disabled viewing this route'}];
+ }
+ if (response.status === 404) {
+ return [{error: 'Garmin Connect route does not exist'}];
+ }
+ let name = `Garmin Connect route ${this.trackId}`;
+ const data = response.responseJSON;
+ if (!data) {
+ return [{name, error: 'UNSUPPORTED'}];
+ }
+ let points = [];
+ let track = data.geoPoints.map((obj) => ({lat: obj.latitude, lng: obj.longitude}));
+ name = data.courseName ? data.courseName : name;
+ return [{
+ name,
+ points,
+ tracks: [track]
+ }];
+ }
+}
+
+class GarminActivity extends GarminBase {
+ urlRe = /^https?:\/\/connect.garmin.com\/modern\/activity\/(\d+)/u;
+
+ requestOptions() {
+ const m = this.urlRe.exec(this.origUrl);
+ const trackId = this.trackId = m[1];
+ return [
+ {
+ url: urlViaCorsProxy(
+ `https://connect.garmin.com/modern/proxy/activity-service/activity/${trackId}/details`),
+ options: {
+ responseType: 'json',
+ isResponseSuccess: (xhr) => xhr.status === 200 || xhr.status === 403 || xhr.status === 404
+ }
+ }
+ ];
+ }
+
+ parseResponse(responses) {
+ const response = responses[0];
+ if (response.status === 403) {
+ return [{error: 'Garmin Connect user disabled viewing this activity'}];
+ }
+ if (response.status === 404) {
+ return [{error: 'Garmin Connect activity does not exist'}];
+ }
+ let name = `Garmin Connect activity ${this.trackId}`;
+ const data = response.responseJSON;
+ if (!data) {
+ return [{name, error: 'UNSUPPORTED'}];
+ }
+ let track = data.geoPolylineDTO.polyline.map((obj) => ({lat: obj.lat, lng: obj.lon}));
+ return [{
+ name,
+ tracks: [track]
+ }];
+ }
+}
+
+export {GarminRoute, GarminActivity};
diff --git a/src/lib/leaflet.control.track-list/lib/services/index.js b/src/lib/leaflet.control.track-list/lib/services/index.js
@@ -9,6 +9,7 @@ import Tracedetrail from './tracedetrail';
import {YandexRuler} from './yandex';
import {NakarteTrack, NakarteUrl} from './nakarte';
import {MovescountMove, MovescountRoute} from './movescount';
+import {GarminActivity, GarminRoute} from './garmin';
import {SportsTrackerActivity} from './sportstracker';
export default [
@@ -24,6 +25,8 @@ export default [
Tracedetrail,
MovescountMove,
MovescountRoute,
+ GarminActivity,
+ GarminRoute,
SportsTrackerActivity,
SimpleService
];
diff --git a/src/lib/leaflet.control.track-list/track-list.js b/src/lib/leaflet.control.track-list/track-list.js
@@ -88,7 +88,7 @@ L.Control.TrackList = L.Control.extend({
<div class="leaflet-control-content">
<div class="header">
<div class="hint"
- title="gpx kml Ozi zip YandexMaps GPSies Strava GPSLib Endomondo Etomesto Movescount SportsTracker OSM Tracedetrail">
+ title="gpx kml Ozi zip YandexMaps GPSies Strava GPSLib Endomondo Etomesto Movescount GarminConnect SportsTracker OSM Tracedetrail">
gpx kml Ozi zip YandexMaps GPSies Strava
<span class="formats-hint-more">…</span>
</div>