summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Schlaeger <chris@linux.com>2014-08-14 21:46:37 +0200
committerChris Schlaeger <chris@linux.com>2014-08-14 21:46:37 +0200
commit23e44d54a2d86113987cd6fa8f53ccad8071ba8a (patch)
tree2c4cf772ac3b594a0573ec6b81a14235398e7610
parentea346a785dc1b3f7c156f6fc33da634e1f1a627b (diff)
downloadpostrunner-23e44d54a2d86113987cd6fa8f53ccad8071ba8a.zip
Don't show track map or chart if no data is available.
-rw-r--r--README.md51
-rw-r--r--lib/postrunner/ActivityView.rb24
-rw-r--r--lib/postrunner/ChartView.rb34
-rw-r--r--lib/postrunner/TrackView.rb19
4 files changed, 82 insertions, 46 deletions
diff --git a/README.md b/README.md
index ab09bd1..3099b11 100644
--- a/README.md
+++ b/README.md
@@ -6,35 +6,66 @@ PostRunner is an application to manage FIT files such as those produced by Garmi
PostRunner is a Ruby application. You need to have a Ruby 2.0 or later runtime environment installed.
- $ gem install postrunner
+```
+$ gem install postrunner
+```
## Usage
To get started you need to connect your device to your computer and mount it as a drive. Only devices that expose their data as FAT file system are supported. Older devices use proprietary drivers and are not supported by postrunner. Once the device is mounted find out the full path to the directory that contains your FIT files. You can then import all files on the device.
- $ postrunner import /var/run/media/user/GARMIN/GARMIN/ACTIVITY/
+```
+$ postrunner import /var/run/media/user/GARMIN/GARMIN/ACTIVITY/
+```
The above command assumes that your device is mounted as /var/run/media/user. Please replace this with the path to your device. Files that have been imported previously will not be imported again.
Now you can list all the FIT files in your data base.
- $ postrunner list
+```
+$ postrunner list
+```
-The first column is the index you can use to reference FIT files. To get a summary of the most recent activity use the following command.
+The first column is the index you can use to reference FIT files. To
+get a summary of the most recent activity use the following command.
+References to already imported activities start with a colon followed
+by the index number.
+
+```
+$ postrunner summary :1
+```
+
+Or you can view the full details of your activity in your browser.
+This view includes a map (internet connection for map data required)
+and charts.
+
+```
+$ postrunner show :1
+```
- $ postrunner summary :1
-
To get a summary of the oldest activity you can use
- $ postrunner summary :-1
-
+```
+$ postrunner summary :-1
+```
+
+To select multiple activities you can use a range.
+
+```
+$ postrunner summary :1-3
+```
+
You can also get a full dump of the content of a FIT file.
- $ postrunner dump 1234568.FIT
+```
+$ postrunner dump 1234568.FIT
+```
If the file is already in the data base you can also use the reference notation.
- $ postrunner dump :1
+```
+$ postrunner dump :1
+```
This will provide you with a lot more information contained in the FIT files that is not available through Garmin Connect or most other tools.
diff --git a/lib/postrunner/ActivityView.rb b/lib/postrunner/ActivityView.rb
index 5d34ca0..ecb069c 100644
--- a/lib/postrunner/ActivityView.rb
+++ b/lib/postrunner/ActivityView.rb
@@ -104,24 +104,6 @@ module PostRunner
float: right;
width: 600px;
}
-.widget_container {
- box-sizing: border-box;
- width: 600px;
- padding: 10px 15px 15px 15px;
- margin: 15px auto 15px auto;
- border: 1px solid #ddd;
- background: #fff;
- background: linear-gradient(#f6f6f6 0, #fff 50px);
- background: -o-linear-gradient(#f6f6f6 0, #fff 50px);
- background: -ms-linear-gradient(#f6f6f6 0, #fff 50px);
- background: -moz-linear-gradient(#f6f6f6 0, #fff 50px);
- background: -webkit-linear-gradient(#f6f6f6 0, #fff 50px);
- box-shadow: 0 3px 10px rgba(0,0,0,0.15);
- -o-box-shadow: 0 3px 10px rgba(0,0,0,0.1);
- -ms-box-shadow: 0 3px 10px rgba(0,0,0,0.1);
- -moz-box-shadow: 0 3px 10px rgba(0,0,0,0.1);
- -webkit-box-shadow: 0 3px 10px rgba(0,0,0,0.1);
-}
EOT
)
end
@@ -150,7 +132,11 @@ EOT
end
def show_in_browser
- system("firefox \"#{@output_file}\" &")
+ cmd = "#{ENV['BROWSER'] || 'firefox'} \"#{@output_file}\" &"
+ unless system(cmd)
+ Log.fatal "Failed to execute the following shell command: #{$cmd}\n" +
+ "#{$!}"
+ end
end
end
diff --git a/lib/postrunner/ChartView.rb b/lib/postrunner/ChartView.rb
index 1ccdc2d..9ec86bd 100644
--- a/lib/postrunner/ChartView.rb
+++ b/lib/postrunner/ChartView.rb
@@ -8,6 +8,7 @@ module PostRunner
def initialize(activity)
@activity = activity
+ @empty_charts = {}
end
def head(doc)
@@ -94,14 +95,9 @@ EOT
def line_graph(field, color = nil)
s = "var #{field}_data = [\n"
- first = true
+ data_set = []
start_time = @activity.fit_activity.sessions[0].start_time.to_i
@activity.fit_activity.records.each do |r|
- if first
- first = false
- else
- s << ', '
- end
value = r.send(field)
if field == 'pace'
if value > 20.0
@@ -110,9 +106,17 @@ EOT
value = (value * 3600.0 * 1000).to_i
end
end
- s << "[ #{((r.timestamp.to_i - start_time) * 1000).to_i}, " +
- "#{value ? value : 'null'} ]"
+ data_set << [ ((r.timestamp.to_i - start_time) * 1000).to_i, value ]
+ end
+
+ # We don't want to plot charts with all nil values.
+ unless data_set.find { |v| v[1] != nil }
+ @empty_charts[field] = true
+ return ''
end
+ s << data_set.map do |set|
+ "[ #{set[0]}, #{set[1] ? set[1] : 'null'} ]"
+ end.join(', ')
s << <<"EOT"
];
@@ -120,7 +124,8 @@ EOT
$.plot("##{field}_chart",
[ { data: #{field}_data,
#{color ? "color: \"#{color}\"," : ''}
- lines: { show: true#{field == 'pace' ? '' : ', fill: true'} } } ],
+ lines: { show: true#{field == 'pace' ? '' :
+ ', fill: true'} } } ],
{ xaxis: { mode: "time" }
EOT
if field == 'pace'
@@ -144,7 +149,7 @@ EOT
start_time = @activity.fit_activity.sessions[0].start_time.to_i
@activity.fit_activity.records.each do |r|
# Undefined values will be discarded.
- next unless (value = r.instance_variable_get('@' + field))
+ next unless (value = r.send(field))
value *= multiplier
# Find the right set by looking at the maximum allowed values for each
@@ -163,6 +168,12 @@ EOT
end
end
+ # We don't want to plot charts with all nil values.
+ if data_sets.values.flatten.empty?
+ @empty_charts[field] = true
+ return ''
+ end
+
# Now generate the JS variable definitions for each set.
s = ''
data_sets.each do |index, ds|
@@ -184,6 +195,9 @@ EOT
end
def chart_div(doc, field, title)
+ # Don't plot frame for graph without data.
+ return if @empty_charts[field]
+
frame(doc, title) {
doc.div({ 'id' => "#{field}_chart", 'class' => 'chart-placeholder'})
}
diff --git a/lib/postrunner/TrackView.rb b/lib/postrunner/TrackView.rb
index 50e314d..9976cd1 100644
--- a/lib/postrunner/TrackView.rb
+++ b/lib/postrunner/TrackView.rb
@@ -10,9 +10,13 @@ module PostRunner
def initialize(activity)
@activity = activity
+ @session = @activity.fit_activity.sessions[0]
+ @has_geo_data = @session.has_geo_data?
end
def head(doc)
+ return unless @has_geo_data
+
doc.link({ 'rel' => 'stylesheet',
'href' => 'openlayers/theme/default/style.css',
'type' => 'text/css' })
@@ -22,6 +26,8 @@ module PostRunner
end
def div(doc)
+ return unless @has_geo_data
+
frame(doc, 'Map') {
doc.div({ 'id' => 'map', 'class' => 'trackmap' })
}
@@ -52,11 +58,10 @@ function init() {
var geographic = new OpenLayers.Projection("EPSG:4326");
EOT
- session = @activity.fit_activity.sessions[0]
- center_long = session.swc_long +
- (session.nec_long - session.swc_long) / 2.0
- center_lat = session.swc_lat +
- (session.nec_lat - session.swc_lat) / 2.0
+ center_long = @session.swc_long +
+ (@session.nec_long - @session.swc_long) / 2.0
+ center_lat = @session.swc_lat +
+ (@session.nec_lat - @session.swc_lat) / 2.0
last_lap = @activity.fit_activity.laps[-1]
js << <<EOT
@@ -84,8 +89,8 @@ EOT
var size = new OpenLayers.Size(21,25);
var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
EOT
- set_marker(js, 'marker-green', session.start_position_long,
- session.start_position_lat)
+ set_marker(js, 'marker-green', @session.start_position_long,
+ @session.start_position_lat)
@activity.fit_activity.laps[0..-2].each do |lap|
set_marker(js, 'marker-blue',
lap.end_position_long, lap.end_position_lat)