diff --git a/README.md b/README.md index d218f44..27334e2 100644 --- a/README.md +++ b/README.md @@ -37,15 +37,16 @@ directory on your machine. For each activity, these files are stored: - - an activity summary file (JSON) + - an activity summary file (JSON) - - an activity details file (JSON) + - an activity details file (JSON) - - an activity GPX file (XML) + - an activity GPX file (XML) - - an activity TCX file (XML) + - an activity TCX file (XML) - - an activity FIT file (binary) + - an activity FIT file (binary) (if available -- the activity may have + been entered manuall rather than imported from a Garmin device). All files are written to the same directory (``activities//`` by default). Each activity file is prefixed by its upload timestamp and its diff --git a/garminexport.py b/garminexport.py index 6b80921..3bac11e 100755 --- a/garminexport.py +++ b/garminexport.py @@ -92,8 +92,9 @@ if __name__ == "__main__": f.write(activity_gpx) with codecs.open(tcx_file, encoding="utf-8", mode="w") as f: f.write(activity_tcx) - with open(fit_file, mode="wb") as f: - f.write(activity_fit) + if activity_fit: + with open(fit_file, mode="wb") as f: + f.write(activity_fit) except Exception as e: exc_type, exc_value, exc_traceback = sys.exc_info() log.error(u"failed with exception: %s", e) diff --git a/garminexport/garminclient.py b/garminexport/garminclient.py index 91b14a5..b253cb7 100755 --- a/garminexport/garminclient.py +++ b/garminexport/garminclient.py @@ -262,22 +262,30 @@ class GarminClient(object): :returns: The TCX representation of the activity as an XML string. :rtype: str """ - response = self.session.get("https://connect.garmin.com/proxy/activity-service-1.3/tcx/course/{}".format(activity_id)) + + response = self.session.get("http://connect.garmin.com/proxy/activity-service-1.1/tcx/activity/{}?full=true".format(activity_id)) if response.status_code != 200: raise Exception(u"failed to fetch TCX for activity {}: {}\n{}".format( activity_id, response.status_code, response.text)) return response.text def get_activity_fit(self, activity_id): - """Return a FIT representation for a given activity. + """Return a FIT representation for a given activity. If the activity + doesn't have a FIT source (for example, if it was entered manually + rather than imported from a Garmin device) a :obj:`None` value is + returned. :param activity_id: Activity identifier. :type activity_id: int - :returns: A string with a FIT file for the activity. + :returns: A string with a FIT file for the activity or :obj:`None` + if no FIT source exists for this activity (e.g., entered manually). :rtype: str """ response = self.session.get("https://connect.garmin.com/proxy/download-service/files/activity/{}".format(activity_id)) + if response.status_code == 404: + # No FIT source available for activity + return None if response.status_code != 200: raise Exception(u"failed to fetch FIT for activity {}: {}\n{}".format( activity_id, response.status_code, response.text))