Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Elevation Gain #719

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 6 additions & 1 deletion .github/workflows/run_data_sync.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ on:

env:
# please change to your own config.
RUN_TYPE: pass # support strava/nike/garmin/coros/garmin_cn/garmin_sync_cn_global/keep/only_gpx/only_fit/nike_to_strava/strava_to_garmin/tcx_to_garmin/strava_to_garmin_cn/garmin_to_strava/garmin_to_strava_cn/codoon/oppo, Please change the 'pass' it to your own
RUN_TYPE: pass # support strava/nike/garmin/coros/garmin_cn/garmin_sync_cn_global/keep/only_gpx/only_fit/nike_to_strava/strava_to_garmin/tcx_to_garmin/strava_to_garmin_cn/garmin_to_strava/garmin_to_strava_cn/codoon/oppo/db_updater, Please change the 'pass' it to your own
ATHLETE: yihong0618
TITLE: Yihong0618 Running
MIN_GRID_DISTANCE: 10 # change min distance here
Expand Down Expand Up @@ -202,6 +202,11 @@ jobs:
# If you want to sync fit activity in gpx format, please consider the following script:
# python run_page/oppo_sync.py ${{ secrets.OPPO_ID }} ${{ secrets.OPPO_CLIENT_SECRET }} ${{ secrets.OPPO_CLIENT_REFRESH_TOKEN }} --with-gpx

- name: Run db updater script to add "Elevation Gain" field to db
if: env.RUN_TYPE == 'db_updater'
run: |
python run_page/db_updater.py

- name: Make svg GitHub profile
if: env.RUN_TYPE != 'pass'
run: |
Expand Down
23 changes: 18 additions & 5 deletions README-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,23 @@
2. python3(python) in README means python3 python
3. use v2.0 need change vercel setting from gatsby to vite
4. 2023.09.26 garmin need secret_string(and in Actions) get

```bash
python run_page/get_garmin_secret.py ${email} ${password}
# if cn
python run_page/get_garmin_secret.py ${email} ${password} --is-cn
```

```bash
python run_page/get_garmin_secret.py ${email} ${password}
# if cn
python run_page/get_garmin_secret.py ${email} ${password} --is-cn
```
5. 2024.09.29: Added `Elevation Gain` field, If you forked the project before this update, please run the following command:
- To resolve errors: `sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such column: activities.elevation_gain`
- If you don't have a local environment, set `RUN_TYPE` to `db_updater` in the `.github/workflows/run_data_sync.yml` file once then change back.

```bash
python run_page/db_updater.py
```
- For old data: To include `Elevation Gain` for past activities, perform a full reimport.
- To show the 'Elevation Gain' column, modify `SHOW_ELEVATION_GAIN` in `src/utils/const.ts`
- note: `Elevation Gain` may be inaccurate. You can use Strava's "Correct Elevation" or Garmin's "Elev Corrections" feature for more precise data.

![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)

