firebase-stats 0.1.0 → 1.0.5
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 +56 -15
 - data/lib/device_utils.rb +24 -0
 - data/lib/firebase-stats.rb +2 -0
 - data/lib/reader.rb +2 -2
 - data/lib/version.rb +5 -0
 - data/lib/wrapper.rb +110 -71
 - metadata +67 -8
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 4c0052a1fd763bfd20e4561f5381098bc8436252f25ca478a51f152d9c9edc1f
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 5057c8cf57c562d489d60ecf7d35fa4172ad025937da9b7fd3ddd72b09e8b86c
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 2e36f05b2e942c81ebd86db0ddaff06aecca5e8167bf233591a32df06489b31b52985d6636d00dfcedd2c82ff914430c03d220297f3d93456b658c012b8240be
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: f74f39bd93fcfc0fc0c93ed6f11d9485d1635cbcbb64c0ca046cd91eb5f0828f8acaa9c3e3c2640cec4c62f00ef4cadf4f92dbe5e9b1dbe5d9c7ea07b5bba498
         
     | 
    
        data/bin/firebase-stats
    CHANGED
    
    | 
         @@ -6,11 +6,11 @@ require 'commander/import' 
     | 
|
| 
       6 
6 
     | 
    
         
             
            require 'firebase-stats'
         
     | 
| 
       7 
7 
     | 
    
         
             
            require 'table_print'
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
            program :name, ' 
     | 
| 
       10 
     | 
    
         
            -
            program :version,  
     | 
| 
       11 
     | 
    
         
            -
            program :description, 'CLI to  
     | 
| 
      
 9 
     | 
    
         
            +
            program :name, 'firebase-stats'
         
     | 
| 
      
 10 
     | 
    
         
            +
            program :version, FirebaseStats::VERSION
         
     | 
| 
      
 11 
     | 
    
         
            +
            program :description, 'A CLI tool to get different stats out of the huge Firebase Analytics CSV'
         
     | 
| 
      
 12 
     | 
    
         
            +
            program :help_formatter, Commander::HelpFormatter::TerminalCompact
         
     | 
| 
       12 
13 
     | 
    
         | 
| 
       13 
     | 
    
         
            -
            global_option('--platform STRING', String, 'Show only stats for this OS. Either ios, android or all (default)')
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
15 
     | 
    
         
             
            def map_platform(options)
         
     | 
| 
       16 
16 
     | 
    
         
             
              raw_platform = options.platform ||= 'all'
         
     | 
| 
         @@ -21,10 +21,12 @@ def map_platform(options) 
     | 
|
| 
       21 
21 
     | 
    
         
             
            end
         
     | 
| 
       22 
22 
     | 
    
         | 
| 
       23 
23 
     | 
    
         
             
            command :devices do |c|
         
     | 
| 
       24 
     | 
    
         
            -
              c.syntax = ' 
     | 
| 
      
 24 
     | 
    
         
            +
              c.syntax = 'devices <path to csv> [options]'
         
     | 
| 
       25 
25 
     | 
    
         
             
              c.summary = 'Prints out device stats'
         
     | 
| 
       26 
     | 
    
         
            -
              c.description = ''
         
     | 
| 
       27 
     | 
    
         
            -
              c.option '--friendly', ' 
     | 
| 
      
 26 
     | 
    
         
            +
              c.description = 'Prints out a table with all of the devices, optionally filtered by OS'
         
     | 
| 
      
 27 
     | 
    
         
            +
              c.option '--friendly', 'Prints out Android device models with their human readable name (this is slow)'
         
     | 
| 
      
 28 
     | 
    
         
            +
              c.option '--limit NUMBER', Integer, 'Limits number of devices output'
         
     | 
| 
      
 29 
     | 
    
         
            +
              c.option '--platform STRING', String, 'Show only stats for this OS. Either ios, android or all (default)'
         
     | 
| 
       28 
30 
     | 
    
         | 
| 
       29 
31 
     | 
    
         
             
              c.action do |args, options|
         
     | 
| 
       30 
32 
     | 
    
         
             
                stats = FirebaseStats::Reader.new
         
     | 
| 
         @@ -32,16 +34,18 @@ command :devices do |c| 
     | 
|
| 
       32 
34 
     | 
    
         | 
| 
       33 
35 
     | 
    
         
             
                platform = map_platform(options)
         
     | 
| 
       34 
36 
     | 
    
         | 
