gooby 1.1.0 → 1.2.0

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 (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,123 @@
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
12
+
13
+ This is a singleton class whose values are loaded from a YAML file when your
14
+ GoobyCommand class is created. The default filename is 'gooby_config.yaml"'.
15
+
16
+ The YAML file contains configuration parameters, such as your Google Map key,
17
+ map HTML options, points of interest, and courses.
18
+
19
+ =end
20
+ class Configuration < GoobyObject
21
+
22
+ @@singleton_instance = nil
23
+
24
+ attr_reader :yaml_filename, :configuration
25
+
26
+ private_class_method :new
27
+
28
+ def Configuration.init(yaml_filename='gooby_config.yaml')
29
+ return @@singleton_instance if @@singleton_instance
30
+ @@singleton_instance = new(yaml_filename)
31
+ end
32
+
33
+ def self.get_config
34
+ @@singleton_instance
35
+ end
36
+
37
+ def initialize(yaml_filename)
38
+ @yaml_filename = yaml_filename
39
+ File.open("#{@yaml_filename}") { |fn| @configuration = YAML::load(fn) }
40
+ end
41
+
42
+ def get(name)
43
+ if name == nil
44
+ return ''
45
+ end
46
+ s = @configuration["#{name}"]
47
+
48
+ # Provide "sensible defaults".
49
+ if s == nil
50
+ if (name == '')
51
+ return ''
52
+ elsif (name == 'english_metric')
53
+ return 'english'
54
+ elsif (name == 'gmap_first_tkpt_number')
55
+ return 1
56
+ elsif (name == 'gmap_last_tkpt_number')
57
+ return 5000
58
+ elsif (name == 'gmap_map_element_id')
59
+ return 'map'
60
+ elsif (name == 'gmap_height')
61
+ return '600'
62
+ elsif (name == 'gmap_icon_url_base')
63
+ return 'http://www.your-web-site.com/gicons/'
64
+ elsif (name == 'gmap_key')
65
+ return 'enter your Google Map Key here'
66
+ elsif (name == 'gmap_type_control')
67
+ return true
68
+ elsif (name == 'gmap_approx_max_points')
69
+ return '200'
70
+ elsif (name == 'gmap_gen_comments')
71
+ return true
72
+ elsif (name == 'gmap_size_control')
73
+ return nil
74
+ elsif (name == 'gmap_type')
75
+ return 'G_NORMAL_MAP'
76
+ elsif (name == 'gmap_zoom_level')
77
+ return 5
78
+ else
79
+ return ''
80
+ end
81
+ end
82
+ s
83
+ end
84
+
85
+ def print_all
86
+ @configuration.keys.sort.each { |key|
87
+ value = get(key)
88
+ puts "#{key}: #{value}"
89
+ }
90
+ end
91
+
92
+ def print_all_poi
93
+ @configuration.keys.sort.each { |key|
94
+ if (key.match(/poi[\.]/))
95
+ val = @configuration["#{key}"]
96
+ poi = Point.new(val)
97
+ puts poi.to_s
98
+ end
99
+ }
100
+ end
101
+
102
+ def get_poi(number)
103
+ val = @configuration["poi.#{number}"]
104
+ (val) ? Point.new(val) : nil
105
+ end
106
+
107
+ def get_course(number)
108
+ val = @configuration["course.#{number}"]
109
+ (val) ? Course.new(val) : nil
110
+ end
111
+
112
+ def size
113
+ @configuration.size
114
+ end
115
+
116
+ # Return a String containing yaml filename and entry count.
117
+ def to_s
118
+ return "# Configuration: filename: #{@yaml_filename} entries: #{@configuration.size}"
119
+ end
120
+
121
+ end
122
+
123
+ end # end of module
@@ -0,0 +1,95 @@
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
+ This class wrappers a Hash object and provides increment/decrement functionality
13
+ for a given key. It is used to sum the number of things (i.e. - xml tags) in a
14
+ collection.
15
+ =end
16
+
17
+ class CounterHash < GoobyObject
18
+
19
+ def initialize
20
+ @hash = Hash.new(0)
21
+ end
22
+
23
+ def size
24
+ @hash.size
25
+ end
26
+
27
+ # Return the Integer count for the given key; zero default.
28
+ def value(key)
29
+ (@hash.has_key?(key)) ? @hash[key] : 0
30
+ end
31
+
32
+ # Increment the count for the given key.
33
+ def increment(key)
34
+ if key == nil
35
+ return
36
+ end
37
+ if (@hash.has_key?(key))
38
+ val = @hash[key]
39
+ @hash[key] = val + 1
40
+ else
41
+ @hash[key] = 1
42
+ end
43
+ end
44
+
45
+ def increment_tokens(text)
46
+ tokens = tokenize(text)
47
+ tokens.each { |token| increment(token) }
48
+ end
49
+
50
+ # Decrement the count for the given key.
51
+ def decrement(key)
52
+ if key == nil
53
+ return
54
+ end
55
+ if (@hash.has_key?(key))
56
+ val = @hash[key]
57
+ @hash[key] = val - 1
58
+ else
59
+ @hash[key] = -1
60
+ end
61
+ end
62
+
63
+ # Return an Array of the sorted keys.
64
+ def sorted_keys
65
+ @hash.keys.sort
66
+ end
67
+
68
+ # Return a String containing all key=val pairs.
69
+ def to_s
70
+ s = "CHash:"
71
+ sorted_keys.each { |key|
72
+ val = @hash[key]
73
+ s << " key: [#{key}] val: [#{val}]\n"
74
+ }
75
+ s
76
+ end
77
+
78
+ # Return an XML String containing all key=val pairs, optionally aligned.
79
+ def to_xml(aligned=false)
80
+ s = "<CHash>"
81
+ sorted_keys.each { |key|
82
+ val = @hash[key]
83
+ (aligned) ? s << "\n " : s << ''
84
+ s << " <entry key='#{key}' value='#{val}'/>"
85
+ }
86
+ if aligned
87
+ s << "\n "
88
+ end
89
+ s << " </CHash>"
90
+ s
91
+ end
92
+
93
+ end
94
+
95
+ end # end of module
@@ -0,0 +1,117 @@
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 Course < GoobyObject
12
+
13
+ attr_accessor :name, :distance, :point_numbers, :points
14
+
15
+ def initialize(yaml_csv)
16
+ @name, @distance = '', 0.0
17
+ @point_numbers, @points, @bad_points = Array.new, Array.new, Array.new
18
+ @points_hash, @matched_points = Hash.new, Hash.new
19
+ tokens = yaml_csv.split(',')
20
+ @name = tokens[0] if tokens.size > 0
21
+ @distance = tokens[1].to_f if tokens.size > 1
22
+ if tokens.size > 2
23
+ index = 0
24
+ tokens.each { |tok|
25
+ index = index + 1
26
+ if (index > 2)
27
+ poi = Configuration.get_config.get_poi(tok)
28
+ if (poi)
29
+ poi.number = "#{tok}"
30
+ @point_numbers << "#{tok}"
31
+ @points << poi
32
+ @points_hash["#{tok}"] = poi
33
+ else
34
+ @bad_points << tok
35
+ end
36
+ end
37
+ }
38
+ end
39
+ end
40
+
41
+ def has_errors
42
+ (@bad_points.size > 0) ? true : false
43
+ end
44
+
45
+ def matched(number, point)
46
+ @matched_points["#{number}"] = point if point
47
+ end
48
+
49
+ def matched?
50
+ (@matched_points.size == @point_numbers.size) ? true : false
51
+ end
52
+
53
+ def display_matches
54
+ puts ''
55
+ calculate_matches
56
+ @point_numbers.each { |num|
57
+ point = @points_hash["#{num}"]
58
+ mpoint = @matched_points["#{num}"]
59
+ puts ''
60
+ puts " Course Point: #{point.to_formatted_string}" if point
61
+ puts " Matched Point: #{mpoint.to_formatted_string}" if mpoint
62
+ }
63
+ puts ''
64
+ end
65
+
66
+ def reset
67
+ @matched_points = Hash.new
68
+ end
69
+
70
+ def to_s
71
+ "#{@name} #{@distance} points: #{@points.size} errors: #{has_errors}"
72
+ end
73
+
74
+ def dump
75
+ puts "Course: #{@name}"
76
+ puts "Distance: #{@distance}"
77
+ points.each { |pt| puts pt } #{@points.size} errors: #{has_errors}"
78
+ end
79
+
80
+ private
81
+
82
+ def calculate_matches
83
+ # first, identify the high and low distance points and their indices.
84
+ idx, low_dist, low_dist_idx, low_time, high_dist, high_dist_idx = -1, 999999.0, 0, '', -1.0, 0
85
+ @point_numbers.each { |num|
86
+ idx = idx + 1
87
+ mpoint = @matched_points["#{num}"]
88
+ if mpoint && mpoint.distance < low_dist
89
+ low_dist = mpoint.distance
90
+ low_dist_idx = idx
91
+ low_time = mpoint.elapsed
92
+ end
93
+ if mpoint && mpoint.distance > high_dist
94
+ high_dist = mpoint.distance
95
+ high_dist_idx = idx
96
+ end
97
+ }
98
+ low_dttm = DtTm.new("2007-06-09T#{low_time}Z")
99
+
100
+ # reorder the entries in @point_numbers if necessary - 'low-to-high distance'.
101
+ if (high_dist_idx < low_dist_idx)
102
+ @point_numbers.reverse!
103
+ end
104
+
105
+ @point_numbers.each { |num|
106
+ mpoint = @matched_points["#{num}"]
107
+ if mpoint
108
+ mpoint.course_distance = mpoint.distance - low_dist
109
+ dttm = DtTm.new("2007-06-09T#{mpoint.elapsed}Z")
110
+ mpoint.course_elapsed = dttm.hhmmss_diff(low_dttm)
111
+ end
112
+ }
113
+ end
114
+
115
+ end
116
+
117
+ end # end of module
@@ -0,0 +1,71 @@
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 CsvPoint < Point
12
+
13
+ attr_reader :rawdata, :tokens
14
+ attr_reader :id, :run_id, :date, :time, :tkpt_num, :distance, :elapsed, :uom
15
+ attr_reader :lap_number, :lap_distance, :lap_elapsed
16
+ attr_accessor :course_distance, :course_elapsed, :degrees_diff
17
+
18
+ def initialize(csv_line)
19
+ @rawdata = "#{csv_line}"
20
+ @tokens = @rawdata.split(csv_delim)
21
+ if (@tokens.size > 14)
22
+ @id = @tokens[0] # <-- consists of @run_id.@tkpt_num for uniqueness and use as a DB table primary key.
23
+ @run_id = @tokens[1]
24
+ @date = @tokens[2]
25
+ @time = @tokens[3]
26
+ @tkpt_num = @tokens[4].strip.to_i
27
+ @latitude = @tokens[5].to_f
28
+ @longitude = @tokens[6].to_f
29
+ @altitude = @tokens[7].strip.to_f
30
+ @heartbeat = @tokens[8].strip.to_f
31
+ @distance = @tokens[9].strip.to_f
32
+ @uom = @tokens[10].strip
33
+ @elapsed = @tokens[11]
34
+ @lap_number = @tokens[12].strip.to_i
35
+ @lap_distance = @tokens[13].strip.to_f
36
+ @lap_elapsed = @tokens[14]
37
+ end
38
+ end
39
+
40
+ def token_count
41
+ @tokens ? @tokens.size : 0
42
+ end
43
+
44
+ def as_trackpoint
45
+ tkpt = Trackpoint.new(@tkpt_num, @latitude, @longitude, @altitude, @heartbeat, "#{date}T#{time}Z", @uom)
46
+ tkpt.lap_number = @lap_number
47
+ tkpt.lap_distance = @lap_distance
48
+ tkpt.lap_elapsed = @lap_elapsed
49
+ tkpt
50
+ end
51
+
52
+ def to_s
53
+ return "lat: #{@latitude} lng: #{@longitude} alt: #{@altitude} note: #{@note}"
54
+ end
55
+
56
+ def to_formatted_string
57
+ s = "lat: #{@latitude.to_s.ljust(20)}"
58
+ s << " lng: #{@longitude.to_s.ljust(20)}"
59
+ s << " time: #{@time}"
60
+ pad = ''.ljust(70)
61
+ s << "\n#{pad} course elapsed: #{@course_elapsed}"
62
+ s << "\n#{pad} distance: #{@distance}"
63
+ s << "\n#{pad} heartbeat: #{@heartbeat}" if (@heartbeat && (@heartbeat.to_f > 0))
64
+ s << "\n#{pad} course distance: #{@course_distance}"
65
+ s << "\n#{pad} altitude: #{@altitude}"
66
+ s << "\n#{pad} degrees diff: #{@degrees_diff}"
67
+ s
68
+ end
69
+ end
70
+
71
+ end # end of module
@@ -0,0 +1,71 @@
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 CsvReader < GoobyObject
12
+
13
+ attr_reader :files, :csv_points, :col_names
14
+
15
+ def initialize(array_of_filenames=nil)
16
+ @files = Array.new
17
+ @csv_points = Array.new
18
+ if array_of_filenames
19
+ array_of_filenames.each { |filename| add_file(filename) }
20
+ end
21
+ end
22
+
23
+ def add_file(filename)
24
+ if (filename)
25
+ if (File.exist?(filename))
26
+ @files << filename
27
+ end
28
+ end
29
+ end
30
+
31
+ def read
32
+ @files.each { |filename|
33
+ lines = read_lines(filename, true)
34
+ lines.each { |line|
35
+ if (line.match('^#'))
36
+ if (line.match('^#cols: '))
37
+ col_names_header = line[7, line.size]
38
+ @col_names = col_names_header.split('|')
39
+ end
40
+ else
41
+ if (line.size > 50)
42
+ @csv_points << Gooby::CsvPoint.new(line)
43
+ end
44
+ end
45
+ }
46
+ }
47
+ @csv_points
48
+ end
49
+
50
+ def display_formatted_record(record_index=2)
51
+ tokens = @csv_points[record_index].rawdata.split('|')
52
+ puts "\nCsvReader.display_formatted_record hdr_cols=#{@col_names.size} data_cols=#{tokens.size}"
53
+ size = 0
54
+ @col_names.each { |col_name|
55
+ size = size + 1
56
+ if size <= tokens.size
57
+ value = tokens[size - 1]
58
+ puts "#{col_name.strip.ljust(20)} #{(size - 1).to_s.ljust(3)} #{value}"
59
+ end
60
+ }
61
+ end
62
+
63
+ def to_s
64
+ s = "CsvReader - file count: #{files.size} total points: #{csv_points.size}"
65
+ @files.each { |file| s << "\n file: #{file} "}
66
+ s
67
+ end
68
+
69
+ end
70
+
71
+ end # end of module