firebase-stats 1.0.6 → 1.0.7

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fbcdeca6db0a52d5363c394beaaa7eafa626cf9cc33efd6bb50e41c1ad364d89
4
- data.tar.gz: 20249bc78d26a568cf21288b144aae3999e597519a9bcc41e41f3f61890a027a
3
+ metadata.gz: 6f242227d13ffe84bca59bc31022c4d8628e8df5a7685d5ae1d6dd97c1aa937c
4
+ data.tar.gz: 06e6280fdcab4baac6818eb42f1adb9c7a4153e81620557a0da8115b4f21c7bf
5
5
  SHA512:
6
- metadata.gz: 20c75f62fdd228779f51ba1a64b5f783c07b859a280efb65be07e47b5c8aabe6b94859650bb99d85f71056d5a4b1b2336bd9af148b724c67fb208fa4e52390a6
7
- data.tar.gz: 8b8baf3a8985fc72ff61a5b75d69cc6660bc53bd42e0d5271a62e98d5eef262ba86631d99ee3e10226211ecd991327626ccc15e991a0acac77ae0895432a2678
6
+ metadata.gz: c3e663d068be4f12c0c3ea98fd7aeda11184550a0ca3732effe19a1999733fab5fa960c14a6dfbd5f55ba6549908d8665f34d93917d1768b101dff50f69b383b
7
+ data.tar.gz: ef547e9e6b067dba32befac728beb80eeccd1f9217b4641cc358f1f72765eff5bfba90ad79dde97fdc7a09b5d97ff42ae6de3be00164ea8de759ec85d2e6f673
data/bin/firebase-stats CHANGED
@@ -29,13 +29,17 @@ command :devices do |c|
29
29
  c.option '--platform STRING', String, 'Show only stats for this OS. Either ios, android or all (default)'
30
30
 
31
31
  c.action do |args, options|
32
- stats = FirebaseStats::Reader.new
33
- stats.parse_file(args[0])
32
+ begin
33
+ stats = FirebaseStats::Reader.new
34
+ stats.parse_file(args[0])
34
35
 
35
- platform = map_platform(options)
36
+ platform = map_platform(options)
36
37
 
37
- wrapper = FirebaseStats::Wrapper.new(stats)
38
- tp wrapper.devices(friendly: options.friendly, limit: options.limit, platform: platform)
38
+ wrapper = FirebaseStats::Wrapper.new(stats)
39
+ tp wrapper.devices(friendly: options.friendly, limit: options.limit, platform: platform)
40
+ rescue FirebaseStats::SectionNotFoundError => error
41
+ print_data_error(error)
42
+ end
39
43
  end
40
44
  end
41
45
 
@@ -48,19 +52,23 @@ command :os do |c|
48
52
  c.option '--platform STRING', String, 'Show only stats for this OS. Either ios, android or all (default)'
49
53
 
50
54
  c.action do |args, options|
51
- stats = FirebaseStats::Reader.new
52
- stats.parse_file(args[0])
55
+ begin
56
+ stats = FirebaseStats::Reader.new
57
+ stats.parse_file(args[0])
53
58
 
54
- platform = map_platform(options)
59
+ platform = map_platform(options)
55
60
 
56
- wrapper = FirebaseStats::Wrapper.new(stats)
61
+ wrapper = FirebaseStats::Wrapper.new(stats)
57
62
 
58
- grouped = options.grouped || false
59
- major_order = options.version_sorted || false
63
+ grouped = options.grouped || false
64
+ major_order = options.version_sorted || false
60
65
 
61
- data = wrapper.os(platform: platform, grouped: grouped, major_order: major_order)
66
+ data = wrapper.os(platform: platform, grouped: grouped, major_order: major_order)
62
67
 
63
- tp data
68
+ tp data
69
+ rescue FirebaseStats::SectionNotFoundError => error
70
+ print_data_error(error)
71
+ end
64
72
  end
65
73
  end
66
74
 
@@ -70,11 +78,15 @@ command :gender do |c|
70
78
  c.description = 'Prints out a table with number of users of each gender'
71
79
 
72
80
  c.action do |args, options|
