Skip to content

Latest commit

 

History

History
901 lines (618 loc) · 32.5 KB

README-CN.md

File metadata and controls

901 lines (618 loc) · 32.5 KB

running_page

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

English | 简体中文 | Wiki

GIF 展示

running_page

Running page runners
Runner page App
zhubao315 https://zhubao315.github.io/running Strava
shaonianche https://run.duanfei.org Strava
yihong0618 https://yihong.run Nike
superleeyom https://running.leeyom.top Nike
geekplux https://activities.geekplux.com Nike
guanlan https://grun.vercel.app Strava
tuzimoe https://run.tuzi.moe Nike
ben_29 https://running.ben29.xyz Strava
kcllf https://running-tau.vercel.app Garmin-cn
mq https://running-iota.vercel.app Keep
zhaohongxuan https://zhaohongxuan.github.io/workouts Strava
yvetterowe https://run.haoluo.io Strava
love-exercise https://run.kai666666.top Keep
zstone12 https://running-page.zstone12.vercel.app Keep
Lax https://lax.github.io/running Keep
lusuzi https://running.lusuzi.vercel.app Nike
wh1994 https://run4life.fun Garmin
liuyihui https://run.foolishfox.cn Keep
sunyunxian https://sunyunxian.github.io/running_page Strava
AhianZhang https://running.ahianzhang.com Nike
L1cardo https://run.licardo.cn Nike
luckylele666 https://0000928.xyz Strava
MFYDev https://mfydev.run Garmin-cn
Oysmart https://run.ouyang.wang Garmin-cn
Eished https://run.iknow.fun Keep
Liuxin https://liuxin.run Nike
loucx https://loucx.github.io/running Nike
winf42 https://winf42.github.io Garmin-cn
sun0225SUN https://run.sunguoqi.com Nike
Zhan https://run.zlog.in Nike
Dennis https://run.domon.cn Garmin-cn
hanpei https://running.nexts.top Garmin-cn
liugezhou https://run.liugezhou.online Strava
zhubao315 https://zhubao315.github.io/running Strava
Jason Tan https://jason-cqtan.github.io/running_page Nike
Conge https://conge.github.io/running_page Strava
cvvz https://cvvz.github.io/running Strava
zHElEARN https://workouts.zhelearn.com Strava
Rhfeng https://sport.frh.life Garmin-cn
Ym9i https://bobrun.vercel.app/ Strava
jianchengwang https://jianchengwang.github.io/running_page Suunto
fxbin https://fxbin.github.io/sport-records/ Keep
shensl4499 https://waner.run codoon
haowei93 https://haowei93.github.io/ gpx
stevenash0822 https://run.imangry.xyz/ Strava
Vint https://vinton.store/Running/ Keep
Muyids https://muyids.github.io/running Garmin-cn
Gao Hao https://efish2002.github.io/running_page/ Garmin-cn
Jinlei https://jinlei.run/ AW-GPX
Ray Wang https://run.raywang.pro/ Garmin
RealTiny656 https://tiny656.github.io/running_page/ JoyRun
EINDEX https://workouts.eindex.me/ Strava/Nike
Melt https://running.autove.dev/ Strava
deepinwine https://deepin.autove.dev/ Garmin-cn

它是怎么工作的

image

特性

  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

支持

视频教程

下载

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

安装及测试 (node >= 12 and <= 14 python >= 3.7)

pip3 install -r requirements.txt
yarn install
yarn develop

访问 http://localhost:8000/ 查看

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

const MAPBOX_TOKEN =
  'pk.eyJ1IjoieWlob25nMDYxOCIsImEiOiJja2J3M28xbG4wYzl0MzJxZm0ya2Fua2p2In0.PNKfkeQwYuyGOTT_x9BJ4Q';

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

一些个性化选项

  • 在仓库目录下找到 gatsby-config.js,找到以下内容并修改成你自己想要的。
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 文件中的样式:
// styling: 关闭虚线:设置为 `false`
const USE_DASH_LINE = true;
// styling: 透明度:[0, 1]
const LINE_OPACITY = 0.4;
  • 隐私保护:

设置下面环境变量:

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

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

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

你可一用这个,来制作你的 IGNORE_POLYLINE。如果你在中国,请使用卫星图制作,避免火星坐标漂移。

下载您的 Nike Run Club/Strava/Garmin/Garmin-cn/Keep 数据,别忘了在 total 页面生成可视化 SVG

GPX

Make your GPX data

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

python3(python) scripts/gpx_sync.py

TCX

Make your TCX data

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

python3(python) scripts/tcx_sync.py

FIT

Make your FIT data

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

python3(python) scripts/fit_sync.py

Keep

获取您的 Keep 数据

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

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

示例:

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

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

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

示例:

python3(python) scripts/keep_sync.py 13333xxxx example --with-gpx
路线偏移修正

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

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

  • 修改 scripts/keep_sync.py 文件中的参数:
# If your points need trans from gcj02 to wgs84 coordinate which use by Mappbox
TRANS_GCJ02_TO_WGS84 = True

