Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
/*
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

matt-thommo commented Jul 13, 2022

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.

@vakata
Copy link
Author

vakata commented Jul 13, 2022

I have not used this script in quite a while - I guess the api was bumped to v3 - thank you for pointing in out :)

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