gooby 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/README +200 -35
  2. data/bin/code_scan.rb +1 -3
  3. data/bin/gooby_been_there.rb +12 -14
  4. data/bin/gooby_config.rb +11 -3
  5. data/bin/gooby_csv_validation.rb +50 -0
  6. data/bin/gooby_first_trackpoints_as_poi.rb +31 -0
  7. data/bin/gooby_gen_gmap.rb +7 -3
  8. data/bin/gooby_parser.rb +7 -5
  9. data/bin/gooby_splitter.rb +7 -4
  10. data/bin/gooby_version.rb +7 -3
  11. data/bin/run_all.sh +12 -2
  12. data/bin/run_been_there.sh +4 -1
  13. data/bin/run_config.sh +12 -0
  14. data/bin/run_csv_validation.sh +15 -0
  15. data/bin/run_db_gen.sh +1 -1
  16. data/bin/run_db_load.sh +1 -1
  17. data/bin/run_first_trackpoints_as_poi.sh +16 -0
  18. data/bin/run_gen_gmaps.sh +7 -6
  19. data/bin/run_parse_full.sh +45 -0
  20. data/bin/run_parse_samples.sh +21 -0
  21. data/bin/run_split.sh +5 -4
  22. data/bin/run_version.sh +12 -0
  23. data/config/gooby_config.yaml +130 -131
  24. data/data/20050305_corporate_cup_hm.csv +251 -251
  25. data/data/20050430_nashville_marathon_km.csv +1208 -0
  26. data/data/20060115_phoenix_marathon.csv +1280 -1280
  27. data/data/20070101_davidson_11m.csv +251 -0
  28. data/data/{davidson_11m_20070101.xml → 20070101_davidson_11m.xml} +0 -0
  29. data/data/{davidson_5K_20070505.xml → 20070505_davidson_5k.xml} +0 -0
  30. data/data/20070505_davidson_5k_km.csv +286 -0
  31. data/data/hrm1.csv +5 -0
  32. data/lib/gooby.rb +27 -3144
  33. data/lib/gooby_code_scanner.rb +288 -0
  34. data/lib/gooby_command.rb +210 -0
  35. data/lib/gooby_configuration.rb +123 -0
  36. data/lib/gooby_counter_hash.rb +95 -0
  37. data/lib/gooby_course.rb +117 -0
  38. data/lib/gooby_csv_point.rb +71 -0
  39. data/lib/gooby_csv_reader.rb +71 -0
  40. data/lib/gooby_csv_run.rb +28 -0
  41. data/lib/gooby_delim_line.rb +42 -0
  42. data/lib/gooby_dttm.rb +87 -0
  43. data/lib/gooby_duration.rb +86 -0
  44. data/lib/gooby_forerunner_xml_parser.rb +191 -0
  45. data/lib/gooby_forerunner_xml_splitter.rb +115 -0
  46. data/lib/gooby_google_map_generator.rb +385 -0
  47. data/lib/gooby_history.rb +41 -0
  48. data/lib/gooby_kernel.rb +163 -0
  49. data/lib/gooby_lap.rb +30 -0
  50. data/lib/gooby_line.rb +80 -0
  51. data/lib/gooby_object.rb +22 -0
  52. data/lib/gooby_point.rb +172 -0
  53. data/lib/gooby_run.rb +213 -0
  54. data/lib/gooby_simple_xml_parser.rb +50 -0
  55. data/lib/gooby_test_helper.rb +23 -0
  56. data/lib/gooby_track.rb +47 -0
  57. data/lib/gooby_track_point.rb +229 -0
  58. data/lib/gooby_training_center_xml_parser.rb +224 -0
  59. data/lib/gooby_training_center_xml_splitter.rb +116 -0
  60. data/lib/split_code.sh +29 -0
  61. data/samples/20050305_corporate_cup_hm.html +269 -269
  62. data/samples/20050430_nashville_marathon.html +1410 -1266
  63. data/samples/20060115_phoenix_marathon.html +1311 -1311
  64. data/samples/{davidson_11m_20070101.html → 20070101_davidson_11m.html} +267 -267
  65. data/samples/20070505_davidson_5k.html +413 -0
  66. data/samples/been_there.txt +52 -704
  67. data/samples/hrm1.html +87 -0
  68. data/sql/gooby.ddl +20 -16
  69. data/sql/gooby_load.dml +36 -9
  70. metadata +48 -14
  71. data/bin/example_usage.txt +0 -55
  72. data/bin/run_parse.sh +0 -43
  73. data/bin/run_parse_named.sh +0 -19
  74. data/data/20050430_nashville_marathon.csv +0 -1208
  75. data/data/davidson_11m_20070101.csv +0 -251
  76. data/data/davidson_5K_20070505.csv +0 -286
  77. data/data/test1.txt +0 -4
  78. data/samples/davidson_5K_20070505.html +0 -395
