module Core

Constants

CHROME_BUILD
DEVICE_TYPE_NAVIGATOR
DEVICE_TYPE_OS
FIREFOX_VERSION
IE_VERSION
MACOSX_CHROME_BUILD_RANGE
OS_CPU
OS_DEVICE_TYPE
OS_NAVIGATOR
OS_PLATFORM

Public Class Methods

generate_navigator(os: nil, navigator: nil, platform: nil, device_type: nil) click to toggle source
# File lib/fake_useragent/core.rb, line 431
def self.generate_navigator(os: nil, navigator: nil, platform: nil, device_type: nil)
  unless platform.nil?
    os = platform
    warn('The `platform` version is deprecated. Use `os` option instead', uplevel: 3)
  end
  device_type, os_id, navigator_id = pick_config_ids(device_type, os, navigator)
  sys = build_system_components(device_type, os_id, navigator_id)
  app = build_app_components(os_id, navigator_id)
  user_agent = choose_ua_template(device_type, navigator_id, app, sys)
  app_version = build_navigator_app_version(
    os_id, navigator_id, sys['platform_version'], user_agent
  )
  {
    'os_id' => os_id,
    'navigator_id' => navigator_id,
    'platform' => sys['platform'],
    'os_cpu' => sys['os_cpu'],
    'build_version' => app['build_version'],
    'build_id' => app['build_id'],
    'app_version' => app_version,
    'app_name' => app['name'],
    'app_code_name' => 'Mozilla',
    'product' => 'Gecko',
    'product_sub' => app['product_sub'],
    'vendor' => app['vendor'],
    'vendor_sub' => '',
    'user_agent' => user_agent
  }
end

Private Class Methods

build_app_components(os_id, navigator_id) click to toggle source
# File lib/fake_useragent/core.rb, line 281
def self.build_app_components(os_id, navigator_id)
  case navigator_id
  when 'firefox'
    build_version, build_id = firefox_build
    gecko_trail = if %w[win linux mac].include? os_id
                    '20100101'
                  else
                    build_version
                  end
    res = {
      'name' => 'Netscape',
      'product_sub' => '20100101',
      'vendor' => '',
      'build_version' => build_version,
      'build_id' => build_id,
      'gecko_trail' => gecko_trail
    }
  when 'chrome'
    res = {
      'name' => 'Netscape',
      'product_sub' => '20030107',
      'vendor' => 'Google Inc.',
      'build_version' => chrome_build,
      'build_id' => ''
    }
  when 'ie'
    num_ver, build_version, trident_version = ie_build
    app_name = if num_ver >= 11
                 'Netscape'
               else
                 'Microsoft Internet Explorer'
               end
    res = {
      'name' => app_name,
      'product_sub' => '',
      'vendor' => '',
      'build_version' => build_version.to_s,
      'build_id' => '',
      'trident_version' => trident_version
    }
  end
  res
end
build_navigator_app_version(os_id, navigator_id, platform_version, user_agent) click to toggle source
# File lib/fake_useragent/core.rb, line 411
def self.build_navigator_app_version(os_id, navigator_id, platform_version, user_agent)
  if %w[chrome ie].include? navigator_id
    raise 'User agent doesn\'t start with "Mozilla/"' unless user_agent.to_s.start_with? 'Mozilla/'

    app_version = user_agent.split('Mozilla/')[1]
  elsif navigator_id == 'firefox'
    if os_id == 'android'
      app_version = "5.0 (#{platform_version})"
    else
      os_token = {
        'win' => 'Windows',
        'mac' => 'Macintosh',
        'linux' => 'X11'
      }[os_id]
      app_version = "5.0 (#{os_token})"
    end
  end
  app_version