| 
       35 
     | 
    
         
            -
                wrapper = FirebaseStats::Wrapper.new(stats 
     | 
| 
       36 
     | 
    
         
            -
                tp wrapper.devices(friendly: options.friendly)
         
     | 
| 
      
 37 
     | 
    
         
            +
                wrapper = FirebaseStats::Wrapper.new(stats)
         
     | 
| 
      
 38 
     | 
    
         
            +
                tp wrapper.devices(friendly: options.friendly, limit: options.limit, platform: platform)
         
     | 
| 
       37 
39 
     | 
    
         
             
              end
         
     | 
| 
       38 
40 
     | 
    
         
             
            end
         
     | 
| 
       39 
41 
     | 
    
         | 
| 
       40 
42 
     | 
    
         
             
            command :os do |c|
         
     | 
| 
       41 
     | 
    
         
            -
              c.syntax = ' 
     | 
| 
       42 
     | 
    
         
            -
              c.summary = 'Prints out  
     | 
| 
       43 
     | 
    
         
            -
              c.description = ''
         
     | 
| 
       44 
     | 
    
         
            -
              c.option '--grouped', 'Groups OS versions together'
         
     | 
| 
      
 43 
     | 
    
         
            +
              c.syntax = 'os <path to csv> [options]'
         
     | 
| 
      
 44 
     | 
    
         
            +
              c.summary = 'Prints out OS stats'
         
     | 
| 
      
 45 
     | 
    
         
            +
              c.description = 'Prints out the number of devices per OS version, optionally filtered by OS and grouped by major version'
         
     | 
| 
      
 46 
     | 
    
         
            +
              c.option '--grouped', 'Groups minor OS versions together'
         
     | 
| 
      
 47 
     | 
    
         
            +
              c.option '--version-sorted', 'Sorts by OS version instead of percentage'
         
     | 
| 
      
 48 
     | 
    
         
            +
              c.option '--platform STRING', String, 'Show only stats for this OS. Either ios, android or all (default)'
         
     | 
| 
       45 
49 
     | 
    
         | 
| 
       46 
50 
     | 
    
         
             
              c.action do |args, options|
         
     | 
| 
       47 
51 
     | 
    
         
             
                stats = FirebaseStats::Reader.new
         
     | 
| 
         @@ -49,8 +53,45 @@ command :os do |c| 
     | 
|
| 
       49 
53 
     | 
    
         | 
| 
       50 
54 
     | 
    
         
             
                platform = map_platform(options)
         
     | 
| 
       51 
55 
     | 
    
         | 
| 
       52 
     | 
    
         
            -
                wrapper = FirebaseStats::Wrapper.new(stats 
     | 
| 
      
 56 
     | 
    
         
            +
                wrapper = FirebaseStats::Wrapper.new(stats)
         
     | 
| 
       53 
57 
     | 
    
         | 
| 
       54 
     | 
    
         
            -
                 
     | 
| 
      
 58 
     | 
    
         
            +
                grouped = options.grouped || false
         
     | 
| 
      
 59 
     | 
    
         
            +
                major_order = options.version_sorted || false
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                data = wrapper.os(platform: platform, grouped: grouped, major_order: major_order)
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                tp data
         
     | 
| 
      
 64 
     | 
    
         
            +
              end
         
     | 
| 
      
 65 
     | 
    
         
            +
            end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
            command :gender do |c|
         
     | 
| 
      
 68 
     | 
    
         
            +
              c.syntax = 'gender'
         
     | 
| 
      
 69 
     | 
    
         
            +
              c.summary = 'Prints out gender stats (if available)'
         
     | 
| 
      
 70 
     | 
    
         
            +
              c.description = 'Prints out a table with number of users of each gender'
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
              c.action do |args, options|
         
     | 
| 
      
 73 
     | 
    
         
            +
                stats = FirebaseStats::Reader.new
         
     | 
| 
      
 74 
     | 
    
         
            +
                stats.parse_file(args[0])
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                platform = map_platform(options)
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                wrapper = FirebaseStats::Wrapper.new(stats)
         
     | 
| 
      
 79 
     | 
    
         
            +
                tp wrapper.gender
         
     | 
| 
      
 80 
     | 
    
         
            +
              end
         
     | 
| 
      
 81 
     | 
    
         
            +
            end
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
            command :gender_age do |c|
         
     | 
| 
      
 84 
     | 
    
         
            +
              c.syntax = 'gender_age'
         
     | 
| 
      
 85 
     | 
    
         
            +
              c.summary = 'Prints out age group stats (if available)'
         
     | 
| 
      
 86 
     | 
    
         
            +
              c.description = 'Prints out a table with percentage of users of each gender grouped by age'
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
              c.action do |args, options|
         
     | 
| 
      
 89 
     | 
    
         
            +
                stats = FirebaseStats::Reader.new
         
     | 
| 
      
 90 
     | 
    
         
            +
                stats.parse_file(args[0])
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                platform = map_platform(options)
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                wrapper = FirebaseStats::Wrapper.new(stats)
         
     | 
| 
      
 95 
     | 
    
         
            +
                tp wrapper.gender_age
         
     | 
| 
       55 
96 
     | 
    
         
             
              end
         
     | 
| 
       56 
97 
     | 
    
         
             
            end
         
     | 
    
        data/lib/device_utils.rb
    ADDED
    
    | 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module FirebaseStats
         
     | 
| 
      
 2 
     | 
    
         
            +
              # Parses the Firebase CSV file into sections
         
     | 
| 
      
 3 
     | 
    
         
            +
              class DeviceUtils
         
     | 
| 
      
 4 
     | 
    
         
            +
                # Is this device name an iOS device?
         
     | 
| 
      
 5 
     | 
    
         
            +
                # @param [CSV::Row] device_name
         
     | 
| 
      
 6 
     | 
    
         
            +
                def self.ios_device?(device_name)
         
     | 
| 
      
 7 
     | 
    
         
            +
                  device_name.downcase.include?('iphone') or device_name.downcase.include?('ipad') or device_name.downcase.include?('ipod')
         
     | 
| 
      
 8 
     | 
    
         
            +
                end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                # Filters a device list to only the requested platform
         
     | 
| 
      
 11 
     | 
    
         
            +
                # @param [CSV::Table] device_data
         
     | 
| 
      
 12 
     | 
    
         
            +
                # @param [Symbol] platform One of :all, :ios, :android
         
     | 
| 
      
 13 
     | 
    
         
            +
                def self.filter_device(device_data, platform)
         
     | 
| 
      
 14 
     | 
    
         
            +
                  case platform
         
     | 
| 
      
 15 
     | 
    
         
            +
                  when :android
         
     | 
| 
      
 16 
     | 
    
         
            +
                    device_data.reject { |row| ios_device? row['Device model'] }
         
     | 
| 
      
 17 
     | 
    
         
            +
                  when :ios
         
     | 
| 
      
 18 
     | 
    
         
            +
                    device_data.select { |row| ios_device? row['Device model'] }
         
     | 
| 
      
 19 
     | 
    
         
            +
                  else
         
     | 
| 
      
 20 
     | 
    
         
            +
                    device_data
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/firebase-stats.rb
    CHANGED
    
    
    
        data/lib/reader.rb
    CHANGED
    
    | 
         @@ -1,6 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
      
 3 
     | 
    
         
            +
            module FirebaseStats
         
     | 
| 
       4 
4 
     | 
    
         
             
              require 'csv'
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
6 
     | 
    
         
             
              # Parses the Firebase CSV file into sections
         
     | 
| 
         @@ -22,7 +22,7 @@ class FirebaseStats 
     | 
|
| 
       22 
22 
     | 
    
         
             
                def parse(input)
         
     | 
| 
       23 
23 
     | 
    
         
             
                  curr_lines = []
         
     | 
| 
       24 
24 
     | 
    
         
             
                  input.each_with_index do |line, idx|
         
     | 
| 
       25 
     | 
    
         
            -
                    curr_lines. 
     | 
| 
      
 25 
     | 
    
         
            +
                    curr_lines.push(line) unless comment?(line) || line.strip.empty?
         
     | 
| 
       26 
26 
     | 
    
         | 
| 
       27 
27 
     | 
    
         
             
                    if (idx == input.length - 1) || line.strip.empty?
         
     | 
| 
       28 
28 
     | 
    
         
             
                      process_lines curr_lines unless curr_lines.empty?
         
     | 
    
        data/lib/version.rb
    ADDED
    
    
    
        data/lib/wrapper.rb
    CHANGED
    
    | 
         @@ -1,76 +1,85 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
      
 3 
     | 
    
         
            +
            module FirebaseStats
         
     | 
| 
       4 
4 
     | 
    
         
             
              require 'csv'
         
     | 
| 
       5 
     | 
    
         
            -
               
     | 
| 
      
 5 
     | 
    
         
            +
              require 'android/devices'
         
     | 
| 
      
 6 
     | 
    
         
            +
              require 'open-uri'
         
     | 
| 
       6 
7 
     | 
    
         | 
| 
       7 
8 
     | 
    
         
             
              # Transforms the parsed Firebase file into something more user friendly
         
     | 
| 
       8 
9 
     | 
    
         
             
              class Wrapper
         
     | 
| 
       9 
10 
     | 
    
         
             
                # @param [FirebaseStats::Reader] stats
         
     | 
| 
       10 
     | 
    
         
            -
                 
     | 
| 
       11 
     | 
    
         
            -
                def initialize(stats, platform = :all)
         
     | 
| 
      
 11 
     | 
    
         
            +
                def initialize(stats)
         
     | 
| 
       12 
12 
     | 
    
         
             
                  super()
         
     | 
| 
       13 
13 
     | 
    
         
             
                  @stats = stats
         
     | 
| 
       14 
     | 
    
         
            -
                  @platform = platform
         
     | 
| 
       15 
14 
     | 
    
         
             
                end
         
     | 
| 
       16 
15 
     | 
    
         | 
| 
       17 
     | 
    
         
            -
                 
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
      
 16 
     | 
    
         
            +
                # Get all OS versions, grouped by Major version
         
     | 
| 
      
 17 
     | 
    
         
            +
                # @param [Symbol] platform One of :all, :ios, :android
         
     | 
| 
      
 18 
     | 
    
         
            +
                # @param [Boolean] grouped Group by Major OS version
         
     | 
| 
      
 19 
     | 
    
         
            +
                # @param [Boolean] major_order Order by Major OS version (instead of percentage)
         
     | 
| 
      
 20 
     | 
    
         
            +
                def os(platform: :all, grouped: true, major_order: true)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  os_data = all_os
         
     | 
| 
      
 22 
     | 
    
         
            +
                  filtered = filter_os(os_data, platform)
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                  data = if grouped
         
     | 
| 
      
 25 
     | 
    
         
            +
                           make_group_stats(filtered, platform)
         
     | 
| 
      
 26 
     | 
    
         
            +
                         else
         
     | 
| 
      
 27 
     | 
    
         
            +
                           filtered
         
     | 
| 
      
 28 
     | 
    
         
            +
                         end
         
     | 
| 
       19 
29 
     | 
    
         | 
| 
      
 30 
     | 
    
         
            +
                  major_order ? major_version_sort(data) : data
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                # Gets all devices
         
     | 
| 
      
 34 
     | 
    
         
            +
                # @param [Boolean] friendly Transform the Android model numbers into their human numaes
         
     | 
| 
      
 35 
     | 
    
         
            +
                # @param [Integer] limit Number of devices to turn
         
     | 
| 
      
 36 
     | 
    
         
            +
                # @param [Symbol] platform One of :all, :ios, :android
         
     | 
| 
      
 37 
     | 
    
         
            +
                def devices(friendly: false, limit: 10, platform: :all)
         
     | 
| 
      
 38 
     | 
    
         
            +
                  filtered = DeviceUtils.filter_device(@stats.data[:devices], platform)
         
     | 
| 
      
 39 
     | 
    
         
            +
                  filtered = filtered.take(limit || 10)
         
     | 
| 
       20 
40 
     | 
    
         
             
                  cleaned = []
         
     | 
| 
       21 
41 
     | 
    
         
             
                  filtered.each do |row|
         
     | 
| 
       22 
     | 
    
         
            -
                     
     | 
| 
       23 
     | 
    
         
            -
                      ' 
     | 
| 
       24 
     | 
    
         
            -
                      'count' => row['Users'].to_i,
         
     | 
| 
       25 
     | 
    
         
            -
                      'percentage' => as_percentage(os_total, row['Users'].to_f)
         
     | 
| 
      
 42 
     | 
    
         
            +
                    device = {
         
     | 
| 
      
 43 
     | 
    
         
            +
                      'model' => row['Device model']
         
     | 
| 
       26 
44 
     | 
    
         
             
                    }
         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
      
 45 
     | 
    
         
            +
                    if friendly && ((platform == :all) || (platform == :android))
         
     | 
| 
      
 46 
     | 
    
         
            +
                      mapped = Android::Devices.search_by_model(row['Device model'])
         
     | 
| 
      
 47 
     | 
    
         
            +
                      device['friendly'] = if mapped.nil?
         
     | 
| 
      
 48 
     | 
    
         
            +
                                             row['Device model']
         
     | 
| 
      
 49 
     | 
    
         
            +
                                           else
         
     | 
| 
      
 50 
     | 
    
         
            +
                                             mapped.name
         
     | 
| 
      
 51 
     | 
    
         
            +
                                           end
         
     | 
| 
      
 52 
     | 
    
         
            +
                    end
         
     | 
| 
      
 53 
     | 
    
         
            +
                    device['count'] = row['Users'].to_i
         
     | 
| 
       30 
54 
     | 
    
         | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
                  raw_os = @stats.data[:os_version]
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
                  grouped = case @platform
         
     | 
| 
       35 
     | 
    
         
            -
                            when :ios
         
     | 
| 
       36 
     | 
    
         
            -
                              ios_os_group(raw_os)
         
     | 
| 
       37 
     | 
    
         
            -
                            when :android
         
     | 
| 
       38 
     | 
    
         
            -
                              android_os_group(raw_os)
         
     | 
| 
       39 
     | 
    
         
            -
                            else
         
     | 
| 
       40 
     | 
    
         
            -
                              android_os_group(raw_os).merge ios_os_group(raw_os)
         
     | 
| 
       41 
     | 
    
         
            -
                            end
         
     | 
| 
       42 
     | 
    
         
            -
                  computed = []
         
     | 
| 
       43 
     | 
    
         
            -
                  grouped.each do |k, v|
         
     | 
| 
       44 
     | 
    
         
            -
                    version_name = k
         
     | 
| 
       45 
     | 
    
         
            -
                    total = v.map { |version| version['Users'].to_i }.reduce(0, :+)
         
     | 
| 
       46 
     | 
    
         
            -
                    computed << { 'version' => version_name, 'total' => total, 'percentage' => as_percentage(os_total, total.to_f) }
         
     | 
| 
      
 55 
     | 
    
         
            +
                    cleaned << device
         
     | 
| 
       47 
56 
     | 
    
         
             
                  end
         
     | 
| 
       48 
     | 
    
         
            -
                   
     | 
| 
      
 57 
     | 
    
         
            +
                  cleaned
         
     | 
| 
       49 
58 
     | 
    
         
             
                end
         
     | 
| 
       50 
59 
     | 
    
         | 
| 
       51 
     | 
    
         
            -
                def  
     | 
| 
       52 
     | 
    
         
            -
                   
     | 
| 
       53 
     | 
    
         
            -
                   
     | 
| 
       54 
     | 
    
         
            -
                   
     | 
| 
       55 
     | 
    
         
            -
                     
     | 
| 
      
 60 
     | 
    
         
            +
                def gender
         
     | 
| 
      
 61 
     | 
    
         
            +
                  raw = @stats.data[:gender]
         
     | 
| 
      
 62 
     | 
    
         
            +
                  data = []
         
     | 
| 
      
 63 
     | 
    
         
            +
                  raw.each do |row|
         
     | 
| 
      
 64 
     | 
    
         
            +
                    data << {
         
     | 
| 
      
 65 
     | 
    
         
            +
                      'gender' => row['Gender'],
         
     | 
| 
      
 66 
     | 
    
         
            +
                      'count' => row['Users']
         
     | 
| 
      
 67 
     | 
    
         
            +
                    }
         
     | 
| 
       56 
68 
     | 
    
         
             
                  end
         
     | 
| 
       57 
     | 
    
         
            -
                   
     | 
| 
      
 69 
     | 
    
         
            +
                  data
         
     | 
| 
       58 
70 
     | 
    
         
             
                end
         
     | 
| 
       59 
71 
     | 
    
         | 
| 
       60 
     | 
    
         
            -
                def  
     | 
| 
       61 
     | 
    
         
            -
                   
     | 
| 
       62 
     | 
    
         
            -
                   
     | 
| 
       63 
     | 
    
         
            -
                   
     | 
| 
       64 
     | 
    
         
            -
                     
     | 
| 
       65 
     | 
    
         
            -
                      ' 
     | 
| 
       66 
     | 
    
         
            -
                      ' 
     | 
| 
      
 72 
     | 
    
         
            +
                def gender_age
         
     | 
| 
      
 73 
     | 
    
         
            +
                  raw = @stats.data[:gender_age]
         
     | 
| 
      
 74 
     | 
    
         
            +
                  data = []
         
     | 
| 
      
 75 
     | 
    
         
            +
                  raw.each do |row|
         
     | 
| 
      
 76 
     | 
    
         
            +
                    data << {
         
     | 
| 
      
 77 
     | 
    
         
            +
                      'age' => row['Category'],
         
     | 
| 
      
 78 
     | 
    
         
            +
                      'male' => (row['Male'].to_f * 100).round(2),
         
     | 
| 
      
 79 
     | 
    
         
            +
                      'female' => (row['Female'].to_f * 100).round(2)
         
     | 
| 
       67 
80 
     | 
    
         
             
                    }
         
     | 
| 
       68 
     | 
    
         
            -
                    # if friendly && ((@platform == :all) || (@platform == :android))
         
     | 
| 
       69 
     | 
    
         
            -
                    #   device['friendly'] = Android::Devices.search_by_model(row['Device Model']).name
         
     | 
| 
       70 
     | 
    
         
            -
                    # end
         
     | 
| 
       71 
     | 
    
         
            -
                    cleaned << device
         
     | 
| 
       72 
81 
     | 
    
         
             
                  end
         
     | 
| 
       73 
     | 
    
         
            -
                   
     | 
| 
      
 82 
     | 
    
         
            +
                  data
         
     | 
| 
       74 
83 
     | 
    
         
             
                end
         
     | 
| 
       75 
84 
     | 
    
         | 
| 
       76 
85 
     | 
    
         
             
                private
         
     | 
| 
         @@ -80,32 +89,14 @@ class FirebaseStats 
     | 
|
| 
       80 
89 
     | 
    
         
             
                def filter_os(os_data, platform)
         
     | 
| 
       81 
90 
     | 
    
         
             
                  case platform
         
     | 
| 
       82 
91 
     | 
    
         
             
                  when :android
         
     | 
| 
       83 
     | 
    
         
            -
                    os_data.select { |row| row[' 
     | 
| 
      
 92 
     | 
    
         
            +
                    os_data.select { |row| row['version'].downcase.include?('android') }
         
     | 
| 
       84 
93 
     | 
    
         
             
                  when :ios
         
     | 
| 
       85 
     | 
    
         
            -
                    os_data.select { |row| row[' 
     | 
| 
      
 94 
     | 
    
         
            +
                    os_data.select { |row| row['version'].downcase.include?('ios') }
         
     | 
| 
       86 
95 
     | 
    
         
             
                  else
         
     | 
| 
       87 
96 
     | 
    
         
             
                    os_data
         
     | 
| 
       88 
97 
     | 
    
         
             
                  end
         
     | 
| 
       89 
98 
     | 
    
         
             
                end
         
     | 
| 
       90 
99 
     | 
    
         | 
| 
       91 
     | 
    
         
            -
                # @param [CSV::Table] device_data
         
     | 
| 
       92 
     | 
    
         
            -
                # @param [Symbol] platform One of :all, :ios, :android
         
     | 
| 
       93 
     | 
    
         
            -
                def filter_device(device_data, platform)
         
     | 
| 
       94 
     | 
    
         
            -
                  case platform
         
     | 
| 
       95 
     | 
    
         
            -
                  when :android
         
     | 
| 
       96 
     | 
    
         
            -
                    device_data.reject { |row| ios_device? row['Device model'] }
         
     | 
| 
       97 
     | 
    
         
            -
                  when :ios
         
     | 
| 
       98 
     | 
    
         
            -
                    device_data.select { |row| ios_device? row['Device model'] }
         
     | 
| 
       99 
     | 
    
         
            -
                  else
         
     | 
| 
       100 
     | 
    
         
            -
                    device_data
         
     | 
| 
       101 
     | 
    
         
            -
                  end
         
     | 
| 
       102 
     | 
    
         
            -
                end
         
     | 
| 
       103 
     | 
    
         
            -
             
     | 
| 
       104 
     | 
    
         
            -
                # @param [CSV::Row] device_name
         
     | 
| 
       105 
     | 
    
         
            -
                def ios_device?(device_name)
         
     | 
| 
       106 
     | 
    
         
            -
                  device_name.downcase.include?('iphone') or device_name.downcase.include?('ipad')
         
     | 
| 
       107 
     | 
    
         
            -
                end
         
     | 
| 
       108 
     | 
    
         
            -
             
     | 
| 
       109 
100 
     | 
    
         
             
                def as_percentage(total, value)
         
     | 
| 
       110 
101 
     | 
    
         
             
                  percentage = (value / total) * 100
         
     | 
| 
       111 
102 
     | 
    
         
             
                  if percentage < 0.01
         
     | 
| 
         @@ -116,11 +107,59 @@ class FirebaseStats 
     | 
|
| 
       116 
107 
     | 
    
         
             
                end
         
     | 
| 
       117 
108 
     | 
    
         | 
| 
       118 
109 
     | 
    
         
             
                def ios_os_group(os_details)
         
     | 
| 
       119 
     | 
    
         
            -
                  filter_os(os_details, :ios).group_by { |row| row[' 
     | 
| 
      
 110 
     | 
    
         
            +
                  filter_os(os_details, :ios).group_by { |row| row['version'].match('(iOS [0-9]{1,2})').captures[0] }
         
     | 
| 
       120 
111 
     | 
    
         
             
                end
         
     | 
| 
       121 
112 
     | 
    
         | 
| 
       122 
113 
     | 
    
         
             
                def android_os_group(os_details)
         
     | 
| 
       123 
     | 
    
         
            -
                  filter_os(os_details, :android).group_by { |row| row[' 
     | 
| 
      
 114 
     | 
    
         
            +
                  filter_os(os_details, :android).group_by { |row| row['version'].match('(Android [0-9]{1,2})').captures[0] }
         
     | 
| 
      
 115 
     | 
    
         
            +
                end
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
                # Get all OS versions
         
     | 
| 
      
 118 
     | 
    
         
            +
                def all_os
         
     | 
| 
      
 119 
     | 
    
         
            +
                  data = @stats.data[:os_version]
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
                  data.map do |row|
         
     | 
| 
      
 122 
     | 
    
         
            +
                    {
         
     | 
| 
      
 123 
     | 
    
         
            +
                      'version' => row['OS with version'],
         
     | 
| 
      
 124 
     | 
    
         
            +
                      'count' => row['Users'].to_i
         
     | 
| 
      
 125 
     | 
    
         
            +
                    }
         
     | 
| 
      
 126 
     | 
    
         
            +
                  end
         
     | 
| 
      
 127 
     | 
    
         
            +
                end
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
      
 129 
     | 
    
         
            +
                def make_group_stats(os_data, platform)
         
     | 
| 
      
 130 
     | 
    
         
            +
                  data = make_os_groups(os_data, platform)
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
                  total_devices = os_total(os_data)
         
     | 
| 
      
 133 
     | 
    
         
            +
                  data.map do |k, v|
         
     | 
| 
      
 134 
     | 
    
         
            +
                    version_name = k
         
     | 
| 
      
 135 
     | 
    
         
            +
                    group_total = v.map { |version| version['count'].to_i }.reduce(0, :+)
         
     | 
| 
      
 136 
     | 
    
         
            +
                    { 'version' => version_name,
         
     | 
| 
      
 137 
     | 
    
         
            +
                      'total' => group_total,
         
     | 
| 
      
 138 
     | 
    
         
            +
                      'percentage' => as_percentage(total_devices.to_f, group_total) }
         
     | 
| 
      
 139 
     | 
    
         
            +
                  end
         
     | 
| 
      
 140 
     | 
    
         
            +
                end
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
                def make_os_groups(os_data, platform)
         
     | 
| 
      
 143 
     | 
    
         
            +
                  case platform
         
     | 
| 
      
 144 
     | 
    
         
            +
                  when :ios
         
     | 
| 
      
 145 
     | 
    
         
            +
                    ios_os_group(os_data)
         
     | 
| 
      
 146 
     | 
    
         
            +
                  when :android
         
     | 
| 
      
 147 
     | 
    
         
            +
                    android_os_group(os_data)
         
     | 
| 
      
 148 
     | 
    
         
            +
                  else
         
     | 
| 
      
 149 
     | 
    
         
            +
                    android_os_group(os_data).merge ios_os_group(os_data)
         
     | 
| 
      
 150 
     | 
    
         
            +
                  end
         
     | 
| 
      
 151 
     | 
    
         
            +
                end
         
     | 
| 
      
 152 
     | 
    
         
            +
             
     | 
| 
      
 153 
     | 
    
         
            +
                def os_total(os_data)
         
     | 
| 
      
 154 
     | 
    
         
            +
                  os_data.map { |row| row['count'] }.reduce(0, :+)
         
     | 
| 
      
 155 
     | 
    
         
            +
                end
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
                def major_version_sort(data)
         
     | 
| 
      
 158 
     | 
    
         
            +
                  data.sort_by do |row|
         
     | 
| 
      
 159 
     | 
    
         
            +
                    version = row['version']
         
     | 
| 
      
 160 
     | 
    
         
            +
                    number = version.match('([0-9.]+)').captures[0]
         
     | 
| 
      
 161 
     | 
    
         
            +
                    Gem::Version.new(number)
         
     | 
| 
      
 162 
     | 
    
         
            +
                  end.reverse
         
     | 
| 
       124 
163 
     | 
    
         
             
                end
         
     | 
| 
       125 
164 
     | 
    
         
             
              end
         
     | 
| 
       126 
165 
     | 
    
         
             
            end
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,15 +1,29 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: firebase-stats
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version:  
     | 
| 
      
 4 
     | 
    
         
            +
              version: 1.0.5
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - chedabob
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire:
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2021-03- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2021-03-21 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
      
 13 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 14 
     | 
    
         
            +
              name: android-devices
         
     | 
| 
      
 15 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 16 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 17 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 18 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 19 
     | 
    
         
            +
                    version: '1.0'
         
     | 
| 
      
 20 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 21 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 22 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 23 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 24 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 25 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 26 
     | 
    
         
            +
                    version: '1.0'
         
     | 
| 
       13 
27 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
28 
     | 
    
         
             
              name: commander
         
     | 
| 
       15 
29 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
         @@ -38,7 +52,50 @@ dependencies: 
     | 
|
| 
       38 
52 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       39 
53 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       40 
54 
     | 
    
         
             
                    version: '1.5'
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
      
 55 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 56 
     | 
    
         
            +
              name: rake
         
     | 
| 
      
 57 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 58 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 59 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 60 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 61 
     | 
    
         
            +
                    version: '13'
         
     | 
| 
      
 62 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 63 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 64 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 65 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 66 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 67 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 68 
     | 
    
         
            +
                    version: '13'
         
     | 
| 
      
 69 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 70 
     | 
    
         
            +
              name: rspec
         
     | 
| 
      
 71 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 72 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 73 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 74 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 75 
     | 
    
         
            +
                    version: '3.10'
         
     | 
| 
      
 76 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 77 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 78 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 79 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 80 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 81 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 82 
     | 
    
         
            +
                    version: '3.10'
         
     | 
| 
      
 83 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 84 
     | 
    
         
            +
              name: rubocop
         
     | 
| 
      
 85 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 86 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 87 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 88 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 89 
     | 
    
         
            +
                    version: '1.10'
         
     | 
| 
      
 90 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 91 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 92 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 93 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 94 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 95 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 96 
     | 
    
         
            +
                    version: '1.10'
         
     | 
| 
      
 97 
     | 
    
         
            +
            description: A CLI tool to get different stats out of the huge Firebase Analytics
         
     | 
| 
      
 98 
     | 
    
         
            +
              CSV
         
     | 
| 
       42 
99 
     | 
    
         
             
            email: matt.malone1@gmail.com
         
     | 
| 
       43 
100 
     | 
    
         
             
            executables:
         
     | 
| 
       44 
101 
     | 
    
         
             
            - firebase-stats
         
     | 
| 
         @@ -47,10 +104,12 @@ extra_rdoc_files: [] 
     | 
|
| 
       47 
104 
     | 
    
         
             
            files:
         
     | 
| 
       48 
105 
     | 
    
         
             
            - bin/firebase-stats
         
     | 
| 
       49 
106 
     | 
    
         
             
            - lib/.DS_Store
         
     | 
| 
      
 107 
     | 
    
         
            +
            - lib/device_utils.rb
         
     | 
| 
       50 
108 
     | 
    
         
             
            - lib/firebase-stats.rb
         
     | 
| 
       51 
109 
     | 
    
         
             
            - lib/reader.rb
         
     | 
| 
      
 110 
     | 
    
         
            +
            - lib/version.rb
         
     | 
| 
       52 
111 
     | 
    
         
             
            - lib/wrapper.rb
         
     | 
| 
       53 
     | 
    
         
            -
            homepage: https:// 
     | 
| 
      
 112 
     | 
    
         
            +
            homepage: https://github.com/chedabob/firebase-stats
         
     | 
| 
       54 
113 
     | 
    
         
             
            licenses:
         
     | 
| 
       55 
114 
     | 
    
         
             
            - MIT
         
     | 
| 
       56 
115 
     | 
    
         
             
            metadata: {}
         
     | 
| 
         @@ -60,17 +119,17 @@ require_paths: 
     | 
|
| 
       60 
119 
     | 
    
         
             
            - lib
         
     | 
| 
       61 
120 
     | 
    
         
             
            required_ruby_version: !ruby/object:Gem::Requirement
         
     | 
| 
       62 
121 
     | 
    
         
             
              requirements:
         
     | 
| 
       63 
     | 
    
         
            -
              - - " 
     | 
| 
      
 122 
     | 
    
         
            +
              - - ">="
         
     | 
| 
       64 
123 
     | 
    
         
             
                - !ruby/object:Gem::Version
         
     | 
| 
       65 
     | 
    
         
            -
                  version: ' 
     | 
| 
      
 124 
     | 
    
         
            +
                  version: '2.4'
         
     | 
| 
       66 
125 
     | 
    
         
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
       67 
126 
     | 
    
         
             
              requirements:
         
     | 
| 
       68 
127 
     | 
    
         
             
              - - ">="
         
     | 
| 
       69 
128 
     | 
    
         
             
                - !ruby/object:Gem::Version
         
     | 
| 
       70 
129 
     | 
    
         
             
                  version: '0'
         
     | 
| 
       71 
130 
     | 
    
         
             
            requirements: []
         
     | 
| 
       72 
     | 
    
         
            -
            rubygems_version: 3.2. 
     | 
| 
      
 131 
     | 
    
         
            +
            rubygems_version: 3.2.14
         
     | 
| 
       73 
132 
     | 
    
         
             
            signing_key:
         
     | 
| 
       74 
133 
     | 
    
         
             
            specification_version: 4
         
     | 
| 
       75 
     | 
    
         
            -
            summary: Firebase CSV Stats  
     | 
| 
      
 134 
     | 
    
         
            +
            summary: Firebase CSV Stats CLI
         
     | 
| 
       76 
135 
     | 
    
         
             
            test_files: []
         
     |