@@ -0,0 +1,50 @@
1
+ =begin
2
+
3
+ Gooby = Google APIs + Ruby
4
+ Gooby - Copyright 2007 by Chris Joakim.
5
+ Gooby is available under GNU General Public License (GPL) license.
6
+
7
+ =end
8
+
9
+ module Gooby
10
+
11
+ =begin rdoc
12
+ Sample implementation of a REXML::StreamListener SAX parser.
13
+ This class isn't actually used in Gooby, but is retained for future use.
14
+ =end
15
+
16
+ class SimpleXmlParser
17
+
18
+ include REXML::StreamListener
19
+
20
+ attr_accessor :tag_count, :watched_tags
21
+
22
+ def initialize
23
+ @tag_count = 0
24
+ @counter_hash = CounterHash.new
25
+ end
26
+
27
+ public
28
+
29
+ # SAX API method. Increments the tagname in the counter hash.
30
+ def tag_start(tag_name, attrs)
31
+ @tag_count = @tag_count + 1
32
+ @counter_hash.increment(tag_name)
33
+ end
34
+
35
+ # SAX API method. No impl.
36
+ def tag_end(tagname)
37
+ end
38
+
39
+ # SAX API method. No impl.
40
+ def text(txt)
41
+ end
42
+
43
+ # Prints the state of this object (the counter hash).
44
+ def dump
45
+ puts @counter_hash.to_s
46
+ end
47
+
48
+ end
49
+
50
+ end # end of module
@@ -0,0 +1,23 @@
1
+ =begin
2
+
3
+ Gooby = Google APIs + Ruby
4
+ Gooby - Copyright 2007 by Chris Joakim.
5
+ Gooby is available under GNU General Public License (GPL) license.
6
+
7
+ =end
8
+
9
+ module Gooby
10
+
11
+ module TestHelper
12
+
13
+ def setup
14
+ puts "test: #{name}"
15
+ end
16
+
17
+ def teardown
18
+ @debug = false
19
+ end
20
+
21
+ end
22
+
23
+ end # end of module
@@ -0,0 +1,47 @@
1
+ =begin
2
+
3
+ Gooby = Google APIs + Ruby
4
+ Gooby - Copyright 2007 by Chris Joakim.
5
+ Gooby is available under GNU General Public License (GPL) license.
6
+
7
+ =end
8
+
9
+ module Gooby
10
+
11
+ =begin rdoc
12
+ Instances of this class represent a <Track> aggregate object from a Forerunner
13
+ XML file. Note that a <Run> may contain more than one <Track> aggregates.
14
+ =end
15
+
16
+ class Track < GoobyObject
17
+
18
+ attr_reader :number, :descr, :trackpoints
19
+
20
+ def initialize(num=0, descr='')
21
+ @number = num
22
+ @descr = descr
23
+ @trackpoints = Array.new
24
+ end
25
+
26
+ public
27
+
28
+ def add_trackpoint(tkpt)
29
+ @trackpoints.push(tkpt)
30
+ end
31
+
32
+ def size
33
+ @trackpoints.size
34
+ end
35
+
36
+ def to_s
37
+ return "Trk: #{@descr} tkpts: #{size}"
38
+ end
39
+
40
+ def dump
41
+ puts "Track: '#{@descr}' tkpts: #{size}"
42
+ @trackpoints.each { |tkpt| puts tkpt.to_csv }
43
+ end
44
+
45
+ end
46
+
47
+ end # end of module
@@ -0,0 +1,229 @@
1
+ =begin
2
+
3
+ Gooby = Google APIs + Ruby
4
+ Gooby - Copyright 2007 by Chris Joakim.
5
+ Gooby is available under GNU General Public License (GPL) license.
6
+
7
+ =end
8
+
9
+ module Gooby
10
+
11
+ class Trackpoint < Point
12
+
13
+ attr_accessor :first, :last, :number, :run_number, :dttm, :prev_tkpt, :lap_number, :lap_seq, :lap_distance, :lap_elapsed
14
+ attr_accessor :cumulative_distance, :cumulative_pace, :incremental_distance, :split, :prev_split
15
+ attr_accessor :first, :last, :run_id, :run_number
16
+ attr_accessor :run_start_dttm
17
+
18
+ def initialize(num, lat, lng, alt, hb, time_string, uom, auxInfoHash=Hash.new(''))
19
+ @number = num
20
+ @run_number = 0
21
+ @auxInfoHash = auxInfoHash
22
+ @lap_seq = 1
23
+ @lap_distance = 0
24
+ lap_num = @auxInfoHash['lap_number']
25
+ if (lap_num && lap_num.size > 0)
26
+ @lap_number = lap_num.to_i
27
+ else
28
+ @lap_number = 0
29
+ end
30
+ # initialize superclass variables:
31
+ @latitude = lat.to_s
32
+ @longitude = lng.to_s
33
+ @altitude = alt.to_f
34
+ @uom = uom
35
+ @altitude = @altitude * 3.2736 if (@uom == 'm')
36
+ @heartbeat = hb.to_s
37
+ if ((@heartbeat == nil) || (@heartbeat == ''))
38
+ @heartbeat = -1
39
+ end
40
+ @note = note.to_s
41
+ @dttm = DtTm.new(time_string)
42
+ @first = false
43
+ @last = false
44
+ @prev_tkpt = nil
45
+ @cumulative_distance, @incremental_distance, @split = 0.0, 0.0, 0.0
46
+ @cumulative_pace = ""
47
+ end
48
+
49
+ public
50
+
51
+ def point
52
+ Point.new(@latitude, @longitude, @altitude, @note)
53
+ end
54
+
55
+ def position
56
+ Point.new(@latitude, @longitude, @altitude, @note)
57
+ end
58
+
59
+ def to_s
60
+ "Tkpt: #{@number} #{super.to_s} date: #{@dttm.to_s} cdist: #{@cumulative_distance}"
61
+ end
62
+
63
+ def to_csv(prev_tkpt=nil)
64
+ first_lap_start_time_s = @auxInfoHash['first_lap_start_time']
65
+ curr_lap_start_time_s = @auxInfoHash['curr_lap_start_time']
66
+ lap_elapsed = ''
67
+ total_elapsed = ''
68
+
69
+ if (first_lap_start_time_s && (first_lap_start_time_s.size > 0) &&
70
+ curr_lap_start_time_s && (curr_lap_start_time_s.size > 0)) # garmin205 & 305
71
+ first_lap_start_time = DtTm.new(first_lap_start_time_s)
72
+ first_lap_start_time = @run_start_dttm
73
+ curr_lap_start_time = DtTm.new(curr_lap_start_time_s)
74
+ lap_elapsed = @dttm.hhmmss_diff(curr_lap_start_time)
75
+ total_elapsed = @dttm.hhmmss_diff(first_lap_start_time)
76
+ else # garmin 201
77
+ total_elapsed = @dttm.hhmmss_diff(@run_start_dttm)
78
+ lap_elapsed = total_elapsed
79
+ end
80
+
81
+ delim = csv_delim
82
+ csv = "#{@run_id}.#{@number}" # <-- primary key
83
+ csv << "#{delim}#{@run_id}"
84
+ csv << "#{delim}#{@dttm.yyyy_mm_dd_hh_mm_ss('|')}"
85
+ csv << "#{delim}#{@number}"
86
+ csv << "#{delim}#{position.to_csv}"
87
+ csv << "#{delim}#{@heartbeat}"
88
+ csv << "#{delim}#{@cumulative_distance}"
89
+ csv << "#{delim}#{uom}"
90
+ csv << "#{delim}#{total_elapsed}"
91
+ csv << "#{delim}#{@lap_seq}"
92
+ csv << "#{delim}#{@lap_distance}"
93
+ csv << "#{delim}#{lap_elapsed}"
94
+ csv
95
+ end
96
+
97
+ def self.csv_header
98
+ "#cols: primary_key|run_id|date|time|tkpt_num|latitude|longitude|altitude|heartbeat|run_distance|uom|run_elapsed|lap_tkpt_number|lap_distance|lap_elapsed"
99
+ end
100
+
101
+ def to_geo_s
102
+ ss = position.to_csv
103
+ "Tkpt: #{@number} | #{ss} | #{@descr}"
104
+ end
105
+
106
+ def compute_distance_and_pace(curr_index, start_dttm, prev_cumulative_dist, prev_trackpoint)
107
+ @prev_tkpt = prev_trackpoint
108
+ @cumulative_distance = prev_cumulative_dist.to_f
109
+ @run_start_dttm = start_dttm
110
+
111
+ if @prev_tkpt
112
+ @incremental_distance = proximity(@prev_tkpt, @uom)
113
+ if (!@incremental_distance.nan?)
114
+ @cumulative_distance = @cumulative_distance + @incremental_distance.to_f
115
+ if (@lap_number == prev_trackpoint.lap_number)
116
+ @lap_seq = prev_trackpoint.lap_seq + 1
117
+ @lap_distance = prev_trackpoint.lap_distance + @incremental_distance
118
+ else
119
+ @lap_seq = 1
120
+ @lap_distance = @incremental_distance
121
+ end
122
+ end
123
+ compute_cumulative_pace(start_dttm)
124
+ @cumulative_distance
125
+ else
126
+ @lap_seq = 1
127
+ 0
128
+ end
129
+ end
130
+
131
+ def compute_cumulative_pace(start_dttm)
132
+ if @cumulative_distance > 0
133
+ secsDiff = @dttm.seconds_diff(start_dttm)
134
+ secsMile = ((secsDiff.to_f) / (@cumulative_distance.to_f))
135
+ minsMile = (secsMile / 60)
136
+ wholeMins = minsMile.floor
137
+ fractMins = minsMile - (wholeMins.to_f)
138
+ fractSecs = fractMins * 60
139
+ secsStr = fractSecs.to_s
140
+ tokens = secsStr.split('.')
141
+ whole, fract = '', ''
142
+ if tokens.size > 1
143
+ whole = tokens[0]
144
+ fract = tokens[1]
145
+ fract = fract[0,3] if fract.size > 3
146
+ if (whole.to_f < 10)
147
+ secsStr = "0#{whole}.#{fract}"
148
+ else
149
+ secsStr = "#{whole}.#{fract}"
150
+ end
151
+ end
152
+ #s1 = " | #{secsDiff} #{secsMile} #{minsMile} #{wholeMins} #{fractMins} #{fractSecs} #{whole} #{fract} #{@cumulative_distance} "
153
+ s2 = sprintf("%d:%5s", minsMile, secsStr)
154
+ @cumulative_pace = "#{s2} per #{@uom}"
155
+ else
156
+ @cumulative_pace = ""
157
+ end
158
+ end
159
+
160
+ def set_split(n, tkpt)
161
+ @split, @prev_split = n, tkpt
162
+ end
163
+
164
+ def is_split()
165
+ (@split >= 1)
166
+ end
167
+
168
+ def split_info(dtTm)
169
+ if is_split
170
+ hhmmss = ''
171
+ if @prev_split
172
+ return "#{@split} #{@dttm.hhmmss_diff(@prev_split.dttm())}"
173
+ else
174
+ return "#{@split} #{@dttm.hhmmss_diff(dtTm)}"
175
+ end
176
+ else
177
+ ""
178
+ end
179
+ end
180
+
181
+ public
182
+
183
+ def as_glatlng(comment_out, gen_comments, tkpt_count, curr_idx, start_dttm)
184
+ comment_out ? comment = '// ' : comment = ''
185
+ if gen_comments
186
+ secs_diff = @dttm.seconds_diff(start_dttm)
187
+ fmt_time = @dttm.hhmmss_diff(start_dttm)
188
+ "\n #{comment}points.push(new GLatLng(#{latitude_as_float},#{longitude_as_float})); " +
189
+ "// (#{curr_idx + 1} of #{tkpt_count}) #{@dttm.to_s} #{secs_diff} #{fmt_time} #{@cumulative_distance} #{split_info(start_dttm)} #{project_embedded_comment} "
190
+ else
191
+ "\n #{comment}points.push(new GLatLng(#{latitude_as_float},#{longitude_as_float})); // #{project_embedded_comment} "
192
+ end
193
+ end
194
+
195
+ def as_info_window_html(checkpoint, start_dttm)
196
+ s = "\"<table align='left'>"
197
+ if checkpoint
198
+ secs_diff = @dttm.seconds_diff(start_dttm)
199
+ fmt_time = @dttm.hhmmss_diff(start_dttm)
200
+
201
+ if checkpoint == 'Start'
202
+ s << "<tr><td colspan='2'><b>Start!</b></td></tr>"
203
+ elsif checkpoint == 'Finish'
204
+ s << "<tr><td colspan='2'><b>Finish!</b></td></tr>"
205
+ else
206
+ if (@uom == 'km')
207
+ s << "<tr><td colspan='2'><b>Kilometer #{checkpoint}</b></td></tr>"
208
+ else
209
+ s << "<tr><td colspan='2'><b>Mile #{checkpoint}</b></td></tr>"
210
+ end
211
+ end
212
+ s << "<tr><td>Distance:</td><td>#{@cumulative_distance} #{@uom}</td></tr>"
213
+ s << "<tr><td>Time of Day:</td><td>#{@dttm.to_s}</td></tr>"
214
+ s << "<tr><td>Elapsed Time:</td><td>#{fmt_time}</td></tr>"
215
+ s << "<tr><td>Average Pace:</td><td>#{@cumulative_pace}</td></tr>"
216
+ s << "<tr><td>Lat/Lng:</td><td>#{latitude_as_float} , #{longitude_as_float}</td></tr>"
217
+ s << "<tr><td>Altitude:</td><td>#{altitude_as_float}</td></tr>"
218
+ if (@heartbeat && (@heartbeat.size > 1) && (@heartbeat.to_i > 0))
219
+ s << "<tr><td>Heartbeat:</td><td>#{@heartbeat}</td></tr>"
220
+ end
221
+ s
222
+ end
223
+ s << "</table>\""
224
+ s
225
+ end
226
+
227
+ end
228
+
229
+ end # end of module
@@ -0,0 +1,224 @@
1
+ =begin
2
+
3
+ Gooby = Google APIs + Ruby
4
+ Gooby - Copyright 2007 by Chris Joakim.
5
+ Gooby is available under GNU General Public License (GPL) license.
6
+
7
+ =end
8
+
9
+ module Gooby
10
+
11
+ =begin rdoc
12
+ Instances of this class are used to parse a Garmin TrainingCenter XML(TCX) file
13
+ in a SAX-like manner. Instances of the model classes - History, Run, Track,
14
+ Trackpoint, etc. are created in this parsing process.
15
+
16
+ See http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd for the XML
17
+ Schema Definition for Garmin TrainingCenter XML.
18
+ =end
19
+
20
+ class TrainingCenterXmlParser
21
+
22
+ DETAIL_TAGS = %w( Notes StartTime Duration Length Time
23
+ TotalTimeSeconds DistanceMeters
24
+ LatitudeDegrees LongitudeDegrees AltitudeMeters HeartRateBpm Value BeginPosition EndPosition )
25
+
26
+ include REXML::StreamListener
27
+
28
+ attr_reader :uom, :history, :cvHash, :tagCount
29
+
30
+ def initialize(uom)
31
+ @uom = uom
32
+ @cv_hash = Hash.new("")
33
+ @tag_count = 0
34
+ @run_count = 0
35
+ @lap_count = 0
36
+ @track_count = 0
37
+ @trackpoint_count = 0
38
+ @curr_text = "";
39
+ @history = History.new
40
+ @curr_run = nil
41
+ @curr_lap = nil
42
+ @curr_track = nil
43
+ @curr_begin_position = nil
44
+ @@curr_end_position = nil
45
+ @first_lap_start_time = nil
46
+ @curr_lap_start_time = ''
47
+ @in_heart_rate_bpm = false
48
+ @in_value = false
49
+ end
50
+
51
+ public
52
+
53
+ # SAX API method; handles 'Activity', 'Lap', 'Track', 'HeartRateBpm'.
54
+ def tag_start(tagname, attrs)
55
+ @tag_count += 1
56
+ @currTag = tagname
57
+ @cv_hash[tagname] = ''
58
+
59
+ if detail_tag?(tagname)
60
+ @inDetail = true
61
+ end
62
+
63
+ if is_tag?('Activity', tagname)
64
+ @run_count = @run_count + 1
65
+ @lap_count = 0
66
+ @track_count = 0
67
+ @trackpoint_count = 0
68
+ @curr_run = Run.new(@run_count)
69
+ @history.add_run(@curr_run)
70
+ @cv_hash['Notes'] = ''
71
+ return
72
+ end
73
+
74
+ if is_tag?('Lap', tagname)
75
+ @lap_count = @lap_count + 1
76
+ @curr_lap = Lap.new(@lap_count)
77
+
78
+ attrs.each { |attr|
79
+ name = attr[0]
80
+ val = attr[1]
81
+ if (name && (name == 'StartTime'))
82
+ if (@first_lap_start_time == nil)
83
+ @first_lap_start_time = "#{val}"
84
+ end
85
+ @curr_lap_start_time = "#{val}"
86
+ end
87
+ }
88
+ return
89
+ end
90
+
91
+ if is_tag?('Track', tagname)
92
+ @track_count = @track_count + 1
93
+ @curr_track = Track.new(@track_count)
94
+ return
95
+ end
96
+
97
+ if is_tag?('HeartRateBpm', tagname)
98
+ @in_heart_rate_bpm = true
99
+ return
100
+ end
101
+
102
+ end
103
+
104
+ # SAX API method; handles 'Position', 'Trackpoint', 'Track', 'Lap', 'Run', 'HeartRateBpm', 'Value'.
105
+ def tag_end(tagname)
106
+ if @inDetail
107
+ if is_tag?('Value', tagname) && @in_heart_rate_bpm
108
+ @cv_hash['HeartRateBpm'] = "#{@curr_text.strip!}"
109
+ else
110
+ @cv_hash[tagname] = @curr_text
111
+ end
112
+ else
113
+ if is_tag?('Position', tagname)
114
+ lat = @cv_hash['LatitudeDegrees']
115
+ long = @cv_hash['LongitudeDegrees']
116
+ @curr_begin_position = Point.new(lat.strip, long.strip)
117
+ @@curr_end_position = Point.new(lat.strip, long.strip)
118
+ end
119
+
120
+ if is_tag?('BeginPosition', tagname)
121
+ lat = @cv_hash['LatitudeDegrees']
122
+ long = @cv_hash['LongitudeDegrees']
123
+ @curr_begin_position = Point.new(lat.strip, long.strip)
124
+ end
125
+
126
+ if is_tag?('EndPosition', tagname)
127
+ lat = @cv_hash['LatitudeDegrees']
128
+ long = @cv_hash['LongitudeDegrees']
129
+ @@curr_end_position = Point.new(lat.strip, long.strip)
130
+ end
131
+
132
+ if is_tag?('Trackpoint', tagname)
133
+ @trackpoint_count = @trackpoint_count + 1
134
+ lat = @cv_hash['LatitudeDegrees']
135
+ long = @cv_hash['LongitudeDegrees']
136
+ alt = @cv_hash['AltitudeMeters']
137
+ hb = @cv_hash['HeartRateBpm']
138
+ hb ? hb = hb.to_s : hb = '-1'
139
+ time = @cv_hash['Time']
140
+ hash = Hash.new('')
141
+ hash['lap_number'] = "#{@lap_count}"
142
+ hash['first_lap_start_time'] = "#{@first_lap_start_time}"
143
+ hash['curr_lap_start_time'] = "#{@curr_lap_start_time}"
144
+ tp = Trackpoint.new(@trackpoint_count, lat, long, alt, hb, time, @uom, hash)
145
+ @curr_track.add_trackpoint(tp) if tp.has_coordinates?
146
+
147
+ @cv_hash['LatitudeDegrees'] = ''
148
+ @cv_hash['LongitudeDegrees'] = ''
149
+ @cv_hash['AltitudeMeters'] = ''
150
+ @cv_hash['HeartRateBpm'] = ''
151
+ @cv_hash['Time'] = ''
152
+ end
153
+
154
+ if is_tag?('Track', tagname)
155
+ if @curr_run != nil
156
+ @curr_run.add_track(@curr_track)
157
+ end
158
+ end
159
+
160
+ if is_tag?('Lap', tagname)
161
+ @curr_run.add_lap(@curr_lap)
162
+ end
163
+
164
+ if is_tag?('Activity', tagname)
165
+ @curr_run.notes = @cv_hash['Notes']
166
+ end
167
+
168
+ if is_tag?('HeartRateBpm', tagname)
169
+ @in_heart_rate_bpm = false
170
+ return
171
+ end
172
+
173
+ end
174
+
175
+ @inDetail = false
176
+ @curr_text = ""
177
+ @currTag = ""
178
+ end
179
+
180
+ # SAX API method.
181
+ def text(txt)
182
+ if @inDetail
183
+ @curr_text = @curr_text + txt
184
+ end
185
+ end
186
+
187
+ # Iterate all parsed Run objects and print each with to_s.
188
+ def gdump()
189
+ @history.runs().each { |run| puts run.to_s }
190
+ end
191
+
192
+ # Iterate all parsed Run objects and print each with to_s.
193
+ def dump()
194
+ @history.runs().each { |run| puts run.to_s }
195
+ end
196
+
197
+ # Iterate all parsed Run objects and print each with put_csv.
198
+ def put_run_csv()
199
+ @history.runs().each { |run| run.put_csv() }
200
+ end
201
+
202
+ # Iterate all parsed Run objects and print each with put_tkpt_csv.
203
+ def put_all_run_tkpt_csv()
204
+ @history.runs.each { |run| run.put_tkpt_csv() }
205
+ end
206
+
207
+ private
208
+
209
+ def is_tag?(tagname, value)
210
+ tagname == value
211
+ end
212
+
213
+ def detail_tag?(tagname)
214
+ DETAIL_TAGS.each { |typ|
215
+ if typ == tagname
216
+ return true
217
+ end
218
+ }
219
+ return false
220
+ end
221
+
222
+ end
223
+
224
+ end # end of module