git-fit 0.10.4 → 0.10.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/git-fit.rb +8 -0
- data/lib/git_fit/auth/garmin_token.rb +32 -0
- data/lib/git_fit/auth/strava.rb +223 -0
- data/lib/git_fit/cli/export.rb +20 -1
- data/lib/git_fit/cli/sync.rb +54 -0
- data/lib/git_fit/cli.rb +29 -0
- data/lib/git_fit/config_template.rb +9 -0
- data/lib/git_fit/dedup/field_elector.rb +81 -0
- data/lib/git_fit/dedup/group_consolidator.rb +58 -0
- data/lib/git_fit/dedup/log_writer.rb +33 -0
- data/lib/git_fit/dedup/matcher.rb +90 -0
- data/lib/git_fit/dedup/service.rb +207 -0
- data/lib/git_fit/dedup/trajectory.rb +255 -0
- data/lib/git_fit/export/gpx.rb +133 -0
- data/lib/git_fit/export/json.rb +31 -8
- data/lib/git_fit/export.rb +1 -0
- data/lib/git_fit/fit.rb +6 -0
- data/lib/git_fit/sync/base.rb +11 -0
- data/lib/git_fit/sync/igpsport.rb +1 -1
- data/lib/git_fit/sync/strava.rb +31 -18
- data/lib/git_fit/sync/xoss.rb +1 -1
- data/lib/git_fit/version.rb +1 -1
- metadata +24 -1
data/lib/git_fit/export/json.rb
CHANGED
|
@@ -7,10 +7,11 @@ module GitFit
|
|
|
7
7
|
class JSON
|
|
8
8
|
PLACEHOLDER_POLYLINE = 'gqqrFurkeU??'
|
|
9
9
|
|
|
10
|
-
def initialize(db:, output:, activity_filter: nil)
|
|
10
|
+
def initialize(db:, output:, activity_filter: nil, tracks_output: nil)
|
|
11
11
|
@db = db
|
|
12
12
|
@output = output
|
|
13
13
|
@activity_filter = activity_filter
|
|
14
|
+
@tracks_output = tracks_output
|
|
14
15
|
end
|
|
15
16
|
|
|
16
17
|
def call
|
|
@@ -24,23 +25,40 @@ module GitFit
|
|
|
24
25
|
|
|
25
26
|
group_members_cache = {}
|
|
26
27
|
|
|
28
|
+
tracks = @tracks_output ? {} : nil
|
|
29
|
+
|
|
27
30
|
formatted = activities.map do |a|
|
|
28
31
|
gid = run_id_to_group[a[:run_id]]
|
|
29
32
|
if gid
|
|
30
33
|
group_members_cache[gid] ||= @db[:dedup_group_members].where(group_id: gid).all
|
|
31
|
-
composite_activity(a, gid, group_members_cache[gid])
|
|
34
|
+
composite_activity(a, gid, group_members_cache[gid], tracks)
|
|
32
35
|
else
|
|
33
|
-
format_activity(a)
|
|
36
|
+
format_activity(a, tracks)
|
|
34
37
|
end
|
|
35
38
|
end
|
|
36
39
|
|
|
37
40
|
File.write(@output, ::JSON.pretty_generate(formatted))
|
|
41
|
+
File.write(@tracks_output, ::JSON.generate(tracks)) if @tracks_output
|
|
38
42
|
formatted.size
|
|
39
43
|
end
|
|
40
44
|
|
|
41
45
|
private
|
|
42
46
|
|
|
43
|
-
def
|
|
47
|
+
def extract_polyline(a)
|
|
48
|
+
return nil if a[:source] == 'keep' && a[:summary_polyline] == PLACEHOLDER_POLYLINE
|
|
49
|
+
|
|
50
|
+
a[:summary_polyline]
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def pick_best_polyline(group_activities)
|
|
54
|
+
candidates = group_activities.filter_map { |a| extract_polyline(a) }
|
|
55
|
+
candidates.max_by { |p| p.to_s.length }
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def format_activity(a, tracks = nil)
|
|
59
|
+
polyline = extract_polyline(a)
|
|
60
|
+
tracks[a[:run_id]] = polyline if tracks && polyline
|
|
61
|
+
|
|
44
62
|
base = {
|
|
45
63
|
run_id: a[:run_id],
|
|
46
64
|
name: a[:name],
|
|
@@ -51,8 +69,7 @@ module GitFit
|
|
|
51
69
|
start_date: a[:start_date],
|
|
52
70
|
start_date_local: a[:start_date_local],
|
|
53
71
|
location_country: a[:location_country],
|
|
54
|
-
summary_polyline:
|
|
55
|
-
nil : a[:summary_polyline],
|
|
72
|
+
summary_polyline: tracks ? nil : polyline,
|
|
56
73
|
average_heartrate: a[:average_heartrate] && a[:average_heartrate] != 0 ? a[:average_heartrate] : nil,
|
|
57
74
|
max_heartrate: a[:max_heartrate],
|
|
58
75
|
average_cadence: a[:average_cadence],
|
|
@@ -71,7 +88,7 @@ module GitFit
|
|
|
71
88
|
base
|
|
72
89
|
end
|
|
73
90
|
|
|
74
|
-
def composite_activity(activity, group_id, members)
|
|
91
|
+
def composite_activity(activity, group_id, members, tracks = nil)
|
|
75
92
|
run_ids = members.map { |m| m[:run_id] }
|
|
76
93
|
group_activities = @db[:activities].where(run_id: run_ids).all
|
|
77
94
|
|
|
@@ -85,11 +102,17 @@ module GitFit
|
|
|
85
102
|
end
|
|
86
103
|
result
|
|
87
104
|
else
|
|
88
|
-
members.first&.slice(:run_id, :distance, :moving_time, :elapsed_time,
|
|
105
|
+
composite = members.first&.slice(:run_id, :distance, :moving_time, :elapsed_time,
|
|
89
106
|
:average_heartrate, :max_heartrate, :elevation_gain,
|
|
90
107
|
:average_speed, :average_cadence, :max_cadence) || {}
|
|
108
|
+
composite[:summary_polyline] = pick_best_polyline(group_activities)
|
|
109
|
+
composite
|
|
91
110
|
end
|
|
92
111
|
|
|
112
|
+
polyline = composite[:summary_polyline]
|
|
113
|
+
tracks[activity[:run_id]] = polyline if tracks && polyline
|
|
114
|
+
composite[:summary_polyline] = tracks ? nil : polyline
|
|
115
|
+
|
|
93
116
|
composite[:run_id] = activity[:run_id]
|
|
94
117
|
composite[:source] = activity[:source]
|
|
95
118
|
composite[:sport_type] = activity[:sport_type]
|
data/lib/git_fit/export.rb
CHANGED
data/lib/git_fit/fit.rb
CHANGED
data/lib/git_fit/sync/base.rb
CHANGED
|
@@ -235,6 +235,17 @@ module GitFit
|
|
|
235
235
|
.select_map(:run_id)
|
|
236
236
|
.map { |rid| rid.sub(/\A#{Regexp.escape(prefix)}/, '') }
|
|
237
237
|
end
|
|
238
|
+
|
|
239
|
+
def normalize_fit_timestamps(points)
|
|
240
|
+
points.map do |pt|
|
|
241
|
+
ts = pt['timestamp']
|
|
242
|
+
next pt unless ts.is_a?(Numeric)
|
|
243
|
+
|
|
244
|
+
pt = pt.dup
|
|
245
|
+
pt['timestamp'] = Time.at(FIT::FIT_EPOCH + ts).utc.iso8601
|
|
246
|
+
pt
|
|
247
|
+
end
|
|
248
|
+
end
|
|
238
249
|
end
|
|
239
250
|
end
|
|
240
251
|
end
|
|
@@ -140,7 +140,7 @@ module GitFit
|
|
|
140
140
|
FileUtils.mkdir_p(dir)
|
|
141
141
|
tmp = File.join(dir, ".#{ride_id}.json.tmp")
|
|
142
142
|
final = File.join(dir, "#{ride_id}.json")
|
|
143
|
-
File.write(tmp, JSON.generate(wgs_points))
|
|
143
|
+
File.write(tmp, JSON.generate(normalize_fit_timestamps(wgs_points)))
|
|
144
144
|
File.rename(tmp, final)
|
|
145
145
|
end
|
|
146
146
|
|
data/lib/git_fit/sync/strava.rb
CHANGED
|
@@ -134,27 +134,40 @@ module GitFit
|
|
|
134
134
|
coords = Geo::Polyline.decode(polyline)
|
|
135
135
|
return nil if coords.empty?
|
|
136
136
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
137
|
+
streams_data = %w[altitude time heartrate cadence watts temp velocity_smooth distance].to_h do |k|
|
|
138
|
+
[k, streams[k]&.dig('data')]
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
start_time = begin
|
|
142
|
+
Time.parse(detail['start_date'])
|
|
143
|
+
rescue StandardError
|
|
144
|
+
nil
|
|
145
|
+
end
|
|
145
146
|
|
|
146
147
|
coords.each_with_index.map do |latlng, i|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
pt
|
|
148
|
+
build_l2_point(latlng, i, streams_data, start_time)
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def build_l2_point(latlng, i, streams_data, start_time)
|
|
153
|
+
pt = { positionLat: latlng[0], positionLong: latlng[1] }
|
|
154
|
+
pt[:altitude] = stream_at(streams_data, 'altitude', i)
|
|
155
|
+
ts = stream_at(streams_data, 'time', i)
|
|
156
|
+
if ts
|
|
157
|
+
pt[:timestamp] = start_time ? (start_time + ts).utc.iso8601 : ts
|
|
157
158
|
end
|
|
159
|
+
pt[:heartRate] = stream_at(streams_data, 'heartrate', i)
|
|
160
|
+
pt[:cadence] = stream_at(streams_data, 'cadence', i)
|
|
161
|
+
pt[:power] = stream_at(streams_data, 'watts', i)
|
|
162
|
+
pt[:temperature] = stream_at(streams_data, 'temp', i)
|
|
163
|
+
pt[:speed] = stream_at(streams_data, 'velocity_smooth', i)
|
|
164
|
+
pt[:distance] = stream_at(streams_data, 'distance', i)
|
|
165
|
+
pt
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def stream_at(streams_data, key, i)
|
|
169
|
+
data = streams_data[key]
|
|
170
|
+
data && i < data.size ? data[i] : nil
|
|
158
171
|
end
|
|
159
172
|
|
|
160
173
|
def build_attrs(act, category, polyline = nil, external_id: nil)
|
data/lib/git_fit/sync/xoss.rb
CHANGED
|
@@ -348,7 +348,7 @@ module GitFit
|
|
|
348
348
|
FileUtils.mkdir_p(dir)
|
|
349
349
|
tmp = File.join(dir, ".#{act_id}.json.tmp")
|
|
350
350
|
final = File.join(dir, "#{act_id}.json")
|
|
351
|
-
File.write(tmp, JSON.generate(points))
|
|
351
|
+
File.write(tmp, JSON.generate(normalize_fit_timestamps(points)))
|
|
352
352
|
File.rename(tmp, final)
|
|
353
353
|
end
|
|
354
354
|
|
data/lib/git_fit/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: git-fit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.10.
|
|
4
|
+
version: 0.10.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Lax
|
|
@@ -177,6 +177,20 @@ dependencies:
|
|
|
177
177
|
- - "~>"
|
|
178
178
|
- !ruby/object:Gem::Version
|
|
179
179
|
version: '1.0'
|
|
180
|
+
- !ruby/object:Gem::Dependency
|
|
181
|
+
name: webrick
|
|
182
|
+
requirement: !ruby/object:Gem::Requirement
|
|
183
|
+
requirements:
|
|
184
|
+
- - "~>"
|
|
185
|
+
- !ruby/object:Gem::Version
|
|
186
|
+
version: '1.9'
|
|
187
|
+
type: :runtime
|
|
188
|
+
prerelease: false
|
|
189
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
190
|
+
requirements:
|
|
191
|
+
- - "~>"
|
|
192
|
+
- !ruby/object:Gem::Version
|
|
193
|
+
version: '1.9'
|
|
180
194
|
- !ruby/object:Gem::Dependency
|
|
181
195
|
name: ostruct
|
|
182
196
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -218,6 +232,8 @@ files:
|
|
|
218
232
|
- db/migrations/002_iso8601_time_format.rb
|
|
219
233
|
- exe/git-fit
|
|
220
234
|
- lib/git-fit.rb
|
|
235
|
+
- lib/git_fit/auth/garmin_token.rb
|
|
236
|
+
- lib/git_fit/auth/strava.rb
|
|
221
237
|
- lib/git_fit/cli.rb
|
|
222
238
|
- lib/git_fit/cli/export.rb
|
|
223
239
|
- lib/git_fit/cli/geo_cli.rb
|
|
@@ -232,10 +248,17 @@ files:
|
|
|
232
248
|
- lib/git_fit/db/cli.rb
|
|
233
249
|
- lib/git_fit/db/connection.rb
|
|
234
250
|
- lib/git_fit/db/rebuild.rb
|
|
251
|
+
- lib/git_fit/dedup/field_elector.rb
|
|
252
|
+
- lib/git_fit/dedup/group_consolidator.rb
|
|
253
|
+
- lib/git_fit/dedup/log_writer.rb
|
|
254
|
+
- lib/git_fit/dedup/matcher.rb
|
|
255
|
+
- lib/git_fit/dedup/service.rb
|
|
256
|
+
- lib/git_fit/dedup/trajectory.rb
|
|
235
257
|
- lib/git_fit/export.rb
|
|
236
258
|
- lib/git_fit/export/calculator.rb
|
|
237
259
|
- lib/git_fit/export/csv.rb
|
|
238
260
|
- lib/git_fit/export/defaults.rb
|
|
261
|
+
- lib/git_fit/export/gpx.rb
|
|
239
262
|
- lib/git_fit/export/json.rb
|
|
240
263
|
- lib/git_fit/export/stats.rb
|
|
241
264
|
- lib/git_fit/fit.rb
|