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 +4 -4
- data/bin/firebase-stats +51 -23
- data/lib/firebase-stats.rb +1 -0
- data/lib/reader.rb +43 -17
- data/lib/section_not_found_error.rb +9 -0
- data/lib/version.rb +1 -1
- data/lib/wrapper.rb +13 -4
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f242227d13ffe84bca59bc31022c4d8628e8df5a7685d5ae1d6dd97c1aa937c
|
4
|
+
data.tar.gz: 06e6280fdcab4baac6818eb42f1adb9c7a4153e81620557a0da8115b4f21c7bf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
33
|
-
|
32
|
+
begin
|
33
|
+
stats = FirebaseStats::Reader.new
|
34
|
+
stats.parse_file(args[0])
|
34
35
|
|
35
|
-
|
36
|
+
platform = map_platform(options)
|
36
37
|
|
37
|
-
|
38
|
-
|
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
|
-
|
52
|
-
|
55
|
+
begin
|
56
|
+
stats = FirebaseStats::Reader.new
|
57
|
+
stats.parse_file(args[0])
|
53
58
|
|
54
|
-
|
59
|
+
platform = map_platform(options)
|
55
60
|
|
56
|
-
|
61
|
+
wrapper = FirebaseStats::Wrapper.new(stats)
|
57
62
|
|
58
|
-
|
59
|
-
|
63
|
+
grouped = options.grouped || false
|
64
|
+
major_order = options.version_sorted || false
|
60
65
|
|
61
|
-
|
66
|
+
data = wrapper.os(platform: platform, grouped: grouped, major_order: major_order)
|
62
67
|
|
63
|
-
|
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
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
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
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
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
|
data/lib/firebase-stats.rb
CHANGED
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
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
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
|
-
|
46
|
-
|
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
|
data/lib/version.rb
CHANGED
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.
|
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.
|
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.
|
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.
|
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.
|
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:
|
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
|