Skip to content

Commit

Permalink
my Tracker app upload to github
Browse files Browse the repository at this point in the history
  • Loading branch information
fishonamos committed May 15, 2021
0 parents commit 0f4bb1f
Show file tree
Hide file tree
Showing 3,638 changed files with 5,833,901 additions and 0 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
52 changes: 52 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
FROM node:alpine as frontend

WORKDIR /app

RUN apk --no-cache add make

COPY Makefile package.json package-lock.json ./
RUN make install-deps
COPY tailwind.config.js ./tailwind.config.js
COPY main.css ./main.css
COPY pkg ./pkg
COPY views ./views
COPY assets ./assets

RUN make build-dist build-tw

FROM golang:alpine as backend
ARG BUILD_TIME
ARG GIT_COMMIT
ARG GIT_REF
ARG GIT_REF_NAME
ARG GIT_REF_TYPE

WORKDIR /app

COPY go.mod go.sum ./
RUN go mod download

COPY main.go ./main.go
COPY pkg ./pkg
COPY vendor ./vendor
COPY views ./views
COPY assets ./assets
COPY translations ./translations
COPY --from=frontend /app/assets/output.css ./assets/output.css
COPY --from=frontend /app/assets/dist ./assets/dist

ENV CGO_ENABLED=0
RUN go build \
-ldflags "-X 'main.buildTime=${BUILD_TIME}' -X 'main.gitCommit=${GIT_COMMIT}' -X 'main.gitRef=${GIT_REF}' -X 'main.gitRefName=${GIT_REF_NAME}' -X 'main.gitRefType=${GIT_REF_TYPE}'" \
-o /workout-tracker ./

FROM alpine:latest

RUN apk add --no-cache tzdata
VOLUME /data /imports
WORKDIR /app
COPY --from=backend /workout-tracker ./workout-tracker

WORKDIR /data
ENTRYPOINT ["/app/workout-tracker"]
EXPOSE 8080
20 changes: 20 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

123 changes: 123 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
GIT_REF ?= $(shell git symbolic-ref HEAD)
GIT_REF_NAME ?= $(shell git branch --show-current)
GIT_REF_TYPE ?= branch
GIT_COMMIT ?= $(shell git rev-parse HEAD)
BUILD_TIME ?= $(shell date -u --rfc-3339=seconds)
OUTPUT_FILE ?= tmp/main

I18N_LANGUAGES ?= nl de fr
LANG_TO_GENERATE = $(patsubst generate-translation-%,%,$@)
THEME_SCREENSHOT_WIDTH ?= 1200
THEME_SCREENSHOT_HEIGHT ?= 900

.PHONY: all clean test build screenshots

all: clean install-deps test build

install-deps:
npm install

clean:
rm -fv ./assets/output.css ./workout-tracker
rm -rf ./tmp/ ./node_modules/ ./assets/dist/

dev:
air

build: build-swagger build-dist build-tw build-server build-docker screenshots

build-server:
go build \
-ldflags "-X 'main.buildTime=$(BUILD_TIME)' -X 'main.gitCommit=$(GIT_COMMIT)' -X 'main.gitRef=$(GIT_REF)' -X 'main.gitRefName=$(GIT_REF_NAME)' -X 'main.gitRefType=$(GIT_REF_TYPE)'" \
-o $(OUTPUT_FILE) ./

build-docker:
docker build -t workout-tracker --pull \
--build-arg BUILD_TIME="$(BUILD_TIME)" \
--build-arg GIT_COMMIT="$(GIT_COMMIT)" \
--build-arg GIT_REF="$(GIT_REF)" \
--build-arg GIT_REF_NAME="$(GIT_REF_NAME)" \
--build-arg GIT_REF_TYPE="$(GIT_REF_TYPE)" \
.

build-swagger:
swag init \
--parseDependency \
--dir ./pkg/app/,./,./vendor/gorm.io/gorm/,./vendor/github.com/codingsince1985/geo-golang/ \
--generalInfo api_handlers.go

build-tw:
npx tailwindcss -i ./main.css -o ./assets/output.css

clean-dist:
rm -rf ./assets/dist/