Expand Down Expand Up @@ -251,6 +262,8 @@ const LINE_OPACITY = 0.4;
const PRIVACY_MODE = false;
// styling: 默认关灯: 设置为 `false`, 仅在隐私模式关闭时生效(`PRIVACY_MODE` = false)
const LIGHTS_ON = true;
// styling: 是否显示列 ELEVATION_GAIN
const SHOW_ELEVATION_GAIN = false;
```

> 隐私保护:设置下面环境变量:
Expand Down
26 changes: 19 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,23 @@
1. clone or Fork before vercel 404 need to pull the latest code
2. python3(python) in README means python3 python
3. use v2.0 need change vercel setting from gatsby to vite
4. 2023.09.26 garmin need secret_string(and in Actions) get

```bash
python run_page/get_garmin_secret.py ${email} ${password}
# if cn
python run_page/get_garmin_secret.py ${email} ${password} --is-cn
```
4. 2023.09.26 garmin need secret_string(and in Actions) get
```bash
python run_page/get_garmin_secret.py ${email} ${password}
# if cn
python run_page/get_garmin_secret.py ${email} ${password} --is-cn
```

5. 2024.09.29: Added `Elevation Gain` field, If you forked the project before this update, please run the following command:
- To resolve errors: `sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such column: activities.elevation_gain`
- If you don't have a local environment, set `RUN_TYPE` to `db_updater` in the `.github/workflows/run_data_sync.yml` file once then change back.

```bash
python run_page/db_updater.py
```
- For old data: To include `Elevation Gain` for past activities, perform a full reimport.
- To show the 'Elevation Gain' column, modify `SHOW_ELEVATION_GAIN` in `src/utils/const.ts`
- note: `Elevation Gain` may be inaccurate. You can use Strava's "Correct Elevation" or Garmin's "Elev Corrections" feature for more precise data.

<p align="center">
<img width="150" src="https://raw.githubusercontent.com/shaonianche/gallery/master/running_page/running_page_logo.png" />
Expand Down Expand Up @@ -235,6 +245,8 @@ const LINE_OPACITY = 0.4;
const PRIVACY_MODE = false;
// styling: set to `false` if you want to make light off as default, only effect when `PRIVACY_MODE` = false
const LIGHTS_ON = true;
// set to `true` if you want to show the 'Elevation Gain' column
const SHOW_ELEVATION_GAIN = true;
```

- To use Google Analytics, you need to modify the configuration in the `src/utils/const.ts` file.
Expand Down
16 changes: 10 additions & 6 deletions run_page/codoon_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ def parse_points_to_gpx(self, run_points_data):
for p in points_dict_list:
point = gpxpy.gpx.GPXTrackPoint(**p)
gpx_segment.points.append(point)
return gpx.to_xml()
return gpx

def get_single_run_record(self, route_id):
print(f"Get single run for codoon id {route_id}")
Expand Down Expand Up @@ -528,11 +528,14 @@ def parse_raw_data_to_namedtuple(
p["latitude"] = latlng_data[i][0]
p["longitude"] = latlng_data[i][1]

if with_gpx:
# pass the track no points
if str(log_id) not in old_gpx_ids and run_points_data:
gpx_data = self.parse_points_to_gpx(run_points_data)
download_codoon_gpx(gpx_data, str(log_id))
elevation_gain = None
if run_points_data:
gpx_data = self.parse_points_to_gpx(run_points_data)
elevation_gain = gpx_data.get_uphill_downhill().uphill
if with_gpx:
# pass the track no points
if str(log_id) not in old_gpx_ids:
download_codoon_gpx(gpx_data.to_xml(), str(log_id))
heart_rate_dict = run_data.get("heart_rate")
heart_rate = None
if heart_rate_dict:
Expand Down Expand Up @@ -569,6 +572,7 @@ def parse_raw_data_to_namedtuple(
seconds=int((end_date.timestamp() - start_date.timestamp()))
),
"average_speed": run_data["total_length"] / run_data["total_time"],
"elevation_gain": elevation_gain,
"location_country": location_country,
"source": "Codoon",
}
Expand Down
25 changes: 25 additions & 0 deletions run_page/db_updater.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from generator.db import init_db, Activity
from config import SQL_FILE
import sqlalchemy
from sqlalchemy import text
from config import GPX_FOLDER, JSON_FILE, SQL_FILE
from utils import make_activities_file


def add_column_elevation_gain(session):
# check if column elevation_gain is already added
# if not add it to the db
try:
session.query(Activity).first()
print("column elevation_gain already added, skipping")
except sqlalchemy.exc.OperationalError:
sql_statement = 'alter TABLE "activities" add column elevation_gain Float after average_heartrate'
session.execute(text(sql_statement))
print("column elevation_gain added successfully")


