Skip to content

Commit

Permalink
Merge pull request #143 from jrast/garmin-upload-improvements
Browse files Browse the repository at this point in the history
Improved garmin upload by using new methods provided by garth
  • Loading branch information
longstone authored Oct 7, 2023
2 parents 383bf00 + 6166ef2 commit c0f9f8e
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 26 deletions.
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", "garth", "python-dotenv"],
install_requires=["lxml", "requests", "garth>=0.4.32", "python-dotenv"],
entry_points={
"console_scripts": ["withings-sync=withings_sync.sync:main"],
},
Expand Down
38 changes: 14 additions & 24 deletions withings_sync/garmin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import logging
import garth
import os
import io

log = logging.getLogger("garmin")

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

@staticmethod
def get_session(email=None, password=None):
def __init__(self) -> None:
self.client = garth.Client()

def login(self, email=None, password=None):
logged_in = False
if os.path.exists('./garmin_session'):
garth.resume('./garmin_session')
self.client.load('./garmin_session')
try:
garth.client.username
self.client.username
logged_in = True
except Exception:
pass

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


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

def upload_file(self, ffile):
"""upload fit file to Garmin connect"""
files = {"data": ("withings.fit", ffile)}
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:
raise KeyError
except (ValueError, KeyError):
if res.status_code == 204: # HTTP result 204 - 'no content'
log.error("No data to upload, try to use --fromdate and --todate")
else:
log.error("Bad response during GC upload: %s", res.status_code)

return res.status_code in [200, 201, 204]
# Convert the fitfile to a in-memory file for upload
fit_file = io.BytesIO(ffile.getvalue())
fit_file.name = 'withings.fit'
self.client.upload(fit_file)
return True
2 changes: 1 addition & 1 deletion withings_sync/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ def sync_garmin(fit_file):
"""Sync generated fit file to Garmin Connect"""
garmin = GarminConnect()
garmin.login(ARGS.garmin_username, ARGS.garmin_password)
return garmin.upload_file(fit_file.getvalue())
return garmin.upload_file(fit_file)


def sync_trainerroad(last_weight):
Expand Down

0 comments on commit c0f9f8e

Please sign in to comment.