postrunner 0.0.4 → 0.0.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.
@@ -1,3 +1,15 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = FlexiTable.rb -- PostRunner - Manage the data from your Garmin sport devices.
5
+ #
6
+ # Copyright (c) 2014 by Chris Schlaeger <cs@taskjuggler.org>
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of version 2 of the GNU General Public License as
10
+ # published by the Free Software Foundation.
11
+ #
12
+
1
13
  require 'postrunner/HTMLBuilder'
2
14
 
3
15
  module PostRunner
@@ -11,6 +23,7 @@ module PostRunner
11
23
  def initialize(attrs = {})
12
24
  @min_terminal_width = nil
13
25
  @halign = nil
26
+ @width = nil
14
27
 
15
28
  attrs.each do |name, value|
16
29
  ivar_name = '@' + name.to_s
@@ -70,8 +83,18 @@ module PostRunner
70
83
  end
71
84
 
72
85
  def to_html(doc)
73
- doc.td(@content.respond_to?('to_html') ?
74
- @content.to_html(doc) : @content.to_s)
86
+ text_align = get_attribute(:halign)
87
+ attrs = { :class => 'ft_cell' }
88
+ width = get_attribute(:width)
89
+ attrs[:width] = width if width
90
+ attrs[:style] = "text-align: #{text_align.to_s}" if text_align
91
+ if @content.respond_to?('to_html')
92
+ doc.td(attrs) {
93
+ @content.to_html(doc)
94
+ }
95
+ else
96
+ doc.td(@content.to_s, attrs)
97
+ end
75
98
  end
76
99
 
77
100
  private
@@ -79,7 +102,8 @@ module PostRunner
79
102
  def get_attribute(name)
80
103
  @attributes[name] ||
81
104
  @row.attributes[name] ||
82
- @table.column_attributes[@column_index][name]
105
+ (@table.column_attributes[@column_index] ?
106
+ @table.column_attributes[@column_index][name] : nil)
83
107
  end
84
108
 
85
109
  end
@@ -88,8 +112,9 @@ module PostRunner
88
112
 
89
113
  attr_reader :attributes
90
114
 
91
- def initialize(table)
115
+ def initialize(table, section)
92
116
  @table = table
117
+ @section = section
93
118
  @attributes = Attributes.new
94
119
  super()
95
120
  end
@@ -101,6 +126,7 @@ module PostRunner
101
126
  end
102
127
 
103
128
  def set_indicies(col_idx, row_idx)
129
+ @index = row_idx
104
130
  self[col_idx].set_indicies(col_idx, row_idx)
105
131
  end
106
132
 
@@ -120,7 +146,9 @@ module PostRunner
120
146
  end
121
147
 
122
148
  def to_html(doc)