build-dist: clean-dist
mkdir -p ./assets/dist/
cp -v ./node_modules/fullcalendar/index.global.min.js ./assets/dist/fullcalendar.min.js
cp -v ./node_modules/leaflet/dist/leaflet.css ./assets/dist/
cp -v ./node_modules/leaflet/dist/leaflet.js ./assets/dist/
cp -v ./node_modules/sorttable/sorttable.js ./assets/dist/
cp -v ./node_modules/shareon/dist/shareon.iife.js ./assets/dist/
cp -v ./node_modules/shareon/dist/shareon.min.css ./assets/dist/
cp -R ./node_modules/@fortawesome/fontawesome-free/ ./assets/dist/fontawesome/
cp -v ./node_modules/apexcharts/dist/apexcharts.min.js ./assets/dist/
cp -v ./node_modules/apexcharts/dist/apexcharts.css ./assets/dist/


watch-tw:
npx tailwindcss -i ./main.css -o ./assets/output.css --watch

generate-messages:
xspreak -p ./translations/ -f json --template-keyword "i18n" -t "views/**/*.html"

generate-translations: $(patsubst %,generate-translation-%, $(I18N_LANGUAGES))

$(patsubst %,generate-translation-%, $(I18N_LANGUAGES)):
xspreak merge -i translations/messages.json \
-o translations/${LANG_TO_GENERATE}.json -l ${LANG_TO_GENERATE}
prettier --write translations/${LANG_TO_GENERATE}.json

serve:
$(OUTPUT_FILE)

test: test-go test-assets

test-assets:
prettier --check .

test-go:
go test -short -count 1 -mod vendor -covermode=atomic ./...
golangci-lint run --allow-parallel-runners

screenshots: generate-screenshots screenshots-theme screenshots-responsive

generate-screenshots:
K6_BROWSER_ARGS="force-dark-mode" k6 run screenshots.js

screenshots-theme:
mkdir -p tmp/
convert docs/single_workout-dark.png \
-resize $(THEME_SCREENSHOT_WIDTH)x$(THEME_SCREENSHOT_HEIGHT)\! \
tmp/dark_resized.jpg
convert docs/single_workout-light.png \
-resize $(THEME_SCREENSHOT_WIDTH)x$(THEME_SCREENSHOT_HEIGHT)\! \
tmp/light_resized.jpg
convert -size $(THEME_SCREENSHOT_WIDTH)x$(THEME_SCREENSHOT_HEIGHT) \
xc:white -draw "polygon 0,0 $(THEME_SCREENSHOT_WIDTH),0 $(THEME_SCREENSHOT_WIDTH),$(THEME_SCREENSHOT_HEIGHT)" \
tmp/mask.png
convert tmp/dark_resized.jpg tmp/light_resized.jpg tmp/mask.png \
-composite docs/single_workout-theme.jpg
rm -f tmp/dark_resized.jpg tmp/light_resized.jpg tmp/mask.png

screenshots-responsive:
montage -density 300 -tile 3x0 -geometry +5+5 -background none docs/dashboard-responsive.png docs/single_workout-responsive.png docs/statistics-responsive.png docs/responsive.png

go-cover:
go test -short -count 1 -mod vendor -covermode=atomic -coverprofile=coverage.out ./...
go tool cover -func=coverage.out
rm -vf coverage.out

update-deps:
npm update
go get -d -t ./...
162 changes: 162 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
A workout tracking web application for personal use with everything included.

## Getting started

### Docker

Run the latest image from GitHub Container Registry (latest and release images
are available for amd64 and arm64). The current directory is mounted as the data
directory.

```bash
# Latest master build
docker run -p 8080:8080 -v .:/data ghcr.io/jovandeginste/workout-tracker:latest

# Tagged release
docker run -p 8080:8080 -v .:/data ghcr.io/jovandeginste/workout-tracker:0.11.3
docker run -p 8080:8080 -v .:/data ghcr.io/jovandeginste/workout-tracker:0.11
docker run -p 8080:8080 -v .:/data ghcr.io/jovandeginste/workout-tracker:0

# Latest release
docker run -p 8080:8080 -v .:/data ghcr.io/jovandeginste/workout-tracker:release

# Run as non-root user; make sure . is owned by uid 1000
docker run -p 8080:8080 -v .:/data -u 1000:1000 ghcr.io/jovandeginste/workout-tracker
```