73
- stats = FirebaseStats::Reader.new
74
- stats.parse_file(args[0])
75
-
76
- wrapper = FirebaseStats::Wrapper.new(stats)
77
- tp wrapper.gender
81
+ begin
82
+ stats = FirebaseStats::Reader.new
83
+ stats.parse_file(args[0])
84
+
85
+ wrapper = FirebaseStats::Wrapper.new(stats)
86
+ tp wrapper.gender
87
+ rescue FirebaseStats::SectionNotFoundError => error
88
+ print_data_error(error)
89
+ end
78
90
  end
79
91
  end
80
92
 
@@ -84,10 +96,26 @@ command :gender_age do |c|
84
96
  c.description = 'Prints out a table with percentage of users of each gender grouped by age'
85
97
 
86
98
  c.action do |args, options|
87
- stats = FirebaseStats::Reader.new
88
- stats.parse_file(args[0])
89
-
90
- wrapper = FirebaseStats::Wrapper.new(stats)
91
- tp wrapper.gender_age
99
+ begin
100
+ stats = FirebaseStats::Reader.new
101
+ stats.parse_file(args[0])
102
+
103
+ wrapper = FirebaseStats::Wrapper.new(stats)
104
+ tp wrapper.gender_age
105
+ rescue FirebaseStats::SectionNotFoundError => error
106
+ print_data_error(error)
107
+ end
92
108
  end
93
109
  end
110
+
111
+ private
112
+
113
+
114
+ # @param [SectionNotFoundError] error
115
+ def print_data_error(error)
116
+ tip = FirebaseStats::Wrapper.tip(error.section)
117
+ expected_header = FirebaseStats::Reader.search_string(error.section)
118
+ puts "Unable to find that specific data in the input file"
119
+ puts "For the data you requested, the following CSV header should be contained within the file: '#{expected_header}'"
120
+ puts tip unless tip.nil?
121
+ end
@@ -4,3 +4,4 @@ require 'reader'
4
4
  require 'wrapper'
5
5
  require 'version'
6
6
  require 'device_utils'
7
+ require 'section_not_found_error'
data/lib/reader.rb CHANGED
@@ -5,13 +5,21 @@ module FirebaseStats
5
5
 
6
6
  # Parses the Firebase CSV file into sections
7
7
  class Reader
8
- attr_reader :data
9
-
10
8
  def initialize
11
9
  super
12
10
  @data = {}
13
11
  end
14
12
 
13
+ def num_sections
14
+ @data.length
15
+ end
16
+
17
+ def get(section)
18
+ found = @data[section]
19
+ raise SectionNotFoundError.new(section) if found.nil?
20
+ found
21
+ end
22
+
15
23
  # @param [String] filename
16
24
  def parse_file(filename)
17
25
  lines = File.readlines(filename)
@@ -20,6 +28,7 @@ module FirebaseStats
20
28
 
21
29
  # @param [Array<String>] input
22
30
  def parse(input)
31
+ @data = {}
23
32
  curr_lines = []
24
33
  input.each_with_index do |line, idx|
25
34
  curr_lines.push(line) unless comment?(line) || line.strip.empty?
@@ -31,22 +40,15 @@ module FirebaseStats
31
40
  end
32
41
  end
33
42
 
34
- private
35
-
36
- # @param [Array<String>] lines
37
- def process_lines(lines)
38
- section = match_header lines[0]
39
- return if section.nil?
40
-
41
- parsed = CSV.parse(lines.join, headers: true)
42
- @data[section] = parsed if @data[section].nil?
43
+ # Get the string that is used to find a given section in the CSV
44
+ def self.search_string(section)
45
+ header = Reader.mappings.key(section)
46
+ header = "Category,Male,Other,Female" if header.nil? and section == :gender_age
47
+ return header
43
48
  end
44
49
 