123
- doc.tr {
149
+ css_class = @section == :head ? 'ft_head_row' :
150
+ @index % 2 == 0 ? 'ft_even_row' : 'ft_odd_row'
151
+ doc.tr({ :class => css_class }) {
124
152
  each { |c| c.to_html(doc) }
125
153
  }
126
154
  end
@@ -139,12 +167,17 @@ module PostRunner
139
167
  @current_row = nil
140
168
 
141
169
  @frame = true
170
+ @html_attrs = { :class => 'flexitable' }
142
171
 
143
172
  @column_attributes = []
144
173
 
145
174
  instance_eval(&block) if block_given?
146
175
  end
147
176
 
177
+ def set_html_attrs(name, value)
178
+ @html_attrs[name] = value
179
+ end
180
+
148
181
  def head
149
182
  @current_section = :head
150
183
  end
@@ -172,7 +205,7 @@ module PostRunner
172
205
  @foot_rows
173
206
  else
174
207
  raise "Unknown section #{@current_section}"
175
- end << (@current_row = Row.new(self))
208
+ end << (@current_row = Row.new(self, @current_section))
176
209
  end
177
210
  @current_row.cell(content, attributes)
178
211
  end
@@ -217,7 +250,9 @@ module PostRunner
217
250
  end
218
251
 
219
252
  def to_html(doc)
220
- doc.table {
253
+ index_table
254
+
255
+ doc.table(@html_attrs) {
221
256
  @head_rows.each { |r| r.to_html(doc) }
222
257
  @body_rows.each { |r| r.to_html(doc) }
223
258
  @foot_rows.each { |r| r.to_html(doc) }
@@ -1,3 +1,15 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = HTMLBuilder.rb -- PostRunner - Manage the data from your Garmin sport devices.
5
+ #
6
+ # Copyright (c) 2014 by Chris Schlaeger <cs@taskjuggler.org>
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of version 2 of the GNU General Public License as
10
+ # published by the Free Software Foundation.
11
+ #
12
+
1
13
  require 'nokogiri'
2
14
 
3
15
  module PostRunner
@@ -1,8 +1,21 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = Main.rb -- PostRunner - Manage the data from your Garmin sport devices.
5
+ #
6
+ # Copyright (c) 2014 by Chris Schlaeger <cs@taskjuggler.org>
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of version 2 of the GNU General Public License as
10
+ # published by the Free Software Foundation.
11
+ #
12
+
1
13
  require 'optparse'
2
14
  require 'logger'
3
15
  require 'fit4ruby'
4
16
 
5
17
  require 'postrunner/version'
18
+ require 'postrunner/RuntimeConfig'
6
19
  require 'postrunner/ActivitiesDB'
7
20
 
8
21
  module PostRunner
@@ -24,6 +37,7 @@ module PostRunner
24
37
 
25
38
  return if (args = parse_options(args)).nil?
26
39
 
40
+ @cfg = RuntimeConfig.new(@db_dir)
27
41
  execute_command(args)
28
42
  end
29
43
 
@@ -105,8 +119,10 @@ check [ <fit file> | <ref> ... ]
105
119
  dump <fit file> | <ref>
106
120
  Dump the content of the FIT file.
107
121
 
108
- import <fit file> | <directory>
109
- Import the provided FIT file(s) into the postrunner database.
122
+ import [ <fit file> | <directory> ]
123
+ Import the provided FIT file(s) into the postrunner database. If no
124
+ file or directory is provided, the directory that was used for the
125
+ previous import is being used.
110
126
 
111
127
  delete <ref>
112
128
  Delete the activity from the archive.
@@ -121,11 +137,23 @@ rename <ref>
121
137
  Replace the FIT file name with a more meaningful name that describes
122
138
  the activity.
123
139
 
124
- show <ref>
125
- Show the FIT activity in a web browser.
140
+ show [ <ref> ]
141
+ Show the referenced FIT activity in a web browser. If no reference
142
+ is provided show the list of activities in the database.
126
143
 
127
144
  summary <ref>
128
145
  Display the summary information for the FIT file.
146
+
147
+ units metric | statute
148
+ Change the unit system.
149
+
150
+
151
+ <fit file> An absolute or relative name of a .FIT file.
152
+
153
+ <ref> The index or a range of indexes to activities in the database.
154
+ :1 is the newest imported activity
155
+ :-1 is the oldest imported activity
156
+ :1-2 refers to the first and second activity in the database
129
157
  EOT
130
158
 
131
159
  end
@@ -134,7 +162,7 @@ EOT
134
162
  end
135
163
 
136
164
  def execute_command(args)
137
- @activities = ActivitiesDB.new(@db_dir)
165
+ @activities = ActivitiesDB.new(@db_dir, @cfg)
138
166
 
139
167
  case (cmd = args.shift)
140
168
  when 'check'
@@ -149,7 +177,18 @@ EOT
149
177
  @filter = Fit4Ruby::FitFilter.new unless @filter
150
178
  process_files_or_activities(args, :dump)
151
179
  when 'import'
152
- process_files(args, :import)
180
+ if args.empty?
181
+ # If we have no file or directory for the import command, we get the
182
+ # most recently used directory from the runtime config.
183
+ process_files([ @cfg.get_option(:import_dir) ], :import)
184
+ else
185
+ process_files(args, :import)
186
+ if args.length == 1 && Dir.exists?(args[0])
187
+ # If only one directory was specified as argument we store the
188
+ # directory for future use.
189
+ @cfg.set_option(:import_dir, args[0])
190
+ end
191
+ end
153
192
  when 'list'
154
193
  @activities.list
155
194
  when 'records'
@@ -157,9 +196,15 @@ EOT
157
196
  when 'rename'
158
197
  process_activities(args, :rename)
159
198
  when 'show'
160
- process_activities(args, :show)
199
+ if args.empty?
200
+ @activities.show_list_in_browser
201
+ else
202
+ process_activities(args, :show)
203
+ end
161
204
  when 'summary'
162
205
  process_activities(args, :summary)
206
+ when 'units'
207
+ change_unit_system(args)
163
208
  when nil
164
209
  Log.fatal("No command provided. " +
165
210
  "See 'postrunner -h' for more information.")
@@ -180,6 +225,10 @@ EOT
180
225
  end
181
226
 
182
227
  def process_activities(activity_refs, command)
228
+ if activity_refs.empty?
229
+ Log.fatal("You must provide at least one activity reference.")
230
+ end
231
+
183
232
  activity_refs.each do |a_ref|
184
233
  if a_ref[0] == ':'
185
234
  activities = @activities.find(a_ref[1..-1])
@@ -192,12 +241,11 @@ EOT
192
241
  Log.fatal "Activity references must start with ':': #{a_ref}"
193
242
  end
194
243
  end
195
-
196
244
  end
197
245
 
198
246
  def process_files(files_or_dirs, command)
199
247
  if files_or_dirs.empty?
200
- Log.fatal("You must provide at least one .FIT file name")
248
+ Log.fatal("You must provide at least one .FIT file name.")
201
249
  end
202
250
 
203
251
  files_or_dirs.each do |fod|
@@ -249,6 +297,17 @@ EOT
249
297
  end
250
298
  end
251
299
 
300
+ def change_unit_system(args)
301
+ if args.length != 1 || !%w( metric statute ).include?(args[0])
302
+ Log.fatal("You must specify 'metric' or 'statute' as unit system.")
303
+ end
304
+
305
+ if @cfg[:unit_system].to_s != args[0]
306
+ @cfg.set_option(:unit_system, args[0].to_sym)
307
+ @activities.generate_all_html_reports
308
+ end
309
+ end
310
+
252
311
  end
253
312
 
254
313
  end
@@ -1,3 +1,15 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = PersonalRecords.rb -- PostRunner - Manage the data from your Garmin sport devices.
5
+ #
6
+ # Copyright (c) 2014 by Chris Schlaeger <cs@taskjuggler.org>
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of version 2 of the GNU General Public License as
10
+ # published by the Free Software Foundation.
11
+ #
12
+
1
13
  require 'fileutils'
2
14
  require 'yaml'
3
15
 
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = ActivitiesDB.rb -- PostRunner - Manage the data from your Garmin sport devices.
5
+ #
6
+ # Copyright (c) 2014 by Chris Schlaeger <cs@taskjuggler.org>
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of version 2 of the GNU General Public License as
10
+ # published by the Free Software Foundation.
11
+ #
12
+
13
+ require 'yaml'
14
+ require 'fit4ruby'
15
+
16
+ module PostRunner
17
+
18
+ # Simple class to manage runtime configuration options which are persisted
19
+ # in a YAML file.
20
+ class RuntimeConfig
21
+
22
+ # Create a new RC object.
23
+ # @param dir [String] the directory to hold the config.yml file.
24
+ def initialize(dir)
25
+ @options = {
26
+ :unit_system => :metric,
27
+ :import_dir => nil
28
+ }
29
+ @config_file = File.join(dir, 'config.yml')
30
+
31
+ load_options if File.exist?(@config_file)
32
+ end
33
+
34
+ # Shortcut for get_option.
35
+ # @param name [Symbol] the name of the config option.
36
+ # @return [Object] the value of the config option.
37
+ def [](name)
38
+ get_option(name)
39
+ end
40
+
41
+ # Get a config option value.
42
+ # @param name [Symbol] the name of the config option.
43
+ # @return [Object] the value of the config option.
44
+ def get_option(name)
45
+ @options[name]
46
+ end
47
+
48
+ # Set a config option and update the RC file.
49
+ # @param name [Symbol] The name of the config option.
50
+ # @param value [Object] The value of the config option.
51
+ def set_option(name, value)
52
+ @options[name] = value
53
+ save_options
54
+ end
55
+
56
+ private
57
+
58
+ def load_options
59
+ begin
60
+ opts = YAML::load_file(@config_file)
61
+ rescue IOError
62
+ Log.error "Cannot load config file '#{@config_file}': #{$!}"
63
+ end
64
+ # Merge the loaded options into the @options hash.
65
+ opts.each { |key, value| @options[key] = value }
66
+ end
67
+
68
+ def save_options
69
+ begin
70
+ File.write(@config_file, @options.to_yaml)
71
+ Log.info "Runtime config file '#{@config_file}' written"
72
+ rescue
73
+ Log.error "Cannot write config file '#{@config_file}': #{$!}"
74
+ end
75
+ end
76
+
77
+ end
78
+
79
+ end
80
+
@@ -1,3 +1,15 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = TrackView.rb -- PostRunner - Manage the data from your Garmin sport devices.
5
+ #
6
+ # Copyright (c) 2014 by Chris Schlaeger <cs@taskjuggler.org>
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of version 2 of the GNU General Public License as
10
+ # published by the Free Software Foundation.
11
+ #
12
+
1
13
  require 'fit4ruby'
2
14
 
3
15
  require 'postrunner/ViewWidgets'
@@ -10,9 +22,13 @@ module PostRunner
10
22
 
11
23
  def initialize(activity)
12
24
  @activity = activity
25
+ @session = @activity.fit_activity.sessions[0]
26
+ @has_geo_data = @session.has_geo_data?
13
27
  end
14
28
 
15
29
  def head(doc)
30
+ return unless @has_geo_data
31
+
16
32
  doc.link({ 'rel' => 'stylesheet',
17
33
  'href' => 'openlayers/theme/default/style.css',
18
34
  'type' => 'text/css' })
@@ -22,6 +38,8 @@ module PostRunner
22
38
  end
23
39
 
24
40
  def div(doc)
41
+ return unless @has_geo_data
42
+
25
43
  frame(doc, 'Map') {
26
44
  doc.div({ 'id' => 'map', 'class' => 'trackmap' })
27
45
  }
@@ -36,7 +54,7 @@ module PostRunner
36
54
  }
37
55
 
38
56
  .trackmap {
39
- width: 570px;
57
+ width: 565px;
40
58
  height: 400px;
41
59
  border: 2px solid #545454;
42
60
  }
@@ -52,11 +70,10 @@ function init() {
52
70
  var geographic = new OpenLayers.Projection("EPSG:4326");
53
71
  EOT
54
72
 
55
- session = @activity.fit_activity.sessions[0]
56
- center_long = session.swc_long +
57
- (session.nec_long - session.swc_long) / 2.0
58
- center_lat = session.swc_lat +
59
- (session.nec_lat - session.swc_lat) / 2.0
73
+ center_long = @session.swc_long +
74
+ (@session.nec_long - @session.swc_long) / 2.0
75
+ center_lat = @session.swc_lat +
76
+ (@session.nec_lat - @session.swc_lat) / 2.0
60
77
  last_lap = @activity.fit_activity.laps[-1]
61
78
 
62
79
  js << <<EOT
@@ -84,8 +101,8 @@ EOT
84
101
  var size = new OpenLayers.Size(21,25);
85
102
  var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
86
103
  EOT
87
- set_marker(js, 'marker-green', session.start_position_long,
88
- session.start_position_lat)
104
+ set_marker(js, 'marker-green', @session.start_position_long,
105
+ @session.start_position_lat)
89
106
  @activity.fit_activity.laps[0..-2].each do |lap|
90
107
  set_marker(js, 'marker-blue',
91
108
  lap.end_position_long, lap.end_position_lat)
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = UserProfileView.rb -- PostRunner - Manage the data from your Garmin sport devices.
5
+ #
6
+ # Copyright (c) 2014 by Chris Schlaeger <cs@taskjuggler.org>
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of version 2 of the GNU General Public License as
10
+ # published by the Free Software Foundation.
11
+ #
12
+
13
+ require 'fit4ruby'
14
+
15
+ require 'postrunner/ViewWidgets'
16
+
17
+ module PostRunner
18
+
19
+ class UserProfileView
20
+
21
+ include ViewWidgets
22
+
23
+ def initialize(fit_activity, unit_system)
24
+ @fit_activity = fit_activity
25
+ @unit_system = unit_system
26
+ end
27
+
28
+ def to_html(doc)
29
+ return nil if @fit_activity.user_profiles.empty?
30
+
31
+ frame(doc, 'User Profile') {
32
+ profile.to_html(doc)
33
+ }
34
+ end
35
+
36
+ def to_s
37
+ return '' if @fit_activity.user_profiles.empty?
38
+ profile.to_s
39
+ end
40
+
41
+ private
42
+
43
+ def profile
44
+ t = FlexiTable.new
45
+ profile = @fit_activity.user_profiles.first
46
+ if profile.height
47
+ unit = { :metric => 'm', :statute => 'ft' }[@unit_system]
48
+ height = profile.get_as('height', unit)
49
+ t.cell('Height:', { :width => '40%' })
50
+ t.cell("#{'%.1f' % height} #{unit}", { :width => '60%' })
51
+ t.new_row
52
+ end
53
+ if profile.weight
54
+ unit = { :metric => 'kg', :statute => 'lbs' }[@unit_system]
55
+ weight = profile.get_as('weight', unit)
56
+ t.row([ 'Weight:', "#{'%.1f' % weight} #{unit}" ])
57
+ end
58
+ t.row([ 'Gender:', profile.gender ]) if profile.gender
59
+ t.row([ 'Age:', "#{profile.age} years" ]) if profile.age
60
+ t.row([ 'Max. Heart Rate:', "#{profile.max_hr} bpm" ]) if profile.max_hr
61
+ if profile.activity_class
62
+ t.row([ 'Activity Class:', profile.activity_class ])
63
+ end
64
+ t
65
+ end
66
+
67
+ end
68
+
69
+ end
70
+
@@ -1,9 +1,50 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = ViewWidgets.rb -- PostRunner - Manage the data from your Garmin sport devices.
5
+ #
6
+ # Copyright (c) 2014 by Chris Schlaeger <cs@taskjuggler.org>
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of version 2 of the GNU General Public License as
10
+ # published by the Free Software Foundation.
11
+ #
12
+
1
13
  module PostRunner
2
14
 
3
15
  module ViewWidgets
4
16
 
5
17
  def view_widgets_style(doc)
6
18
  doc.style(<<EOT
19
+ .titlebar {
20
+ width: 100%;
21
+ height: 50px;
22
+ margin: 0px;
23
+ background: linear-gradient(#7FA1FF 0, #002EAC 50px);
24
+ }
25
+ .title {
26
+ float: left;
27
+ font-size: 24pt;
28
+ font-style: italic;
29
+ font-weight: bold;
30
+ color: #F8F8F8;
31
+ text-shadow: -1px -1px 0 #5C5C5C,
32
+ 1px -1px 0 #5C5C5C,
33
+ -1px 1px 0 #5C5C5C,
34
+ 1px 1px 0 #5C5C5C;
35
+ padding: 3px 30px;
36
+ }
37
+ .navigator {
38
+ float: right;
39
+ padding: 3px 30px;
40
+ }
41
+ .active_button {
42
+ padding: 5px;
43
+ }
44
+ .inactive_button {
45
+ padding: 5px;
46
+ opacity: 0.4;
47
+ }
7
48
  .widget_frame {
8
49
  box-sizing: border-box;
9
50
  width: 600px;
@@ -23,7 +64,36 @@ module PostRunner
23
64
  -webkit-box-shadow: 0 3px 10px rgba(0,0,0,0.1);
24
65
  }
25
66
  .widget_frame_title {
67
+ font-size:13pt;
26
68
  padding-bottom: 5px;
69
+ text-align: left;
70
+ }
71
+ .flexitable {
72
+ width: 100%;
73
+ border: 2px solid #545454;
74
+ border-collapse: collapse;
75
+ font-size:11pt;
76
+ }
77
+ .ft_head_row {
78
+ background-color: #DEDEDE
79
+ }
80
+ .ft_even_row {
81
+ background-color: #FCFCFC
82
+ }
83
+ .ft_odd_row {
84
+ background-color: #F1F1F1
85
+ }
86
+ .ft_cell {
87
+ border: 1px solid #CCCCCC;
88
+ padding: 1px 3px;
89
+ }
90
+ .footer {
91
+ clear: both;
92
+ width: 100%;
93
+ height: 30px;
94
+ padding: 15px;
95
+ text-align: center;
96
+ font-size: 9pt;
27
97
  }
28
98
  EOT
29
99
  )
@@ -40,6 +110,43 @@ EOT
40
110
  }
41
111
  end
42
112
 
113
+ def titlebar(doc, first_page = nil, prev_page = nil, home_page = nil,
114
+ next_page = nil, last_page = nil)
115
+ # The top title bar.
116
+ doc.div({ :class => 'titlebar' }) {
117
+ doc.div('PostRunner', { :class => 'title' })
118
+ doc.div({ :class => 'navigator' }) {
119
+ button(doc, first_page, 'first.png')
120
+ button(doc, prev_page, 'back.png')
121
+ button(doc, home_page, 'home.png')
122
+ button(doc, next_page, 'forward.png')
123
+ button(doc, last_page, 'last.png')
124
+ }
125
+ }
126
+ end
127
+
128
+ def button(doc, link, icon)
129
+ if link
130
+ doc.a({ :href => link }) {
131
+ doc.img({ :src => "icons/#{icon}", :class => 'active_button' })
132
+ }
133
+ else
134
+ doc.img({ :src => "icons/#{icon}", :class => 'inactive_button' })
135
+ end
136
+ end
137
+
138
+ def footer(doc)
139
+ doc.div({ :class => 'footer' }){
140
+ doc.hr
141
+ doc.div({ :class => 'copyright' }) {
142
+ doc.text("Generated by ")
143
+ doc.a('PostRunner',
144
+ { :href => 'https://github.com/scrapper/postrunner' })
145
+ doc.text(" #{VERSION} on #{Time.now}")
146
+ }
147
+ }
148
+ end
149
+
43
150
  end
44
151
 
45
152
  end
@@ -1,3 +1,15 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = version.rb -- PostRunner - Manage the data from your Garmin sport devices.
5
+ #
6
+ # Copyright (c) 2014 by Chris Schlaeger <cs@taskjuggler.org>
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of version 2 of the GNU General Public License as
10
+ # published by the Free Software Foundation.
11
+ #
12
+
1
13
  module PostRunner
2
- VERSION = "0.0.4"
14
+ VERSION = "0.0.5"
3
15
  end
data/lib/postrunner.rb CHANGED
@@ -1,3 +1,15 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = postrunner.rb -- PostRunner - Manage the data from your Garmin sport devices.
5
+ #
6
+ # Copyright (c) 2014 by Chris Schlaeger <cs@taskjuggler.org>
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of version 2 of the GNU General Public License as
10
+ # published by the Free Software Foundation.
11
+ #
12
+
1
13
  $:.unshift(File.join(File.dirname(__FILE__), '..', '..', 'fit4ruby', 'lib'))
2
14
  $:.unshift(File.dirname(__FILE__))
3
15
 
Binary file