end
build_system_components(device_type, os_id, navigator_id) click to toggle source
# File lib/fake_useragent/core.rb, line 216
def self.build_system_components(device_type, os_id, navigator_id)
  case os_id
  when 'win'
    platform_version = OS_PLATFORM['win'].sample.to_s
    cpu = OS_CPU['win'].sample
    platform = if cpu
                 "#{platform_version}; #{cpu}"
               else
                 platform_version.to_s
               end
    res = {
      'platform_version' => platform_version,
      'platform' => platform,
      'ua_platform' => platform,
      'os_cpu' => platform
    }
  when 'linux'
    cpu = OS_CPU['linux'].sample
    platform_version = OS_PLATFORM['linux'].sample
    platform = "#{platform_version}; #{cpu}"
    res = {
      'platform_version' => platform_version,
      'platform' => platform,
      'ua_platform' => platform,
      'os_cpu' => "Linux #{cpu}"
    }
  when 'mac'
    cpu = OS_CPU['mac'].sample
    platform_version = OS_PLATFORM['mac'].sample
    platform = platform_version
    platform = fix_chrome_mac_platform(platform) if navigator_id == 'chrome'
    res = {
      'platform_version' => platform_version.to_s,
      'platform' => 'MacIntel',
      'ua_platform' => platform.to_s,
      'os_cpu' => "Intel Mac OS X #{platform.split(' ')[-1]}"
    }
  when 'android'
    raise "#{navigator_id} not firefox or chrome" unless %w[firefox chrome].include? navigator_id
    raise "#{device_type} not smartphone or tablet" unless %w[smartphone tablet].include? device_type

    platform_version = OS_PLATFORM['android'].sample
    case navigator_id
    when 'firefox'
      case device_type
      when 'smartphone'
        ua_platform = "#{platform_version}; Mobile"
      when 'tablet'
        ua_platform = "#{platform_version}; Tablet"
      end
    when 'chrome'
      device_id = SMARTPHONE_DEV_IDS.sample
      ua_platform = "Linux; #{platform_version}; #{device_id}"
    end
    os_cpu = "Linux #{OS_CPU['android'].sample}"
    res = {
      'platform_version' => platform_version,
      'ua_platform' => ua_platform,
      'platform' => os_cpu,
      'os_cpu' => os_cpu
    }
  end
  res
end
choose_ua_template(device_type, navigator_id, app, sys) click to toggle source
# File lib/fake_useragent/core.rb, line 389
def self.choose_ua_template(device_type, navigator_id, app, sys)
  tpl_name = navigator_id
  case navigator_id
  when 'ie'
    tpl_name = if app['build_version'] == 'MSIE 11.0'
                 'ie_11'
               else
                 'ie_less_11'
               end
  when 'chrome'
    tpl_name = case device_type
               when 'smartphone'
                 'chrome_smartphone'
               when 'tablet'
                 'chrome_tablet'
               else
                 'chrome'
               end
  end
  user_agent_template(tpl_name, sys, app)
end
chrome_build() click to toggle source
# File lib/fake_useragent/core.rb, line 199
def self.chrome_build
  CHROME_BUILD.sample
end
firefox_build() click to toggle source
# File lib/fake_useragent/core.rb, line 182
def self.firefox_build
  firefox_ver = FIREFOX_VERSION.sample
  build_ver = firefox_ver[0]
  date_from = firefox_ver[1].to_i

  begin
    idx = FIREFOX_VERSION.index(firefox_ver)
    date_to = FIREFOX_VERSION.fetch(idx + 1)[1].to_i
  rescue IndexError
    date_to = date_from + 86_399
  end
  sec_range = date_to - date_from
  build_rnd_time = Time.at(date_from + rand(sec_range))

  [build_ver, build_rnd_time.strftime('%Y%m%d%H%M%S')]
end
fix_chrome_mac_platform(platform) click to toggle source
# File lib/fake_useragent/core.rb, line 207
def self.fix_chrome_mac_platform(platform)
  ver = platform.split('OS X ')[1]
  build_range = 0...MACOSX_CHROME_BUILD_RANGE[ver][1]
  build = rand(build_range)
  mac_version = "#{ver.sub('.', '_')}_#{build}"

  "Macintosh; Intel Mac OS X #{mac_version}"
