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.
@@ -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
+