Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
# Conflicts:
#	README.md
  • Loading branch information
freekode committed Dec 28, 2024
2 parents 7a32596 + 8a40bac commit 29104c9
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 69 deletions.
128 changes: 63 additions & 65 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,47 +11,82 @@ Runs on MacOS (DMG), Windows (EXE installer), Linux (AppImage). Alternatively th

All files are available for download on [Release page](https://github.com/freekode/tp2intervals/releases/latest).

### TrainerRoad Updates ⚠️

* [List of features](#list-of-features)
+ [TrainingPeaks features](#trainingpeaks-features)
+ [TrainerRoad features](#trainerroad-features)
+ [Strava features](#strava-features)
* [Configuration](#configuration)
+ [Intervals.icu](#config-intervalsicu)
+ [TrainingPeaks](#trainingpeaks)
+ [TrainerRoad](#trainerroad)
* [Other ways to run the app](#other-ways-to-run-the-app)
+ [Executable JAR](#executable-jar)
+ [Docker](#docker)
* [FAQ](#faq)
+ [General](#general)
+ [Sync automatically planned workouts to TrainingPeaks](#sync-automatically-planned-workouts-to-trainingpeaks)
+ [Info regarding scheduling for the next day with TrainingPeaks free account](#info-regarding-scheduling-for-the-next-day-with-trainingpeaks-free-account)
+ [How to export HAR file](#how-to-export-har-file)
+ [How to get logs for your issue](#how-to-get-logs-for-your-issue)



**TrainerRoad Updates ⚠️**

I don't have access to TrainerRoad anymore. Account, which I used, cancelled subscription. I don't use the platform and it's too expensive to have it for occasional fixes.
To fix issues I can only relay on logs and HAR files from you.

### TrainingPeaks features

#### For athlete account
## List of features

### TrainingPeaks features
**Athlete account**
* Sync planned workouts from Intervals to TrainingPeaks for today and tomorrow (free TP account)
* Copy whole training plan from TrainingPeaks
* Create training plan or workout folder on Intervals from planned workouts on TrainingPeaks

#### For coach account

**Coach account**
* Copy whole training plan and workout library from TrainingPeaks

### TrainerRoad features

* Copy workouts from TrainerRoad library to Intervals
* Create training plan or workout folder on Intervals from planned workouts on TrainerRoad

### Strava features
* Sync activities. App exports original file from Strava and uploads it to Intervals.icu. Only recorded activities are supported.

* Sync activities. App exports original file from Strava and uploads it to Intervals.icu. Only recorded activities are supported.
<img src="https://github.com/freekode/tp2intervals/blob/main/docs/tp.png?raw=true" width="30%"><img src="https://github.com/freekode/tp2intervals/blob/main/docs/tr.png?raw=true" width="30%">

### Beta features
**Only for educational purposes**

Beta features can be enabled in Configuration
## Configuration

* Step Modifier (TrainingPeaks). Based on selecton `power=1s`, `power=3s` will be added for each step on Intervals.
* Remove HTML tags from description (TrainerRoad). Cleans up workouts descriptions from HTML tags.
Before using the application you need to configure access to platforms.
Access to Intervals.icu is required, access to other platforms is optional.

<img src="https://github.com/freekode/tp2intervals/blob/main/docs/tp.png?raw=true" width="30%"><img src="https://github.com/freekode/tp2intervals/blob/main/docs/tr.png?raw=true" width="30%">
After you gathered all required configuration, you can click Confirm button.
If everything is fine, you will be redirected to the home page.

If your configuration is wrong. You will see an error that there is no access to particular platform.
Check all your values and save configuration again.

<h3 id="config-intervalsicu">Intervals.icu</h3>
Copy API key and Athlete Id from [Settings page](https://intervals.icu/settings) in Developer Settings section on Intervals.icu web page.

<h3 id="config-trainingpeaks">TrainingPeaks</h3>
To use TrainingPeaks Copy cookie `Production_tpAuth` (key and value, smth like `Production_tpAuth=very_long_string`) from the browser on TrainingPeaks page.
Another guide is available here https://forum.intervals.icu/t/implemented-push-workout-to-wahoo/783/87

<img src="https://github.com/freekode/tp2intervals/blob/main/docs/tp_guide.jpg?raw=true">

<h3 id="config-trainerroad">TrainerRoad</h3>
Configuration is very similar to TrainingPeaks. Copy cookie `SharedTrainerRoadAuth` (key
and value, smth like `SharedTrainerRoadAuth=very_long_string`) from the browser on TrainerRoad page.

**Only for educational purposes**

## Other ways to run the app

### Executable JAR

The project has executable jar with web UI. It requires JDK 21. To run jar:
```shell
java -jar tp2intervals.jar
Expand All @@ -63,7 +98,6 @@ java -Dserver.port=9090 -jar tp2intervals.jar
```

### Docker

Docker image also built for every release

To run docker execute:
Expand All @@ -83,42 +117,19 @@ services:
- '8080:8080'
```
## How to configure
After you successfully started the application and were able to open the web UI page.
You need to configure it to gain access to Intervals.icu and to your other platform.
Nice post how to do it is written here https://forum.intervals.icu/t/implemented-push-workout-to-wahoo/783/87
### Intervals API Key and Athlete Id
These values available on [Settings page](https://intervals.icu/settings) in Developer Settings section.
### TrainingPeaks Auth Cookie
If you want ot use TrainingPeaks you need to configure it. Copy cookie `Production_tpAuth` (key and value, smth
like `Production_tpAuth=very_long_string`) from the browser on TrainingPeaks page.

<img src="https://github.com/freekode/tp2intervals/blob/main/docs/tp_guide.jpg?raw=true">

### TrainerRoad Auth Cookie

If you want to use TrainerRoad you need to configure it. Very similar to TrainingPeaks. Copy cookie `SharedTrainerRoadAuth` (key
and value, smth like `SharedTrainerRoadAuth=very_long_string`) from the browser on TrainerRoad page.

After you gathered all required configuration, you can click Confirm button.
If everything is fine, you will be redirected to the home page.

If your configuration is wrong. You will see an error that there is no access to particular platform.
Check all your values and save configuration again.

### Strava Cookie

For using Strava just copy all your cookies from browser for Strava. It should be enough.
## FAQ
<img src="https://github.com/freekode/tp2intervals/blob/main/docs/strava.jpg?raw=true">
### General
* Only duration based steps in workouts are supported, the app can't work with distance based steps
* Ramp steps in TrainerRoad are not supported
* **MacOS** app is not signed. Usually you need to open it twice. After opening it, be patient, it takes some time to
start
* **Windows** The app will ask to access local network and Internet, you need to allow it. After all it makes HTTP requests
* In case of any problems. You can create an issue on [GitHub](https://github.com/freekode/tp2intervals/issues)
or write directly to me [email protected]. Add logs from your app, it can help a lot to resolve the issue. Or in case of TrainerRoad create HAR file
* More info you can find on the forum https://forum.intervals.icu/t/tp2intervals-copy-trainingpeaks-and-trainerroad-workouts-plans-to-intervals/63375
### Sync automatically planned workouts to TrainingPeaks

If you are using app in docker container, you can set up automatic sync of planned workouts for TrainingPeaks.
Run command on your machine:
Expand All @@ -128,17 +139,6 @@ docker exec -it <container name> ln -s /scripts/sync-planned-to-tp.sh /etc/perio
Script `sync-planned-to-tp.sh` will be executed at 02:00 everyday.
You can also edit crontab configuration manually and set your own schedule.

## FAQ

* Only duration based steps in workouts are supported, the app can't work with distance based steps
* Ramp steps in TrainerRoad are not supported
* **MacOS** app is not signed. Usually you need to open it twice. After opening it, be patient, it takes some time to
start
* **Windows** The app will ask to access local network and Internet, you need to allow it. After all it makes HTTP requests
* In case of any problems. You can create an issue on [GitHub](https://github.com/freekode/tp2intervals/issues)
or write directly to me [email protected]. Add logs from your app, it can help a lot to resolve the issue. Or in case of TrainerRoad create HAR file
* More info you can find on the forum https://forum.intervals.icu/t/tp2intervals-copy-trainingpeaks-and-trainerroad-workouts-plans-to-intervals/63375

### Info regarding scheduling for the next day with TrainingPeaks free account
Officially you can't plan workouts for future dates, but practically you can plan workout for tomorrow with free TP account.
You can plan workout for the next day relative to TP server local time. The server is in UTC-6 time zone.
Expand All @@ -150,7 +150,6 @@ E.g your TZ is UTC+12, current local datetime 20.05.2024 18:00. TP server local
Example with [worldtimebuddy](https://www.worldtimebuddy.com/?pl=1&lid=206,100,756135,2193733&h=206&hf=0)

### How to export HAR file

1. Open new tab in your browser
2. Open dev tools, check Preserve log (Firefox Cog -> Persist Logs)

Expand All @@ -163,11 +162,10 @@ Example with [worldtimebuddy](https://www.worldtimebuddy.com/?pl=1&lid=206,100,7


### How to get logs for your issue

1. Go to Configuration
2. In Generic section set Log Level to DEBUG, click Confirm
4. Reproduce your issue
5. Find log file according to your system
2. In General section set Log Level to DEBUG, click Confirm
3. Reproduce your issue
4. Find log file according to your system

* Linux: ~/.config/tp2intervals/logs/main.log
* MacOS: ~/Library/Logs/tp2intervals/main.log
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import org.freekode.tp2intervals.domain.config.PlatformInfo
import org.freekode.tp2intervals.domain.config.UpdateConfigurationRequest
import org.freekode.tp2intervals.domain.workout.structure.StepModifier
import org.freekode.tp2intervals.rest.ErrorResponseDTO
import org.slf4j.LoggerFactory
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
Expand All @@ -18,15 +19,18 @@ import org.springframework.web.bind.annotation.RestController
class ConfigurationController(
private val configurationService: ConfigurationService,
) {
private val log = LoggerFactory.getLogger(this.javaClass)

@GetMapping("/api/configuration")
fun getConfigurations(): AppConfigurationDTO {
log.info("Received request for getting all configurations")
val configurations = configurationService.getConfigurations()
return AppConfigurationDTO(configurations.configMap)
}

@PutMapping("/api/configuration")
fun updateConfiguration(@RequestBody requestDTO: UpdateConfigurationRequestDTO): ResponseEntity<ErrorResponseDTO> {
log.info("Received request for updating configuration: $requestDTO")
val errors = configurationService.updateConfiguration(UpdateConfigurationRequest(requestDTO.config))
if (errors.isNotEmpty()) {
return ResponseEntity.badRequest().body(ErrorResponseDTO(errors.joinToString()))
Expand All @@ -47,6 +51,7 @@ class ConfigurationController(

@GetMapping("/api/configuration/{platform}")
fun getConfigurations(@PathVariable platform: Platform): PlatformInfo {
log.info("Received request for getting configurations for platform: $platform")
return configurationService.platformInfo(platform)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import org.freekode.tp2intervals.app.plan.CopyPlanResponse
import org.freekode.tp2intervals.app.plan.LibraryService
import org.freekode.tp2intervals.domain.Platform
import org.freekode.tp2intervals.domain.librarycontainer.LibraryContainer
import org.slf4j.LoggerFactory
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
Expand All @@ -15,14 +16,17 @@ import org.springframework.web.bind.annotation.RestController
class LibraryController(
private val libraryService: LibraryService
) {
private val log = LoggerFactory.getLogger(this.javaClass)

@GetMapping("/api/library-container")
fun getLibraryContainers(@RequestParam platform: Platform): List<LibraryContainer> {
log.info("Received request for getting library containers: $platform")
return libraryService.findByPlatform(platform)
}

@PostMapping("/api/library-container/copy")
fun copyLibraryContainer(@RequestBody request: CopyLibraryRequest): CopyPlanResponse {
log.info("Received request to copy the library container: $request")
return libraryService.copyLibrary(request)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import org.freekode.tp2intervals.app.workout.CopyFromLibraryToLibraryRequest
import org.freekode.tp2intervals.app.workout.CopyWorkoutsResponse
import org.freekode.tp2intervals.app.workout.WorkoutService
import org.freekode.tp2intervals.domain.Platform
import org.slf4j.LoggerFactory
import org.springframework.web.bind.annotation.DeleteMapping
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PostMapping
Expand All @@ -17,24 +18,29 @@ import org.springframework.web.bind.annotation.RestController
class WorkoutController(
private val workoutService: WorkoutService
) {
private val log = LoggerFactory.getLogger(this.javaClass)

@PostMapping("/api/workout/copy-calendar-to-calendar")
fun copyWorkoutsFromCalendarToCalendar(@RequestBody request: CopyFromCalendarToCalendarRequest): CopyWorkoutsResponse {
log.info("Received request for copy calendar to calendar: $request")
return workoutService.copyWorkoutsFromCalendarToCalendar(request)
}

@PostMapping("/api/workout/copy-calendar-to-library")
fun copyWorkoutsFromCalendarToLibrary(@RequestBody request: CopyFromCalendarToLibraryRequest): CopyWorkoutsResponse {
log.info("Received request for copy calendar to library: $request")
return workoutService.copyWorkoutsFromCalendarToLibrary(request)
}

@PostMapping("/api/workout/copy-library-to-library")
fun copyWorkoutFromLibraryToLibrary(@RequestBody request: CopyFromLibraryToLibraryRequest): CopyWorkoutsResponse {
log.info("Received request for copy library to library: $request")
return workoutService.copyWorkoutFromLibraryToLibrary(request)
}

@GetMapping("/api/workout/find")
fun findWorkoutsByName(@RequestParam platform: Platform, @RequestParam name: String): List<WorkoutDetailsDTO> {
log.info("Received request for find workouts by name, platform: $platform, name: $name")
return workoutService.findWorkoutsByName(platform, name)
.map { workoutDetails ->
WorkoutDetailsDTO(
Expand All @@ -48,6 +54,7 @@ class WorkoutController(

@DeleteMapping("/api/workout")
fun deleteWorkoutsFromCalendar(@RequestBody request: DeleteWorkoutRequestDTO) {
log.info("Received request to delete workouts from calendar: $request")
workoutService.deleteWorkoutsFromCalendar(request)
}
}
8 changes: 4 additions & 4 deletions ui/src/app/configuration/configuration.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<form [formGroup]="formGroup" novalidate (ngSubmit)="onSubmit()">
<div>
<h2>Intervals.icu</h2>
<h2>Intervals.icu <a href="https://github.com/freekode/tp2intervals?tab=readme-ov-file#config-intervalsicu" target="_blank"><i class="bi bi-question-circle"></i></a></h2>

<mat-form-field class="full-width">
<mat-label>Intervals API Key</mat-label>
Expand Down Expand Up @@ -41,7 +41,7 @@ <h2>Intervals.icu</h2>
</div>

<div>
<h2>TrainingPeaks</h2>
<h2>TrainingPeaks <a href="https://github.com/freekode/tp2intervals?tab=readme-ov-file#config-trainingpeaks" target="_blank"><i class="bi bi-question-circle"></i></a></h2>

<mat-form-field class="full-width">
<mat-label>TrainingPeaks Auth Cookie</mat-label>
Expand All @@ -53,7 +53,7 @@ <h2>TrainingPeaks</h2>
</div>

<div>
<h2>TrainerRoad</h2>
<h2>TrainerRoad <a href="https://github.com/freekode/tp2intervals?tab=readme-ov-file#config-trainerroad" target="_blank"><i class="bi bi-question-circle"></i></a></h2>

<mat-form-field class="full-width">
<mat-label>TrainerRoad Auth Cookie</mat-label>
Expand Down Expand Up @@ -81,7 +81,7 @@ <h2>Strava</h2>
</div>

<div>
<h2>Generic</h2>
<h2>General</h2>

<mat-form-field class="full-width">
<mat-label>Log Level (saved only for current session)</mat-label>
Expand Down

0 comments on commit 29104c9

Please sign in to comment.