fabulator / endomondo-api-handler Goto Github PK
View Code? Open in Web Editor NEWUnofficial handler for Endomondo API
License: Apache License 2.0
Unofficial handler for Endomondo API
License: Apache License 2.0
Hi,
I tried to filter the workouts which are requested by following the example provided in the README.md. It appears the afterDate filter does not exist but after is the proper filter keyword.
Hi,
I simply copied the script from https://www.npmjs.com/package/endomondo-api-handler#export-your-workouts-to-gpx and it failed with the following error.
TypeError: workout.hasGPSData is not a function
at /Users/vincent..bouchet/www/endo/test.js:14:23
at /Users/vincent..bouchet/www/node_modules/endomondo-api-handler/dist/index.js:957:14
at Array.map ()
at Api.processWorkouts (/Users/vincent..bouchet/www/node_modules/endomondo-api-handler/dist/index.js:956:40)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
at async /Users/vincent..bouchet/www/endo/test.js:11:5
I commented the condition and it is working probably because I don't have any workout without GPS data.
Hello,
I'm using the code below:
require('cross-fetch/polyfill');
const fs = require('fs');
const { Api } = require('endomondo-api-handler');
const api = new Api();
(async () => {
await api.login('[email protected]', 'XXXX');
await api.processWorkouts({}, async (workout) => {
console.log(workout.toString());
if (workout.hasGPSData()) {
fs.writeFileSync(`gpx/${workout.getId()}.gpx`, await api.getWorkoutGpx(workout.getId()), 'utf8');
}
});
})();
And it is downloading most of the workouts, but a lot of them are returning:
(node:91306) UnhandledPromiseRejectionWarning: Error: Endomondo Error: "Uncaught REST API exception:\nURL: http://www.endomondo.com/rest/v1/users/1503573/workouts/1004869752/export\nMethod: GET\nParameters: {format=[GPX]}\n"
at DefaultResponseProcessor.processResponse (/Users/ruslan/Downloads/exporter/node_modules/rest-api-handler/dist/index.js:358:13)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at async resolveProcessors (/Users/ruslan/Downloads/exporter/node_modules/rest-api-handler/dist/index.js:27:100)
at async Api.getWorkoutGpx (/Users/ruslan/Downloads/exporter/node_modules/endomondo-api-handler/dist/api/Api.js:133:9)
at async /Users/ruslan/Downloads/exporter/exporter.js:13:60
at emitUnhandledRejectionWarning (internal/process/promises.js:168:15)
at processPromiseRejections (internal/process/promises.js:247:11)
at processTicksAndRejections (internal/process/task_queues.js:94:32)
(node:91306) Error: Endomondo Error: "Uncaught REST API exception:\nURL: http://www.endomondo.com/rest/v1/users/1503573/workouts/1004869752/export\nMethod: GET\nParameters: {format=[GPX]}\n"
at DefaultResponseProcessor.processResponse (/Users/ruslan/Downloads/exporter/node_modules/rest-api-handler/dist/index.js:358:13)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at async resolveProcessors (/Users/ruslan/Downloads/exporter/node_modules/rest-api-handler/dist/index.js:27:100)
at async Api.getWorkoutGpx (/Users/ruslan/Downloads/exporter/node_modules/endomondo-api-handler/dist/api/Api.js:133:9)
at async /Users/ruslan/Downloads/exporter/exporter.js:13:60
What does it mean and what can be done about that?
thank you very much!
When I tried to export all activities to gpx (using example from README.md), in some activities I got RangeError because of Invalid time value. I don't know what is the reason of, but I ommit this by adding exception catch in script:
try { fs.writeFileSync('tmp/${workout.getId()}.gpx', workout.toGpx(), 'utf8'); } catch (RangeError) { console.error(RangeError); }
This activities are skipped but their IDs are displayed in terminal and they need to be downloaded manually from Endomondo webiste. (I have about 5% of workouts with this error so it's not too much ;) )
Hi,
I successfully exported all my workouts using the example to download the gpx files:
await api.processWorkouts({}, (workout) => {
console.log(workout.toString());
if (workout.hasGPSData()) {
fs.writeFileSync(`tmp/${workout.getId()}.gpx`, workout.toGpx(), 'utf8');
}
});
However, when I tried to import these in my Garmin account, the workouts were uncategorized. Nothing to do with the script, it looks like an issue on Garmin side.
I noticed that importing the tcx file properly categorized the workout. I decided to adapt the code to download the files using the getWorkoutTcx() method. Here is my code:
await api.processWorkouts({}, (workout) => {
console.log(workout.toString());
api.getWorkoutTcx(workout.getId(), workout.getSource().author.id).then(function(tcx) {
fs.writeFileSync(`tmp/${workout.getId()}.tcx`, tcx, 'utf8');
}).catch(function(err) {
console.error(err);
});
});
The script itself works properly but when I tried to import few workouts in my Garmin account, only one is properly imported and the other ones are flagged as duplicate and hence are not imported. For one of these faulty tcx file, I downloaded it manually from Endomondo and compared it with the one I get using the script.
These are identical unless the attribute. For some reason, all the tcx exported via the script have <Id>2011-08-02T10:08:02Z</Id>
(even if the workout is actually older than this date).
I have very basic NodeJS knowledge but a brief look at the code shows that getWorkoutTcx() simply does a GET request to https://www.endomondo.com/rest/v1/users//workouts//export?format=TCX which is the same endpoint that is used when downloading from Endomondo UI.
That is confusing ...
Terminal display this error after running script:
(node:436) UnhandledPromiseRejectionWarning: Error: Endomondo Error: User id is not defined at Api.getUserApiUrl (/Desktop/node_modules/endomondo-api-handler/dist/index.js:942:13) at Api.getWorkoutsApiUrl (/Desktop/node_modules/endomondo-api-handler/dist/index.js:953:17) at Api.getWorkouts (/Desktop/node_modules/endomondo-api-handler/dist/index.js:1056:42) at Api.processWorkouts (/Desktop/node_modules/endomondo-api-handler/dist/index.js:1084:29) at /Desktop/endomondo.js:10:15 at process.internalTickCallback (internal/process/next_tick.js:77:7) (node:436) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2) (node:436) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
There is no problem (with this; I get other errors with workout) when I write profile id manually in 938 line of index.js
There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.
Error type: Preset name not found within published preset config (fabulator)
I get this error when I try to use workout.toGpx() function
(node:469) UnhandledPromiseRejectionWarning: TypeError: this.schemaLocation is not iterable at new GarminBuilder (/Desktop/node_modules/gpx-builder/dist/index.js:812:13) at Workout.toGpx (/Desktop/node_modules/endomondo-api-handler/dist/index.js:853:21) at api.processWorkouts (/Desktop/endomondo.js:13:68) at workouts.map.workout (/Desktop/node_modules/endomondo-api-handler/dist/index.js:1089:14) at Array.map (<anonymous>) at Api.processWorkouts (/Desktop/node_modules/endomondo-api-handler/dist/index.js:1088:40) at process.internalTickCallback (internal/process/next_tick.js:77:7) (node:469) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1) (node:469) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Hi,
I exported some of my workouts using the script. When I tried to import these in my Garmin account, it was said being invalid.
When opening the generated gpx, it appears the points only contain the latitude/longitude but nothing more (no time, no hr, no elevation, etc).
I downloaded the same workout from Endomondo directly and the points contain the time.
This is the workout I used as example: https://www.endomondo.com/users/1863517/workouts/282212961 (public).
I attached the downloaded and generated files to help investigation. I had to zip these together given Github does not accept gpx files.
workout.zip
Hello,
Can not download all my workouts gpx'es
index.js
require('cross-fetch/polyfill');
const fs = require('fs');
const { Api } = require('endomondo-api-handler');
const api = new Api();
(async () => {
await api.login("{username}","{password}");
await api.processWorkouts({}, async (workout) => {
console.log(workout.toString());
if (workout.hasGPSData()) {
fs.writeFileSync(`tmp/${workout.getId()}.gpx`, await api.getWorkoutGpx(workout.getId()), 'utf8');
}
});
})();
error
/Users/arek/IdeaProjects/export-endomondo/node_modules/.pnpm/[email protected]/node_modules/rest-api-handler/dist/index.js:358
throw new this.Exception(toRespond, request);
^
EndomondoApiException [Error]: Endomondo Error: "Uncaught REST API exception:\nURL: http://www.endomondo.com/rest/v1/users/{userId}/workouts/history\nMethod: GET\nParameters: {expand=[points,workout]}\n"
at DefaultResponseProcessor.processResponse (/Users/arek/IdeaProjects/export-endomondo/node_modules/.pnpm/[email protected]/node_modules/rest-api-handler/dist/index.js:358:13)
at processTicksAndRejections (node:internal/process/task_queues:93:5)
at async resolveProcessors (/Users/arek/IdeaProjects/export-endomondo/node_modules/.pnpm/[email protected]/node_modules/rest-api-handler/dist/index.js:27:100)
at async Api.getWorkouts (/Users/arek/IdeaProjects/export-endomondo/node_modules/.pnpm/[email protected]/node_modules/endomondo-api-handler/dist/api/Api.js:192:22)
at async Api.processWorkouts (/Users/arek/IdeaProjects/export-endomondo/node_modules/.pnpm/[email protected]/node_modules/endomondo-api-handler/dist/api/Api.js:215:9)
at async /Users/arek/IdeaProjects/export-endomondo/index.js:10:5 {
response: {
data: 'Uncaught REST API exception:\n' +
'URL: http://www.endomondo.com/rest/v1/users/{userId}/workouts/history\n' +
'Method: GET\n' +
'Parameters: {expand=[points,workout]}\n',
status: 500,
source: Response {
size: 0,
timeout: 0,
[Symbol(Body internals)]: {
body: PassThrough {
_readableState: ReadableState {
objectMode: false,
highWaterMark: 16384,
buffer: [BufferList],
length: 0,
pipes: [],
flowing: true,
ended: true,
endEmitted: true,
reading: false,
constructed: true,
sync: false,
needReadable: false,
emittedReadable: false,
readableListening: false,
resumeScheduled: false,
errorEmitted: false,
emitClose: true,
autoDestroy: true,
destroyed: true,
errored: null,
closed: true,
closeEmitted: true,
defaultEncoding: 'utf8',
awaitDrainWriters: null,
multiAwaitDrain: false,
readingMore: false,
decoder: null,
encoding: null,
[Symbol(kPaused)]: false
},
_events: [Object: null prototype] {
prefinish: [Function: prefinish],
error: [Array],
data: [Function (anonymous)],
end: [Function (anonymous)]
},
_eventsCount: 4,
_maxListeners: undefined,
_writableState: WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: true,
needDrain: false,
ending: true,
ended: true,
finished: true,
destroyed: true,
decodeStrings: true,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: false,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: null,
writelen: 0,
afterWriteTickInfo: null,
buffered: [],
bufferedIndex: 0,
allBuffers: true,
allNoop: true,
pendingcb: 0,
constructed: true,
prefinished: true,
errorEmitted: false,
emitClose: true,
autoDestroy: true,
errored: null,
closed: true,
closeEmitted: true,
[Symbol(kOnFinished)]: []
},
allowHalfOpen: true,
[Symbol(kCapture)]: false,
[Symbol(kCallback)]: null
},
disturbed: true,
error: null
},
[Symbol(Response internals)]: {
url: 'https://www.endomondo.com/rest/v1/users/{userId}/workouts/history?expand=points%2Cworkout',
status: 500,
statusText: 'Internal Server Error',
headers: Headers {
[Symbol(map)]: [Object: null prototype] {
'content-type': [Array],
'content-length': [Array],
connection: [Array],
'cache-control': [Array],
date: [Array],
server: [Array],
'x-cache': [Array],
via: [Array],
'x-amz-cf-pop': [Array],
'x-amz-cf-id': [Array]
}
},
counter: 0
}
},
request: Request {
size: 0,
timeout: 0,
follow: 20,
compress: true,
counter: 0,
agent: undefined,
[Symbol(Body internals)]: { body: null, disturbed: false, error: null },
[Symbol(Request internals)]: {
method: 'GET',
redirect: 'follow',
headers: Headers {
[Symbol(map)]: [Object: null prototype] {
'content-type': [Array],
'x-csrf-token': [Array],
cookie: [Array]
}
},
parsedURL: Url {
protocol: 'https:',
slashes: true,
auth: null,
host: 'www.endomondo.com',
port: null,
hostname: 'www.endomondo.com',
hash: null,
search: '?expand=points%2Cworkout',
query: 'expand=points%2Cworkout',
pathname: '/rest/v1/users/{userId}/workouts/history',
path: '/rest/v1/users/{userId}/workouts/history?expand=points%2Cworkout',
href: 'https://www.endomondo.com/rest/v1/users/{userId}/workouts/history?expand=points%2Cworkout'
},
signal: null
}
}
}
}
ERROR Command failed with exit code 1.
Looks like https://www.endomondo.com/rest/v1/users/{userId}/workouts/history?expand=points%2Cworkout
call is a problem.
Uncaught REST API exception:
URL: http://www.endomondo.com/rest/v1/users/{userId}/workouts/history
Method: GET
Parameters: {expand=[points,workout]}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.