Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
c5da5a4
Update README.md
freekode Jan 13, 2025
c5806f9
Merge branch 'dev'
freekode Jan 16, 2025
f321c8b
Scheduled job for workout sync (#93)
freekode Jan 18, 2025
747038e
scheduled workouts readme
freekode Jan 19, 2025
a95a36b
scheduled job duplication fix
freekode Jan 19, 2025
1f67913
scheduled job duplication fix
freekode Jan 19, 2025
3e08b90
readme upd
freekode Jan 19, 2025
2fb7b75
Update README.md
freekode Jan 19, 2025
4de0a8e
Update README.md
freekode Jan 19, 2025
56b3f2e
fix tp premium detection (#94)
freekode Jan 19, 2025
9ab5b94
changelog
freekode Jan 19, 2025
f3834f5
version 0.11.0
freekode Jan 19, 2025
9cea0fe
fix #96 (#98)
freekode Feb 11, 2025
c687ef2
changelog
freekode Feb 11, 2025
25b05db
version 0.11.1
freekode Feb 11, 2025
c905de1
Persistent scheduling (#101)
freekode Mar 12, 2025
8aac5a1
Docker multi arch (#102)
freekode Mar 12, 2025
b0b64ba
Update workflow-docker-image-new.yml
freekode Mar 13, 2025
b3a34dd
Update workflow-docker-image-new.yml
freekode Mar 13, 2025
0f8d6a9
Update README.md
freekode Mar 13, 2025
2b94c5f
Update README.md
freekode Mar 13, 2025
b651464
Update workflow-docker-image-new.yml
freekode Mar 13, 2025
f6876f7
Update workflow-docker-image-new.yml
freekode Mar 13, 2025
0d9288b
Update README.md
freekode Mar 13, 2025
916e2b0
Update README.md
freekode Mar 13, 2025
40daf24
Update CHANGELOG.md
freekode Mar 13, 2025
c3d0d1a
Update CHANGELOG.md
freekode Mar 13, 2025
2a9a8d1
version 0.12.0
freekode Mar 13, 2025
62847e8
Delete scripts directory
freekode Mar 13, 2025
4daaf91
Update Dockerfile
freekode Mar 17, 2025
60938d0
Fix remove button position
freekode Mar 19, 2025
f6f4f20
version 0.12.1
freekode Mar 19, 2025
3c7573f
Update CHANGELOG.md
freekode Mar 19, 2025
6f28d36
remove premium check, add warn sign
freekode Apr 15, 2025
62ec105
version 0.12.2
freekode Apr 15, 2025
af73acd
Update CHANGELOG.md
freekode Apr 15, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/workflows/branch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ jobs:
jar-artifact-name: tp2intervals-jar
image-name: tp2intervals
image-tag: ${{ needs.extract_branch_name.outputs.branch_name }}

docker-image-new:
needs:
- jar
uses: ./.github/workflows/workflow-docker-image-new.yml
secrets: inherit
with:
jar-name: tp2intervals
jar-artifact-name: tp2intervals-jar
dry-run: false

electron:
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,10 @@ jobs:
docker-image:
needs:
- jar
uses: ./.github/workflows/workflow-docker-image.yml
uses: ./.github/workflows/workflow-docker-image-new.yml
with:
jar-name: tp2intervals
jar-artifact-name: tp2intervals-jar
image-name: tp2intervals

electron:
needs:
Expand Down
10 changes: 10 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ jobs:
image-tag: latest
dry-run: false

docker-image-new:
needs:
- jar
uses: ./.github/workflows/workflow-docker-image-new.yml
secrets: inherit
with:
jar-name: tp2intervals
jar-artifact-name: tp2intervals-jar
dry-run: false

electron:
needs:
- jar
Expand Down
115 changes: 115 additions & 0 deletions .github/workflows/workflow-docker-image-new.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
name: Docker Image

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

on:
workflow_call:
inputs:
jar-name:
required: true
type: string
jar-artifact-name:
required: true
type: string
dry-run:
required: false
type: boolean
default: true

env:
# Use docker.io for Docker Hub if empty
REGISTRY: ghcr.io
# github.repository as <account>/<repo>
IMAGE_NAME: ${{ github.repository }}


jobs:
build:

runs-on: ubuntu-latest
permissions:
contents: read
packages: write
# This is used to complete the identity challenge
# with sigstore/fulcio when running outside of PRs.
id-token: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

- uses: actions/download-artifact@master
with:
name: ${{ inputs.jar-artifact-name }}
path: artifact

# Install the cosign tool except on PR
# https://github.com/sigstore/cosign-installer
- name: Install cosign
if: ${{ inputs.dry-run == false }}
uses: sigstore/cosign-installer@v3.8.1
with:
cosign-release: 'v2.2.4'

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

# Set up BuildKit Docker container builder to be able to build
# multi-platform images and export cache
# https://github.com/docker/setup-buildx-action
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 # v3.0.0

# Login against a Docker registry except on PR
# https://github.com/docker/login-action
- name: Log into registry ${{ env.REGISTRY }}
if: ${{ inputs.dry-run == false }}
uses: docker/login-action@v3 # v3.0.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# Extract metadata (tags, labels) for Docker
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v5 # v5.0.0
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=raw,value=latest,enable={{is_default_branch}}
type=ref,event=tag

# Build and push Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action
- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@v6 # v5.0.0
with:
context: .
push: ${{ inputs.dry-run == false }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
platforms: linux/amd64,linux/arm64
build-args: "JAR_PATH=artifact/${{ inputs.jar-name }}.jar"

# Sign the resulting Docker image digest except on PRs.
# This will only write to the public Rekor transparency log when the Docker
# repository is public to avoid leaking data. If you would like to publish
# transparency data even for private images, pass --force to cosign below.
# https://github.com/sigstore/cosign
- name: Sign the published Docker image
if: ${{ inputs.dry-run == false }}
env:
# https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-an-intermediate-environment-variable
TAGS: ${{ steps.meta.outputs.tags }}
DIGEST: ${{ steps.build-and-push.outputs.digest }}
# This step uses the identity token to provision an ephemeral certificate
# against the sigstore community Fulcio instance.
run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST}
23 changes: 20 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,22 @@
<a name="0.10.0"></a>
### 0.12.2
- Fixed TP Premium users coulndt select future dates to sync workouts

### 0.12.1
- Fixed invisible remove button for scheduled job

### 0.12.0
- Multiarch docker image
- Persistent scheduled job

### 0.11.1
- Fix docker image

### 0.11.0
- Added scheduled job to sync planned workouts in calendars
- Added support arm64 for Mac
- Added support to skip already synced workouts when syncing to Intervals.icu
- Fixed null workout name in TrainingPeaks

### 0.10.0
- Added calendar sync between TrainerRoad, TrainingPeaks and Intervals
- Added bash script for automatic calendar sync with cron
Expand All @@ -9,6 +27,5 @@
- Added TrainerRoad configuration tutorial
- Removed Strava support


### 0.9.0
- Added support distance based steps in workouts
- Added support distance based steps in workouts
1 change: 0 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@

ARG JAR_PATH='boot/build/libs/tp2intervals.jar'
COPY $JAR_PATH /app/app.jar
COPY scripts /scripts
ENTRYPOINT java -jar /app/app.jar

Check warning on line 6 in Dockerfile

View workflow job for this annotation

GitHub Actions / docker-image / build

JSON arguments recommended for ENTRYPOINT/CMD to prevent unintended behavior related to OS signals

JSONArgsRecommended: JSON arguments recommended for ENTRYPOINT to prevent unintended behavior related to OS signals More info: https://docs.docker.com/go/dockerfile/rule/json-args-recommended/
63 changes: 22 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ 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).

**Only for educational purposes**

<img src="https://github.com/freekode/tp2intervals/blob/main/docs/tp.png?raw=true" width="25%"><img src="https://github.com/freekode/tp2intervals/blob/main/docs/tr.png?raw=true" width="25%">

* [List of features](#list-of-features)
Expand All @@ -23,38 +25,46 @@ All files are available for download on [Release page](https://github.com/freeko
+ [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)
* [Troubleshooting](#troubleshooting)
+ [How to get logs](#how-to-get-logs)
+ [How to record HAR file](#how-to-record-har-file)


**TrainerRoad Updates ⚠️**

**New Docker image location ⚠️**

**New image url: `ghcr.io/freekode/tp2intervals`**

Old image url: `ghcr.io/freekode/tp2intervals/tp2intervals`

**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.

## List of features

### TrainingPeaks features
**Athlete account**
**TrainingPeaks**

Athlete account
* Sync planned workouts in calendar between Intervals.icu and TrainingPeaks (for today and tomorrow with free TP account)
* Copy whole training plan from TrainingPeaks
* Create training plan or workout folder on Intervals.icu from planned workouts on TrainingPeaks

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

### TrainerRoad features
**TrainerRoad**
* Sync planned workouts in calendar from TrainerRoad to TrainingPeaks or Intervals.icu
* Copy workouts from TrainerRoad library to Intervals
* Create training plan or workout folder on Intervals.icu from planned workouts on TrainerRoad

**Only for educational purposes**
Automatically schedule workouts for today, by checking your calendar every 20 minutes.
To clear up scheduled jobs just restart the application.

## Configuration

## Configuration
Before using the application you need to configure access to platforms.
Access to Intervals.icu is required, access to other platforms is optional.

Expand Down Expand Up @@ -87,7 +97,6 @@ Cookie `SharedTrainerRoadAuth` (key and value, smth like `SharedTrainerRoadAuth=
Be aware, Firefox cuts long strings in Dev Tool window. Copy cookie value with right click -> Copy Value.

## Other ways to run the app

### Executable JAR
The project has executable jar with web UI. It requires JDK 21. To run jar:
```shell
Expand All @@ -102,19 +111,13 @@ java -Dserver.port=9090 -jar tp2intervals.jar
### Docker
Docker image also built for every release

To run docker execute:

```shell
docker run --rm --name tp2intervals -p 8080:8080 ghcr.io/freekode/tp2intervals/tp2intervals:latest
```

Or with `docker compose`

```yaml
services:
app:
image: ghcr.io/freekode/tp2intervals/tp2intervals:latest
image: ghcr.io/freekode/tp2intervals:latest
container_name: tp2intervals
volumes:
- ./tp2intervals.sqlite:/tp2intervals.sqlite
ports:
- '8080:8080'
```
Expand All @@ -125,32 +128,10 @@ services:
* Ramp steps in TrainerRoad are not supported
* **MacOS arm64** Error: `"tp2intervals" is damaged and can’t be opened.`
Run command in terminal `xattr -d com.apple.quarantine /Applications/tp2intervals.app` and then open app again
* **MacOS** app is not signed. Usually you need to open it twice. After opening it, be patient, it takes some time to
start
* **MacOS** app is not signed. Usually you need to open it twice
* **Windows** The app will ask to access local network and Internet, you need to allow it. After all it makes HTTP requests
* More info you can find on the forum https://forum.intervals.icu/t/tp2intervals-copy-trainingpeaks-and-trainerroad-workouts-plans-to-intervals/63375


### Bash script to sync planned workouts
To sync workouts without clicking buttons on UI there is a script [sync-planned-workouts.sh](scripts/sync-planned-workouts.sh).

```sh
./sync-planned-workouts.sh <sync date or just tomorrow> <source platform> <target platform> <is standalone app>
```

Example, sync workouts from TrainerRoad to TrainingPeaks for tomorrow in standalone app:
```sh
./sync-planned-workouts.sh tomorrow TRAINER_ROAD TRAINING_PEAKS standalone
```

Example, sync workouts from Intervals.icu to TrainingPeaks for 2025-01-05 in docker:
```sh
./sync-planned-workouts.sh 2025-01-05 INTERVALS TRAINING_PEAKS
```

Docker image has build in cron, you can edit its configuration and add script to run it on schedule


### Info regarding scheduling for the next day with TrainingPeaks free account
Officially if you have a free TP account, you can't plan workouts for future dates, but practically you can.
You can plan a workout for the next day relative to TrainingPeaks server local time. The server is in UTC-6 time zone. Let's check some examples:
Expand Down
2 changes: 2 additions & 0 deletions boot/src/main/kotlin/org/freekode/tp2intervals/Application.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.boot.runApplication
import org.springframework.cache.annotation.EnableCaching
import org.springframework.cloud.openfeign.EnableFeignClients
import org.springframework.scheduling.annotation.EnableScheduling

@SpringBootApplication
@EnableFeignClients
@EnableCaching
@EnableScheduling
@EnableConfigurationProperties(DefaultConfiguration::class)
class Application

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ class ConfigurationService(
return errors
}

fun platformInfo() =
platformInfoRepositoryMap.entries.associate { it.key to it.value.platformInfo() }

fun platformInfo(platform: Platform): PlatformInfo {
return platformInfoRepositoryMap[platform]!!.platformInfo()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ data class CopyFromCalendarToCalendarRequest(
val skipSynced: Boolean,
val sourcePlatform: Platform,
val targetPlatform: Platform
)
)
Loading
Loading