diff --git a/README.md b/README.md index 3f2e0b8..0966a27 100644 --- a/README.md +++ b/README.md @@ -40,9 +40,9 @@ This script opens a browser window where you can log in to your Google account a ## Usage -Run `fitsync.py` to download data from Fitbit and upload to Google, +Use the `patch` command to download data from Fitbit and upload to Google, - $ python fitsync.py + $ python fitsync.py patch Use the `delete` command to remove data from Google, @@ -52,6 +52,11 @@ Use the `get` command to see the data stored in Google, $ python fitsync.py get +There are a few options supported, + + $ python fitsync.py --help + + ## See your data To view weight data on [Google Fit](https://fit.google.com), diff --git a/fitsync.py b/fitsync.py old mode 100644 new mode 100755 index 625f314..bdb03cc --- a/fitsync.py +++ b/fitsync.py @@ -1,7 +1,11 @@ +#!/usr/bin/env python + import httplib2 import sys import time import yaml +import argparse +import logging import fitbit from apiclient.discovery import build @@ -14,17 +18,20 @@ POUNDS_PER_KILOGRAM = 2.20462 TIME_FORMAT = "%a, %d %b %Y %H:%M:%S" - -def GetFitbitClient(): - credentials = yaml.load(open('fitbit.yaml')) +def GetFitbitClient(filename): + logging.debug("Creating Fitbit client") + credentials = yaml.load(open(filename)) client = fitbit.Fitbit(**credentials) + logging.debug("Fitbit client created") return client -def GetGoogleClient(): - credentials = Storage('google.json').get() +def GetGoogleClient(filename): + logging.debug("Creating Google client") + credentials = Storage(filename).get() http = credentials.authorize(httplib2.Http()) client = build('fitness', 'v1', http=http) + logging.debug("Google client created") return client @@ -57,12 +64,23 @@ def GetDataSourceId(dataSource): def main(): - fitbitClient = GetFitbitClient() + parser = argparse.ArgumentParser("Transfer Fitbit weight data to Google Fit") + parser.add_argument("command", choices=('patch', 'get', 'delete'), help="What to do") + parser.add_argument("-d", "--debug", action="count", default=0, help="Increase debugging level") + parser.add_argument("-g", "--google-creds", default="google.json", help="Google credentials file") + parser.add_argument("-f", "--fitbit-creds", default="fitbit.yaml", help="Fitbit credentials file") + args = parser.parse_args() + + debugLevel = logging.WARNING - (args.debug * 10) + logging.basicConfig(level=max(debugLevel, 0)) + logging.root.name = "fitsync" + + fitbitClient = GetFitbitClient(args.fitbit_creds) devices = fitbitClient.get_devices() (scale,) = (device for device in devices if device['type'] == 'SCALE') - fitbitBodyweight = fitbitClient.get_bodyweight(period='30d') + fitbitBodyweight = fitbitClient.get_bodyweight(period='1m') fitbitWeightLogs = fitbitBodyweight['weight'] fitbitWeightLogTimes = [log['logId'] / 1000 for log in fitbitWeightLogs] @@ -72,7 +90,7 @@ def main(): googleWeightLogs = [FitbitWeightToGoogleWeight(log) for log in fitbitWeightLogs] - googleClient = GetGoogleClient() + googleClient = GetGoogleClient(args.google_creds) dataSource = dict( type='raw', @@ -121,12 +139,8 @@ def main(): set(point['startTimeNanos'] for point in left['point']) - set(point['startTimeNanos'] for point in right['point'])) - command = 'patch' - if len(sys.argv) > 1: - command = sys.argv[1] - # Get weight dataset. - if command == 'get': + if args.command == 'get': data = GetData() numpoints = 0 for point in data['point']: @@ -136,22 +150,22 @@ def main(): readableTime = time.strftime(TIME_FORMAT, time.localtime(startTimeSecs)) weightKgs = float(fpVal) weightLbs = float(fpVal) * POUNDS_PER_KILOGRAM - print "%.1f lbs ( %.2f kgs ), %s" % (weightLbs, weightKgs, readableTime) + print("%.1f lbs ( %.2f kgs ), %s" % (weightLbs, weightKgs, readableTime)) numpoints += 1 - print "Total %d points (in Google Fit)" % numpoints + print("Total %d points (in Google Fit)" % numpoints) # Delete weight dataset. - elif command == 'delete': + elif args.command == 'delete': dataPrior = GetData() googleClient.users().dataSources().datasets().delete( userId='me', dataSourceId=dataSourceId, datasetId=datasetId).execute() dataPost = GetData() - print "Deleted %d points (from Google Fit)" % PointsDifference(dataPrior, dataPost) + print("Deleted %d points (from Google Fit)" % PointsDifference(dataPrior, dataPost)) # Upload weight dataset. - elif command == 'patch': + elif args.command == 'patch': dataPrior = GetData() googleClient.users().dataSources().datasets().patch( userId='me', @@ -164,10 +178,8 @@ def main(): point=googleWeightLogs, )).execute() dataPost = GetData() - print "Added %d points (to Google Fit)" % PointsDifference(dataPost, dataPrior) + print("Added %d points (to Google Fit)" % PointsDifference(dataPost, dataPrior)) - else: - print "bad command" def PointInData(startTimeNanos, data): @@ -179,3 +191,4 @@ def PointInData(startTimeNanos, data): if __name__ == '__main__': main() +