gooby 0.9.4 → 0.9.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. data/README +48 -67
  2. data/bin/20050305_corporate_cup_hm_to_csv.rb +9 -0
  3. data/bin/20050430_nashville_marathon_to_csv.rb +9 -0
  4. data/bin/20060115_phoenix_marathon_to_csv.rb +9 -0
  5. data/bin/activity_2007_03_10_13_02_32.xml_to_csv.rb +9 -0
  6. data/bin/{tests_gen.rb → code_scan.rb} +6 -4
  7. data/bin/example_usage.rb +2 -3
  8. data/bin/example_usage.sh +52 -0
  9. data/bin/gen_gap_phx.rb +10 -0
  10. data/bin/gen_gmap_cc_2005.rb +10 -0
  11. data/bin/gen_gmap_cc_2007.rb +10 -0
  12. data/bin/gen_gmap_nashville.rb +10 -0
  13. data/bin/gen_gmap_phx.rb +10 -0
  14. data/bin/phx_to_csv.rb +47 -0
  15. data/bin/split_forerunner_logbook_2007.rb +10 -0
  16. data/bin/split_training_center_2007.rb +8 -0
  17. data/data/{2007_03_04.tcx → 2007_03_10.tcx} +11694 -0
  18. data/data/activity_2007_03_10_13_02_32.csv +1168 -0
  19. data/data/activity_2007_03_10_13_02_32.xml +11695 -0
  20. data/data/forerunner_2007.xml +0 -227142
  21. data/img/gicons/readme.txt +3 -0
  22. data/lib/gooby.rb +625 -552
  23. data/samples/20050305_corporate_cup_hm.html +271 -269
  24. data/samples/20050430_nashville_marathon.html +1240 -246
  25. data/samples/20060115_phoenix_marathon.html +1596 -0
  26. data/samples/20070310_corporate_cup_hm.html +1367 -0
  27. data/samples/phoenix_marathon.html +1312 -258
  28. data/tests/ts_gooby.rb +423 -551
  29. data/tests/ts_gooby_min.rb +550 -0
  30. metadata +25 -67
  31. data/bin/tcx_ex.rb +0 -35
  32. data/data/20051124_hyatt_turkey_trot_8K.csv +0 -321
  33. data/data/20051124_hyatt_turkey_trot_8K.xml +0 -2651
  34. data/data/2007_03_03.tcx +0 -6207
  35. data/data/activity_2007_03_04_15_22_36.xml +0 -10545
  36. data/data/run_2007_01_01_16_38_27.xml +0 -2020
  37. data/data/run_2007_02_24_15_01_35.csv +0 -484
  38. data/data/run_2007_02_24_15_01_35.xml +0 -3884
  39. data/lib/gooby/cls_counter_hash.rb +0 -78
  40. data/lib/gooby/cls_delim_line.rb +0 -35
  41. data/lib/gooby/cls_dttm.rb +0 -79
  42. data/lib/gooby/cls_duration.rb +0 -79
  43. data/lib/gooby/cls_forerunner_xml_parser.rb +0 -178
  44. data/lib/gooby/cls_forerunner_xml_splitter.rb +0 -109
  45. data/lib/gooby/cls_geo_data.rb +0 -181
  46. data/lib/gooby/cls_gooby_command.rb +0 -46
  47. data/lib/gooby/cls_gooby_object.rb +0 -18
  48. data/lib/gooby/cls_google_map_generator.rb +0 -363
  49. data/lib/gooby/cls_history.rb +0 -33
  50. data/lib/gooby/cls_lap.rb +0 -22
  51. data/lib/gooby/cls_line.rb +0 -75
  52. data/lib/gooby/cls_options.rb +0 -67
  53. data/lib/gooby/cls_position.rb +0 -44
  54. data/lib/gooby/cls_run.rb +0 -194
  55. data/lib/gooby/cls_simple_xml_parser.rb +0 -41
  56. data/lib/gooby/cls_test_regen.rb +0 -182
  57. data/lib/gooby/cls_track.rb +0 -47
  58. data/lib/gooby/cls_trackpoint.rb +0 -200
  59. data/lib/gooby/cls_training_center_parser.rb +0 -183
  60. data/lib/gooby/cls_training_center_splitter.rb +0 -109
  61. data/lib/gooby/mod_introspect.rb +0 -26
  62. data/lib/gooby/mod_io.rb +0 -58
  63. data/lib/gooby/mod_project_info.rb +0 -80
  64. data/lib/gooby/mod_string.rb +0 -19
  65. data/lib/gooby/mod_test_helper.rb +0 -15
  66. data/samples/20041113_richmond_marathon.html +0 -532
  67. data/samples/run_2007_01_10_22_44_54.html +0 -201
  68. data/samples/run_2007_02_24_15_01_35.html +0 -298
  69. data/tests/tc_cls_counter_hash.rb +0 -107
  70. data/tests/tc_cls_delim_line.rb +0 -74
  71. data/tests/tc_cls_dttm.rb +0 -131
  72. data/tests/tc_cls_duration.rb +0 -51
  73. data/tests/tc_cls_forerunner_xml_parser.rb +0 -70
  74. data/tests/tc_cls_geo_data.xxx +0 -71
  75. data/tests/tc_cls_gooby_object.rb +0 -26
  76. data/tests/tc_cls_google_map_generator.rb +0 -109
  77. data/tests/tc_cls_history.rb +0 -46
  78. data/tests/tc_cls_lap.rb +0 -38
  79. data/tests/tc_cls_line.rb +0 -110
  80. data/tests/tc_cls_options.rb +0 -79
  81. data/tests/tc_cls_position.rb +0 -66
  82. data/tests/tc_cls_run.rb +0 -142
  83. data/tests/tc_cls_simple_xml_parser.rb +0 -50
  84. data/tests/tc_cls_track.rb +0 -70
  85. data/tests/tc_cls_trackpoint.rb +0 -145
  86. data/tests/tc_mod_introspect.rb +0 -32
  87. data/tests/tc_mod_io.rb +0 -53
  88. data/tests/tc_mod_project_info.rb +0 -79
  89. data/tests/tc_mod_string.rb +0 -58
  90. /data/data/{phx.csv → 20060115_phoenix_marathon.csv} +0 -0
  91. /data/data/{phx.xml → 20060115_phoenix_marathon.xml} +0 -0
