strava-cli 0.0.1 → 0.0.2
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/strava/activity.rb +33 -0
- data/lib/strava/app.rb +97 -35
- data/lib/strava/version.rb +1 -1
- data/lib/strava.rb +5 -0
- data/strava.gemspec +1 -0
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0d795febc4b2b8ba8c192ffd1011d7c3d10090ae
|
4
|
+
data.tar.gz: e62ff619b626dd2de5275ae79ad0a2060e86b1ed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5b10992a18ffdcfa8deda09e5e38b5b4628073f8193504fdc7dd13227667d3d1bc79d4468fbc462c2d59b0f2d47ae28a62b0b13c6f18915d26f82a010893c3df
|
7
|
+
data.tar.gz: 9f84c2b6147871938fa2ae154a2788f262b8c56a95ea30ee47ce0d0e163b57a4ff00c75a1007fe6a05e9af929886f02aad640b27410043b36fcb26a1c138b1cf
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'time'
|
2
|
+
|
3
|
+
# Strava activity model
|
4
|
+
class Activity
|
5
|
+
attr_accessor :date, :distance_km, :elapsed_time_min, :avg_speed
|
6
|
+
|
7
|
+
# Initialize an activity from the raw API json from Strava
|
8
|
+
#
|
9
|
+
# +raw_activity+ [Hash]
|
10
|
+
def initialize(raw_activity)
|
11
|
+
@date = Time.parse(raw_activity.start_date_local)
|
12
|
+
@distance_km = (raw_activity.distance / 1000.0).round(3)
|
13
|
+
@elapsed_time_min = (raw_activity.elapsed_time / 60.0).round(2)
|
14
|
+
elapsed_time_hour = (raw_activity.elapsed_time / 3600.0)
|
15
|
+
@avg_speed = (distance_km / elapsed_time_hour).round(2)
|
16
|
+
end
|
17
|
+
|
18
|
+
def human_date
|
19
|
+
date.strftime("%d %h %Y")
|
20
|
+
end
|
21
|
+
|
22
|
+
def human_distance_km
|
23
|
+
"#{distance_km} km"
|
24
|
+
end
|
25
|
+
|
26
|
+
def human_elapsed_time
|
27
|
+
"#{elapsed_time_min} min"
|
28
|
+
end
|
29
|
+
|
30
|
+
def human_avg_speed
|
31
|
+
"#{avg_speed} km/h"
|
32
|
+
end
|
33
|
+
end
|
data/lib/strava/app.rb
CHANGED
@@ -1,12 +1,8 @@
|
|
1
1
|
require 'easy_app_helper'
|
2
2
|
require 'terminal-table'
|
3
|
+
require 'ascii_charts'
|
3
4
|
require 'strava/api/v3'
|
4
5
|
require 'vcr'
|
5
|
-
require 'time'
|
6
|
-
|
7
|
-
# Method access to Hash content
|
8
|
-
require 'hashie'
|
9
|
-
class Hash; include Hashie::Extensions::MethodAccess; end
|
10
6
|
|
11
7
|
# Configure HTTP records
|
12
8
|
VCR.configure do |config|
|
@@ -21,7 +17,8 @@ module Strava
|
|
21
17
|
NAME = 'Strava Dashboard'
|
22
18
|
DESCRIPTION = 'Fetchs data from strava to report what you have done'
|
23
19
|
|
24
|
-
attr_accessor :client, :types, :
|
20
|
+
attr_accessor :client, :types, :graph, :activities
|
21
|
+
|
25
22
|
def initialize
|
26
23
|
config.config_file_base_name = 'strava'
|
27
24
|
config.describes_application app_name: NAME,
|
@@ -31,6 +28,7 @@ module Strava
|
|
31
28
|
config.add_command_line_section('Strava options') do |slop|
|
32
29
|
slop.on :strava_access_token, 'Strava access token', argument: true, as: String
|
33
30
|
slop.on :activity, 'Display this activity type only (Run, Ride, Swim)', argument: true
|
31
|
+
slop.on :graph, 'Display a graph instead of a table', argument: false
|
34
32
|
end
|
35
33
|
|
36
34
|
if config[:help]
|
@@ -43,7 +41,8 @@ module Strava
|
|
43
41
|
else
|
44
42
|
@types = %w(Run Ride Swim)
|
45
43
|
end
|
46
|
-
@
|
44
|
+
@graph = config[:graph]
|
45
|
+
@activities = []
|
47
46
|
end
|
48
47
|
|
49
48
|
def configure_api_client
|
@@ -53,44 +52,107 @@ module Strava
|
|
53
52
|
def run
|
54
53
|
configure_api_client
|
55
54
|
|
56
|
-
|
57
|
-
|
58
|
-
VCR.use_cassette("activities", record: :new_episodes) do
|
59
|
-
page = 0
|
60
|
-
per_page = 100
|
61
|
-
while activities.count == page*per_page
|
62
|
-
page +=1
|
63
|
-
activities += client.list_athlete_activities(per_page: per_page,page: page)
|
64
|
-
end
|
65
|
-
end
|
55
|
+
fetch_activities_data
|
66
56
|
|
67
57
|
for type in types
|
68
|
-
rows = []
|
69
|
-
month = -1
|
70
|
-
activities.select { |activity| activity.type == type }.each do |activity|
|
71
|
-
date = Time.parse(activity.start_date_local)
|
72
|
-
current_month = date.month
|
73
|
-
distance_km = (activity.distance/1000.0).round(3)
|
74
|
-
elapsed_time_min = (activity.elapsed_time/60.0).round(2)
|
75
|
-
elapsed_time_hour = (activity.elapsed_time/3600.0)
|
76
|
-
avg_speed = (distance_km/elapsed_time_hour).round(2)
|
77
|
-
if current_month != month && month != -1
|
78
|
-
rows << :separator
|
79
|
-
end
|
80
|
-
month = current_month
|
81
|
-
rows << [date , "#{distance_km} km", "#{elapsed_time_min} min", "#{avg_speed} km/h"]
|
82
|
-
end
|
83
58
|
|
84
|
-
|
59
|
+
if graph
|
60
|
+
output_screen = build_graph_speed(type)
|
61
|
+
else
|
62
|
+
output_screen = build_table(type)
|
63
|
+
end
|
85
64
|
|
86
|
-
if
|
65
|
+
if output_screen.nil?
|
87
66
|
puts "No activity found. Go out and start #{type}ing!"
|
88
67
|
else
|
89
|
-
puts
|
68
|
+
puts output_screen
|
90
69
|
end
|
91
70
|
puts "\n"
|
92
71
|
end
|
93
72
|
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def build_table(activity_type)
|
77
|
+
fields = ["Date", "Distance", "Elapsed time", "Avg speed"]
|
78
|
+
rows = []
|
79
|
+
date = -1
|
80
|
+
|
81
|
+
select_activities(activity_type).each do |raw_activity|
|
82
|
+
activity = Activity.new(raw_activity)
|
83
|
+
current_date = activity.date
|
84
|
+
|
85
|
+
rows << :separator if date != -1 && current_date.month != date.month
|
86
|
+
|
87
|
+
date = current_date
|
88
|
+
rows << [
|
89
|
+
activity.human_date,
|
90
|
+
activity.human_distance_km,
|
91
|
+
activity.human_elapsed_time,
|
92
|
+
activity.human_avg_speed
|
93
|
+
]
|
94
|
+
end
|
95
|
+
|
96
|
+
Terminal::Table.new(
|
97
|
+
title: activity_type,
|
98
|
+
headings: fields,
|
99
|
+
rows: rows
|
100
|
+
) unless rows.empty?
|
101
|
+
end
|
102
|
+
|
103
|
+
def build_graph_speed(activity_type)
|
104
|
+
graph = ''
|
105
|
+
|
106
|
+
all = select_activities(activity_type).map do |raw_activity|
|
107
|
+
Activity.new(raw_activity)
|
108
|
+
end
|
109
|
+
|
110
|
+
activities_by_year = all.group_by do |activity|
|
111
|
+
activity.date.year
|
112
|
+
end
|
113
|
+
|
114
|
+
activities_by_year.each do |year, a|
|
115
|
+
data = []
|
116
|
+
|
117
|
+
activities_by_month = a.group_by do |activity|
|
118
|
+
activity.date.month
|
119
|
+
end
|
120
|
+
|
121
|
+
activities_by_month.each do |month, activities|
|
122
|
+
avg_speed = activities.sum(&:avg_speed) / activities.size
|
123
|
+
|
124
|
+
data << [
|
125
|
+
"#{month}/#{year}",
|
126
|
+
avg_speed
|
127
|
+
]
|
128
|
+
end
|
129
|
+
|
130
|
+
if data.size > 1
|
131
|
+
graph += AsciiCharts::Cartesian.new(
|
132
|
+
data.reverse,
|
133
|
+
title: "#{year} - #{activity_type} avg speed",
|
134
|
+
step_size: 0.3
|
135
|
+
).draw + "\n"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
graph unless graph.empty?
|
140
|
+
end
|
141
|
+
|
142
|
+
def fetch_activities_data
|
143
|
+
VCR.use_cassette("activities", record: :new_episodes) do
|
144
|
+
page = 0
|
145
|
+
per_page = 100
|
146
|
+
while activities.count == page*per_page
|
147
|
+
page +=1
|
148
|
+
@activities += client.list_athlete_activities(per_page: per_page,page: page)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def select_activities(type)
|
154
|
+
activities.select { |activity| activity.type == type }
|
155
|
+
end
|
94
156
|
end
|
95
157
|
end
|
96
158
|
|
data/lib/strava/version.rb
CHANGED
data/lib/strava.rb
CHANGED
data/strava.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: strava-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Bonaud
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-08-
|
11
|
+
date: 2017-08-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: easy_app_helper
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: ascii-charts
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: pry
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -302,6 +316,7 @@ files:
|
|
302
316
|
- Gemfile
|
303
317
|
- bin/strava
|
304
318
|
- lib/strava.rb
|
319
|
+
- lib/strava/activity.rb
|
305
320
|
- lib/strava/app.rb
|
306
321
|
- lib/strava/version.rb
|
307
322
|
- strava.gemspec
|