JoyRun(悦跑圈)

获取您的悦跑圈数据

获取登陆验证码:

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

点击获取验证码

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

image

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

示例:

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

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

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

示例:

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

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

image

示例:

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

Codoon(咕咚)

获取您的咕咚数据
python3(python) scripts/codoon_sync.py ${your mobile or email} ${your password}

示例:

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

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

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

示例:

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

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

image

示例:

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 需要根据您的实际情况设定,程序会修正这一天之前的运动记录

# 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 授权页面获取账号 TOKEN(不会过期,只能访问 2021 年之后的数据),并在仓库的 GitHub Actions 环境配置中添加TULIPSPORT_TOKEN配置。

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

示例:

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

Garmin

获取您的 Garmin 数据
如果你只想同步跑步数据增加命令 --only-run

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

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

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

示例:

python3(python) scripts/garmin_sync.py example@gmail.com example

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

获取您的 Garmin-CN 数据

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

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

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

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

示例:

python3(python) scripts/garmin_sync.py example@gmail.com example --is-cn

仅同步跑步数据:

python3(python) scripts/garmin_sync.py example@gmail.com 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 官网
  2. In Developer -> Application-> Storage -> https:unite.nike.com 中找到 refresh_token

image 3. 在项目根目录下执行:

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

示例:

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

example img

Strava

获取 Strava 数据
  1. 注册/登陆 Strava 账号

  2. 登陆成功后打开 Strava Developers -> Create & Manage Your App

  3. 创建 My API Application 输入下列信息: My API Application 创建成功:

  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

  1. 提取授权后返回链接中的 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 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

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

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

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

python3(python) scripts/strava_sync.py ${client_id} ${client_secret} ${refresh_token}

其他资料参见 https://developers.strava.com/docs/getting-started https://github.com/barrald/strava-uploader https://github.com/strava/go.strava

TCX_to_Strava

上传所有的 tcx 格式的跑步数据到 strava
  1. 完成 strava 的步骤
  2. 把 tcx 文件全部拷贝到 TCX_OUT 中
  3. 在项目根目录下执行:
python3(python) scripts/tcx_to_strava_sync.py ${client_id} ${client_secret} ${strava_refresh_token}

示例:

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

python3(python) scripts/tcx_to_strava_sync.py xxx xxx xxx --all
  1. 如果你已经上传过需要跳过判断增加参数 --all

GPX_to_Strava

上传所有的 gpx 格式的跑步数据到 strava
  1. 完成 strava 的步骤
  2. 把 gpx 文件全部拷贝到 GPX_OUT 中
  3. 在项目根目录下执行:
python3(python) scripts/gpx_to_strava_sync.py ${client_id} ${client_secret} ${strava_refresh_token}

示例:

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

python3(python) scripts/gpx_to_strava_sync.py xxx xxx xxx --all
  1. 如果你已经上传过需要跳过判断增加参数 --all

Nike+Strava

获取 Nike Run Club 的跑步数据然后同步到 Strava
  1. 完成 nike 和 strava 的步骤
  2. 在项目根目录下执行:
python3(python) scripts/nike_to_strava_sync.py ${nike_refresh_token} ${client_id} ${client_secret} ${strava_refresh_token}

示例:

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

Garmin_to_Strava

获取你的佳明 的跑步数据,然后同步到 Strava
  1. 完成 garmin 和 strava 的步骤
  2. 在项目根目录下执行:
python3(python) scripts/garmin_to_strava_sync.py  ${client_id} ${client_secret} ${strava_refresh_token} ${garmin_email} ${garmin_password} --is-cn

示例:

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_EMAILsecrets.STRAVA_PASSWORD
  2. 在项目根目录下执行:
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 }}

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

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

最终执行的命令如下:

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

生成数据展示

注:感兴趣的同学可以改下方参数 (--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

更多展示效果参见: https://github.com/flopp/GpxTrackPoster

server(recommend vercel)

使用 Vercel 部署
  1. vercel 连接你的 GitHub repo

image

  1. import repo

image

  1. 等待部署完毕
  2. 访问
使用 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中的siteMetadata节点; (按需)如果启用自定义域名模式或者变更 Fork 后的仓库名称,请变更pathPrefix的值。
    2. 更新 GitHub CI 的配置 .github/workflows/run_data_sync.yml 中的配置;
    3. (按需)如需使用自定义域名,可以修改 .github/workflows/gh-pages.yml 中的 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 源码 需要做如下步骤

  1. 更改成你的 app type 及 info image
  2. 在 repo Settings > Secrets 中增加你的 secret (只添加你需要的即可) image 我的 secret 如下 image

Fit 文件

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

已调试设备:

  • 佳明手表
  • 迈金码表

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

TODO

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

参与项目

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

提交 PR 前:

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

特别感谢

推荐的 Forks

赞赏

谢谢就够了

FAQ

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

https://www.strava.com/settings/api https://developers.strava.com/docs/#rate-limiting

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

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