Skip to content

Commit

Permalink
Merge pull request #132 from jrast/store-garth-session
Browse files Browse the repository at this point in the history
Store the garth session information and upload the fit file via garth
  • Loading branch information
longstone authored Oct 2, 2023
2 parents d281331 + 8febfe5 commit 23c9eeb
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 20 deletions.
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
lxml
requests
cloudscraper
garth
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def read(fname):
"Topic :: Utilities",
"License :: OSI Approved :: MIT License",
],
install_requires=["lxml", "requests", "cloudscraper", "garth"],
install_requires=["lxml", "requests", "garth"],
entry_points={
"console_scripts": ["withings-sync=withings_sync.sync:main"],
},
Expand Down
34 changes: 18 additions & 16 deletions withings_sync/garmin.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
"""This module handles the Garmin connectivity."""
import logging
import cloudscraper
import garth

import os

log = logging.getLogger("garmin")

Expand All @@ -22,31 +21,34 @@ class APIException(Exception):
class GarminConnect:
"""Main GarminConnect class"""

UPLOAD_URL = "https://connect.garmin.com/upload-service/upload/.fit"

# From https://github.com/cpfair/tapiriik
@staticmethod
def get_session(email=None, password=None):
"""tapiriik get_session code"""
session = cloudscraper.CloudScraper()

try:
garth.login(email, password)
except Exception as ex:
raise APIException("Authentication failure: {}. Did you enter correct credentials?".format(ex))
logged_in = False
if os.path.exists('./garmin_session'):
garth.resume('./garmin_session')
try:
garth.client.username
logged_in = True
except Exception:
pass

if not logged_in:
try:
garth.login(email, password)
garth.save('./garmin_session')
except Exception as ex:
raise APIException("Authentication failure: {}. Did you enter correct credentials?".format(ex))

session.headers.update({'NK': 'NT', 'authorization': garth.client.oauth2_token.__str__(), 'di-backend': 'connectapi.garmin.com'})
return session

@staticmethod
def login(username, password):
"""login to Garmin"""
return GarminConnect.get_session(email=username, password=password)

def upload_file(self, ffile, session):
def upload_file(self, ffile):
"""upload fit file to Garmin connect"""
files = {"data": ("withings.fit", ffile)}
res = session.post(self.UPLOAD_URL, files=files, headers={"nk": "NT"})
res = garth.client.post('connect', '/upload-service/upload/.fit', files=files, api=True, headers={'di-backend': 'connectapi.garmin.com'})
try:
resp = res.json()
if "detailedImportResult" not in resp:
Expand Down
4 changes: 2 additions & 2 deletions withings_sync/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,8 @@ def date_parser(date_string):
def sync_garmin(fit_file):
"""Sync generated fit file to Garmin Connect"""
garmin = GarminConnect()
session = garmin.login(ARGS.garmin_username, ARGS.garmin_password)
return garmin.upload_file(fit_file.getvalue(), session)
garmin.login(ARGS.garmin_username, ARGS.garmin_password)
return garmin.upload_file(fit_file.getvalue())


def sync_trainerroad(last_weight):
Expand Down

0 comments on commit 23c9eeb

Please sign in to comment.