-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrun.py
executable file
·159 lines (133 loc) · 6.09 KB
/
run.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
#!/usr/bin/python3
import os
import re
import subprocess
import csv
import sys
# CONSTANTS ------------------------------------
UNZIPPED_FOLDER = "unzipped"
STRAVA_ACTIVITIES_SUBFOLDER = "activities"
STRAVA_ACTIVITIES_FILE = "activities.csv"
# ----------------------------------------------
# unzip and delete the archive -----------------
def unzip(file):
import gzip
import shutil
with gzip.open(file, 'rb') as f_in:
with open(file.lower().replace('.gz', ''), 'wb') as f_out:
shutil.copyfileobj(f_in, f_out)
os.remove(file)
# helper for executing babel -------------------
def exec_cmd(command):
result = subprocess.Popen(command, shell=True)
text = result.communicate()[0]
return_code = result.returncode
if return_code != 0:
return False
return True
# exit with error ------------------------------
def die(error):
print("Error: " + error)
quit()
# main -----------------------------------------
def main():
global UNZIPPED_FOLDER
global STRAVA_ACTIVITIES_SUBFOLDER
global STRAVA_ACTIVITIES_FILE
# assemble paths
strava_unzipped_folder = os.path.join(".", UNZIPPED_FOLDER)
strava_unzipped_activities_folder = os.path.join(".", UNZIPPED_FOLDER, STRAVA_ACTIVITIES_SUBFOLDER)
strava_unzipped_activities_file = os.path.join(".", UNZIPPED_FOLDER, STRAVA_ACTIVITIES_FILE)
# gpsbabel command, expecting to be in PATH. You may put the absolute path to the executable (mostly for Windows users)
gpsbabel_command = "gpsbabel -w -t -i gtrnctr -f {filename_tcx} -o gpx,gpxver=1.1 -F {filename_gpx} > /dev/null"
# pre-check
if not os.path.exists(strava_unzipped_folder):
die("Folder with expected unzipped Strava archive '{path}' doesn't exits.".format(path=strava_unzipped_folder))
if not os.path.exists(strava_unzipped_activities_folder):
die("Folder with activities in unzipped Strava archive '{path}' doesn't exits.".format(path=strava_unzipped_activities_folder))
if not os.path.isfile(strava_unzipped_activities_file):
die("File with activities in unzipped Strava archive '{path}' doesn't exits.".format(path=strava_unzipped_activities_file))
# reading the activities.csv file and storing the list in activities_list
print("Reading '{path}'".format(path=strava_unzipped_activities_file));
try:
with open(strava_unzipped_activities_file, newline='\n', encoding='utf-8') as csvfile:
reader = csv.DictReader(csvfile)
activities_list = list(reader)
except Exception as ex:
die("Cannot read '{path}'. {err}".format(path=strava_unzipped_activities_file, err=str(ex)))
# get the count of the activities
cnt = len(activities_list)
print("Found {cnt} activities ".format(cnt=str(cnt)))
# let's go through the list and unzip any .gz files if exists
print("Unzipping ...")
sys.stdout.write("Progress: ")
ucnt = 0
for line in activities_list:
x = 0
filename = os.path.join(strava_unzipped_folder, line['filename'])
ucnt += 1
sys.stdout.write("{:2.0%}".format(ucnt / cnt).rjust(5, " "))
sys.stdout.flush()
if filename.endswith(".gz") and os.path.exists(filename):
unzip(filename)
line['filename'] = line['filename'].replace(".gz", "")
sys.stdout.write("\b\b\b\b\b")
sys.stdout.flush()
x += 1
sys.stdout.write("\n")
# now remove extra \n from GPX and convert TCX to GPX using gpsbabel
print("Normalizing ...")
for line in activities_list:
filename = os.path.join(strava_unzipped_folder, line['filename'])
extension = os.path.splitext(filename)[1][1:].strip().lower()
print(filename.ljust(40," ") + "| " + line["type"].ljust(13," ") + "| " + str(line["name"])[:70])
if os.path.exists(filename):
if extension == "gpx":
with open(filename, encoding='utf-8') as file:
content = file.read()
fixed = re.sub(r'>\s\s+<', '><', content).strip()
with open(filename, "w", encoding='utf-8') as filew:
filew.write(fixed)
# strip spaces from tcx
if extension == "tcx":
with open(filename, encoding='utf-8') as file:
content = file.read()
fixed = re.sub(r'>\s\s+<', '><', content).strip()
with open(filename, "w", encoding='utf-8') as filew:
filew.write(fixed)
print(re.findall(r'<[Aa][Cc][Tt][Ii][Vv][Ii][Tt][Yy][ ]{1,}[Ss][Pp][Oo][Rr][Tt]="([^"]*)">', fixed))
filename_gpx = filename.replace(".tcx", ".gpx")
rc = exec_cmd(gpsbabel_command.format(
filename_gpx=filename_gpx,
filename_tcx=filename)
)
if not rc:
print('error')
else:
os.remove(filename)
line['filename'] = line['filename'].replace(".tcx", ".gpx")
# assemble the filename for the backup file
new_activities_file = strava_unzipped_activities_file + ".original"
print("Backing up the original activities as '{new}' ...".format(new=new_activities_file))
os.rename(strava_unzipped_activities_file, new_activities_file)
# rewrite the activities file
print("Saving new activities ...")
with open(strava_unzipped_activities_file, 'w', newline='\n', encoding='utf-8') as csvfile:
fieldnames = ['id',
'date',
'name',
'type',
'description',
'elapsed_time',
'distance',
'commute',
'gear',
'filename'
]
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for line in activities_list:
writer.writerow(line)
# run ------------------------------------------------------
if __name__ == "__main__":
main()