dropped garminexport.py in favor of the incremental_backup.py script, now renamed to garminbackup.py
This commit is contained in:
		
							parent
							
								
									71c95330ba
								
							
						
					
					
						commit
						012c029c83
					
				
							
								
								
									
										75
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										75
									
								
								README.md
									
									
									
									
									
								
							@ -1,15 +1,19 @@
 | 
				
			|||||||
Garmin Connect activity exporter
 | 
					Garmin Connect activity backup tool
 | 
				
			||||||
================================
 | 
					===================================
 | 
				
			||||||
``garminexport.py`` is a program that downloads *all* 
 | 
					``garminbackup.py`` is a program that downloads activities for a 
 | 
				
			||||||
activities for a given [Garmin Connect](http://connect.garmin.com/) 
 | 
					given [Garmin Connect](http://connect.garmin.com/) account and stores 
 | 
				
			||||||
account and stores them in a backup directory locally on the user's 
 | 
					them in a backup directory locally on the user's computer. The first time 
 | 
				
			||||||
computer.
 | 
					the program is run, it will download *all* activities. After that, it will
 | 
				
			||||||
 | 
					do incremental backups of your account. That is, the script will only download
 | 
				
			||||||
 | 
					activities that haven't already been downloaded to the backup directory.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The ``incremental_backup.py`` program can be used for incremental backups
 | 
					The library contains a simple utility program, ``get_activity.py`` for 
 | 
				
			||||||
 of your account. This script only downloads
 | 
					downloading a single Garmin Connect activity. Run ``./get_activity.py --help``
 | 
				
			||||||
activities that haven't already been downloaded to a certain backup directory.
 | 
					for more details.
 | 
				
			||||||
It is typically a quicker alternative (except for the first time when all
 | 
					
 | 
				
			||||||
activities will need to be downloaded).
 | 
					The library also contains a ``garminclient`` module that could be used by third-party
 | 
				
			||||||
 | 
					projects that need to communicate over the Garmin Connect API. See the 
 | 
				
			||||||
 | 
					Library Import section below for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Prerequisites
 | 
					Prerequisites
 | 
				
			||||||
@ -35,46 +39,41 @@ Install the required dependencies in this virtual environment:
 | 
				
			|||||||
    pip install -r requirements.txt
 | 
					    pip install -r requirements.txt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Running the export program
 | 
					 | 
				
			||||||
==========================
 | 
					 | 
				
			||||||
The export program is run as follows (use the ``--help`` flag for a list of
 | 
					 | 
				
			||||||
available options).
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ./garminexport.py <username or email>
 | 
					Running
 | 
				
			||||||
 | 
					=======
 | 
				
			||||||
 | 
					The backup program is run as follows (use the ``--help`` flag for a full list 
 | 
				
			||||||
 | 
					of available options):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ./garminbackup.py --backup-dir=activities <username or email>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Once started, the program will prompt you for your account password and then
 | 
					Once started, the program will prompt you for your account password and then
 | 
				
			||||||
log in to your Garmin Connect account to download *all* activities to a 
 | 
					log in to your Garmin Connect account to download activities to the specified
 | 
				
			||||||
destination directory on your machine.
 | 
					backup directory on your machine. The program will only download activities 
 | 
				
			||||||
 | 
					that aren't already in the backup directory.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
For each activity, these files are stored: 
 | 
					Activities can be exported in any of the formats outlined below. Note that
 | 
				
			||||||
 | 
					by default, the program downloads all formats for every activity. Use the
 | 
				
			||||||
 | 
					``--format`` option to narrow the selection.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  -   an activity summary file (JSON)
 | 
					Supported export formats:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  -   an activity details file (JSON)
 | 
					  -   ``json_summary``: activity summary file (JSON)
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
  -   an activity GPX file (XML)
 | 
					  -   ``json_details``: activity details file (JSON)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  -   an activity TCX file (XML)
 | 
					  -   ``gpx``: activity GPX file (XML)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  -   an activity FIT file (binary) (if available -- the activity may have
 | 
					  -   ``tcx``: an activity TCX file (XML)
 | 
				
			||||||
      been entered manually rather than imported from a Garmin device).
 | 
					
 | 
				
			||||||
 | 
					  -   ``fit``: activity FIT file (binary format).
 | 
				
			||||||
 | 
					      *Note: a ``.fit`` file may not always be possible to export, for example
 | 
				
			||||||
 | 
					      if an activity was entered manually rather than imported from a Garmin device.*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
All files are written to the same directory (``activities/`` by default).
 | 
					All files are written to the same directory (``activities/`` by default).
 | 
				
			||||||
Each activity file is prefixed by its upload timestamp and its 
 | 
					Each activity file is prefixed by its upload timestamp and its activity id.
 | 
				
			||||||
activity id.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Running the incremental backup program
 | 
					 | 
				
			||||||
======================================
 | 
					 | 
				
			||||||
The incremental backup program is run in a similar fashion to the export 
 | 
					 | 
				
			||||||
program (use the ``--help`` flag for a list of available options):
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ./incremental_backup.py --backup-dir=activities <username or email>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
In this example, it will only download activities that aren't already in
 | 
					 | 
				
			||||||
the ``activities/`` directory. Note: The incremental backup program saves
 | 
					 | 
				
			||||||
the same files for each activity as the export program (see above).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Library import
 | 
					Library import
 | 
				
			||||||
==============
 | 
					==============
 | 
				
			||||||
 | 
				
			|||||||
@ -33,9 +33,7 @@ def get_backed_up(activities, backup_dir, formats):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    :rtype: list of int
 | 
					    :rtype: list of int
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    # backed up activities follow this pattern: <ISO8601>_<id>_summary.json
 | 
					    # backed up activities follow this pattern: <ISO8601>_<id>_<suffix>
 | 
				
			||||||
    activity_file_pattern = r'[\d:T\+\-]+_([0-9]+).tcx'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    format_suffix = dict(json_summary="_summary.json", json_details="_details.json", gpx=".gpx", tcx=".tcx", fit=".fit")
 | 
					    format_suffix = dict(json_summary="_summary.json", json_details="_details.json", gpx=".gpx", tcx=".tcx", fit=".fit")
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    backed_up = set()
 | 
					    backed_up = set()
 | 
				
			||||||
@ -1,82 +0,0 @@
 | 
				
			|||||||
#! /usr/bin/env python
 | 
					 | 
				
			||||||
"""A program that downloads all activities for a given Garmin Connect account
 | 
					 | 
				
			||||||
and stores them locally on the user's computer.
 | 
					 | 
				
			||||||
"""
 | 
					 | 
				
			||||||
import argparse
 | 
					 | 
				
			||||||
import getpass
 | 
					 | 
				
			||||||
from garminexport.garminclient import GarminClient
 | 
					 | 
				
			||||||
import garminexport.util
 | 
					 | 
				
			||||||
import logging
 | 
					 | 
				
			||||||
import os
 | 
					 | 
				
			||||||
import sys
 | 
					 | 
				
			||||||
import traceback
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
logging.basicConfig(
 | 
					 | 
				
			||||||
    level=logging.INFO, format="%(asctime)-15s [%(levelname)s] %(message)s")
 | 
					 | 
				
			||||||
log = logging.getLogger(__name__)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
LOG_LEVELS = {
 | 
					 | 
				
			||||||
    "DEBUG": logging.DEBUG,
 | 
					 | 
				
			||||||
    "INFO": logging.INFO,
 | 
					 | 
				
			||||||
    "WARNING": logging.WARNING,
 | 
					 | 
				
			||||||
    "ERROR": logging.ERROR
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
"""Command-line (string-based) log-level mapping to logging module levels."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if __name__ == "__main__":
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    parser = argparse.ArgumentParser(
 | 
					 | 
				
			||||||
        description="Downloads all activities for a given Garmin Connect account.")
 | 
					 | 
				
			||||||
    # positional args
 | 
					 | 
				
			||||||
    parser.add_argument(
 | 
					 | 
				
			||||||
        "username", metavar="<username>", type=str, help="Account user name.")
 | 
					 | 
				
			||||||
    # optional args
 | 
					 | 
				
			||||||
    parser.add_argument(
 | 
					 | 
				
			||||||
        "--password", type=str, help="Account password.")
 | 
					 | 
				
			||||||
    parser.add_argument(
 | 
					 | 
				
			||||||
        "--destination", metavar="DIR", type=str,
 | 
					 | 
				
			||||||
        help=("Destination directory for downloaded activities. Default: "
 | 
					 | 
				
			||||||
              "./activities/"), default=os.path.join(".", "activities"))
 | 
					 | 
				
			||||||
    parser.add_argument(
 | 
					 | 
				
			||||||
        "--log-level", metavar="LEVEL", type=str,
 | 
					 | 
				
			||||||
        help=("Desired log output level (DEBUG, INFO, WARNING, ERROR). "
 | 
					 | 
				
			||||||
              "Default: INFO."), default="INFO")
 | 
					 | 
				
			||||||
    parser.add_argument(
 | 
					 | 
				
			||||||
        "-f", "--format", choices=garminexport.util.export_formats,
 | 
					 | 
				
			||||||
        default=None, action='append',
 | 
					 | 
				
			||||||
        help=("Desired output formats ("+', '.join(garminexport.util.export_formats)+"). "
 | 
					 | 
				
			||||||
              "Default: ALL."))
 | 
					 | 
				
			||||||
    parser.add_argument(
 | 
					 | 
				
			||||||
        "-E", "--ignore-errors", action='store_true',
 | 
					 | 
				
			||||||
        help="Ignore errors and keep going. Default: FALSE")
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    args = parser.parse_args()
 | 
					 | 
				
			||||||
    if not args.log_level in LOG_LEVELS:
 | 
					 | 
				
			||||||
        raise ValueError("Illegal log-level argument: {}".format(args.log_level))
 | 
					 | 
				
			||||||
    logging.root.setLevel(LOG_LEVELS[args.log_level])
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
    try:
 | 
					 | 
				
			||||||
        if not os.path.isdir(args.destination):
 | 
					 | 
				
			||||||
            os.makedirs(args.destination)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if not args.password:
 | 
					 | 
				
			||||||
            args.password = getpass.getpass("Enter password: ")
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        with GarminClient(args.username, args.password) as client:
 | 
					 | 
				
			||||||
            log.info("fetching activities for {} ...".format(args.username))
 | 
					 | 
				
			||||||
            all_activities = client.list_activities()
 | 
					 | 
				
			||||||
            for index, (id, start) in enumerate(activity_ids):
 | 
					 | 
				
			||||||
                log.info("processing activity {} from {} ({} out of {}) ...".format(
 | 
					 | 
				
			||||||
                    id, start, index+1, len(activity_ids)))
 | 
					 | 
				
			||||||
                try:
 | 
					 | 
				
			||||||
                    garminexport.util.export_activity(
 | 
					 | 
				
			||||||
                        client, id, args.backup_dir, args.format)
 | 
					 | 
				
			||||||
                except Exception as e:
 | 
					 | 
				
			||||||
                    log.error(u"failed with exception: %s", e)
 | 
					 | 
				
			||||||
                    if not args.ignore_errors:
 | 
					 | 
				
			||||||
                        raise
 | 
					 | 
				
			||||||
    except Exception as e:
 | 
					 | 
				
			||||||
        exc_type, exc_value, exc_traceback = sys.exc_info()
 | 
					 | 
				
			||||||
        log.error(u"failed with exception: %s", e)
 | 
					 | 
				
			||||||
        raise
 | 
					 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user