agent_orange 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
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