agent_orange 0.1.3 → 0.1.4

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/Gemfile CHANGED
@@ -2,3 +2,4 @@ source "http://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in agent_orange.gemspec
4
4
  gemspec
5
+ gem 'rspec'
data/README.rdoc CHANGED
@@ -78,7 +78,7 @@ If you're going to use it with Rails then add the gem to your Gemfile.
78
78
 
79
79
  === Looking at the operating system
80
80
 
81
- >> os = ua.device.os
81
+ >> os = ua.device.operating_system
82
82
  => "iPhone OS 4.3"
83
83
  >> os.type
84
84
  => "iphone_os"
@@ -163,6 +163,8 @@ A warm thank you to all contributors to the project, who have put effort and tim
163
163
  * David Rice (@davidjrice) - RSpec tests and bug fixes.
164
164
  * Joshua Siler (@eatenbyagrue) - Bot detection, initial test, and bug fixes.
165
165
  * Alexander Rozumiy (@brain-geek) - Rspec testing for 1.9, updated travis-ci config, updated useragents to test against.
166
+ * Joe Lencioni (@lencioni) - Improved bot detection.
167
+ * Todd Huss (@thuss) of Two Bit Labs (@twobitlabs) - Google Mobile crawler detection as mobile and bot.
166
168
 
167
169
  == License
168
170
 
data/Rakefile CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'bundler/gem_tasks'
2
+ require 'rake/dsl_definition'
2
3
  Dir.glob('./lib/tasks/*.rake').each { |r| import r }
3
4
 
4
5
  begin
@@ -9,6 +10,5 @@ begin
9
10
  # t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
10
11
  # Put spec opts in a file named .rspec in root
11
12
  end
12
-
13
13
  task :default => :spec
14
14
  end
@@ -10,9 +10,12 @@ module AgentOrange
10
10
  :ie => 'MSIE|Internet Explorer|IE',
11
11
  :firefox => 'Firefox',
12
12
  :opera => 'Opera',
13
+ :chrome => 'Chrome',
13
14
  :safari => 'Safari'
14
15
  }
15
16
 
17
+ BROWSER_TITLES = BROWSERS.merge :ie => 'MSIE'
18
+
16
19
  def parse(user_agent)
17
20
  AgentOrange.debug "BROWSER PARSING", 2
18
21
 
