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:support for download Garmin fit file #446

Merged
merged 2 commits into from
Jul 7, 2023
Merged
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
Empty file added FIT_OUT/.gitkeep
Empty file.
9 changes: 8 additions & 1 deletion README-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -427,8 +427,11 @@ python3(python) scripts/tulipsport_sync.py nLgy****RyahI
<summary>获取您的 Garmin 数据</summary>
<br>
如果你只想同步跑步数据增加命令 --only-run

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

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

```python
python3(python) scripts/garmin_sync.py ${your email} ${your password}
```
Expand All @@ -446,7 +449,11 @@ python3(python) scripts/garmin_sync.py example@gmail.com example
<details>
<summary>获取您的 Garmin-CN 数据</summary>

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

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

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

```python
python3(python) scripts/garmin_sync.py ${your email} ${your password} --is-cn
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,11 @@ python3(python) scripts/tcx_sync.py
<summary>Get your <code>Garmin</code> data</summary>
<br>
If you only want to sync `type running` add args --only-run

If you only want `tcx` files add args --tcx

If you only want `fit` files add args --fit

```python
python3(python) scripts/garmin_sync.py ${your email} ${your password}
```
Expand All @@ -270,8 +273,11 @@ python3(python) scripts/garmin_sync.py example@gmail.com example --only-run
<summary>Get your <code>Garmin-CN</code> data</summary>
<br>
If you only want to sync `type running` add args --only-run

If you only want `tcx` files add args --tcx

If you only want `fit` files add args --fit

```python
python3(python) scripts/garmin_sync.py ${your email} ${your password} --is-cn
```
Expand Down
2 changes: 2 additions & 0 deletions scripts/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
OUTPUT_DIR = os.path.join(parent, "activities")
GPX_FOLDER = os.path.join(parent, "GPX_OUT")
TCX_FOLDER = os.path.join(parent, "TCX_OUT")
FIT_FOLDER = os.path.join(parent, "FIT_OUT")
ENDOMONDO_FILE_DIR = os.path.join(parent, "Workouts")
FOLDER_DICT = {
"gpx": GPX_FOLDER,
"tcx": TCX_FOLDER,
"fit": FIT_FOLDER,
}
SQL_FILE = os.path.join(parent, "scripts", "data.db")
JSON_FILE = os.path.join(parent, "src", "static", "activities.json")
Expand Down
26 changes: 26 additions & 0 deletions scripts/garmin_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import sys
import time
import traceback
import zipfile

import aiofiles
import cloudscraper
Expand Down Expand Up @@ -182,6 +183,10 @@ async def get_activities(self, start, limit):

async def download_activity(self, activity_id, file_type="gpx"):
url = f"{self.modern_url}/proxy/download-service/export/{file_type}/activity/{activity_id}"
if file_type == "fit":
url = (
f"{self.modern_url}/proxy/download-service/files/activity/{activity_id}"
)
logger.info(f"Download activity from {url}")
response = await self.req.get(url, headers=self.headers)
response.raise_for_status()
Expand Down Expand Up @@ -295,8 +300,21 @@ async def download_garmin_data(client, activity_id, file_type="gpx"):
try:
file_data = await client.download_activity(activity_id, file_type=file_type)
file_path = os.path.join(folder, f"{activity_id}.{file_type}")
need_unzip = False
if file_type == "fit":
file_path = os.path.join(folder, f"{activity_id}.zip")
need_unzip = True
async with aiofiles.open(file_path, "wb") as fb:
await fb.write(file_data)
if need_unzip:
zip_file = zipfile.ZipFile(file_path, "r")
for file_info in zip_file.infolist():
zip_file.extract(file_info, folder)
os.rename(
os.path.join(folder, f"{activity_id}_ACTIVITY.fit"),
os.path.join(folder, f"{activity_id}.fit"),
)
os.remove(file_path)
except:
print(f"Failed to download activity {activity_id}: ")
traceback.print_exc()
Expand Down Expand Up @@ -375,6 +393,14 @@ async def download_new_activities(
default="gpx",
help="to download personal documents or ebook",
)
parser.add_argument(
"--fit",
dest="download_file_type",
action="store_const",
const="fit",
default="gpx",
help="to download personal documents or ebook",
)
options = parser.parse_args()
email = options.email or config("sync", "garmin", "email")
password = options.password or config("sync", "garmin", "password")
Expand Down