Open your browser at `http://localhost:8080`

To persist data and sessions, run:

```bash
docker run -p 8080:8080 \
-e WT_JWT_ENCRYPTION_KEY=my-secret-key \
-v $PWD/data:/data \
ghcr.io/jovandeginste/workout-tracker:master
```

or use docker compose

```bash
# Create directory that stores your data
mkdir -p /opt/workout-tracker
cd /opt/workout-tracker

# Download the compose.yaml
curl https://raw.githubusercontent.com/jovandeginste/workout-tracker/master/compose.yaml --output compose.yaml

# Start the server
docker compose up -d
```


After starting the server, you can access it at <http://localhost:8080> (the
default port). A login form is shown.

If no users are in the database (eg. when starting with an empty database), a
default `admin` user is created with password `admin`. You should change this
password in a production environment.

## API usage

The API is documented using [swagger](https://swagger.io/). You must enable API access for your user, and copy the API key. You can use the API key as a query parameter (`api-key=${API_KEY}`) or as a header (`Authorization: Bearer ${API_KEY}`).

You can configure some tools to automatically upload files to Workout Tracker, using the `POST /api/v1/import/$program` API endpoint.

### FitoTrack

Read [their documentation](https://codeberg.org/jannis/FitoTrack/wiki/Auto-Export) before you continue.

The path to POST to is: `/api/v1/import/fitotrack?api-key=${API_KEY}`

## Development

### Build and run it yourself

- install go
- clone the repository

```bash
go build ./
./workout-tracker
```

This does not require npm or Tailwind, since the compiled css is included in the
repository.

### Do some development

You need to install Golang and npm.

Because I keep forgetting how to build every component, I created a Makefile.

```bash
# Make everything. This is also the default target.
make all # Run tests and build all components

# Install system dependencies
make install-deps

# Testing
make test # Runs all the tests
make test-assets test-go # Run tests for the individual components

# Building
make build # Builds all components
make build-tw # Builds the Tailwind CSS output file
make build-server # Builds the web server
make build-docker # Performs all builds inside Docker containers, creates a Docker image
make build-swagger # Generates swagger docs

# Translating
make generate-messages # Detects all translatable strings and write them to translations/messages.yaml
make generate-translations # Populates the translation files per language


# Running it
make serve # Runs the compiled binary
make dev # Runs a wrapper that watches for changes, then rebuilds and restarts
make watch-tw # Runs the Tailwind CSS watcher (not useful unless you're debugging Tailwind CSS)

# Cleanin' up
make clean # Removes build artifacts
```

## What is this, technically?

A single binary that runs on any platform, with no dependencies.

The binary contains all assets to serve a web interface, through which you can
upload your GPX files, visualize your tracks and see their statistics and
graphs. The web application is multi-user, with a simple registration and
authentication form, session cookies and JWT tokens). New accounts are inactive
by default. An admin user can activate (or edit, delete) accounts. The default
database storage is a single SQLite file.

## What technologies are used

- Go, with some notable libraries
- [gpxgo](github.com/tkrajina/gpxgo)
- [Echo](https://echo.labstack.com/)
- [Gorm](https://gorm.io)
- [Spreak](https://github.com/vorlif/spreak)
- HTML, CSS and JS
- [Tailwind CSS](https://tailwindcss.com/)
- [Font Awesome](https://fontawesome.com/)
- [FullCalendar](https://fullcalendar.io/)
- [Leaflet](https://leafletjs.com/)
- [sorttable](https://www.kryogenix.org/code/browser/sorttable/)
- [apexcharts](https://apexcharts.com/)
- Docker

The application uses OpenStreetMap as its map provider and for geocoding a GPS
coordinate to a location.

## Compatiblity

This is a work in progress. If you find any problems, please let us know. The
application is tested with GPX files from these sources:

- Garmin Connect (export to GPX)
- FitoTrack (automatic export to GPX)
- Workoutdoors (export to GPX)
Loading

0 comments on commit 0f4bb1f

Please sign in to comment.