@@ -1,78 +0,0 @@
1
- module Gooby
2
-
3
- =begin rdoc
4
- This class wrappers a Hash object and provides increment/decrement functionality
5
- for a given key. It is used to sum the number of things (i.e. - xml tags) in a
6
- collection.
7
- =end
8
-
9
- class CounterHash < GoobyObject
10
-
11
- def initialize
12
- @hash = Hash.new(0)
13
- end
14
-
15
- # Return the Integer count for the given key; zero default.
16
- def value(key)
17
- (@hash.has_key?(key)) ? @hash[key] : 0
18
- end
19
-
20
- # Increment the count for the given key.
21
- def increment(key)
22
- if key == nil
23
- return
24
- end
25
- if (@hash.has_key?(key))
26
- val = @hash[key]
27
- @hash[key] = val + 1
28
- else
29
- @hash[key] = 1
30
- end
31
- end
32
-
33
- # Decrement the count for the given key.
34
- def decrement(key)
35
- if key == nil
36
- return
37
- end
38
- if (@hash.has_key?(key))
39
- val = @hash[key]
40
- @hash[key] = val - 1
41
- else
42
- @hash[key] = -1
43
- end
44
- end
45
-
46
- # Return an Array of the sorted keys.
47
- def sorted_keys
48
- @hash.keys.sort
49
- end
50
-
51
- # Return a String containing all key=val pairs.
52
- def to_s
53
- s = "CHash:"
54
- sorted_keys.each { |key|
55
- val = @hash[key]
56
- s << " key: [#{key}] val: [#{val}]"
57
- }
58
- s
59
- end
60
-
61
- # Return an XML String containing all key=val pairs, optionally aligned.
62
- def to_xml(aligned=false)
63
- s = "<CHash>"
64
- sorted_keys.each { |key|
65
- val = @hash[key]
66
- (aligned) ? s << "\n " : s << ''
67
- s << " <entry key='#{key}' value='#{val}'/>"
68
- }
69
- if aligned
70
- s << "\n "
71
- end
72
- s << " </CHash>"
73
- s
74
- end
75
-
76
- end
77
-
78
- end # end of module
@@ -1,35 +0,0 @@
1
- module Gooby
2
-
3
- =begin rdoc
4
- Instances of this class represent a delimited line of text, such as csv.
5
- =end
6
-
7
- class DelimLine < GoobyObject
8
-
9
- attr_reader :line, :trim, :delim, :tokens
10
-
11
- def initialize(line, trim=true, delim=default_delimiter)
12
- @line = line
13
- @trim = trim
14
- @delim = delim
15
- @tokens = @line.split(@delim)
16
- if trim
17
- @tokens.each { | token | token.strip! }
18
- end
19
- end
20
-
21
- def as_trackpoint(num_idx, lat_idx, lng_idx, alt_idx, dttm_idx)
22
- Trackpoint.new(@tokens[num_idx], @tokens[lat_idx], @tokens[lng_idx], @tokens[alt_idx], @tokens[dttm_idx])
23
- end
24
-
25
- def is_comment?
26
- @line.strip.match('^#') ? true : false
27
- end
28
-
29
- def to_s
30
- "DelimLine: length: #{@line.size} trim: #{@trim} delim: #{@delim} tokens: #{@tokens.size}"
31
- end
32
-
33
- end
34
-
35
- end # end of module
@@ -1,79 +0,0 @@
1
- module Gooby
2
-
3
- =begin rdoc
4
- Instances of this class represent a Date and Time as parsed from a value
5
- such as '2006-01-15T13:41:40Z' in an XML file produced by a GPS device.
6
- It wrappers both a DateTime and Time object.
7
- =end
8
-
9
- class DtTm < GoobyObject
10
-
11
- attr_accessor :rawdata, :dateTime, :time, :valid
12
-
13
- # Constructor; arg is a String like '2006-01-15T13:41:40Z'.
14
- def initialize(raw)
15
- if raw
16
- @rawdata = raw.strip
17
- if @rawdata.size > 18
18
- @dateTime = DateTime.parse(@rawdata[0..18])
19
- @time = Time.parse(@dateTime.to_s)
20
- @valid = true
21
- else
22
- @valid = false
23
- end
24
- else
25
- @rawdata = ''
26
- @valid = false
27
- end
28
- end
29
-
30
- public
31
-
32
- # Return @time.to_i
33
- def to_i()
34
- (@time) ? @time.to_i : invalid_time
35
- end
36
-
37
- # Calculates and returns diff between another instance.
38
- def seconds_diff(anotherDtTm)
39
- if anotherDtTm
40
- to_i - anotherDtTm.to_i
41
- else
42
- invalid_time
43
- end
44
- end
45
-
46
- def yyyy_mm_dd
47
- @time.strftime("%Y-%m-%d")
48
- end
49
-
50
- def yyyy_mm_dd_hh_mm_ss
51
- @time.strftime("%Y-%m-%d %H:%M:%S")
52
- end
53
-
54
- def hh_mm_ss
55
- @time.strftime("%H:%M:%S")
56
- end
57
-
58
- # Calculate and return time diff in 'hh:mm:ss' format.
59
- def hhmmss_diff(anotherDtTm)
60
- if anotherDtTm
61
- t = @time - (anotherDtTm.to_i)
62
- t.strftime("%H:%M:%S")
63
- else
64
- '??:??:??'
65
- end
66
- end
67
-
68
- def to_s
69
- "#{@rawdata}"
70
- end
71
-
72
- # Return a String with state values for debugging.
73
- def print_string
74
- "DtTm: #{yyyy_mm_dd_hh_mm_ss} #{to_i} #{@rawdata}"
75
- end
76
-
77
- end
78
-
79
- end # end of module
@@ -1,79 +0,0 @@
1
- module Gooby
2
-
3
- =begin rdoc
4
- Instances of this class represent the contents of a Forerunner extract
5
- <Duration> tag, such as:
6
- <Duration>PT507.870S</Duration>
7
- =end
8
-
9
- class Duration < GoobyObject
10
-
11
- attr_accessor :rawdata, :seconds, :minutes, :mmss
12
-
13
- # Constructor; arg is a String like 'PT507.870S'.
14
- def initialize(raw)
15
- if raw
16
- @rawdata = scrub(raw)
17
- @seconds = @rawdata.to_f
18
- @minutes = @seconds / 60
19
- @base_min = @minutes.floor
20
- @frac_min = @minutes - @base_min
21
- @frac_sec = @frac_min * 60
22
-
23
- @mmss = ''
24
- if (@base_min < 10)
25
- @mmss << "0#{@base_min}:"
26
- else
27
- @mmss << "#{@base_min}:"
28
- end
29
- if (@frac_sec < 10)
30
- @mmss << "0#{@frac_sec}"
31
- else
32
- @mmss << "#{@frac_sec}"
33
- end
34
- if (@mmss.size > 8)
35
- @mmss = @mmss[0..8]
36
- end
37
- else
38
- @rawdata = ''
39
- @seconds = invalidDistance
40
- @minutes = invalidMinutes
41
- @mmss = '??:??.?'
42
- end
43
- end
44
-
45
- private
46
-
47
- def scrub(raw)
48
- if (raw)
49
- raw.strip!
50
- newStr = ''
51
- raw.each_byte { | b |
52
- if ((b >= 48) && (b <= 57))
53
- newStr << b
54
- end
55
- if (b == 46)
56
- newStr << b
57
- end
58
- }
59
- return newStr
60
- else
61
- ''
62
- end
63
- end
64
-
65
- public
66
-
67
- def to_s
68
- "#{@mmss}"
69
- end
70
-
71
- # Return a String with state values for debugging.
72
- def print_string
73
- "Duration: #{@rawdata} sec: #{@seconds} min: #{@minutes} mmss: #{@mmss} bm: #{@base_min} fm: #{@frac_min} fs: #{@frac_sec}"
74
- end
75
-
76
- end
77
-
78
- end # end of module
79
-
@@ -1,178 +0,0 @@
1
- module Gooby
2
-
3
- =begin rdoc
4
- Instances of this class are used to parse a Forerunner XML file in a SAX-like
5
- manner. Instances of the model classes - History, Run, Track, Trackpoint,
6
- etc. are created in this parsing process.
7
-
8
- See http://www.garmin.com/xmlschemas/ForerunnerLogbookv1.xsd for the XML Schema
9
- Definition for the Garmin Forerunner XML. The Gooby object model mirrors this XSD.
10
- =end
11
-
12
- class ForerunnerXmlParser
13
-
14
- DETAIL_TAGS = %w( Notes StartTime Duration Length Latitude Longitude Altitude Time BeginPosition EndPosition )
15
-
16
- include REXML::StreamListener
17
-
18
- attr_reader :history, :cvHash, :tagCount
19
-
20
- def initialize
21
- @cvHash = Hash.new("")
22
- @tagCount = 0
23
- @runCount = 0
24
- @lapCount = 0
25
- @trackCount = 0
26
- @trackpoint_count = 0
27
- @currText = "";
28
- @history = History.new
29
- @currRun = nil
30
- @currLap = nil
31
- @currTrack = nil
32
- @currBeginPosition = nil
33
- @currEndPosition = nil
34
- end
35
-
36
- public
37
-
38
- # SAX API method; handles 'Run', 'Lap', 'Track'.
39
- def tag_start(tagname, attrs)
40
- @tagCount += 1
41
- @currTag = tagname
42
- @cvHash[tagname] = ''
43
-
44
- if detail_tag?(tagname)
45
- @inDetail = true
46
- end
47
-
48
- if is_tag?('Run', tagname)
49
- @runCount = @runCount + 1
50
- @lapCount = 0
51
- @trackCount = 0
52
- @currRun = Run.new(@runCount)
53
- @history.add_run(@currRun)
54
- @cvHash['Notes'] = ''
55
- return
56
- end
57
-
58
- if is_tag?('Lap', tagname)
59
- @lapCount = @lapCount + 1
60
- @currLap = Lap.new(@lapCount)
61
- return
62
- end
63
-
64
- if is_tag?('Track', tagname)
65
- @trackCount = @trackCount + 1
66
- @currTrack = Track.new(@trackCount)
67
- @trackpoint_count = 0
68
- return
69
- end
70
-
71
- end
72
-
73
- # SAX API method; handles 'Position', 'Trackpoint', 'Track', 'Lap', 'Run'.
74
- def tag_end(tagname)
75
- if @inDetail
76
- @cvHash[tagname] = @currText
77
- else
78
- if is_tag?('Position', tagname)
79
- lat = @cvHash['Latitude']
80
- long = @cvHash['Longitude']
81
- @currBeginPosition = Position.new(lat.strip, long.strip, '')
82
- @currEndPosition = Position.new(lat.strip, long.strip, '')
83
- end
84
-
85
- if is_tag?('BeginPosition', tagname)
86
- lat = @cvHash['Latitude']
87
- long = @cvHash['Longitude']
88
- @currBeginPosition = Position.new(lat.strip, long.strip, '')
89
- end
90
-
91
- if is_tag?('EndPosition', tagname)
92
- lat = @cvHash['Latitude']
93
- long = @cvHash['Longitude']
94
- @currEndPosition = Position.new(lat.strip, long.strip, '')
95
- end
96
-
97
- if is_tag?('Trackpoint', tagname)
98
- @trackpoint_count = @trackpoint_count + 1
99
- lat = @cvHash['Latitude']
100
- long = @cvHash['Longitude']
101
- alt = @cvHash['Altitude']
102
- time = @cvHash['Time']
103
- tp = Trackpoint.new(@trackpoint_count, lat, long, alt, time)
104
- @currTrack.add_trackpoint(tp)
105
- end
106
-
107
- if is_tag?('Track', tagname)
108
- if @currRun != nil
109
- @currRun.add_track(@currTrack)
110
- end
111
- end
112
-
113
- if is_tag?('Lap', tagname)
114
- @currLap.startTime = @cvHash['StartTime']
115
- @currLap.duration = Duration.new(@cvHash['Duration'])
116
- @currLap.length = @cvHash['Length']
117
- @currLap.beginPosition = @currBeginPosition
118
- @currLap.endPosition = @currEndPosition
119
- @currRun.add_lap(@currLap)
120
- end
121
-
122
- if is_tag?('Run', tagname)
123
- @currRun.notes = @cvHash['Notes']
124
- end
125
- end
126
-
127
- @inDetail = false
128
- @currText = ""
129
- @currTag = ""
130
- end
131
-
132
- # SAX API method.
133
- def text(txt)
134
- if @inDetail
135
- @currText = @currText + txt
136
- end
137
- end
138
-
139
- # Iterate all parsed Run objects and print each with to_s.
140
- def gdump()
141
- @history.runs().each { |run| puts run.to_s }
142
- end
143
-
144
- # Iterate all parsed Run objects and print each with to_s.
145
- def dump()
146
- @history.runs().each { |run| puts run.to_s }
147
- end
148
-
149
- # Iterate all parsed Run objects and print each with put_csv.
150
- def put_run_csv()
151
- @history.runs().each { |run| run.put_csv() }
152
- end
153
-
154
- # Iterate all parsed Run objects and print each with put_tkpt_csv.
155
- def put_all_run_tkpt_csv(with_header_comment)
156
- @history.runs.each { |run|
157
- run.put_tkpt_csv(with_header_comment)
158
- }
159
- end
160
-
161
- private
162
-
163
- def is_tag?(tagname, value)
164
- tagname == value
165
- end
166
-
167
- def detail_tag?(tagname)
168
- DETAIL_TAGS.each { |typ|
169
- if typ == tagname
170
- return true
171
- end
172
- }
173
- return false
174
- end
175
-
176
- end
177
-
178
- end # end of module
@@ -1,109 +0,0 @@
1
- module Gooby
2
-
3
- =begin rdoc
4
- Instances of this class are used to split a large ForerunnerLogbook
5
- XML file into individual 'run_' files.
6
- =end
7
-
8
- class ForerunnerXmlSplitter < GoobyObject
9
-
10
- attr_reader :out_dir, :forerunner_files, :out_files_hash
11
-
12
- def initialize(xml_file, out_dir)
13
- @out_dir = out_dir
14
- @forerunner_files = Array.new
15
- @forerunner_files << xml_file
16
- @out_files_hash = Hash.new
17
- end
18
-
19
- def split
20
- @forerunner_files.each { |f| process_file(f) }
21
- write_files
22
- end
23
-
24
- private
25
-
26
- def process_file(forerunnerXmlFile)
27
- @file_name = forerunnerXmlFile
28
- @xml_lines = read_lines(@file_name, false)
29
- @line_num = 0
30
- @run_num = 0
31
- @curr_run_lines = Array.new
32
- @curr_run_tkpts = 0
33
- @start_line_num = 0
34
- @end_line_num = 0
35
- @first_start_time = nil
36
-
37
- @xml_lines.each { |line|
38
- @line_num = @line_num + 1
39
- if (line.match(/<Run>/))
40
- @run_num = @run_num + 1
41
- @start_line_num = @line_num
42
- @curr_run_lines = Array.new
43
- @curr_run_lines << line
44
- elsif (line.match(/<StartTime>/)) # <StartTime>2007-01-13T15:37:06Z</StartTime>
45
- @curr_run_lines << line
46
- if @first_start_time == nil
47
- clone = String.new(line)
48
- clone.gsub!(/[<>]/, ' ')
49
- clone.gsub!(/[-:T]/, '_')
50
- clone.gsub!(/[Z]/, '')
51
- tokens = clone.split
52
- @first_start_time = tokens[1]
53
- end
54
- elsif (line.match(/<Trackpoint>/))
55
- @curr_run_tkpts = @curr_run_tkpts + 1
56
- @curr_run_lines << line
57
- elsif (line.match(/<\/Run>/))
58
- @end_line_num = @line_num
59
- @curr_run_lines << line
60
- end_run
61
- elsif (@curr_run_lines.size > 0)
62
- @curr_run_lines << line
63
- end
64
- }
65
- end
66
-
67
- def end_run
68
- out_file = "#{@out_dir}/run_#{@first_start_time}.xml"
69
- comment = "<!-- file: #{out_file} lines: #{@curr_run_lines.size} (#{@start_line_num} to #{@end_line_num}) tkpts: #{@curr_run_tkpts} --> \n"
70
- @curr_run_lines.insert(0, comment)
71
-
72
- prev_entry = @out_files_hash[out_file]
73
- if prev_entry
74
- if (@curr_run_lines.size >= prev_entry.size)
75
- puts "previous entry overlaid for #{out_file}. curr=#{@curr_run_lines.size} prev=#{prev_entry.size}"
76
- @out_files_hash[out_file] = @curr_run_lines
77
- else
78
- puts "previous entry retained for #{out_file}. curr=#{@curr_run_lines.size} prev=#{prev_entry.size}"
79
- end
80
- else
81
- puts "new entry for #{out_file}. curr=#{@curr_run_lines.size}"
82
- @out_files_hash[out_file] = @curr_run_lines
83
- end
84
-
85
- @curr_run_lines = Array.new
86
- @curr_run_tkpts = 0
87
- @start_line_num = 0
88
- @end_line_num = 0
89
- @first_start_time = nil
90
- end
91
-
92
- def write_files
93
- out_names = @out_files_hash.keys.sort
94
- puts "Writing #{out_names.size} extract files..."
95
- out_names.each { |out_name|
96
- lines = @out_files_hash[out_name]
97
- out = File.new out_name, "w+"
98
- lines.each { |line| out.write line }
99
- out.flush
100
- out.close
101
- puts "File written: #{out_name}"
102
- }
103
- puts "output files written."
104
- end
105
-
106
- end
107
-
108
- end # end of module
109
-