evva 0.1.4.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 90dd43b0fdd3169aa137cf665a8c592693b9d686
4
- data.tar.gz: 12649831ed616d714b7357c3fdff9d1cd7cf41ea
2
+ SHA256:
3
+ metadata.gz: 32699d4abc90a02f944c069ac0cefc8e26fbf972d42342f86ad55652d198f0c2
4
+ data.tar.gz: d9e9c0e5a62a712636ebede3bf3b04a9f47c8bc36bac4f06ea4d27b48ff3703f
5
5
  SHA512:
6
- metadata.gz: 9d043c714969d7d188026015fe15d0ef3a6d0be113d05593c53624e4af1a63f755800bcfab407d35b4512fd00045791ea59085cc6cc918163faae540222dbd5c
7
- data.tar.gz: ec753ef63337efd78777711e1e2b62b46956a3c44ef699d50d2f9761ff54a9f82cec7124527cf774ca5c95fbae6a3a90785d2d9702bcf0396525dabfc692b2aa
6
+ metadata.gz: cd70916584265dc7077907d324049b93000f5805bf43bb9dda152547e36181740ba8524980606400a8bd128c556dbf09ad641d4c634d513e714b2748639a4498
7
+ data.tar.gz: a9a95c538e9d88011507e5a12e64afb84b91fbee6a5b70e0d48f431a05496a0384347c2f6edc97ad3a3164f80677ff05e0b700d4a2c7ea08bce69d7e59ab8145
data/.gitignore CHANGED
@@ -1,6 +1,5 @@
1
1
  *.sublime-*
2
- .ruby-version
3
2
  running
4
3
  coverage
5
4
  .DS_Store*
6
- .byebug_history
5
+ .byebug_history
data/.rspec CHANGED
@@ -1,5 +1,4 @@
1
1
  --color
2
2
  --format documentation
3
3
  --profile
4
- --drb
5
4
  --require spec_helper
data/.rubocop_todo.yml CHANGED
@@ -57,8 +57,8 @@ Layout/EmptyLinesAroundBlockBody:
57
57
  Layout/EmptyLinesAroundClassBody:
58
58
  Exclude:
59
59
  - 'lib/evva/android_generator.rb'
60
- - 'lib/evva/mixpanel_enum.rb'
61
- - 'lib/evva/mixpanel_event.rb'
60
+ - 'lib/evva/analytics_enum.rb'
61
+ - 'lib/evva/analytics_event.rb'
62
62
 
63
63
  # Offense count: 1
64
64
  # Cop supports --auto-correct.
@@ -163,8 +163,8 @@ Layout/TrailingBlankLines:
163
163
  - 'lib/evva/enum_generator.rb'
164
164
  - 'lib/evva/event_generator.rb'
165
165
  - 'lib/evva/google_sheet.rb'
166
- - 'lib/evva/mixpanel_enum.rb'
167
- - 'lib/evva/mixpanel_event.rb'
166
+ - 'lib/evva/analytics_enum.rb'
167
+ - 'lib/evva/analytics_event.rb'
168
168
  - 'spec/lib/evva/enum_generator_spec.rb'
169
169
  - 'spec/lib/evva/event_generator_spec.rb'
170
170
  - 'spec/lib/evva/google_sheet_spec.rb'
@@ -226,8 +226,8 @@ Lint/UselessAssignment:
226
226
  # Offense count: 2
227
227
  Lint/Void:
228
228
  Exclude:
229
- - 'lib/evva/mixpanel_enum.rb'
230
- - 'lib/evva/mixpanel_event.rb'
229
+ - 'lib/evva/analytics_enum.rb'
230
+ - 'lib/evva/analytics_event.rb'
231
231
 
232
232
  # Offense count: 8
233
233
  Metrics/AbcSize:
@@ -309,8 +309,8 @@ Style/Documentation:
309
309
  - 'lib/evva/event_generator.rb'
310
310
  - 'lib/evva/google_sheet.rb'
311
311
  - 'lib/evva/logger.rb'
