postrunner 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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