end
ie_build() click to toggle source
# File lib/fake_useragent/core.rb, line 203
def self.ie_build
  IE_VERSION.sample
end
option_choices(opt_title, opt_value, default_value, all_choices) click to toggle source
# File lib/fake_useragent/core.rb, line 325
def self.option_choices(opt_title, opt_value, default_value, all_choices)
  choices = []
  if opt_value.instance_of? String
    choices = [opt_value]
  elsif opt_value.instance_of? Array
    choices = opt_value
  elsif opt_value.nil?
    choices = default_value
  else
    raise InvalidOption, "Option #{opt_title} has invalid value: #{opt_value}"
  end

  choices = all_choices if choices.include? 'all'

  choices.each do |item|
    raise InvalidOption, "Choices of option #{opt_title} contains invalid item: #{item}" unless all_choices.include? item
  end
  choices
end
pick_config_ids(device_type, os, navigator) click to toggle source
# File lib/fake_useragent/core.rb, line 345
def self.pick_config_ids(device_type, os, navigator)
  default_dev_types = if os.nil?
                        ['desktop']
                      else
                        DEVICE_TYPE_OS.keys
                      end
  dev_type_choices = option_choices(
    'device_type',
    device_type,
    default_dev_types,
    DEVICE_TYPE_OS.keys
  )
  os_choices = option_choices(
    'os',
    os,
    OS_NAVIGATOR.keys,
    OS_NAVIGATOR.keys
  )
  navigator_choices = option_choices(
    'navigator',
    navigator,
    NAVIGATOR_OS.keys,
    NAVIGATOR_OS.keys
  )
  variants = []

  prod = dev_type_choices.product(os_choices, navigator_choices)
  prod.each do |dev, os_, nav|
    if (DEVICE_TYPE_OS[dev].include? os_) && (DEVICE_TYPE_NAVIGATOR[dev].include? nav) && (OS_NAVIGATOR[os_].include? nav)
      variants << [dev, os_, nav]
    end
  end

  raise InvalidOption 'Options device_type, os and navigator conflicts with each other' if variants.nil?

  device_type, os_id, navigator_id = variants.sample

  raise InvalidOption, 'os_id not in OS_PLATFORM' unless OS_PLATFORM.include? os_id
  raise InvalidOption, 'navigator_id not in NAVIGATOR_OS' unless NAVIGATOR_OS.include? navigator_id
  raise InvalidOption, 'navigator_id not in DEVICE_TYPE_IDS' unless DEVICE_TYPE_OS.include? device_type

  [device_type, os_id, navigator_id]
end
user_agent_template(tpl_name, system, app) click to toggle source
# File lib/fake_useragent/core.rb, line 165
def self.user_agent_template(tpl_name, system, app)
  case tpl_name
  when 'firefox'
    "Mozilla/5.0 (#{system['ua_platform']}; rv:#{app['build_version']}) Gecko/#{app['gecko_trail']} Firefox/#{app['build_version']}"
  when 'chrome'
    "Mozilla/5.0 (#{system['ua_platform']}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/#{app['build_version']} Safari/537.36"
  when 'chrome_smartphone'
    "Mozilla/5.0 (#{system['ua_platform']}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/#{app['build_version']} Mobile Safari/537.36"
  when 'chrome_tablet'
    "Mozilla/5.0(#{system['ua_platform']}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/#{app['build_version']} Safari/537.36"
  when 'ie_less_11'
    "Mozilla/5.0 (compatible; #{app['build_version']}; #{system['ua_platform']}; Trident/#{app['trident_version']})"
  when 'ie_11'
    "Mozilla/5.0 (#{system['ua_platform']}; Trident/#{app['trident_version']}; rv:11.0) like Gecko"
  end
end