312
- - 'lib/evva/mixpanel_enum.rb'
313
- - 'lib/evva/mixpanel_event.rb'
312
+ - 'lib/evva/analytics_enum.rb'
313
+ - 'lib/evva/analytics_event.rb'
314
314
 
315
315
  # Offense count: 1
316
316
  # Cop supports --auto-correct.
@@ -407,8 +407,8 @@ Style/RaiseArgs:
407
407
  # Cop supports --auto-correct.
408
408
  Style/RedundantSelf:
409
409
  Exclude:
410
- - 'lib/evva/mixpanel_enum.rb'
411
- - 'lib/evva/mixpanel_event.rb'
410
+ - 'lib/evva/analytics_enum.rb'
411
+ - 'lib/evva/analytics_event.rb'
412
412
  - 'lib/evva/object_extension.rb'
413
413
 
414
414
  # Offense count: 1
data/.travis.yml ADDED
@@ -0,0 +1 @@
1
+ language: ruby
data/Gemfile CHANGED
@@ -1,13 +1,14 @@
1
1
  source 'https://rubygems.org'
2
- ruby '2.3.3'
3
2
 
4
3
  gem 'colorize'
5
- gem 'rubocop'
6
4
  gem 'safe_yaml'
7
- gem 'xml-simple'
8
5
 
9
- gem 'rspec'
10
- gem 'rspec-its'
11
- gem 'simplecov', require: false, group: :test
12
- gem 'simplecov-rcov', require: false
13
- gem 'webmock', '~> 1.20'
6
+ group :test do
7
+ gem 'rake'
8
+ gem 'rspec'
9
+ gem 'rspec-its'
10
+ gem 'simplecov', require: false, group: :test
11
+ gem 'simplecov-rcov', require: false
12
+ gem 'webmock', '~> 1.20'
13
+ gem 'rubocop'
14
+ end
data/Gemfile.lock CHANGED
@@ -1,8 +1,8 @@
1
1
  GEM
2
2
  remote: https://rubygems.org/
3
3
  specs:
4
- addressable (2.5.2)
5
- public_suffix (>= 2.0.2, < 4.0)
4
+ addressable (2.8.0)
5
+ public_suffix (>= 2.0.2, < 5.0)
6
6
  ast (2.3.0)
7
7
  colorize (0.8.1)
8
8
  crack (0.4.3)
@@ -10,15 +10,15 @@ GEM
10
10
  diff-lcs (1.3)
11
11
  docile (1.1.5)
12
12
  hashdiff (0.3.7)
13
- json (2.1.0)
13
+ json (2.3.0)
14
14
  parallel (1.12.0)
15
15
  parser (2.4.0.0)
16
16
  ast (~> 2.2)
17
17
  powerpack (0.1.1)
18
- public_suffix (3.0.0)
18
+ public_suffix (4.0.6)
19
19
  rainbow (2.2.2)
20
20
  rake
21
- rake (12.1.0)
21
+ rake (12.3.3)
22
22
  rspec (3.7.0)
23
23
  rspec-core (~> 3.7.0)
24
24
  rspec-expectations (~> 3.7.0)
@@ -56,13 +56,13 @@ GEM
56
56
  addressable (>= 2.3.6)
57
57
  crack (>= 0.3.2)
58
58
  hashdiff
59
- xml-simple (1.1.5)
60
59
 
61
60
  PLATFORMS
62
61
  ruby
63
62
 
64
63
  DEPENDENCIES
65
64
  colorize
65
+ rake
66
66
  rspec
67
67
  rspec-its
68
68
  rubocop
@@ -70,10 +70,6 @@ DEPENDENCIES
70
70
  simplecov
71
71
  simplecov-rcov
72
72
  webmock (~> 1.20)
73
- xml-simple
74
-
75
- RUBY VERSION
76
- ruby 2.3.3p222
77
73
 
78
74
  BUNDLED WITH
79
- 1.15.4
75
+ 2.2.26
data/README.md CHANGED
@@ -1,4 +1,10 @@
1
1
  Evva
