browscap 0.1.0
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.
- data/Manifest +9 -0
- data/README.rdoc +0 -0
- data/Rakefile +15 -0
- data/browscap.gemspec +30 -0
- data/lib/Manifest +6 -0
- data/lib/browscap-0.1.0.gem +0 -0
- data/lib/browscap.gemspec +30 -0
- data/lib/browscap.ini +16210 -0
- data/lib/browscap.rb +109 -0
- data/lib/spec/browscap_spec.rb +75 -0
- metadata +75 -0
data/lib/browscap.rb
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
require 'inifile'
|
|
2
|
+
|
|
3
|
+
class Browscap
|
|
4
|
+
def initialize(filename = 'browscap.ini')
|
|
5
|
+
@@user_agent_properties ||= {}
|
|
6
|
+
@@user_agent_regexps ||= {}
|
|
7
|
+
@@match_cache ||= {}
|
|
8
|
+
|
|
9
|
+
if @@user_agent_properties.empty? || @@user_agent_regexps.empty?
|
|
10
|
+
ini = IniFile.load(filename)
|
|
11
|
+
|
|
12
|
+
# Remote meta sections
|
|
13
|
+
ini.delete_section '*'
|
|
14
|
+
ini.delete_section 'GJK_Browscap_Version'
|
|
15
|
+
|
|
16
|
+
# Create a list of non-parent sections
|
|
17
|
+
child_sections = ini.sections.dup
|
|
18
|
+
ini.sections.each do |section|
|
|
19
|
+
child_sections.delete ini[section]["Parent"]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Populate user_agent_properties and user_agent_regexps
|
|
23
|
+
child_sections.each do |section|
|
|
24
|
+
properties = _get_browser_props(ini, section)
|
|
25
|
+
|
|
26
|
+
browser = Browser.new
|
|
27
|
+
browser.browser = properties['Browser']
|
|
28
|
+
browser.version = properties['Version']
|
|
29
|
+
browser.major_ver = properties['MajorVer'].to_i
|
|
30
|
+
browser.minor_ver = properties['MinorVer'].to_i
|
|
31
|
+
browser.platform = properties['Platform']
|
|
32
|
+
browser.alpha = properties['Alpha'].downcase == 'true'
|
|
33
|
+
browser.beta = properties['Beta'].downcase == 'true'
|
|
34
|
+
browser.win16 = properties['Win16'].downcase == 'true'
|
|
35
|
+
browser.win32 = properties['Win32'].downcase == 'true'
|
|
36
|
+
browser.win64 = properties['Win64'].downcase == 'true'
|
|
37
|
+
browser.frames = properties['Frames'].downcase == 'true'
|
|
38
|
+
browser.iframes = properties['IFrames'].downcase == 'true'
|
|
39
|
+
browser.tables = properties['Tables'].downcase == 'true'
|
|
40
|
+
browser.cookies = properties['Cookies'].downcase == 'true'
|
|
41
|
+
browser.background_sounds = properties['BackgroundSounds'].downcase == 'true'
|
|
42
|
+
browser.javascript = properties['JavaScript'].downcase == 'true'
|
|
43
|
+
browser.vbscript = properties['VBScript'].downcase == 'true'
|
|
44
|
+
browser.java_applets = properties['JavaApplets'].downcase == 'true'
|
|
45
|
+
browser.activex_controls = properties['ActiveXControls'].downcase == 'true'
|
|
46
|
+
browser.is_banned = properties['isBanned'].downcase == 'true'
|
|
47
|
+
browser.is_mobile_device = properties['isMobileDevice'].downcase == 'true'
|
|
48
|
+
browser.is_syndication_reader = properties['isSyndicationReader'].downcase == 'true'
|
|
49
|
+
browser.crawler = properties['Crawler'].downcase == 'true'
|
|
50
|
+
browser.css_version = properties['CssVersion'].to_i
|
|
51
|
+
browser.supports_css = properties['supportsCSS'].downcase == 'true'
|
|
52
|
+
browser.aol_version = properties['aolVersion'].to_i
|
|
53
|
+
browser.aol = properties['AOL'].downcase == 'true'
|
|
54
|
+
|
|
55
|
+
@@user_agent_properties[section] = browser
|
|
56
|
+
|
|
57
|
+
# Convert .ini file regexp syntax into ruby regexp syntax
|
|
58
|
+
regexp = section.dup
|
|
59
|
+
regexp.gsub! /([\^\$\(\)\[\]\.\-])/, "\\\\\\1"
|
|
60
|
+
regexp.gsub! "?", "."
|
|
61
|
+
regexp.gsub! "*", ".*?"
|
|
62
|
+
|
|
63
|
+
@@user_agent_regexps[section] = Regexp.new("^%s$" % regexp)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Looks up the given user agent string and returns a dictionary containing information on this browser or bot.
|
|
69
|
+
def query(user_agent)
|
|
70
|
+
section = _match(user_agent)
|
|
71
|
+
@@user_agent_properties[section]
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def _match(user_agent)
|
|
75
|
+
return @@match_cache[user_agent] if @@match_cache[user_agent]
|
|
76
|
+
|
|
77
|
+
matching_section = ''
|
|
78
|
+
|
|
79
|
+
@@user_agent_regexps.each do |section, regexp|
|
|
80
|
+
# Find the longest regexp that matches the given user_agent_string. The length check is needed since multiple reg-exps may match the user_agent_string.
|
|
81
|
+
if regexp.match(user_agent) && section.length > matching_section.length
|
|
82
|
+
matching_section = section
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
@@match_cache[user_agent] = matching_section
|
|
87
|
+
matching_section
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Recursively traverses the properties tree (based on 'parent' attribute of each section) and
|
|
91
|
+
# returns a dictionary of all browser properties for the given section name. The properties lower
|
|
92
|
+
# in the tree override those higher in the tree.
|
|
93
|
+
def _get_browser_props(ini, section)
|
|
94
|
+
data = {}
|
|
95
|
+
|
|
96
|
+
if parent = ini[section]["Parent"]
|
|
97
|
+
data.merge! _get_browser_props(ini, parent)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
data.merge! ini[section]
|
|
101
|
+
data
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
class Browser
|
|
106
|
+
attr_accessor :browser, :version, :major_ver, :minor_ver, :platform, :alpha, :beta, :win16, :win32, :win64,
|
|
107
|
+
:frames, :iframes, :tables, :cookies, :background_sounds, :javascript, :vbscript, :java_applets, :activex_controls,
|
|
108
|
+
:is_banned, :is_mobile_device, :is_syndication_reader, :crawler, :css_version, :supports_css, :aol_version, :aol
|
|
109
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
require 'browscap'
|
|
2
|
+
|
|
3
|
+
describe Browscap do
|
|
4
|
+
before(:each) do
|
|
5
|
+
@browscap = Browscap.new
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
it "should detect Konqueror 3.5 on Linux" do
|
|
9
|
+
konq35 = @browscap.query "Mozilla/5.0 (compatible; Konqueror/3.5; Linux; X11; de) KHTML/3.5.2 (like Gecko) Kubuntu 6.06 Dapper"
|
|
10
|
+
konq35.browser.should == 'Konqueror'
|
|
11
|
+
konq35.version.should == '3.5'
|
|
12
|
+
konq35.platform.should == 'Linux'
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "should detect Firefox 1.5 on Linux" do
|
|
16
|
+
ff15 = @browscap.query "Mozilla/5.0 (X11; U; Linux i686; de; rv:1.8.0.5) Gecko/20060731 Ubuntu/dapper-security Firefox/1.5.0.5"
|
|
17
|
+
ff15.browser.should == 'Firefox'
|
|
18
|
+
ff15.version.should == '1.5'
|
|
19
|
+
ff15.platform.should == 'Linux'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "should detect Mozilla 1.7 on Linux" do
|
|
23
|
+
moz17 = @browscap.query "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.12) Gecko/20060216 Debian/1.7.12-1.1ubuntu2"
|
|
24
|
+
moz17.browser.should == 'Mozilla'
|
|
25
|
+
moz17.version.should == '1.7'
|
|
26
|
+
moz17.platform.should == 'Linux'
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "should detect Firefox 1.5 on Linux (2)" do
|
|
30
|
+
ff15 = @browscap.query "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.5) Gecko/20060731 Ubuntu/dapper-security Epiphany/2.14 Firefox/1.5.0.5"
|
|
31
|
+
ff15.browser.should == 'Firefox'
|
|
32
|
+
ff15.version.should == '1.5'
|
|
33
|
+
ff15.platform.should == 'Linux'
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "should detect Opera 9.0 on Linux" do
|
|
37
|
+
opera90 = @browscap.query "Opera/9.00 (X11; Linux i686; U; en)"
|
|
38
|
+
opera90.browser.should == 'Opera'
|
|
39
|
+
opera90.version.should == '9.0'
|
|
40
|
+
opera90.platform.should == 'Linux'
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "shouldn't detect Kazehakase" do
|
|
44
|
+
@browscap.query("Mozilla/5.0 (X11; Linux i686; U;) Gecko/20051128 Kazehakase/0.3.3 Debian/0.3.3-1").should be_nil
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "should detect Galeon 1.3 on Linux" do
|
|
48
|
+
galeon13 = @browscap.query "Mozilla/5.0 (X11; U; Linux i386) Gecko/20063102 Galeon/1.3test"
|
|
49
|
+
galeon13.browser.should == 'Galeon'
|
|
50
|
+
galeon13.version.should == '1.3'
|
|
51
|
+
galeon13.platform.should == 'Linux'
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "should detect MSIE 6.0 on Windows 98" do
|
|
55
|
+
ie6 = @browscap.query "Mozilla/4.0 (compatible; MSIE 6.0; Windows 98)"
|
|
56
|
+
ie6.browser.should == 'IE'
|
|
57
|
+
ie6.version.should == '6.0'
|
|
58
|
+
ie6.platform.should == 'Win98'
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "should detect Wget as crawler" do
|
|
62
|
+
wget = @browscap.query "Wget/1.10.2"
|
|
63
|
+
wget.crawler.should == true
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it "should detect Googlebot as crawler" do
|
|
67
|
+
google = @browscap.query "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
|
|
68
|
+
google.crawler.should == true
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "should detect Yahoo! bot as crawler" do
|
|
72
|
+
yahoo = @browscap.query "Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)"
|
|
73
|
+
yahoo.crawler.should == true
|
|
74
|
+
end
|
|
75
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: browscap
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Matt
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
|
|
12
|
+
date: 2009-10-29 00:00:00 -04:00
|
|
13
|
+
default_executable:
|
|
14
|
+
dependencies: []
|
|
15
|
+
|
|
16
|
+
description: Uses the browscap.ini file in Ruby.
|
|
17
|
+
email: hotiby@gmail.com
|
|
18
|
+
executables: []
|
|
19
|
+
|
|
20
|
+
extensions: []
|
|
21
|
+
|
|
22
|
+
extra_rdoc_files:
|
|
23
|
+
- README.rdoc
|
|
24
|
+
- lib/Manifest
|
|
25
|
+
- lib/browscap-0.1.0.gem
|
|
26
|
+
- lib/browscap.gemspec
|
|
27
|
+
- lib/browscap.ini
|
|
28
|
+
- lib/browscap.rb
|
|
29
|
+
- lib/spec/browscap_spec.rb
|
|
30
|
+
files:
|
|
31
|
+
- README.rdoc
|
|
32
|
+
- Rakefile
|
|
33
|
+
- lib/Manifest
|
|
34
|
+
- lib/browscap-0.1.0.gem
|
|
35
|
+
- lib/browscap.gemspec
|
|
36
|
+
- lib/browscap.ini
|
|
37
|
+
- lib/browscap.rb
|
|
38
|
+
- lib/spec/browscap_spec.rb
|
|
39
|
+
- Manifest
|
|
40
|
+
- browscap.gemspec
|
|
41
|
+
has_rdoc: true
|
|
42
|
+
homepage: http://github.com/lfittl/browscap
|
|
43
|
+
licenses: []
|
|
44
|
+
|
|
45
|
+
post_install_message:
|
|
46
|
+
rdoc_options:
|
|
47
|
+
- --line-numbers
|
|
48
|
+
- --inline-source
|
|
49
|
+
- --title
|
|
50
|
+
- Browscap
|
|
51
|
+
- --main
|
|
52
|
+
- README.rdoc
|
|
53
|
+
require_paths:
|
|
54
|
+
- lib
|
|
55
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
56
|
+
requirements:
|
|
57
|
+
- - ">="
|
|
58
|
+
- !ruby/object:Gem::Version
|
|
59
|
+
version: "0"
|
|
60
|
+
version:
|
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
62
|
+
requirements:
|
|
63
|
+
- - ">="
|
|
64
|
+
- !ruby/object:Gem::Version
|
|
65
|
+
version: "1.2"
|
|
66
|
+
version:
|
|
67
|
+
requirements: []
|
|
68
|
+
|
|
69
|
+
rubyforge_project: browscap
|
|
70
|
+
rubygems_version: 1.3.5
|
|
71
|
+
signing_key:
|
|
72
|
+
specification_version: 3
|
|
73
|
+
summary: Uses the browscap.ini file in Ruby.
|
|
74
|
+
test_files: []
|
|
75
|
+
|