if __name__ == "__main__":
session = init_db(SQL_FILE)
add_column_elevation_gain(session)
# regenerate activities
make_activities_file(SQL_FILE, GPX_FOLDER, JSON_FILE)
1 change: 1 addition & 0 deletions run_page/endomondo_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ def parse_run_endomondo_to_nametuple(en_dict):
"average_speed": en_dict.get("distance_km", 0)
/ en_dict.get("duration_s", 1)
* 1000,
"elevation_gain": None,
"location_country": "",
}
return namedtuple("x", d.keys())(*d.values())
Expand Down
2 changes: 2 additions & 0 deletions run_page/generator/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ def sync(self, force):
activity.map.summary_polyline = filter_out(
activity.map.summary_polyline
)
# strava use total_elevation_gain as elevation_gain
activity.elevation_gain = activity.total_elevation_gain
created = update_or_create_activity(self.session, activity)
if created:
sys.stdout.write("+")
Expand Down
4 changes: 4 additions & 0 deletions run_page/generator/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ def randomword():
"summary_polyline",
"average_heartrate",
"average_speed",
"elevation_gain",
]


Expand All @@ -53,6 +54,7 @@ class Activity(Base):
summary_polyline = Column(String)
average_heartrate = Column(Float)
average_speed = Column(Float)
elevation_gain = Column(Float)
streak = None

def to_dict(self):
Expand Down Expand Up @@ -111,6 +113,7 @@ def update_or_create_activity(session, run_activity):
location_country=location_country,
average_heartrate=run_activity.average_heartrate,
average_speed=float(run_activity.average_speed),
elevation_gain=float(run_activity.elevation_gain),
summary_polyline=(
run_activity.map and run_activity.map.summary_polyline or ""
),
Expand All @@ -125,6 +128,7 @@ def update_or_create_activity(session, run_activity):
activity.type = run_activity.type
activity.average_heartrate = run_activity.average_heartrate
activity.average_speed = float(run_activity.average_speed)
activity.elevation_gain = float(run_activity.elevation_gain)
activity.summary_polyline = (
run_activity.map and run_activity.map.summary_polyline or ""
)
Expand Down
11 changes: 11 additions & 0 deletions run_page/gpxtrackposter/track.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ def __init__(self):
self.length = 0
self.special = False
self.average_heartrate = None
self.elevation_gain = None
self.moving_dict = {}
self.run_id = 0
self.start_latlng = []
Expand Down Expand Up @@ -166,6 +167,7 @@ def _load_tcx_data(self, tcx, file_name):
except:
pass
self.polyline_str = polyline.encode(polyline_container)
self.elevation_gain = tcx.ascent
self.moving_dict = {
"distance": self.length,
"moving_time": datetime.timedelta(seconds=moving_time),
Expand Down Expand Up @@ -229,6 +231,7 @@ def _load_gpx_data(self, gpx):
sum(heart_rate_list) / len(heart_rate_list) if heart_rate_list else None
)
self.moving_dict = self._get_moving_data(gpx)
self.elevation_gain = gpx.get_uphill_downhill().uphill

def _load_fit_data(self, fit: dict):
_polylines = []
Expand All @@ -246,6 +249,9 @@ def _load_fit_data(self, fit: dict):
self.average_heartrate = (
message["avg_heart_rate"] if "avg_heart_rate" in message else None
)
self.elevation_gain = (
message["total_ascent"] if "total_ascent" in message else None
)
self.type = message["sport"].lower()

# moving_dict
Expand Down Expand Up @@ -308,6 +314,10 @@ def append(self, other):
)
self.file_names.extend(other.file_names)
self.special = self.special or other.special
self.average_heartrate = self.average_heartrate or other.average_heartrate
self.elevation_gain = (
self.elevation_gain if self.elevation_gain else 0
) + (other.elevation_gain if other.elevation_gain else 0)
except:
print(
f"something wrong append this {self.end_time},in files {str(self.file_names)}"
Expand Down Expand Up @@ -347,6 +357,7 @@ def to_namedtuple(self, run_from="gpx"):
"average_heartrate": (
int(self.average_heartrate) if self.average_heartrate else None
),
"elevation_gain": (int(self.elevation_gain) if self.elevation_gain else 0),
"map": run_map(self.polyline_str),
"start_latlng": self.start_latlng,
}
Expand Down
Loading