2
+ ========
3
+
4
+ [![Status](https://travis-ci.org/hole19/evva.svg?branch=master)](https://travis-ci.org/hole19/evva?branch=master)
5
+ [![Gem](https://img.shields.io/gem/v/evva.svg?style=flat)](http://rubygems.org/gems/evva "View this project in Rubygems")
6
+
7
+ Evva automatically generates code for triggering events based on a Google Sheets specification. It generated code for both iOS (Swift) and Android (Kotlin).
2
8
 
3
9
  # Instalation
4
10
 
@@ -19,9 +25,13 @@ Evva
19
25
  data_source:
20
26
  type: google_sheet
21
27
  sheet_id: <GOOGLE-DRIVE-SHEET-ID>
28
+ events_url: <GOOGLE-DRIVE-EVENTS-SHEET-URL>
29
+ people_properties_url: <GOOGLE-DRIVE-PEOPLE-PROPERTIES-SHEET-URL>
30
+ enum_classes_url: <GOOGLE-DRIVE-ENUM-CLASSES-SHEET-URL>
22
31
 
23
32
  out_path: /folder/where/analytics/classes/are
24
33
  event_file_name: /file/with/tracking/functions
25
34
  event_enum_file_name: /file/with/event/names
26
35
  people_file_name: /file/with/people/properties
36
+ special_enum_file_name: //file/with/special/enum/properties/
27
37
  ```
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require "rake"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec) do |t|
5
+ t.pattern = Dir.glob("spec/**/*_spec.rb")
6
+ t.rspec_opts = "--format documentation"
7
+ end
8
+
9
+ task default: :spec
data/changelog.md CHANGED
@@ -1,4 +1,20 @@
1
1
  # Change Log
2
+
3
+ ## [0.3.0] - 2021-12-16
4
+ - Revamp Android generator to generate events as classes instead of methods.
5
+
6
+ ## [0.2.0] - 2021-08-30
7
+ - Google Spreadsheet option stopped working due to a change in the API. This version fixes that.
8
+
9
+ Note: You'll need a new setup. View README.
10
+
11
+ ## [0.1.4.4] - 2019-02-04
12
+ - Adds support for dynamic android package name
13
+
14
+ ## [0.1.4.3] - 2018-10-12
15
+ - Fixes swift and kotlin tabs, indentation and property names
16
+ - Merges all special enums in a single file
17
+
2
18
  ## [0.1.4.2] - 2018-02-14
3
19
  - Replaces Swift headers
4
20
 
@@ -19,5 +35,6 @@
19
35
  ## [0.1.1] - 2017-11-07
20
36
  - Fixes mismatch between file name and class name generated.
21
37
 
22
- ## [0.1.0] - 2017/10/26
23
- - Initial Release.
38
+ ## [0.1.0] - 2017-10-26
39
+ - Initial Release.
40
+
data/evva.gemspec CHANGED
@@ -18,7 +18,4 @@ Gem::Specification.new do |s|
18
18
 
19
19
  s.add_runtime_dependency 'safe_yaml', '~> 1.0'
20
20
  s.add_runtime_dependency 'colorize', '~> 0.7'
21
- s.add_runtime_dependency 'xml-simple', '~> 1.1'
22
-
23
- s.add_development_dependency 'webmock', '~> 1.20'
24
21
  end
data/evva_config.yml CHANGED
@@ -3,8 +3,12 @@ type: iOS
3
3
  data_source:
4
4
  type: google_sheet
5
5
  sheet_id: 1LaJd68os3g_GFlerogC64grNIlXb2iukMznOvdml7A4
6
+ events_url: https://path-to-csv
7
+ people_properties_url: https://path-to-csv
8
+ enum_classes_url: https://path-to-csv
6
9
 
7
10
  out_path: analytics
8
- event_file_name: MixpanelAnalytics
9
- event_enum_file_name: MixpanelEvent
10
- people_file_name: MixpanelProperties
11
+ event_file_name: AnalyticsEvent
12
+ event_enum_file_name: AnalyticsEvents
13
+ people_file_name: AnalyticsProperties
14
+ package_name: com.hole19golf.hole19.analytics
@@ -1,5 +1,5 @@
1
1
  module Evva
2
- class MixpanelEnum
2
+ class AnalyticsEnum
3
3
  attr_reader :enum_name, :values
4
4
  def initialize(enum_name, values)
5
5
  @enum_name = enum_name
@@ -1,5 +1,5 @@
1
1
  module Evva
2
- class MixpanelEvent
2
+ class AnalyticsEvent
3
3
  attr_reader :event_name, :properties
4
4
  def initialize(event_name, properties = {})
5
5
  @event_name = event_name
@@ -1,100 +1,112 @@
1
1
  module Evva
2
2
  class AndroidGenerator
3
- KOTLIN_EVENT_HEADER =
4
- "package com.hole19golf.hole19.analytics\n\n"\
5
- "import com.hole19golf.hole19.analytics.Event\n"\
6
- "import com.hole19golf.hole19.analytics.MixpanelAnalyticsMask\n"\
7
- "import org.json.JSONObject\n\n".freeze
8
-
9
- KOTLIN_PEOPLE_HEADER =
10
- "package com.hole19golf.hole19.analytics\n"\
11
- "import com.hole19golf.hole19.analytics.Event\n\n".freeze
12
-
13
- KOTLIN_BUNDLE_HEADER =
14
- "package com.hole19golf.hole19.analytics\n"\
15
- "import com.hole19golf.hole19.analytics.Event\n\n".freeze
16
-
17
- KOTIN_PEOPLE_FUNCTIONS =
18
- "\nopen fun updateProperties(property: MixpanelProperties, value: Any) {\n"\
19
- "\t\tmixpanelMask.updateProperties(property.key, value)"\
20
- "\t\n} \n"\
21
- "\nopen fun incrementCounter(property: MixpanelProperties) {\n"\
22
- "\t\tmixpanelMask.incrementCounter(property.key)"\
23
- "\t\n} \n".freeze
3
+ attr_accessor :package_name
4
+
5
+ def initialize(package_name)
6
+ @package_name = package_name
7
+ end
24
8
 
25
9
  NATIVE_TYPES = %w[Long Int String Double Float Boolean].freeze
26
10
 
27
11
  def events(bundle, file_name)
28
- event_file = KOTLIN_EVENT_HEADER + "open class #{file_name}(private val mixpanelMask: MixpanelAnalyticsMask) {\n".freeze
29
- bundle.each do |event|
30
- event_file += "\n#{kotlin_function(event)}"
12
+ header_footer_wrapper do
13
+ """sealed class #{file_name}(event: AnalyticsEvents) {
14
+ \tval name = event.key
15
+
16
+ \topen val properties: Map<String, Any?>? = null
17
+
18
+ #{bundle.map { |e| event_class(e, file_name) }.join("\n\n")}
19
+ }"""
31
20
  end
32
- event_file += KOTIN_PEOPLE_FUNCTIONS
33
- event_file += "\n}"
34
21
  end
35
22
 
36
23
  def people_properties(people_bundle, file_name)
37
- properties = KOTLIN_PEOPLE_HEADER + "enum class #{file_name}(val key: String) {\n"
38
- properties += people_bundle.map { |prop| "\t\t#{prop.upcase}(\"#{prop}\")" }.join(",\n")
39
- properties += ";\n}\n"
24
+ header_footer_wrapper do
25
+ body = "enum class #{file_name}(val key: String) {\n"
26
+ body << people_bundle.map { |prop| "\t#{prop.upcase}(\"#{prop}\")" }.join(",\n")
27
+ body << ";\n}"
28
+ end
40
29
  end
41
30
 
42
31
  def event_enum(bundle, file_name)
43
- event_file = KOTLIN_BUNDLE_HEADER + "enum class #{file_name}(override val key: String) : Event {\n"
44
- event_file += bundle.map { |event| "\t\t#{event.event_name.upcase}(\"#{event.event_name}\")"}.join(", \n")
45
- event_file += "\n}\n"
32
+ header_footer_wrapper do
33
+ body = "enum class #{file_name}(val key: String) {\n"
34
+ body << bundle.map(&:event_name).map { |prop| "\t#{prop.upcase}(\"#{prop}\")" }.join(",\n")
35
+ body << ";\n}"
36
+ end
46
37
  end
47
38
 
48
- def kotlin_function(event_data)
49
- function_name = 'track' + titleize(event_data.event_name)
50
- function_arguments = event_data.properties.map { |name, type| "#{name}: #{type}" }.join(', ')
51
- if !function_arguments.empty?
52
- props = json_props(event_data.properties)
53
- function_body =
54
- "open fun #{function_name}(#{function_arguments}) {"\
55
- "#{props}"\
56
- "\tmixpanelMask.trackEvent(MixpanelEvent.#{event_data.event_name.upcase}, properties)\n"
57
- else
58
- function_body =
59
- "open fun #{function_name}() {\n"\
60
- "\tmixpanelMask.trackEvent(MixpanelEvent.#{event_data.event_name.upcase})\n"
39
+ def special_property_enums(enums)
40
+ header_footer_wrapper do
41
+ enums.map do |enum|
42
+ body = "enum class #{enum.enum_name}(val key: String) {\n"
43
+ body << enum.values.map { |vals| "\t#{vals.tr(' ', '_').upcase}(\"#{vals}\")"}.join(",\n")
44
+ body << ";\n}"
45
+ end.join("\n\n")
61
46
  end
62
- function_body += "}\n"
63
47
  end
64
48
 
65
- def special_property_enum(enum)
66
- enum_body = "package com.hole19golf.hole19.analytics\n\n"
67
- enum_body += "enum class #{enum.enum_name}(val key: String) {\n"
68
- enum_body += enum.values.map { |vals| "\t#{vals.tr(' ', '_').upcase}(\"#{vals}\")"}.join(",\n")
69
- enum_body += "\n}\n"
49
+ private
50
+
51
+ def imports_header(imports = [])
52
+ return unless imports.length > 0
53
+ imports.map { |ev| ev. gsub("packagename", @package_name) }
54
+ .join("\n") + "\n\n"
70
55
  end
71
56
 
72
- private
57
+ def header_footer_wrapper(imports = [])
58
+ <<-Kotlin
59
+ package #{@package_name}
60
+
61
+ #{imports_header(imports)}/**
62
+ * This file was automatically generated by evva: https://github.com/hole19/evva
63
+ */
64
+
65
+ #{yield.gsub("\t", " ")}
66
+ Kotlin
67
+ end
68
+
69
+ def event_class(event_data, superclass_name)
70
+ class_name = camelize(event_data.event_name)
71
+ class_arguments = event_data.properties.map { |name, type| "val #{camelize(name, false)}: #{type}" }.join(', ')
72
+ if !class_arguments.empty?
73
+ props = props_map(event_data.properties)
73
74
 
74
- def json_props(properties)
75
+ """\tdata class #{class_name}(
76
+ \t\t#{class_arguments}
77
+ \t) : #{superclass_name}(AnalyticsEvents.#{event_data.event_name.upcase}) {
78
+ #{props}
79
+ \t}"""
80
+
81
+ else
82
+ """\tobject #{class_name} : #{superclass_name}(AnalyticsEvents.#{event_data.event_name.upcase})"""
83
+ end
84
+ end
85
+
86
+ def props_map(properties)
75
87
  split_properties =
76
88
  properties
77
- .map do |name, type|
89
+ .map.with_index do |data, index|
90
+ name, type = data
91
+ prop = "\t\t\t\"#{name}\" to #{camelize(name, false)}"
92
+
78
93
  if special_property?(type)
79
94
  if optional_property?(type)
80
- "#{name}?.let { put(\"#{name}\", it.key) }"
81
- else
82
- "put(\"#{name}\", #{name}.key)"
83
- end
84
- else
85
- if optional_property?(type)
86
- "#{name}?.let { put(\"#{name}\", it) }"
87
- else
88
- "put(\"#{name}\", #{name})"
95
+ prop = "#{prop}?"
89
96
  end
97
+ prop = "#{prop}.key"
98
+ end
99
+
100
+ if index < properties.size - 1
101
+ # add list comma to every property except the last one
102
+ prop = "#{prop},"
90
103
  end
104
+
105
+ prop
91
106
  end
92
- .map { |line| "\t\t#{line}" }
93
107
  .join("\n")
94
108
 
95
- resulting_json = "\n\tval properties = JSONObject().apply {\n" +
96
- +split_properties.to_s
97
- resulting_json += "\n\t}\n"
109
+ "\t\toverride val properties = mapOf(\n#{split_properties}\n\t\t)"
98
110
  end
99
111
 
100
112
  def special_property?(type)
@@ -105,8 +117,15 @@ module Evva
105
117
  type.include?('?')
106
118
  end
107
119
 
108
- def titleize(str)
109
- str.split('_').collect(&:capitalize).join
120
+ # extracted from Rails' ActiveSupport
121
+ def camelize(string, uppercase_first_letter = true)
122
+ string = string.to_s
123
+ if uppercase_first_letter
124
+ string = string.sub(/^[a-z\d]*/) { |match| match.capitalize }
125
+ else
126
+ string = string.sub(/^(?:(?=\b|[A-Z_])|\w)/) { |match| match.downcase }
127
+ end
128
+ string.gsub(/(?:_|(\/))([a-z\d]*)/) { "#{$1}#{$2.capitalize}" }.gsub("/", "::")
110
129
  end
111
130
  end
112
131
  end
data/lib/evva/config.rb CHANGED
@@ -39,6 +39,14 @@ module Evva
39
39
  @hash[:event_enum_file_name]
40
40
  end
41
41
 
42
+ def special_enum_file_name
43
+ @hash[:special_enum_file_name]
44
+ end
45
+
46
+ def package_name
47
+ @hash[:package_name]
48
+ end
49
+
42
50
  CONFIG_STRUCT = {
43
51
  type: Hash,
44
52
  elements: {
@@ -49,7 +57,8 @@ module Evva
49
57
  out_path: { type: String },
50
58
  event_file_name: { type: String },
51
59
  event_enum_file_name: { type: String },
52
- people_file_name: { type: String }
60
+ people_file_name: { type: String },
61
+ package_name: { type: String }
53
62
  }
54
63
  }.freeze
55
64
 
@@ -57,7 +66,9 @@ module Evva
57
66
  type: Hash,
58
67
  elements: {
59
68
  type: { type: String },
60
- sheet_id: { type: String }
69
+ events_url: { type: String },
70
+ people_properties_url: { type: String },
71
+ enum_classes_url: { type: String },
61
72
  }
62
73
  }.freeze
63
74
 
@@ -1,83 +1,86 @@
1
1
  require 'net/https'
2
- require 'xmlsimple'
2
+ require 'csv'
3
3
 
4
4
  module Evva
5
5
  class GoogleSheet
6
- def initialize(sheet_id)
7
- @sheet_id = sheet_id
6
+ def initialize(events_url, people_properties_url, enum_classes_url)
7
+ @events_url = events_url
8
+ @people_properties_url = people_properties_url
9
+ @enum_classes_url = enum_classes_url
8
10
  end
9
11
 
10
12
  def events
11
- raw = raw_data(@sheet_id, 0)
12
- Logger.info('Downloading dictionary from Google Sheet...')
13
- non_language_columns = %w[id updated category
14
- title content link]
13
+ Logger.info("Downloading data from Google Sheet at #{@events_url}")
14
+ csv = get_csv(@events_url)
15
+
15
16
  event_list = []
16
- raw['entry'].each do |entry|
17
- filtered_entry = entry.reject { |c| non_language_columns.include?(c) }
18
- event_name = filtered_entry['eventname'].first
19
- properties = hash_parser(filtered_entry['props'].first)
20
- event_list.push(Evva::MixpanelEvent.new(event_name, properties))
17
+ csv.each do |row|
18
+ event_name = row['Event Name']
19
+ properties = hash_parser(row['Event Properties'])
20
+ event_list << Evva::AnalyticsEvent.new(event_name, properties)
21
21
  end
22
22
  event_list
23
23
  end
24
24
 
25
25
  def people_properties
26
- raw = raw_data(@sheet_id, 1)
26
+ Logger.info("Downloading data from Google Sheet at #{@people_properties_url}")
27
+ csv = get_csv(@people_properties_url)
28
+
27
29
  people_list = []
28
- Logger.info('Downloading dictionary from Google Sheet...')
29
- non_language_columns = %w[id updated category title content link]
30
- raw['entry'].each do |entry|
31
- filtered_entry = entry.reject { |c| non_language_columns.include?(c) }
32
- value = filtered_entry['value'].first
30
+ csv.each do |row|
31
+ value = row['Property Name']
33
32
  people_list << value
34
33
  end
35
34
  people_list
36
35
  end
37
36
 
38
37
  def enum_classes
39
- raw = raw_data(@sheet_id, 2)
40
- Logger.info('Downloading dictionary from Google Sheet...')
41
- non_language_columns = %w[id updated category title content link]
38
+ Logger.info("Downloading data from Google Sheet at #{@enum_classes_url}")
39
+ csv = get_csv(@enum_classes_url)
40
+
42
41
  enum_list = []
43
- raw['entry'].each do |entry|
44
- filtered_entry = entry.reject { |c| non_language_columns.include?(c) }
45
- enum_name = filtered_entry['enum'].first
46
- values = filtered_entry['values'].first.split(',')
47
- enum_list.push(Evva::MixpanelEnum.new(enum_name, values))
42
+ csv.each do |row|
43
+ enum_name = row['Enum Name']
44
+ values = row['Possible Values'].split(',')
45
+ enum_list << Evva::AnalyticsEnum.new(enum_name, values)
48
46
  end
49
47
  enum_list
50
48
  end
51
49
 
52
- def xml_data(uri, headers = nil)
53
- uri = URI.parse(uri)
54
- http = Net::HTTP.new(uri.host, uri.port)
55
- http.use_ssl = true
56
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
57
- data = http.get(uri.path, headers)
58
- unless data.code.to_i == 200
59
- raise 'Cannot access sheet at #{uri} - HTTP #{data.code}'
60
- end
50
+ private
51
+
52
+ def get_csv(url)
53
+ data = get(url)
61
54
 
62
55
  begin
63
- XmlSimple.xml_in(data.body, 'KeyAttr' => 'name')
64
- rescue
65
- raise 'Cannot parse. Expected XML at #{uri}'
56
+ CSV.parse(data, headers: true)
57
+ rescue StandardError => e
58
+ raise "Cannot parse. Expected CSV at #{url}: #{e}"
66
59
  end
67
60
  end
68
61
 
69
- def raw_data(sheet_id, sheet_number)
70
- Logger.info('Downloading Google Sheet...')
71
- sheet = xml_data("https://spreadsheets.google.com/feeds/worksheets/#{sheet_id}/public/full")
72
- url = sheet['entry'][sheet_number]['link'][0]['href']
73
- xml_data(url)
74
- end
62
+ def get(url, max_redirects = 1)
63
+ raise "Too may redirects" if max_redirects == -1
75
64
 
76
- private
65
+ uri = URI(url)
66
+
67
+ http = Net::HTTP.new(uri.host, uri.port)
68
+ http.use_ssl = true
69
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
70
+
71
+ request = Net::HTTP::Get.new(uri.request_uri)
72
+ response = http.request(request)
73
+
74
+ return get(response['location'], max_redirects - 1) if response.is_a? Net::HTTPRedirection
75
+
76
+ raise "Http Error #{response.body}" if response.code.to_i >= 400
77
+
78
+ response.body
79
+ end
77
80
 
78
81
  def hash_parser(property_array)
79
82
  h = {}
80
- unless property_array.empty?
83
+ unless property_array.nil? || property_array.empty?
81
84
  property_array.split(',').each do |prop|
82
85
  split_prop = prop.split(':')
83
86
  prop_name = split_prop[0].to_sym