45
- # @param [String] header
46
- # @return [Symbol, nil]
47
- # rubocop:disable Metrics/MethodLength
48
- def match_header(header)
49
- mappings = {
50
+ def self.mappings
51
+ {
50
52
  'Day,28-Day,7-Day,1-Day' => :active_users,
51
53
  'Day,Average engagement time' => :daily_engagement,
52
54
  'Page path and screen class,User engagement,Screen views' => :screens,
@@ -62,15 +64,39 @@ module FirebaseStats
62
64
  'Platform,Users' => :platform,
63
65
  'Platform,Users,% Total,User engagement,Total revenue' => :platform_engagement
64
66
  }
67
+ end
68
+
69
+ private
70
+
71
+ # @param [Array<String>] lines
72
+ def process_lines(lines)
73
+ section = match_header lines[0]
74
+ return if section.nil?
75
+
76
+ parsed = CSV.parse(lines.join, headers: true)
77
+ @data[section] = parsed if @data[section].nil?
78
+ end
79
+
80
+ # Maps a given CSV header to a section
81
+ # @param [String] header The CSV header line to parse
82
+ # @return [Symbol, nil] The section, or nil if not found
83
+ # rubocop:disable Metrics/MethodLength
84
+ def match_header(header)
85
+ # All of the section headers that can be found in the CSV file, mapping to our internal section symbols
86
+
65
87
  cleaned_header = header.strip
66
- section = mappings[cleaned_header]
88
+ section = Reader.mappings[cleaned_header]
67
89
 
90
+ # Kludge for gender_age parsing as the headers aren't always in the right order, so rule out
91
+ # all the other sections first
68
92
  section = :gender_age if section.nil? and cleaned_header.include? 'Category,'
69
93
  section
70
94
  end
71
95
  # rubocop:enable Metrics/MethodLength
72
96
 
97
+ # Is this line a comment
73
98
  # @param [String] line
99
+ # @return [Boolean]
74
100
  def comment?(line)
75
101
  line.include?('#')
76
102
  end
@@ -0,0 +1,9 @@
1
+ module FirebaseStats
2
+ class SectionNotFoundError < StandardError
3
+ attr_reader :section
4
+
5
+ def initialize(section)
6
+ @section = section
7
+ end
8
+ end
9
+ end
data/lib/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FirebaseStats
4
- VERSION = '1.0.6'
4
+ VERSION = '1.0.7'
5
5
  end
data/lib/wrapper.rb CHANGED
@@ -35,7 +35,7 @@ module FirebaseStats
35
35
  # @param [Integer] limit Number of devices to turn
36
36
  # @param [Symbol] platform One of :all, :ios, :android
37
37
  def devices(friendly: false, limit: 10, platform: :all)
38
- filtered = DeviceUtils.filter_device(@stats.data[:devices], platform)
38
+ filtered = DeviceUtils.filter_device(@stats.get(:devices), platform)
39
39
  filtered = filtered.take(limit || 10)
40
40
  cleaned = []
41
41
  filtered.each do |row|
@@ -58,7 +58,7 @@ module FirebaseStats
58
58
  end
59
59
 
60
60
  def gender
61
- raw = @stats.data[:gender]
61
+ raw = @stats.get(:gender)
62
62
  data = []
63
63
  raw.each do |row|
64
64
  data << {
@@ -70,7 +70,7 @@ module FirebaseStats
70
70
  end
71
71
 
72
72
  def gender_age
73
- raw = @stats.data[:gender_age]
73
+ raw = @stats.get(:gender_age)
74
74
  data = []
75
75
  raw.each do |row|
76
76
  data << {
@@ -117,7 +117,7 @@ module FirebaseStats
117
117
 
118
118
  # Get all OS versions
119
119
  def all_os
120
- data = @stats.data[:os_version]
120
+ data = @stats.get(:os_version)
121
121
 
122
122
  data.map do |row|
123
123
  {
@@ -162,5 +162,14 @@ module FirebaseStats
162
162
  Gem::Version.new(number)
163
163
  end.reverse
164
164
  end
165
+
166
+ def self.tip(section)
167
+ tips = {
168
+ :os_version => "This data can now be found in the Audiences section of Firebase Analytics. Before you export the CSV file, change one of the charts to `Users` by `OS with version`",
169
+ :gender_age => "Note: The columns for Gender+Age are not always in the same order, but this is taken into account when searching",
170
+ :devices => "Note: If you export from the Tech Details: Device Model page, this is currently unsupported as it has two different headers. Use the export from the main Dashboard page"
171
+ }
172
+ tips[section]
173
+ end
165
174
  end
166
175
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: firebase-stats
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.6
4
+ version: 1.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - chedabob
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-28 00:00:00.000000000 Z
11
+ date: 2022-01-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: android-devices
@@ -106,6 +106,7 @@ files:
106
106
  - lib/device_utils.rb
107
107
  - lib/firebase-stats.rb
108
108
  - lib/reader.rb
109
+ - lib/section_not_found_error.rb
109
110
  - lib/version.rb
110
111
  - lib/wrapper.rb
111
112
  homepage: https://github.com/chedabob/firebase-stats