Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/bpazy/my_running_page

Make your own running home page
https://github.com/bpazy/my_running_page

codoon data-visualization garmin gpx keep nike strava

Last synced: about 1 month ago
JSON representation

Make your own running home page

Awesome Lists containing this project

README

        

![running_page](https://socialify.git.ci/yihong0618/running_page/image?description=1&font=Inter&forks=1&issues=1&language=1&logo=https%3A%2F%2Fraw.githubusercontent.com%2Fshaonianche%2Fgallery%2Fmaster%2Frunning_page%2Frunning_page_logo_150*150.jpg&owner=1&pulls=1&stargazers=1&theme=Light)

# [这里是白银越野赛全部 21 位逝者的故事](https://github.com/yihong0618/running_page/issues/135)

R.I.P. 希望大家都能健康顺利的跑过终点,逝者安息。

# [打造个人跑步主页](https://yihong.run/running)

[English](README.md) | 简体中文 | [Wiki](https://wiki.mfydev.run/)

GIF 展示

![running_page](https://user-images.githubusercontent.com/15976103/98808834-c02f1d80-2457-11eb-9a7c-70e91faa5e30.gif)

## [大家的跑步主页展示](https://github.com/yihong0618/running_page/issues/12)

Running page runners

| Runner | page | App |
| ------------------------------------------------- | ---------------------------------------------- | --------- |
| [zhubao315](https://github.com/zhubao315) | | Strava |
| [shaonianche](https://github.com/shaonianche) | | Strava |
| [yihong0618](https://github.com/yihong0618) | | Nike |
| [superleeyom](https://github.com/superleeyom) | | Nike |
| [geekplux](https://github.com/geekplux) | | Nike |
| [guanlan](https://github.com/guanlan) | | Strava |
| [tuzimoe](https://github.com/tuzimoe) | | Nike |
| [ben_29](https://github.com/ben-29) | | Strava |
| [kcllf](https://github.com/kcllf) | | Garmin-cn |
| [mq](https://github.com/MQ-0707) | | Keep |
| [zhaohongxuan](https://github.com/zhaohongxuan) | | Strava |
| [yvetterowe](https://github.com/yvetterowe) | | Strava |
| [love-exercise](https://github.com/KaiOrange) | | Keep |
| [zstone12](https://github.com/zstone12) | | Keep |
| [Lax](https://github.com/Lax) | | Keep |
| [lusuzi](https://github.com/lusuzi) | | Nike |
| [wh1994](https://github.com/wh1994) | | Garmin |
| [liuyihui](https://github.com/YiHui-Liu) | | Keep |
| [sunyunxian](https://github.com/sunyunxian) | | Strava |
| [AhianZhang](https://github.com/AhianZhang) | | Nike |
| [L1cardo](https://github.com/L1cardo) | | Nike |
| [luckylele666](https://github.com/luckylele666) | | Strava |
| [MFYDev](https://github.com/MFYDev) | | Garmin-cn |
| [Oysmart](https://github.com/oysmart) | | Garmin-cn |
| [Eished](https://github.com/eished) | | Keep |
| [Liuxin](https://github.com/liuxindtc) | | Nike |
| [loucx](https://github.com/loucx) | | Nike |
| [winf42](https://github.com/winf42) | | Garmin-cn |
| [sun0225SUN](https://github.com/sun0225SUN) | | Nike |
| [Zhan](https://www.zlog.in/about) | | Nike |
| [Dennis](https://run.domon.cn) | | Garmin-cn |
| [hanpei](https://running.nexts.top) | | Garmin-cn |
| [liugezhou](https://github.com/liugezhou) | | Strava |
| [zhubao315](https://github.com/zhubao315) | | Strava |
| [Jason Tan](https://github.com/Jason-cqtan) | | Nike |
| [Conge](https://github.com/conge) | | Strava |
| [cvvz](https://github.com/cvvz) | | Strava |
| [zHElEARN](https://github.com/zHElEARN) | | Strava |
| [Rhfeng](https://sport.frh.life) | | Garmin-cn |
| [Ym9i](https://github.com/Ym9i) | | Strava |
| [jianchengwang](https://github.com/jianchengwang) | | Suunto |
| [fxbin](https://github.com/fxbin) | | Keep |
| [shensl4499](https://github.com/shensl4499) | | codoon |
| [haowei93](https://github.com/haowei93) | | gpx |
| [stevenash0822](https://github.com/stevenash0822) | | Strava |
| [Vint](https://github.com/VintLin) | | Keep |
| [Muyids](https://github.com/muyids) | | Garmin-cn |
| [Gao Hao](https://github.com/efish2002) | | Garmin-cn |
| [Jinlei](https://github.com/iamjinlei0312) | | AW-GPX |
| [Ray Wang](https://github.com/raywangsy) | | Garmin |
| [RealTiny656](https://github.com/tiny656) | | JoyRun |
| [EINDEX](https://github.com/eindex) | | Strava/Nike|
| [Melt](https://github.com/fpGHwd) | | Strava |
| [deepinwine](https://github.com/deepinwine) | | Garmin-cn |

## 它是怎么工作的

![image](https://user-images.githubusercontent.com/15976103/105784027-e1ad9900-5fb2-11eb-9479-372be21482f1.png)

## 特性

1. GitHub Actions 管理自动同步跑步进程及自动生成新的页面
2. Gatsby 生成的静态网页,速度快
3. 支持 Vercel(推荐) 和 GitHub Pages 自动部署
4. React Hooks
5. Mapbox 进行地图展示
6. Nike 及 Runtastic(Adidas Run) 以及佳明(佳明中国)及 Keep 等,自动备份 gpx 数据,方便备份及上传到其它软件

> 因为数据存在 gpx 和 data.db 中,理论上支持几个软件一起,你可以把之前各类 app 的数据都同步到这里(建议本地同步,之后 actions 选择正在用的 app)

> 注:如果你不想公开数据,可以选择 strava 的模糊处理,或 private 仓库。

缩放地图彩蛋

![image](https://user-images.githubusercontent.com/15976103/95644909-a31bcd80-0aec-11eb-9270-869b0a94f59f.png)

## 支持

- **[Strava](#strava)**
- **[Nike Run Club](#nike-run-club)**
- **[Garmin](#garmin)**
- **[Garmin-cn](#garmin-cn-大陆用户请用这个)**
- **[Keep](#keep)**
- **[悦跑圈](#joyrun悦跑圈,因悦跑圈限制单个设备原因,无法自动化)**
- **[咕咚](#codoon咕咚,因咕咚限制单个设备原因,无法自动化)**
- **[郁金香运动](#tulipsport)**
- **[GPX](#gpx)**
- **[TCX](#tcx)**
- **[FIT](#fit)**
- **[Tcx+Strava(upload all tcx data to strava)](#tcx_to_strava)**
- **[Gpx+Strava(upload all tcx data to strava)](#gpx_to_strava)**
- **[Nike+Strava(Using NRC Run, Strava backup data)](#nikestrava)**
- **[Garmin_to_Strava(Using Garmin Run, Strava backup data)](#garmin_to_strava)**
- **[Strava_to_Garmin(Using Strava Run, Garmin backup data)](#strava_to_garmin)**

## 视频教程

- https://www.youtube.com/watch?v=reLiY9p8EJk
- https://www.youtube.com/watch?v=VdNkFxTX5QQ

## 下载

```
git clone https://github.com/yihong0618/running_page.git --depth=1
```

## 安装及测试 (node >= 14.15.0 python >= 3.7)

```
pip3 install -r requirements.txt
yarn install
yarn develop
```

访问 查看

## Docker

```
#构建
# NRC
docker build -t running_page:latest . --build-arg app=NRC --build-arg nike_refresh_token=""
# Garmin
docker build -t running_page:latest . --build-arg app=Garmin --build-arg email="" --build-arg password=""
# Garmin-CN
docker build -t running_page:latest . --build-arg app=Garmin-CN --build-arg email="" --build-arg password=""
# Strava
docker build -t running_page:latest . --build-arg app=Strava --build-arg client_id="" --build-arg client_secret="" --build-arg refresh_token=""
#Nike_to_Strava
docker build -t running_page:latest . --build-arg app=Nike_to_Strava --build-arg nike_refresh_token="" --build-arg client_id="" --build-arg client_secret="" --build-arg refresh_token=""

#启动
docker run -itd -p 80:80 running_page:latest

#访问
访问 ip:80 查看

```

## 替换 `src/utils/const.js` 文件中的 Mapbox token

> 建议有能力的同学把代码中的 Mapbox token 自己的 [Mapbox token](https://www.mapbox.com/)

```javascript
const MAPBOX_TOKEN =
'pk.eyJ1IjoieWlob25nMDYxOCIsImEiOiJja2J3M28xbG4wYzl0MzJxZm0ya2Fua2p2In0.PNKfkeQwYuyGOTT_x9BJ4Q';
```

### 如果你是海外用户请更改 `IS_CHINESE = false` in `src/utils/const.js`

## 一些个性化选项

- 在仓库目录下找到 `gatsby-config.js`,找到以下内容并修改成你自己想要的。

```javascript
siteMetadata: {
siteTitle: 'Running Page', #网站标题
siteUrl: 'https://yihong.run', #网站域名
logo: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQTtc69JxHNcmN1ETpMUX4dozAgAN6iPjWalQ&usqp=CAU', #左上角LOGO
description: 'Personal site and blog',
navLinks: [
{
name: 'Blog', #右上角导航名称
url: 'https://yihong.run/running', #右上角导航链接
},
{
name: 'About',
url: 'https://github.com/yihong0618/running_page/blob/master/README-CN.md',
},
],
},
```

- 修改 `src/utils/const.js` 文件中的样式:

```javascript
// styling: 关闭虚线:设置为 `false`
const USE_DASH_LINE = true;
// styling: 透明度:[0, 1]
const LINE_OPACITY = 0.4;
```

- 隐私保护:

设置下面环境变量:

```shell
IGNORE_START_END_RANGE = 200 # 忽略每个 polyline 的起点和终点的长度(单位:米)。

IGNORE_RANGE = 200 # 忽略下面 polyline 中每个点的距离的圆圈(单位:米)。
IGNORE_POLYLINE = ktjrFoemeU~IorGq}DeB # 包含要忽略的点的折线。

# 在保存到数据库之前进行过滤,你会丢失一些数据,但可以保护你的隐私,如果你使用的是公共仓库,建议设置为1。不设置可关闭。
IGNORE_BEFORE_SAVING = 1
```

你可一用[这个](https://developers.google.com/maps/documentation/utilities/polylineutility),来制作你的 `IGNORE_POLYLINE`。如果你在中国,请使用卫星图制作,避免火星坐标漂移。

## 下载您的 Nike Run Club/Strava/Garmin/Garmin-cn/Keep 数据,[别忘了在 `total` 页面生成可视化 SVG](#total-data-analysis)

### GPX

Make your GPX data

把其它软件生成的 gpx files 拷贝到 GPX_OUT 之后运行

```python
python3(python) scripts/gpx_sync.py
```

### TCX

Make your TCX data

把其它软件生成的 tcx files 拷贝到 TCX_OUT 之后运行

```python
python3(python) scripts/tcx_sync.py
```

### FIT

Make your FIT data

把其它软件生成的 fit files 拷贝到 FIT_OUT 之后运行

```python
python3(python) scripts/fit_sync.py
```

### Keep

获取您的 Keep 数据

> 确保自己的账号能用手机号 + 密码登陆 (不要忘记添加 secret 和更改自己的账号,在 GitHub Actions 中), 注:海外手机号需要换成国内 +86 的手机号

```python
python3(python) scripts/keep_sync.py ${your mobile} ${your password}
```

示例:

```python
python3(python) scripts/keep_sync.py 13333xxxx example
```

> 注:我增加了 keep 可以导出 gpx 功能(因 keep 的原因,距离和速度会有一定缺失), 执行如下命令,导出的 gpx 会加入到 GPX_OUT 中,方便上传到其它软件

```python
python3(python) scripts/keep_sync.py ${your mobile} ${your password} --with-gpx
```

示例:

```python
python3(python) scripts/keep_sync.py 13333xxxx example --with-gpx
```

路线偏移修正

如果您得到的运动路线与实际路线对比有整体偏移,可以修改代码中的参数进行修正

> 注:Keep 目前采用的是 GCJ-02 坐标系,因此导致得到运动数据在使用 WGS-84 坐标系的平台(Mapbox、佳明等)中显示轨迹整体偏移

- 修改 `scripts/keep_sync.py` 文件中的参数:

```python
# If your points need trans from gcj02 to wgs84 coordinate which use by Mappbox
TRANS_GCJ02_TO_WGS84 = True
```

### JoyRun(悦跑圈)

获取您的悦跑圈数据

获取登陆验证码:

确保自己的账号能用手机号 + 验证码登陆

点击获取验证码

> 注:不要在手机输入验证码,拿到验证码就好,用这个验证码放到下方命令中

![image](https://user-images.githubusercontent.com/15976103/102352588-e3af3000-3fe2-11eb-8131-14946b0262eb.png)

```python
python3(python) scripts/joyrun_sync.py ${your mobile} ${your 验证码}
```

示例:

```python
python3(python) scripts/joyrun_sync.py 13333xxxx xxxx
```

> 注:我增加了 joyrun 可以导出 gpx 功能,执行如下命令,导出的 gpx 会加入到 GPX_OUT 中,方便上传到其它软件

```python
python3(python) scripts/joyrun_sync.py ${your mobile} ${your 验证码} --with-gpx
```

示例:

```python
python3(python) scripts/joyrun_sync.py 13333xxxx example --with-gpx
```

> 注:因为验证码有过期时间,我增加了 cookie uid sid 登陆的方式,uid 及 sid 在您登陆过程中会在控制台打印出来

![image](https://user-images.githubusercontent.com/15976103/102354069-05a9b200-3fe5-11eb-9b30-221c32bbc607.png)

示例:

```python
python3(python) scripts/joyrun_sync.py 1393xx30xxxx 97e5fe4997d20f9b1007xxxxx --from-uid-sid --with-gpx
```

### Codoon(咕咚)

获取您的咕咚数据

```python
python3(python) scripts/codoon_sync.py ${your mobile or email} ${your password}
```

示例:

```python
python3(python) scripts/codoon_sync.py 13333xxxx xxxx
```

> 注:我增加了 Codoon 可以导出 gpx 功能,执行如下命令,导出的 gpx 会加入到 GPX_OUT 中,方便上传到其它软件

```python
python3(python) scripts/codoon_sync.py ${your mobile or email} ${your password} --with-gpx
```

示例:

```python
python3(python) scripts/codoon_sync.py 13333xxxx xxxx --with-gpx
```

> 注:因为登录 token 有过期时间限制,我增加了 refresh_token&user_id 登陆的方式,refresh_token 及 user_id 在您登陆过程中会在控制台打印出来

![image](https://user-images.githubusercontent.com/6956444/105690972-9efaab00-5f37-11eb-905c-65a198ad2300.png)

示例:

```python
python3(python) scripts/codoon_sync.py 54bxxxxxxx fefxxxxx-xxxx-xxxx --from-auth-token
```

路线偏移修正

如果您得到的运动路线与实际路线对比有整体偏移,可以修改代码中的参数进行修正

> 注:咕咚最初采用 GCJ-02 坐标系,在 2014 年 3 月份左右升级为 WGS-84 坐标系,导致升级之前的运动数据在使用 WGS-84 坐标系的平台(Mapbox、佳明等)中显示轨迹整体偏移

- 修改 `scripts/codoon_sync.py` 文件中的参数:

> 注:TRANS_END_DATE 需要根据您的实际情况设定,程序会修正这一天之前的运动记录

```python
# If your points need trans from gcj02 to wgs84 coordinate which use by Mappbox
TRANS_GCJ02_TO_WGS84 = True
# trans the coordinate data until the TRANS_END_DATE, work with TRANS_GCJ02_TO_WGS84 = True
TRANS_END_DATE = "2014-03-24"
```

### TulipSport

获取您的郁金香运动数据

> 郁金香运动数据的获取方式采用开放平台授权模式,通过访问[RunningPage 授权页面](https://tulipsport.rdshoep.com)获取账号 TOKEN(不会过期,只能访问 2021 年之后的数据),并在仓库的 GitHub Actions 环境配置中添加`TULIPSPORT_TOKEN`配置。

```python
python3(python) scripts/tulipsport_sync.py ${tulipsport_token}
```

示例:

```python
python3(python) scripts/tulipsport_sync.py nLgy****RyahI
```

### Garmin

获取您的 Garmin 数据


如果你只想同步跑步数据增加命令 --only-run

如果你想同步 `tcx` 格式,增加命令 --tcx

如果你想同步 `fit` 格式,增加命令 --fit

```python
python3(python) scripts/garmin_sync.py ${your email} ${your password}
```

示例:

```python
python3(python) scripts/garmin_sync.py [email protected] example
```

### Garmin-CN (大陆用户请用这个)

获取您的 Garmin-CN 数据

如果你只想同步跑步数据请增加 --only-run

如果你想同步 `tcx` 格式,增加命令 --tcx

如果你想同步 `fit` 格式,增加命令 --fit

```python
python3(python) scripts/garmin_sync.py ${your email} ${your password} --is-cn
```

示例:

```python
python3(python) scripts/garmin_sync.py [email protected] example --is-cn
```

仅同步跑步数据:

```python
python3(python) scripts/garmin_sync.py [email protected] example --is-cn --only-run
```

### Nike Run Club

获取 Nike Run Club 数据

> 请注意:当您选择将 running_page 部署在自己的服务器上时,由于 Nike 已经封禁了一部分 IDC 的服务器 IP 段,您的服务器可能不能正常同步 Nike Run Club 的数据并显示 `403 error` ,这时您将不得不选择其他的托管方式。

获取 Nike 的 refresh_token

1. 登录 [Nike](https://www.nike.com) 官网
2. In Developer -> Application-> Storage -> https:unite.nike.com 中找到 refresh_token

![image](https://user-images.githubusercontent.com/15976103/94448123-23812b00-01dd-11eb-8143-4b0839c31d90.png) 3. 在项目根目录下执行:

```python
python3(python) scripts/nike_sync.py ${nike refresh_token}
```

示例:

```python
python3(python) scripts/nike_sync.py eyJhbGciThiMTItNGIw******
```

![example img](https://raw.githubusercontent.com/shaonianche/gallery/master/running_page/nike_sync_%20example.png)

### Strava

获取 Strava 数据

1. 注册/登陆 [Strava](https://www.strava.com/) 账号
2. 登陆成功后打开 [Strava Developers](http://developers.strava.com) -> [Create & Manage Your App](https://strava.com/settings/api)

3. 创建 `My API Application`
输入下列信息:
![My API Application](https://raw.githubusercontent.com/shaonianche/gallery/master/running_page/strava_settings_api.png)
创建成功:
![](https://raw.githubusercontent.com/shaonianche/gallery/master/running_page/created_successfully_1.png)
4. 使用以下链接请求所有权限
将 ${your_id} 替换为 My API Application 中的 Client ID 后访问完整链接

```
https://www.strava.com/oauth/authorize?client_id=${your_id}&response_type=code&redirect_uri=http://localhost/exchange_token&approval_prompt=force&scope=read_all,profile:read_all,activity:read_all,profile:write,activity:write
```

![get_all_permissions](https://raw.githubusercontent.com/shaonianche/gallery/master/running_page/get_all_permissions.png)

5. 提取授权后返回链接中的 code 值
例如:

```
http://localhost/exchange_token?state=&code=1dab37edd9970971fb502c9efdd087f4f3471e6e&scope=read,activity:write,activity:read_all,profile:write,profile:read_all,read_all
```

`code` 数值为:

```
1dab37edd9970971fb502c9efdd087f4f3471e6
```

![get_code](https://raw.githubusercontent.com/shaonianche/gallery/master/running_page/get_code.png) 6. 使用 Client_id、Client_secret、Code 请求 refresh_token
在 `终端/iTerm` 中执行:

```
curl -X POST https://www.strava.com/oauth/token \
-F client_id=${Your Client ID} \
-F client_secret=${Your Client Secret} \
-F code=${Your Code} \
-F grant_type=authorization_code
```

示例:

```
curl -X POST https://www.strava.com/oauth/token \
-F client_id=12345 \
-F client_secret=b21******d0bfb377998ed1ac3b0 \
-F code=d09******b58abface48003 \
-F grant_type=authorization_code
```

![get_refresh_token](https://raw.githubusercontent.com/shaonianche/gallery/master/running_page/get_refresh_token.png)

7. 同步数据至 Strava
在项目根目录执行:

> 第一次同步 Strava 数据时需要更改在 strava_sync.py 中的第 12 行代码 False 改为 True,运行完成后,再改为 False。

如果你只想同步跑步数据增加命令 --only-run
```python
python3(python) scripts/strava_sync.py ${client_id} ${client_secret} ${refresh_token}
```

其他资料参见

### TCX_to_Strava

上传所有的 tcx 格式的跑步数据到 strava


1. 完成 strava 的步骤
2. 把 tcx 文件全部拷贝到 TCX_OUT 中
3. 在项目根目录下执行:

```python
python3(python) scripts/tcx_to_strava_sync.py ${client_id} ${client_secret} ${strava_refresh_token}
```

示例:

```python
python3(python) scripts/tcx_to_strava_sync.py xxx xxx xxx

python3(python) scripts/tcx_to_strava_sync.py xxx xxx xxx --all
```

4. 如果你已经上传过需要跳过判断增加参数 `--all`

### GPX_to_Strava

上传所有的 gpx 格式的跑步数据到 strava


1. 完成 strava 的步骤
2. 把 gpx 文件全部拷贝到 GPX_OUT 中
3. 在项目根目录下执行:

```python
python3(python) scripts/gpx_to_strava_sync.py ${client_id} ${client_secret} ${strava_refresh_token}
```

示例:

```python
python3(python) scripts/gpx_to_strava_sync.py xxx xxx xxx

python3(python) scripts/gpx_to_strava_sync.py xxx xxx xxx --all
```

3. 如果你已经上传过需要跳过判断增加参数 `--all`

### Nike+Strava

获取 Nike Run Club 的跑步数据然后同步到 Strava


1. 完成 nike 和 strava 的步骤
2. 在项目根目录下执行:

```python
python3(python) scripts/nike_to_strava_sync.py ${nike_refresh_token} ${client_id} ${client_secret} ${strava_refresh_token}
```

示例:

```python
python3(python) scripts/nike_to_strava_sync.py eyJhbGciThiMTItNGIw****** xxx xxx xxx
```

### Garmin_to_Strava

获取你的佳明 的跑步数据,然后同步到 Strava


1. 完成 garmin 和 strava 的步骤
2. 在项目根目录下执行:

```python
python3(python) scripts/garmin_to_strava_sync.py ${client_id} ${client_secret} ${strava_refresh_token} ${garmin_email} ${garmin_password} --is-cn
```

示例:

```python
python3(python) scripts/garmin_to_strava_sync.py xxx xxx xxx xx xxx
```

### Strava_to_Garmin

获取你的Strava 的跑步数据然后同步到 Garmin


1. 完成 garmin 和 strava 的步骤,同时,还需要在 Github Actions secret 那新增 Strava 配置:`secrets.STRAVA_EMAIL`、`secrets.STRAVA_PASSWORD`
2. 在项目根目录下执行:

```python
python3(python) scripts/strava_to_garmin_sync.py ${{ secrets.STRAVA_CLIENT_ID }} ${{ secrets.STRAVA_CLIENT_SECRET }} ${{ secrets.STRAVA_CLIENT_REFRESH_TOKEN }} ${{ secrets.GARMIN_EMAIL }} ${{ secrets.GARMIN_PASSWORD }} ${{ secrets.STRAVA_EMAIL }} ${{ secrets.STRAVA_PASSWORD }}
```

如果你的佳明账号是中国区,执行如下的命令:

```python
python3(python) scripts/strava_to_garmin_sync.py ${{ secrets.STRAVA_CLIENT_ID }} ${{ secrets.STRAVA_CLIENT_SECRET }} ${{ secrets.STRAVA_CLIENT_REFRESH_TOKEN }} ${{ secrets.GARMIN_CN_EMAIL }} ${{ secrets.GARMIN_CN_PASSWORD }} ${{ secrets.STRAVA_EMAIL }} ${{ secrets.STRAVA_PASSWORD }} --is-cn
```

如果要在同步到Garmin的运动记录中添加Garmin设备信息,需要添加`--use_fake_garmin_device`参数,这将在同步的Garmin锻炼记录中添加一个Garmin设备(默认情况下为 `Garmin Forerunner 245`,您可以在`garmin_device_adaptor.py`中更改设备信息),运动记录中有了设备信息之后就可以同步到其他APP中,比如数字心动(攒上马积分)这类不能通过Apple Watch同步的APP,当然也可以同步到Keep,悦跑圈,咕咚等APP。

image

最终执行的命令如下:

```python
python3(python) scripts/strava_to_garmin_sync.py ${{ secrets.STRAVA_CLIENT_ID }} ${{ secrets.STRAVA_CLIENT_SECRET }} ${{ secrets.STRAVA_CLIENT_REFRESH_TOKEN }} ${{ secrets.GARMIN_CN_EMAIL }} ${{ secrets.GARMIN_CN_PASSWORD }} ${{ secrets.STRAVA_EMAIL }} ${{ secrets.STRAVA_PASSWORD }} --use_fake_garmin_device
```

注意:**首次初始化的时候,如果你有大量的 strava 跑步数据,可能有些数据会上传失败,只需要多重试几次即可。**

### Total Data Analysis

生成数据展示

- 生成数据展示 SVG
- 展示效果:[点击查看](https://raw.githubusercontent.com/yihong0618/running_page/master/assets/github.svg)、[点击查看](https://raw.githubusercontent.com/yihong0618/running_page/28fa801e4e30f30af5ae3dc906bf085daa137936/assets/grid.svg)

> 注:感兴趣的同学可以改下方参数 (--special-distance 10 --special-distance2 20, 10km~20km 展示为 special-color1 20km 以上展示为 special-color2, --min-distance 10.0 用来筛选 10km 以上的)

```
python3(python) scripts/gen_svg.py --from-db --title "${{ env.TITLE }}" --type github --athlete "${{ env.ATHLETE }}" --special-distance 10 --special-distance2 20 --special-color yellow --special-color2 red --output assets/github.svg --use-localtime --min-distance 0.5
```

```
python3(python) scripts/gen_svg.py --from-db --title "${{ env.TITLE_GRID }}" --type grid --athlete "${{ env.ATHLETE }}" --output assets/grid.svg --min-distance 10.0 --special-color yellow --special-color2 red --special-distance 20 --special-distance2 40 --use-localtime
```

生成年度环形数据

```
python3(python) scripts/gen_svg.py --from-db --type circular --use-localtime
```

更多展示效果参见:

## server(recommend vercel)

使用 Vercel 部署

1. vercel 连接你的 GitHub repo

![image](https://user-images.githubusercontent.com/15976103/94452465-2599b880-01e2-11eb-9538-582f0f46c421.png)

2. import repo

![image](https://user-images.githubusercontent.com/15976103/94452556-3f3b0000-01e2-11eb-97a2-3789c2d60766.png)

2. 等待部署完毕
3. 访问

使用 Cloudflare 部署

1. 在 `Pages` 中点击 `Create a project` 以连接到你的仓库

2. 点击 `Begin setup` 后,修改项目的 `Build settings`。

3. 在 `Framework preset` 中选择 `Gatsby` 框架。

4. 向下滚动,点击 `Environment variables` 修改变量如下:

> Variable name = `PYTHON_VERSION`, Value = `3.7`

5. 点击 `Save and Deploy`,完成部署。

部署到 GitHub Pages

1. 为 GitHub Actions 添加代码提交权限
访问仓库的 `Settings > Actions > General`页面,找到`Workflow permissions`的设置项,将选项配置为`Read and write permissions`,支持 CI 将运动数据更新后提交到仓库中。
2. 更新配置并提交代码
1. 更新[./gatsby-config.js](./gatsby-config.js#L3)中的`siteMetadata`节点;
(按需)如果启用自定义域名模式或者变更 Fork 后的仓库名称,请变更`pathPrefix`的值。
2. 更新 GitHub CI 的配置 [.github/workflows/run_data_sync.yml](.github/workflows/run_data_sync.yml#L24) 中的配置;
3. (按需)如需使用自定义域名,可以修改 [.github/workflows/gh-pages.yml](.github/workflows/gh-pages.yml#L60) 中的 `fqdn`(默认已注释掉)
4. 在仓库的`Settings > Secrets and variables > Actions`页面添加对应服务的环境配置信息,参考不同平台[配置](#支持)。
3. 同步数据并发布 GitHub Pages
1. 手动触发`Run Data Sync`的 Github Action 完成数据同步,完成后会自动触发`Publish GitHub Pages`的任务执行,等待执行完成;
2. 开通仓库 GitHub Pages 功能,选择`gh-pages`分支和`/(root)`目录。

## GitHub Actions (Fork 的同学请一定不要忘了把 GitHub Token 改成自己的,否则会 push 到我的 repo 中,谢谢大家。)

修改 GitHub Actions Token

Actions [源码](https://github.com/yihong0618/running_page/blob/master/.github/workflows/run_data_sync.yml)
需要做如下步骤

1. 更改成你的 app type 及 info
![image](https://user-images.githubusercontent.com/15976103/94450124-73f98800-01df-11eb-9b3c-ac1a6224f46f.png)

2. 在 repo Settings > Secrets 中增加你的 secret (只添加你需要的即可)

![image](https://user-images.githubusercontent.com/15976103/94450295-aacf9e00-01df-11eb-80b7-a92b9cd1461e.png)
我的 secret 如下
![image](https://user-images.githubusercontent.com/15976103/94451037-8922e680-01e0-11eb-9bb9-729f0eadcdb7.png)

## 把数据文件放在github cache中

把数据文件放在github cache中

`run_data_sync.yml`中的`SAVE_DATA_IN_GITHUB_CACHE`设置为`true`时,可以把脚本抓取和中间产生的数据文件放到github action cache中。这样可以让你的github commit历史和目录保持干净。

如果你用github pages部署建议把这个值设置成`true`。

如果你使用`Vervel`,需要在vercel后台进行下面几步操作:

1. 在`General`的`Build & Development Settings`的Framework Preset选择Other,然后把override全部打开,命令行内容全部设置成空。

![General](https://user-images.githubusercontent.com/413855/255507920-76932fb9-61d6-423e-92e2-2e92b5bbd432.png)

2. 在Git模块中,`Production Branch`的Branch name填入`gh-pages`

![Branch name](https://user-images.githubusercontent.com/413855/255508137-ef742815-8418-419a-86b4-6756ff68e1db.png)

3. `run_data_sync.yml`中的`BUILD_GH_PAGES`设置为`true`

# Fit 文件

测试发现,不同厂商在写fit文件的时候有略微差异。

已调试设备:

- [x] 佳明手表
- [x] 迈金码表

如果发现自己的fit文件解析有问题。可以提issue。

# TODO

- [x] 完善这个文档
- [x] 支持佳明,佳明中国
- [x] 支持 keep
- [ ] 支持苹果自带运动
- [x] 支持 nike + strava
- [x] 支持咕咚
- [ ] 尝试支持小米运动
- [x] 支持英语
- [x] 完善代码
- [x] 清理整个项目
- [x] 完善前端代码
- [x] better actions
- [ ] tests
- [ ] 支持不同的运动类型

# 参与项目

- 任何 Issues PR 均欢迎。
- 可以提交 PR share 自己的 Running page 在 README 中。

提交 PR 前:

- 使用 black 对 Python 代码进行格式化。(`black .`)

# 特别感谢

- @[flopp](https://github.com/flopp) 特别棒的项目 [GpxTrackPoster](https://github.com/flopp/GpxTrackPoster)
- @[danpalmer](https://github.com/danpalmer) 原始的 UI 设计
- @[shaonianche](https://github.com/shaonianche) icon 设计及文档
- @[geekplux](https://github.com/geekplux) 帮助及鼓励,重构了前端代码,学到了不少
- @[ben-29](https://github.com/ben-29) 搞定了咕咚,和我一起搞定了悦跑圈,太厉害了
- @[MFYDev](https://github.com/MFYDev) Wiki

# 推荐的 Forks

- @[gongzili456](https://github.com/gongzili456) for [摩托车骑行版本](https://github.com/gongzili456/running_page)
- @[ben-29](https://github.com/ben-29) for [多种运动类型支持](https://github.com/ben-29/workouts_page)
- @[geekplux](https://github.com/geekplux) for [多种运动类型支持](https://github.com/geekplux/activities)

# 赞赏

谢谢就够了

# FAQ

### Strava 100 每 15 分钟的请求,1000 每日限制

等待时间限制(这里是 strava 接口请求限制),不要关闭终端,这里会自动执行下一组上传数据

```
Strava API Rate Limit Exceeded. Retry after 100 seconds
Strava API Rate Limit Timeout. Retry in 799.491622 seconds
```