Skip to content

Instantly share code, notes, and snippets.

@rapsar
Forked from bilan/sports-tracker-download.js
Created April 13, 2025 12:27
Show Gist options
  • Select an option

  • Save rapsar/5a3a3c8d6a16f06fc21ab5d50488ef39 to your computer and use it in GitHub Desktop.

Select an option

Save rapsar/5a3a3c8d6a16f06fc21ab5d50488ef39 to your computer and use it in GitHub Desktop.
Download all workouts from sports-tracker
// Bilan: My fork fixed some api changes, added images downloading and informative gpx file names. Works on 2020/11/02.
//
// You can then upload it to Strava using this oneliner:
// find * -name '*.gpx' -print0 | while read -d $'\0' i; do ID=`echo $i | sed 's/.*id--//' | sed 's/--activity.*//'`; ACTIVITY=`echo $i | sed 's/.*--activity--//' | sed 's/--title.*//'`; NAME=`echo $i | sed 's/--file.gpx//' | sed 's/.*--title--//'`" ($ID/$ACTIVITY)"; echo "\n$NAME\n"; curl -X POST https://www.strava.com/api/v3/uploads -H "Authorization: Bearer ___TOKEN___" -F file=@"$i" -F data_type="gpx" -F description="SportsTracker import" -F name="$NAME" -F external_id="$i"; sleep 10;done
//
// Original desc:
// based entirely on this blog post:
// http://druss.co/2016/04/export-all-workouts-from-sports-tracker/
// unfortunately the original script no longer works, moslty because jQuery is
// no longer available on sports-tracker pages.
//
// I've compiled the changes proposed in the comments in the script below.
// to use the script, login to your sports-tracker account
// change URL to http://www.sports-tracker.com/diary/workout-list
// open browser console (Cmd-Shift-I)
// paste the script, hit enter - it'll run and print something like this to the cosole:
// curl -o SportsTracker-<..id..>.gpx "http://www.sports-tracker.com/apiserver....."
// right-click on the colsole and save the contents to a file, call it download-all-workouts.sh
// open terminal, change to the directory where you saved the contents of the console
// edit the file - remove the javascript at the beginning of the file leaving only curl commands
// fix permissions:
// $>chmod +x download-all-workouts.sh
// run the script:
// $>./download-all-workouts.sh
const key = "sessionkey=";
const valueStartIndex = document.cookie.indexOf(key) + key.length;
const token = document.cookie.substring(valueStartIndex, document.cookie.indexOf(';', valueStartIndex));
const activities = {0:"walk",1:"run",2:"ride",11:"hike",13:"alpineski",14:"rowing",15:"rowing"};
function downloadOne(item) {
const href = item.href;
const id = href.substr(href.lastIndexOf('/') + 1, 24);
const url = 'https://api.sports-tracker.com/apiserver/v1/workout/exportGpx/' + id + '?token=' + token;
const activityId = item.querySelector(".activity-icon").getAttribute('activity-icon');
const filename = `id--${id}--activity--${activities[activityId]}--title--${item.querySelector(".description").title.replace('/',',')}--file.gpx`;
console.log(`mkdir "${id}"`);
console.log(`curl -o "${id}/${filename}" "${url}";`);
downloadImages(id);
}
async function downloadImages(id) {
const imagesUrl = 'https://api.sports-tracker.com/apiserver/v1/images/workout/' + id + '?token=' + token;
const imageApiResponse = await fetch(imagesUrl);
const images = (await imageApiResponse.json()).payload;
for (let i = 0; i < images.length; i++) {
let image = images[i];
let filename = `${id}-${image.key}-${image.location.x}-${image.location.y}-${image.timestamp}.jpg`;
let url = `https://api.sports-tracker.com/apiserver/v1/image/scale/${image.key}.jpg?width=${image.width}&height=${image.height}`;
console.log(`curl -o "${id}/${filename}" "${url}";`);
}
}
function loopThroughItems(items) {
for (let i = 0; i < items.length; i++) {
downloadOne(items[i]);
}
}
const items = document.querySelectorAll("ul.diary-list__workouts li a");
document.body.innerHtml = '';
loopThroughItems(items);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment