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,28 @@
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 CsvRun < GoobyObject
12
+
13
+ attr_reader :id, :points
14
+
15
+ def initialize(id)
16
+ @id = "#{id}"
17
+ @points = Array.new
18
+ end
19
+
20
+ def add_point(point)
21
+ if point
22
+ @points << point
23
+ end
24
+ end
25
+
26
+ end
27
+
28
+ end # end of module
@@ -0,0 +1,42 @@
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 delimited line of text, such as csv.
13
+ =end
14
+
15
+ class DelimLine < GoobyObject
16
+
17
+ attr_reader :line, :trim, :delim, :tokens
18
+
19
+ def initialize(line, trim=true, delim=default_delimiter)
20
+ @line = line
21
+ @trim = trim
22
+ @delim = delim
23
+ @tokens = @line.split(@delim)
24
+ if trim
25
+ @tokens.each { | token | token.strip! }
26
+ end
27
+ end
28
+
29
+ def as_trackpoint(num_idx, lat_idx, lng_idx, alt_idx, dttm_idx)
30
+ Trackpoint.new(@tokens[num_idx], @tokens[lat_idx], @tokens[lng_idx], @tokens[alt_idx], @tokens[dttm_idx])
31
+ end
32
+
33
+ def is_comment?
34
+ @line.strip.match('^#') ? true : false
35
+ end
36
+
37
+ def to_s
38
+ "DelimLine: length: #{@line.size} trim: #{@trim} delim: #{@delim} tokens: #{@tokens.size}"
39
+ end
40
+ end
41
+
42
+ end # end of module
data/lib/gooby_dttm.rb ADDED
@@ -0,0 +1,87 @@
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 Date and Time as parsed from a value
13
+ such as '2006-01-15T13:41:40Z' in an XML file produced by a GPS device.
14
+ It wrappers both a DateTime and Time object.
15
+ =end
16
+
17
+ class DtTm < GoobyObject
18
+
19
+ attr_accessor :rawdata, :dateTime, :time, :valid
20
+
21
+ # Constructor; arg is a String like '2006-01-15T13:41:40Z'.
22
+ def initialize(raw)
23
+ if raw
24
+ @rawdata = raw.strip
25
+ if @rawdata.size > 18
26
+ @date_time = DateTime.parse(@rawdata[0..18])
27
+ @time = Time.parse(@date_time.to_s)
28
+ @valid = true
29
+ else
30
+ @valid = false
31
+ end
32
+ else
33
+ @rawdata = ''
34
+ @valid = false
35
+ end
36
+ end
37
+
38
+ public
39
+
40
+ # Return @time.to_i
41
+ def to_i()
42
+ (@time) ? @time.to_i : invalid_time
43
+ end
44
+
45
+ # Calculates and returns diff between another instance.
46
+ def seconds_diff(anotherDtTm)
47
+ if anotherDtTm
48
+ to_i - anotherDtTm.to_i
49
+ else
50
+ invalid_time
51
+ end
52
+ end
53
+
54
+ def yyyy_mm_dd
55
+ @time.strftime("%Y-%m-%d")
56
+ end
57
+
58
+ def yyyy_mm_dd_hh_mm_ss(delim=' ')
59
+ @time.strftime("%Y-%m-%d#{delim}%H:%M:%S")
60
+ end
61
+
62
+ def hh_mm_ss
63
+ @time.strftime("%H:%M:%S")
64
+ end
65
+
66
+ # Calculate and return time diff in 'hh:mm:ss' format.
67
+ def hhmmss_diff(anotherDtTm)
68
+ if anotherDtTm
69
+ t = @time - (anotherDtTm.to_i)
70
+ t.strftime("%H:%M:%S")
71
+ else
72
+ '00:00:00'
73
+ end
74
+ end
75
+
76
+ def to_s
77
+ "#{@rawdata}"
78
+ end
79
+
80
+ # Return a String with state values for debugging.
81
+ def print_string
82
+ "DtTm: #{yyyy_mm_dd_hh_mm_ss} #{to_i} #{@rawdata}"
83
+ end
84
+
85
+ end
86
+
87
+ end # end of module
@@ -0,0 +1,86 @@
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 the contents of a Forerunner extract
13
+ <Duration> tag, such as:
14
+ <Duration>PT507.870S</Duration>
15
+ =end
16
+
17
+ class Duration < GoobyObject
18
+
19
+ attr_accessor :rawdata, :seconds, :minutes, :mmss
20
+
21
+ # Constructor; arg is a String like 'PT507.870S'.
22
+ def initialize(raw)
23
+ if raw
24
+ @rawdata = scrub("#{raw}")
25
+ @seconds = @rawdata.to_f
26
+ @minutes = @seconds / 60
27
+ @base_min = @minutes.floor
28
+ @frac_min = @minutes - @base_min
29
+ @frac_sec = @frac_min * 60
30
+
31
+ @mmss = ''
32
+ if (@base_min < 10)
33
+ @mmss << "0#{@base_min}:"
34
+ else
35
+ @mmss << "#{@base_min}:"
36
+ end
37
+ if (@frac_sec < 10)
38
+ @mmss << "0#{@frac_sec}"
39
+ else
40
+ @mmss << "#{@frac_sec}"
41
+ end
42
+ if (@mmss.size > 8)
43
+ @mmss = @mmss[0..8]
44
+ end
45
+ else
46
+ @rawdata = ''
47
+ @seconds = invalidDistance
48
+ @minutes = invalidMinutes
49
+ @mmss = '??:??.?'
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ def scrub(raw)
56
+ if (raw)
57
+ raw.strip!
58
+ newStr = ''
59
+ raw.each_byte { | b |
60
+ if ((b >= 48) && (b <= 57))
61
+ newStr << b
62
+ end
63
+ if (b == 46)
64
+ newStr << b
65
+ end
66
+ }
67
+ return newStr
68
+ else
69
+ ''
70
+ end
71
+ end
72
+
73
+ public
74
+
75
+ def to_s
76
+ "#{@mmss}"
77
+ end
78
+
79
+ # Return a String with state values for debugging.
80
+ def print_string
81
+ "Duration: #{@rawdata} sec: #{@seconds} min: #{@minutes} mmss: #{@mmss} bm: #{@base_min} fm: #{@frac_min} fs: #{@frac_sec}"
82
+ end
83
+
84
+ end
85
+
86
+ end # end of module
@@ -0,0 +1,191 @@
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 Forerunner XML file in a SAX-like
13
+ manner. Instances of the model classes - History, Run, Track, Trackpoint,
14
+ etc. are created in this parsing process.
15
+
16
+ See http://www.garmin.com/xmlschemas/ForerunnerLogbookv1.xsd for the XML Schema
17
+ Definition for the Garmin Forerunner XML. The Gooby object model mirrors this XSD.
18
+ =end
19
+
20
+ class ForerunnerXmlParser
21
+
22
+ DETAIL_TAGS = %w( Notes StartTime Duration Length Latitude Longitude Altitude Time BeginPosition EndPosition )
23
+
24
+ include REXML::StreamListener
25
+
26
+ attr_reader :uom, :history, :cvHash, :tagCount
27
+
28
+ def initialize(uom)
29
+ @uom = uom
30
+ @cv_hash = Hash.new("")
31
+ @tag_count = 0
32
+ @run_count = 0
33
+ @lap_count = 0
34
+ @track_count = 0
35
+ @trackpoint_count = 0
36
+ @curr_text = "";
37
+ @history = History.new
38
+ @curr_run = nil
39
+ @curr_lap = nil
40
+ @curr_track = nil
41
+ @curr_begin_position = nil
42
+ @@curr_end_position = nil
43
+ end
44
+
45
+ public
46
+
47
+ # SAX API method; handles 'Run', 'Lap', 'Track'.
48
+ def tag_start(tagname, attrs)
49
+ @tag_count += 1
50
+ @currTag = tagname
51
+ @cv_hash[tagname] = ''
52
+
53
+ if detail_tag?(tagname)
54
+ @inDetail = true
55
+ end
56
+
57
+ if is_tag?('Run', tagname)
58
+ @run_count = @run_count + 1
59
+ @lap_count = 0
60
+ @track_count = 0
61
+ @trackpoint_count = 0
62
+ @curr_run = Run.new(@run_count)
63
+ @history.add_run(@curr_run)
64
+ @cv_hash['Notes'] = ''
65
+ return
66
+ end
67
+
68
+ if is_tag?('Lap', tagname)
69
+ @lap_count = @lap_count + 1
70
+ @curr_lap = Lap.new(@lap_count)
71
+ return
72
+ end
73
+
74
+ if is_tag?('Track', tagname)
75
+ @track_count = @track_count + 1
76
+ @curr_track = Track.new(@track_count)
77
+ return
78
+ end
79
+ end
80
+
81
+ # SAX API method; handles 'Position', 'Trackpoint', 'Track', 'Lap', 'Run'.
82
+ def tag_end(tagname)
83
+ if @inDetail
84
+ @cv_hash[tagname] = @curr_text
85
+ else
86
+ if is_tag?('Position', tagname)
87
+ lat = @cv_hash['Latitude']
88
+ long = @cv_hash['Longitude']
89
+ @curr_begin_position = Point.new(lat.strip, long.strip)
90
+ @@curr_end_position = Point.new(lat.strip, long.strip)
91
+ end
92
+
93
+ if is_tag?('BeginPosition', tagname)
94
+ lat = @cv_hash['Latitude']
95
+ long = @cv_hash['Longitude']
96
+ @curr_begin_position = Point.new(lat.strip, long.strip)
97
+ end
98
+
99
+ if is_tag?('EndPosition', tagname)
100
+ lat = @cv_hash['Latitude']
101
+ long = @cv_hash['Longitude']
102
+ @@curr_end_position = Point.new(lat.strip, long.strip)
103
+ end
104
+
105
+ if is_tag?('Trackpoint', tagname)
106
+ @trackpoint_count = @trackpoint_count + 1
107
+ lat = @cv_hash['Latitude']
108
+ long = @cv_hash['Longitude']
109
+ alt = @cv_hash['Altitude']
110
+ hb = @cv_hash['HeartRateBpm']
111
+ time = @cv_hash['Time']
112
+ tp = Trackpoint.new(@trackpoint_count, lat, long, alt, hb, time, @uom)
113
+ @curr_track.add_trackpoint(tp)
114
+
115
+ @cv_hash['Latitude'] = ''
116
+ @cv_hash['Longitude'] = ''
117
+ @cv_hash['Altitude'] = ''
118
+ @cv_hash['HeartRateBpm'] = ''
119
+ @cv_hash['Time'] = ''
120
+ end
121
+
122
+ if is_tag?('Track', tagname)
123
+ if @curr_run != nil
124
+ @curr_run.add_track(@curr_track)
125
+ end
126
+ end
127
+
128
+ if is_tag?('Lap', tagname)
129
+ @curr_lap.startTime = @cv_hash['StartTime']
130
+ @curr_lap.duration = Duration.new(@cv_hash['Duration'])
131
+ @curr_lap.length = @cv_hash['Length']
132
+ @curr_lap.begin_position = @curr_begin_position
133
+ @curr_lap.end_position = @@curr_end_position
134
+ @curr_run.add_lap(@curr_lap)
135
+ end
136
+
137
+ if is_tag?('Run', tagname)
138
+ @curr_run.notes = @cv_hash['Notes']
139
+ end
140
+ end
141
+
142
+ @inDetail = false
143
+ @curr_text = ""
144
+ @currTag = ""
145
+ end
146
+
147
+ # SAX API method.
148
+ def text(txt)
149
+ if @inDetail
150
+ @curr_text = @curr_text + txt
151
+ end
152
+ end
153
+
154
+ # Iterate all parsed Run objects and print each with to_s.
155
+ def gdump()
156
+ @history.runs().each { |run| puts run.to_s }
157
+ end
158
+
159
+ # Iterate all parsed Run objects and print each with to_s.
160
+ def dump()
161
+ @history.runs().each { |run| puts run.to_s }
162
+ end
163
+
164
+ # Iterate all parsed Run objects and print each with put_csv.
165
+ def put_run_csv()
166
+ @history.runs().each { |run| run.put_csv() }
167
+ end
168
+
169
+ # Iterate all parsed Run objects and print each with put_tkpt_csv.
170
+ def put_all_run_tkpt_csv()
171
+ @history.runs.each { |run| run.put_tkpt_csv() }
172
+ end
173
+
174
+ private
175
+
176
+ def is_tag?(tagname, value)
177
+ tagname == value
178
+ end
179
+
180
+ def detail_tag?(tagname)
181
+ DETAIL_TAGS.each { |typ|
182
+ if typ == tagname
183
+ return true
184
+ end
185
+ }
186
+ return false
187
+ end
188
+
189
+ end
190
+
191
+ end # end of module
@@ -0,0 +1,115 @@
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 split a large ForerunnerLogbook
13
+ XML file into individual 'run_' files.
14
+ =end
15
+
16
+ class ForerunnerXmlSplitter < GoobyObject
17
+
18
+ attr_reader :out_dir, :forerunner_files, :out_files_hash
19
+
20
+ def initialize(xml_file, out_dir)
21
+ @out_dir = out_dir
22
+ @forerunner_files = Array.new
23
+ @forerunner_files << xml_file
24
+ @out_files_hash = Hash.new
25
+ end
26
+
27
+ def split
28
+ @forerunner_files.each { |f| process_file(f) }
29
+ write_files
30
+ end
31
+
32
+ private
33
+
34
+ def process_file(forerunnerXmlFile)
35
+ @file_name = forerunnerXmlFile
36
+ @xml_lines = read_lines(@file_name, false)
37
+ @line_num = 0
38
+ @run_num = 0
39
+ @curr_run_lines = Array.new
40
+ @curr_run_tkpts = 0
41
+ @start_line_num = 0
42
+ @end_line_num = 0
43
+ @first_start_time = nil
44
+
45
+ @xml_lines.each { |line|
46
+ @line_num = @line_num + 1
47
+ if (line.match(/<Run>/))
48
+ @run_num = @run_num + 1
49
+ @start_line_num = @line_num
50
+ @curr_run_lines = Array.new
51
+ @curr_run_lines << line
52
+ elsif (line.match(/<StartTime>/)) # <StartTime>2007-01-13T15:37:06Z</StartTime>
53
+ @curr_run_lines << line
54
+ if @first_start_time == nil
55
+ clone = String.new(line)
56
+ clone.gsub!(/[<>]/, ' ')
57
+ clone.gsub!(/[-:T]/, '_')
58
+ clone.gsub!(/[Z]/, '')
59
+ tokens = clone.split
60
+ @first_start_time = tokens[1]
61
+ end
62
+ elsif (line.match(/<Trackpoint>/))
63
+ @curr_run_tkpts = @curr_run_tkpts + 1
64
+ @curr_run_lines << line
65
+ elsif (line.match(/<\/Run>/))
66
+ @end_line_num = @line_num
67
+ @curr_run_lines << line
68
+ end_run
69
+ elsif (@curr_run_lines.size > 0)
70
+ @curr_run_lines << line
71
+ end
72
+ }
73
+ end
74
+
75
+ def end_run
76
+ out_file = "#{@out_dir}/run_#{@first_start_time}.xml"
77
+ comment = "<!-- file: #{out_file} lines: #{@curr_run_lines.size} (#{@start_line_num} to #{@end_line_num}) tkpts: #{@curr_run_tkpts} --> \n"
78
+ @curr_run_lines.insert(0, comment)
79
+
80
+ prev_entry = @out_files_hash[out_file]
81
+ if prev_entry
82
+ if (@curr_run_lines.size >= prev_entry.size)
83
+ puts "previous entry overlaid for #{out_file}. curr=#{@curr_run_lines.size} prev=#{prev_entry.size}"
84
+ @out_files_hash[out_file] = @curr_run_lines
85
+ else
86
+ puts "previous entry retained for #{out_file}. curr=#{@curr_run_lines.size} prev=#{prev_entry.size}"
87
+ end
88
+ else
89
+ puts "new entry for #{out_file}. curr=#{@curr_run_lines.size}"
90
+ @out_files_hash[out_file] = @curr_run_lines
91
+ end
92
+
93
+ @curr_run_lines = Array.new
94
+ @curr_run_tkpts = 0
95
+ @start_line_num = 0
96
+ @end_line_num = 0
97
+ @first_start_time = nil
98
+ end
99
+
100
+ def write_files
101
+ out_names = @out_files_hash.keys.sort
102
+ puts "Writing #{out_names.size} extract files..."
103
+ out_names.each { |out_name|
104
+ lines = @out_files_hash[out_name]
105
+ out = File.new out_name, "w+"
106
+ lines.each { |line| out.write line }
107
+ out.flush
108
+ out.close
109
+ puts "File written: #{out_name}"
110
+ }
111
+ puts "output files written."
112
+ end
113
+ end
114
+
115
+ end # end of module