gooby 0.9.4 → 0.9.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.
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
-