-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathstravaupload.py
executable file
·176 lines (142 loc) · 5.36 KB
/
stravaupload.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#!/usr/bin/env python
""" Upload files to Strava
"""
import glob
import os
import sys
import webbrowser
from argparse import ArgumentParser
from requests.exceptions import ConnectionError, HTTPError
from ConfigParser import SafeConfigParser
from stravalib import Client, exc, model
def data_type_from_filename(filename):
"""Return the data type from the filename's extension.
Exit if not supported.
"""
data_type = None
for ext in ['.fit', '.fit.gz', '.tcx', '.tcx.gz', '.gpx', '.gpx.gz']:
if filename.endswith(ext):
data_type = ext.lstrip('.')
if not data_type:
exit('Extension not supported')
return data_type
def name_and_description_from_file(filename):
"""Find the name and description from GPX files.
Other files not yet supported.
"""
if filename.endswith('.gpx') or filename.endswith('.gpx.gz'):
import gpxpy
if filename.endswith('.gpx.gz'):
import gzip
with gzip.open(filename) as info:
gpx_data = info.read()
gpx = gpxpy.parse(gpx_data)
elif filename.endswith('.gpx'):
with open(filename) as gpx_data:
gpx = gpxpy.parse(gpx_data)
return gpx.name, gpx.description
return None, None
def upload_file(strava, filename, activity_name, activity_description,
activity_type, private, view, test, may_exit=True):
"""Upload a single file
"""
# Find the data type
data_type = data_type_from_filename(filename)
# Extract name and description from the file
if not activity_name or not activity_description:
new_name, new_description = name_and_description_from_file(filename)
if not activity_name:
activity_name = new_name
if not activity_description:
activity_description = new_description
# Try to upload
print 'Uploading...'
try:
if test:
print 'Test mode: not actually uploading.'
else:
upload = strava.upload_activity(
activity_file=open(filename, 'r'),
data_type=data_type,
name=activity_name,
description=activity_description,
private=True if private else False,
activity_type=activity_type
)
except exc.ActivityUploadFailed as error:
print 'An exception occurred: ',
print error
if may_exit:
exit(1)
return
except ConnectionError as error:
print 'No internet connection'
if may_exit:
exit(1)
return
print 'Upload succeeded.'
if view:
print 'Waiting for activity...'
try:
activity = upload.wait()
except HTTPError as error:
if error.args[0].startswith('401'):
print "You don't have permission to view this activity"
else:
print 'HTTPError: ' + ', '.join(str(i) for i in error.args)
return
print 'Activity id: ' + str(activity.id)
url = 'https://www.strava.com/activities/' + str(activity.id)
webbrowser.open_new_tab(url)
def main():
"""Main function
"""
# Parse the input arguments
parser = ArgumentParser(description='Upload files to Strava')
parser.add_argument('input', help='Input filename')
parser.add_argument('-t', '--title', help='Title of activity')
parser.add_argument('-d', '--description', help='Description of activity')
parser.add_argument('-p', '--private', action='store_true',
help='Make the activity private')
parser.add_argument('-a', '--activity', choices=model.Activity.TYPES,
metavar='',
help='Possible values: {%(choices)s}')
parser.add_argument('-v', '--view', action='store_true',
help='Open the activity in a web browser.')
parser.add_argument('-x', '--test', action='store_true',
help="Don't actually upload anything.")
args = parser.parse_args()
# Check if an access token is provided
configfile = [os.path.expanduser('~/.stravaupload.cfg'),
'.stravaupload.cfg']
config = SafeConfigParser()
config.read(configfile)
if config.has_option('access', 'token'):
access_token = config.get('access', 'token')
else:
print 'No access_token found in %s' % configfile
sys.exit(0)
# Get activity type
activity_type = None
if args.activity:
activity_type = args.activity
elif config.has_option('default', 'activity'):
activity_type = config.get('default', 'activity')
strava = Client()
strava.access_token = access_token
# Is the input a single file or wildcard?
if os.path.isfile(args.input):
upload_file(strava, args.input, args.title, args.description,
activity_type, args.private, args.view, args.test)
else:
filenames = glob.glob(args.input)
if len(filenames) == 0:
sys.exit('No input files found')
else:
for i, filename in enumerate(filenames):
print i+1, "/", len(filenames)
upload_file(strava, filename, args.title, args.description,
activity_type, args.private, args.view, args.test,
may_exit=False)
if __name__ == '__main__':
main()