Skip to content

Instantly share code, notes, and snippets.

@lildude
Forked from vakata/trainerroad-trainingpeaks.js
Created October 19, 2021 16:27
Show Gist options
  • Save lildude/b99a1987626e300277bae3e673c1bd07 to your computer and use it in GitHub Desktop.
Save lildude/b99a1987626e300277bae3e673c1bd07 to your computer and use it in GitHub Desktop.
/*
1) Open your calendar on trainerroad
2) Press F12 to open developer tools, select console and paste the script below
3) OPTIONAL - modify the two dates (beg & end) to suit your needs
4) Copy the result of the execution (something like TRData = ...)
*/
(function () {
var beg = '2021-01-01';
var end = '2022-01-01';
function normalizeDate(dat) {
var tmp = dat.split('-');
return tmp[2]+'-'+tmp[0]+'-'+tmp[1];
}
function shitDate(dat) {
var tmp = dat.split('-');
return tmp[1]+'-'+tmp[2]+'-'+tmp[0];
}
function find() {
if (jQuery('.calendar__day[id='+shitDate(beg)+']').length) {
collect();
return;
}
if (normalizeDate(jQuery('.calendar__day').eq(0).attr('id')) < beg) {
jQuery(window).scrollTop(jQuery(window).scrollTop() + 250);
setTimeout(function () { find() }, 500);
} else {
jQuery(window).scrollTop(jQuery(window).scrollTop() - 250);
setTimeout(function () { find() }, 500);
}
}
var plan = {};
function collect() {
var scroll = true;
jQuery('.calendar__day').each(function () {
var dat = normalizeDate(jQuery(this).attr('id'));
if (dat > end) {
scroll = false;
return false;
}
if (plan[dat] || dat < beg) {
return true;
}
var events = jQuery(this).find('.calendar__event');
if (!events.length) {
return true;
}
plan[dat] = [];
jQuery(this).find('.calendar__event').each(function () {
plan[dat].push({
type: jQuery(this).find('.icon-run').length ? "run" : (jQuery(this).find('.icon-swim').length ? "swim" : "bike"),
title: jQuery(this).find('.calendar__event-title').text(),
duration: jQuery(this).find(".data-group--duration > .data-group__stat").text().replace(/[^\d,.:]/g, ''),
tss: jQuery(this).find(".data-group--tss > .data-group__stat").text().replace(/[^\d,.:]/g, ''),
if: jQuery(this).find(".data-group--if > .data-group__stat").text().replace(/[^\d,.:]/g, '')
});
});
});
if (scroll) {
jQuery(window).scrollTop(jQuery(window).scrollTop() + 250);
setTimeout(function () { collect() }, 500);
} else {
console.log("TRData = " + JSON.stringify(plan));
}
}
find();
}());
/*
1) Open your calendar on trainingpeaks
2) Press F12 to open developer tools, select console and paste the TRData = ... code obtained from trainerroad
3) Paste the script below and wait for it to complete
*/
(function () {
function duration(inp) {
var tmp = inp.split(':');
var sec = parseInt(tmp[0], 10) * 3600 + parseInt(tmp[1], 10) * 60 + parseInt(tmp[2], 10);
return sec / 3600;
}
if (!TRData) { return alert("you need to paste Trainerroad data first"); }
fetch(
"https://tpapi.trainingpeaks.com/users/v3/user",
{"mode":"cors", "credentials":"include"}
)
.then(function (response) {
return response.json();
})
.then(function (data) {
var userId = data.user.userId;
var types = { run:3, bike:2, swim:1, brick:4 };
for(var dat in TRData) {
for(var workout in TRData[dat]) {
fetch(
"https://tpapi.trainingpeaks.com/fitness/v1/athletes/"+userId+"/workouts",
{
"mode":"cors",
"credentials":"include",
"method" : "POST",
headers: {
'Content-Type': 'application/json'
},
"body" : JSON.stringify({
athleteId:userId,
ifPlanned:parseFloat(TRData[dat][workout].if),
publicSettingValue:0,
completed:false,
tssPlanned:parseInt(TRData[dat][workout].tss),
totalTimePlanned:duration(TRData[dat][workout].duration),
workoutTypeValueId:types[TRData[dat][workout].type],
title:TRData[dat][workout].title,
description:'',
workoutDay:dat
})
}
);
}
}
});
}());
@matt-thommo
Copy link

I love your work, but I think there is an error on line 93.

"https://tpapi.trainingpeaks.com/fitness/v1/athletes/"+userId+"/workouts",
should be
"https://tpapi.trainingpeaks.com/fitness/v3/athletes/"+userId+"/workouts",

or at least I was having problems with running this and the fix above got me working again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment