diff --git a/README.md b/README.md index d284cef..a8de3e3 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ Upload FIT, TCX and GPX files to strava.com from the command line. ## Prerequisites * POSIX shell * cURL +* Python 3 ## Setup 1. Sign up at http://www.strava.com/ @@ -14,9 +15,11 @@ STRAVAUP_CLIENT_ID=FIXME STRAVAUP_CLIENT_SECRET=FIXME ~~~ 4. Get your authorization code -* Go to https://www.strava.com/oauth/authorize?client_id=YOUR_STRAVAUP_CLIENT_ID&response_type=code&redirect_uri=http://localhost/index.php&approval_prompt=force&scope=write -* Select 'Authorize' which will lead to a redirect URL -* Copy the code from the redirect URL into your .stravauprc: + On the first run of the program, you will be prompted to visit a URL + with your browser and click `Authorize`. + The browser must be running on the same computer as the _stravaup_ script. + Alternatively, after clicking on `Authorize`, copy the `code` parameter + from the redirect URL into your .stravauprc: ~~~ STRAVAUP_CODE=FIXME ~~~ diff --git a/server.py b/server.py new file mode 100644 index 0000000..b756f67 --- /dev/null +++ b/server.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 +# +# Web server to capture the code provided by the redirect link +# when "Authorize" is pressed in the Strave app authorization form. +# + +from http.server import BaseHTTPRequestHandler, HTTPServer +from urllib.parse import urlparse, parse_qs +from sys import exit + +class CaptureHandler(BaseHTTPRequestHandler): + def do_GET(self): + parsed_path = urlparse(self.path) + path = parsed_path.path + query_params = parse_qs(parsed_path.query) + + if path == '/capture': + # Obtain and report code to stdout + code_value = query_params.get('code', [''])[0] + print(code_value) + + # Respond + self.send_response(200) + self.send_header('Content-type', 'text/html') + self.end_headers() + self.wfile.write(b"Captured 'code'") + + # Stop server after capturing + server.server_close() + exit(0) + else: + self.send_response(404) + self.end_headers() + + def log_message(self, format, *args): + return # Suppress log messages + + +if __name__ == '__main__': + server = HTTPServer(('localhost', 8080), CaptureHandler) + server.serve_forever() diff --git a/stravaup b/stravaup index a380276..1466791 100755 --- a/stravaup +++ b/stravaup @@ -63,17 +63,32 @@ if [ "$STRAVAUP_CODE" = "" ]; then echo "Please open the following URL in a browser" echo -n "https://www.strava.com/oauth/authorize?client_id=" echo -n "$STRAVAUP_CLIENT_ID" - echo "&response_type=code&redirect_uri=http://localhost/index.php&approval_prompt=force&scope=write" - echo "Select 'Authorize' which will lead to a redirect into a localhost address. Copy the authorization" - echo "code into .stravauprc" - echo " STRAVAUP_CODE = [insert your own]" - exit 1 + echo "&response_type=code&redirect_uri=http://localhost:8080/capture&approval_prompt=force&scope=activity:write" + echo "Select 'Authorize' to provide this script with the required authorization code." + STRAVAUP_CODE=$(python3 $(dirname $0)/server.py) + if [ -z "$STRAVAUP_CODE" ] ; then + echo "Unable to obtain authorization code" 1>&2 + exit 1 + fi + echo "STRAVAUP_CODE=$STRAVAUP_CODE" >> ${HOME}/.stravauprc fi # Get auth token +# If needed, get refresh token +if [ "$STRAVAUP_REFRESH_TOKEN" = "" ]; then + echo "Exchanging authorization token for refresh token..." + STRAVAUP_REFRESH_TOKEN=$(curl -s -X POST https://www.strava.com/oauth/token -F client_id="$STRAVAUP_CLIENT_ID" -F client_secret="$STRAVAUP_CLIENT_SECRET" -F code="$STRAVAUP_CODE" -F grant_type=authorization_code | cut -d':' -f5 | cut -d',' -f1 | sed -e 's/[^a-z0-9]//g') + echo "STRAVAUP_REFRESH_TOKEN=$STRAVAUP_REFRESH_TOKEN" >> ${HOME}/.stravauprc +fi + +echo "Getting auth token..." +TOKEN=$(curl -s -X POST https://www.strava.com/oauth/token -F client_id="$STRAVAUP_CLIENT_ID" -F client_secret="$STRAVAUP_CLIENT_SECRET" -F grant_type=refresh_token -F refresh_token="$STRAVAUP_REFRESH_TOKEN" | grep access_token | cut -d':' -f3 | cut -d',' -f1 | sed -e 's/[^a-z0-9]//g') + if [ "$TOKEN" = "" ]; then - TOKEN=$(curl -s -X POST https://www.strava.com/oauth/token -F client_id="$STRAVAUP_CLIENT_ID" -F client_secret="$STRAVAUP_CLIENT_SECRET" -F code="$STRAVAUP_CODE" | grep -Po '"access_token":.*?[^\\]",' | cut -d':' -f2 | sed -e 's/[^a-z0-9]//g') + echo "Unable to get auth token. Consider deleting STRAVAUP_REFRESH_TOKEN." 1>&2 + exit 1 fi # Upload file +echo "Uploading file..." curl -X POST https://www.strava.com/api/v3/uploads -H "Authorization: Bearer $TOKEN" -F file=@"$1" -F data_type="$datatype"