@@ -21,6 +24,7 @@ module AgentOrange
21
24
  if content[:name] =~ /(#{BROWSERS.collect{|cat,regex| regex}.join(')|(')})/i
22
25
  # Matched group against name
23
26
  self.populate(content)
27
+ break
24
28
  elsif content[:comment] =~ /(#{BROWSERS.collect{|cat,regex| regex}.join(')|(')})/i
25
29
  # Matched group against comment
26
30
  chosen_content = { :name => nil, :version => nil }
@@ -28,6 +32,11 @@ module AgentOrange
28
32
  additional_groups.each do |additional_content|
29
33
  if additional_content[:name] =~ /(#{BROWSERS.collect{|cat,regex| regex}.join(')|(')})/i
30
34
  chosen_content = additional_content
35
+
36
+ #Additional checking for chromeframe, iemobile, etc.
37
+ BROWSERS.each do |cat, regex|
38
+ chosen_content[:name] = BROWSER_TITLES[cat] if additional_content[:name] =~ /(#{regex})/i
39
+ end
31
40
  end
32
41
  end
33
42
 
@@ -6,15 +6,18 @@ require 'agent_orange/version'
6
6
 
7
7
  module AgentOrange
8
8
  class Device < Base
9
- attr_accessor :type, :name, :version
9
+ attr_accessor :type, :name, :version, :bot
10
10
  attr_accessor :platform
11
11
  attr_accessor :operating_system
12
12
  attr_accessor :engine
13
13
 
14
14
  DEVICES = {
15
15
  :computer => 'windows|macintosh|x11|linux',
16
- :mobile => 'ipod|ipad|iphone|palm|android|opera mini|hiptop|windows ce|smartphone|mobile|treo|psp',
17
- :bot => 'bot|googlebot|crawler|spider|robot|crawling'
16
+ :mobile => 'ipod|ipad|iphone|palm|android|opera mini|hiptop|windows ce|smartphone|mobile|treo|psp'
17
+ }
18
+
19
+ BOTS = {
20
+ :bot => 'alexa|bot|crawl(er|ing)|facebookexternalhit|feedburner|google web preview|nagios|postrank|pingdom|slurp|spider|yahoo!|yandex'
18
21
  }
19
22
 
20
23
  def parse(user_agent)
@@ -22,7 +25,8 @@ module AgentOrange
22
25
 
23
26
  groups = parse_user_agent_string_into_groups(user_agent)
24
27
  groups.each_with_index do |content,i|
25
- if content[:comment] =~ /(#{DEVICES.collect{|cat,regex| regex}.join(')|(')})/i
28
+ devices_and_bots = DEVICES.merge(BOTS)
29
+ if content[:comment] =~ /(#{devices_and_bots.collect{|cat,regex| regex}.join(')|(')})/i
26
30
  # Matched group against name
27
31
  self.populate(content)
28
32
  end
@@ -40,6 +44,10 @@ module AgentOrange
40
44
  AgentOrange.debug "", 2
41
45
 
42
46
  self.type = self.determine_type(DEVICES, content[:comment])
47
+ self.bot = self.determine_type(BOTS, content[:comment]) == :bot
48
+ if (self.bot && self.type == "other")
49
+ self.type = :bot # backwards compatability
50
+ end
43
51
  self.name = self.type.to_s.capitalize
44
52
  self.version = nil
45
53
  self
@@ -86,7 +94,7 @@ module AgentOrange
86
94
  return self.name.downcase.include?(name.to_s.downcase)
87
95
  end
88
96
  else
89
- (self.type == :bot)
97
+ self.bot
90
98
  end
91
99
  end
92
100
 
@@ -1,5 +1,5 @@
1
1
  module AgentOrange
2
- VERSION = "0.1.3" # This is for the gem and does not conflict with the rest of the functionality
2
+ VERSION = "0.1.4" # This is for the gem and does not conflict with the rest of the functionality
3
3
 
4
4
  class Version
5
5
  attr_accessor :major, :minor, :patch_level, :build_number
@@ -0,0 +1,58 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+ require 'net/http'
3
+ require 'iconv'
4
+
5
+ describe AgentOrange::UserAgent do
6
+ describe 'checking with real browsers list' do
7
+ before do
8
+ @lists = [Iconv.new('UTF-8//IGNORE', 'UTF-8').iconv( File.open("spec/fixtures/browser_ids.htm").read)]
9
+
10
+ begin
11
+ @lists.push Net::HTTP.get('www.zytrax.com', '/tech/web/browser_ids.htm')
12
+ rescue
13
+ end
14
+ end
15
+
16
+ it "should parse browsers from list" do
17
+ [
18
+ {
19
+ :a_name => 'chrome',
20
+ :browser_names => ['Chrome', 'Safari']
21
+ },
22
+ {
23
+ :a_name => 'safari',
24
+ :browser_names => ['Safari']
25
+ },
26
+ {
27
+ :a_name => 'firefox',
28
+ :browser_names => ['Firefox']
29
+ },
30
+ {
31
+ :a_name => 'msie',
32
+ #chromeframe!
33
+ :browser_names => ['MSIE', 'Chrome']
34
+ },
35
+ {
36
+ :a_name => 'opera',
37
+ :browser_names => ['Opera']
38
+ }
39
+ ].each do |params|
40
+ part = ''
41
+
42
+ @lists.each do |list|
43
+ part += list.scan(/<a name="#{params[:a_name]}">.+?<a name="/m).first.to_s
44
+ end
45
+
46
+ part.scan(/<p class="g-c-s">([^<]+)<\/p>/).each do |q|
47
+ unless params[:browser_names]== ['Opera'] && q.first == 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)'
48
+ ua = AgentOrange::UserAgent.new(q.first)
49
+ br_name = ua.device.engine.browser.name
50
+
51
+ puts "Test failing at user id: '#{q}'" unless params[:browser_names].include?(br_name)
52
+ params[:browser_names].should include(br_name)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,15 +1,6 @@
1
1
  require 'rubygems'
2
- require 'bundler'
3
- begin
4
- Bundler.setup(:default, :development)
5
- rescue Bundler::BundlerError => e
6
- $stderr.puts e.message
7
- $stderr.puts "Run `bundle install` to install missing gems"
8
- exit e.status_code
9
- end
10
-
11
- require File.join(File.dirname(__FILE__), "user_agent_matcher")
12
-
2
+ require 'bundler/setup'
3
+ require File.join(File.dirname(__FILE__), 'user_agent_matcher')
13
4
 
14
5
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
15
6
  $LOAD_PATH.unshift(File.dirname(__FILE__))
@@ -9,6 +9,7 @@ describe AgentOrange::UserAgent do
9
9
  ua.device.type.should == :computer
10
10
  ua.device.name.should == "Computer"
11
11
  ua.device.version.should == nil
12
+ ua.device.bot.should == false
12
13
 
13
14
  ua.device.operating_system.name.should == "Mac OS X"
14
15
  ua.device.operating_system.version.to_s.should == "10.6.8"
@@ -22,24 +23,6 @@ describe AgentOrange::UserAgent do
22
23
  ua.device.engine.browser.name.should == "Safari"
23
24
  ua.device.engine.browser.version.to_s.should == "533.21.1"
24
25
  end
25
-
26
- detect "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_1) AppleWebKit/535.5 (KHTML, like Gecko) Chrome/16.0.891.1 Safari/535.5" do |ua|
27
- ua.device.type.should == :computer
28
- ua.device.name.should == "Computer"
29
- ua.device.version.should == nil
30
-
31
- ua.device.operating_system.name.should == "Mac OS X"
32
- ua.device.operating_system.version.to_s.should == "10.7.1"
33
-
34
- ua.device.platform.name.should == "Macintosh"
35
- ua.device.platform.version.should == nil
36
-
37
- ua.device.engine.name.should == "AppleWebKit"
38
- ua.device.engine.version.to_s.should == "535.5"
39
-
40
- ua.device.engine.browser.name.should == "Safari"
41
- ua.device.engine.browser.version.to_s.should == "535.5"
42
- end
43
26
  end
44
27
 
45
28
  describe "Firefox" do
@@ -47,6 +30,7 @@ describe AgentOrange::UserAgent do
47
30
  ua.device.type.should == :computer
48
31
  ua.device.name.should == "Computer"
49
32
  ua.device.version.should == nil
33
+ ua.device.bot.should == false
50
34
 
51
35
  ua.device.operating_system.name.should == "Linux"
52
36
  ua.device.operating_system.version.to_s.should == "i686"
@@ -68,6 +52,7 @@ describe AgentOrange::UserAgent do
68
52
  ua.device.type.should == :computer
69
53
  ua.device.name.should == "Computer"
70
54
  ua.device.version.should == nil
55
+ ua.device.bot.should == false
71
56
 
72
57
  ua.device.operating_system.name.should == "Windows"
73
58
  ua.device.operating_system.version.to_s.should == "5.1"
@@ -78,61 +63,66 @@ describe AgentOrange::UserAgent do
78
63
  ua.device.engine.name.should == "AppleWebKit"
79
64
  ua.device.engine.version.to_s.should == "535.2"
80
65
 
81
- # TODO should be Chrome.
82
- ua.device.engine.browser.name.should == "Safari"
83
- ua.device.engine.browser.version.to_s.should == "535.2"
66
+ ua.device.engine.browser.name.should == "Chrome"
67
+ ua.device.engine.browser.version.to_s.should == "15.0.872.0"
84
68
  end
85
- end
86
69
 
87
- describe 'checking with real browsers list' do
88
- before do
89
- @lists = [Iconv.new('UTF-8//IGNORE', 'UTF-8').iconv( File.open("spec/fixtures/browser_ids.htm").read)]
70
+ detect "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_1) AppleWebKit/535.5 (KHTML, like Gecko) Chrome/16.0.891.1 Safari/535.5" do |ua|
71
+ ua.device.type.should == :computer
72
+ ua.device.name.should == "Computer"
73
+ ua.device.version.should == nil
74
+ ua.device.bot.should == false
75
+
76
+ ua.device.operating_system.name.should == "Mac OS X"
77
+ ua.device.operating_system.version.to_s.should == "10.7.1"
90
78
 
91
- begin
92
- @lists.push Net::HTTP.get('www.zytrax.com', '/tech/web/browser_ids.htm')
93
- rescue
94
- end
95
- end
79
+ ua.device.platform.name.should == "Macintosh"
80
+ ua.device.platform.version.should == nil
81
+
82
+ ua.device.engine.name.should == "AppleWebKit"
83
+ ua.device.engine.version.to_s.should == "535.5"
96
84
 
97
- it "should parse browsers from list" do
98
- [
99
- {
100
- :a_name => 'chrome',
101
- :browser_names => ['Safari']
102
- },
103
- {
104
- :a_name => 'safari',
105
- :browser_names => ['Safari']
106
- },
107
- {
108
- :a_name => 'firefox',
109
- :browser_names => ['Firefox']
110
- },
111
- {
112
- :a_name => 'msie',
113
- :browser_names => ['MSIE','IEMobile']
114
- },
115
- {
116
- :a_name => 'opera',
117
- :browser_names => ['Opera']
118
- }
119
- ].each do |params|
120
- part = ''
121
-
122
- @lists.each do |list|
123
- part += list.scan(/<a name="#{params[:a_name]}">.+?<a name="/m).first.to_s
124
- end
125
-
126
- part.scan(/<p class="g-c-s">([^<]+)<\/p>/).each do |q|
127
- ua = AgentOrange::UserAgent.new(q.first)
128
- br_name = ua.device.engine.browser.name
129
-
130
- params[:browser_names].should include(br_name)
131
- end
132
- end
85
+ ua.device.engine.browser.name.should == "Chrome"
86
+ ua.device.engine.browser.version.to_s.should == "16.0.891.1"
133
87
  end
134
88
 
89
+ detect "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; chromeframe/13.0.782.218; chromeframe; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)" do |ua|
90
+ ua.device.type.should == :computer
91
+ ua.device.name.should == "Computer"
92
+ ua.device.version.should == nil
93
+ ua.device.bot.should == false
94
+
95
+ ua.device.engine.browser.name.should == "Chrome"
96
+ ua.device.engine.browser.version.to_s.should == "13.0.782.218"
97
+ end
135
98
  end
99
+
100
+ describe "Google User Agents" do
101
+ detect "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 (compatible; Googlebot-Mobile/2.1; +http://www.google.com/bot.html)" do |ua|
102
+ ua.device.type.should == :mobile
103
+ ua.device.name.should == "Mobile"
104
+ ua.device.version.should == nil
105
+ ua.device.bot.should == true
106
+ ua.is_mobile?.should == true
107
+ ua.is_computer?.should == false
108
+ ua.is_bot?.should == true
136
109
 
110
+ ua.device.engine.browser.name.should == "Safari"
111
+ ua.device.engine.browser.version.to_s.should == "6531.22.7"
112
+ end
113
+
114
+ detect "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" do |ua|
115
+ ua.device.type.should == :bot
116
+ ua.device.name.should == "Bot"
117
+ ua.device.version.should == nil
118
+ ua.device.bot.should == true
119
+ ua.is_mobile?.should == false
120
+ ua.is_computer?.should == false
121
+ ua.is_bot?.should == true
137
122
 
123
+ ua.device.engine.browser.name.should == nil
124
+ ua.device.engine.browser.version.to_s.should == ""
125
+ end
126
+
127
+ end
138
128
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: agent_orange
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-12-08 00:00:00.000000000Z
12
+ date: 2012-10-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
16
- requirement: &70263619758660 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,15 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70263619758660
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: rspec
27
- requirement: &70263619755860 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
35
  - - ! '>='
@@ -32,10 +37,15 @@ dependencies:
32
37
  version: '0'
33
38
  type: :development
34
39
  prerelease: false
35
- version_requirements: *70263619755860
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
36
46
  - !ruby/object:Gem::Dependency
37
47
  name: bundler
38
- requirement: &70263619747260 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
39
49
  none: false
40
50
  requirements:
41
51
  - - ! '>='
@@ -43,7 +53,12 @@ dependencies:
43
53
  version: '0'
44
54
  type: :development
45
55
  prerelease: false
46
- version_requirements: *70263619747260
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
47
62
  description: Parse and process User Agents like a secret one
48
63
  email:
49
64
  - kevin@welikeinc.com
@@ -71,6 +86,7 @@ files:
71
86
  - lib/tasks/allagents.xml
72
87
  - lib/tasks/bot_agent_test.rake
73
88
  - spec/fixtures/browser_ids.htm
89
+ - spec/long_user_agent_spec.rb
74
90
  - spec/spec_helper.rb
75
91
  - spec/user_agent_matcher.rb
76
92
  - spec/user_agent_spec.rb
@@ -86,20 +102,27 @@ required_ruby_version: !ruby/object:Gem::Requirement
86
102
  - - ! '>='
87
103
  - !ruby/object:Gem::Version
88
104
  version: '0'
105
+ segments:
106
+ - 0
107
+ hash: 3447996973066074909
89
108
  required_rubygems_version: !ruby/object:Gem::Requirement
90
109
  none: false
91
110
  requirements:
92
111
  - - ! '>='
93
112
  - !ruby/object:Gem::Version
94
113
  version: '0'
114
+ segments:
115
+ - 0
116
+ hash: 3447996973066074909
95
117
  requirements: []
96
118
  rubyforge_project: agent_orange
97
- rubygems_version: 1.8.10
119
+ rubygems_version: 1.8.24
98
120
  signing_key:
99
121
  specification_version: 3
100
122
  summary: Parse and process User Agents like a secret one
101
123
  test_files:
102
124
  - spec/fixtures/browser_ids.htm
125
+ - spec/long_user_agent_spec.rb
103
126
  - spec/spec_helper.rb
104
127
  - spec/user_agent_matcher.rb
105
128
  - spec/user_agent_spec.rb