agent_orange 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -29,6 +29,9 @@ def process_user_agent(ua_str)
29
29
  puts '='*120
30
30
  end
31
31
 
32
+ AgentOrange::DEBUG = true
33
+ AgentOrange::DEBUG_LEVEL = 2
34
+
32
35
  user_agent_strings.each do |ua_str|
33
36
  process_user_agent(ua_str)
34
37
  end
@@ -0,0 +1,58 @@
1
+ module AgentOrange
2
+ class Base
3
+
4
+ def initialize(user_agent)
5
+ self.parse(user_agent)
6
+ end
7
+
8
+ def parse_user_agent_string_into_groups(user_agent)
9
+ results = user_agent.scan(/([^\/[:space:]]*)(\/([^[:space:]]*))?([[:space:]]*\[[a-zA-Z][a-zA-Z]\])?[[:space:]]*(\((([^()]|(\([^()]*\)))*)\))?[[:space:]]*/i)
10
+ groups = []
11
+ results.each do |result|
12
+ if result[0] != "" # Add the group of content if name isn't blank
13
+ groups << { :name => result[0], :version => result[2], :comment => result[5] }
14
+ end
15
+ end
16
+ groups
17
+ end
18
+
19
+ def parse_comment(comment)
20
+ groups = []
21
+ comment.split('; ').each do |piece|
22
+ content = { :name => nil, :version => nil }
23
+
24
+ # Remove 'like Mac OS X' or similar since it distracts from real results
25
+ piece = piece.scan(/(.+) like .+$/i)[0][0] if piece =~ /(.+) like (.+)$/i
26
+
27
+ if piece =~ /(.+)[ \/]([\w.]+)$/i
28
+ chopped = piece.scan(/(.+)[ \/]([\w.]+)$/i)[0]
29
+ groups << { :name => chopped[0], :version => chopped[1] }
30
+ end
31
+ end
32
+ groups
33
+ end
34
+
35
+ def determine_type(types={}, content="")
36
+ # Determine type
37
+ type = nil
38
+ types.each do |key, value|
39
+ type = key if content =~ /(#{value})/i
40
+ end
41
+ type = "other" if type.nil?
42
+ type
43
+ end
44
+
45
+ def debug_raw_content(content)
46
+ AgentOrange.debug " Raw Name : #{content[:name]}", 2
47
+ AgentOrange.debug " Raw Version: #{content[:version]}", 2
48
+ AgentOrange.debug " Raw Comment: #{content[:comment]}", 2
49
+ end
50
+
51
+ def debug_content(content)
52
+ AgentOrange.debug " Type: #{self.type}", 2
53
+ AgentOrange.debug " Name: #{self.name}", 2
54
+ AgentOrange.debug " Version: #{self.version}", 2
55
+ end
56
+
57
+ end
58
+ end
@@ -1,7 +1,8 @@
1
+ require 'agent_orange/base'
1
2
  require 'agent_orange/version'
2
3
 
3
4
  module AgentOrange
4
- class Browser
5
+ class Browser < Base
5
6
  attr_accessor :type, :name, :version
6
7
  attr_accessor :security
7
8
 
@@ -12,53 +13,44 @@ module AgentOrange
12
13
  :safari => 'Safari'
13
14
  }
14
15
 
15
- def initialize(user_agent)
16
- self.parse(user_agent)
17
- end
18
-
19
16
  def parse(user_agent)
20
17
  AgentOrange.debug "BROWSER PARSING", 2
21
- groups = user_agent.scan(/([^\/[:space:]]*)(\/([^[:space:]]*))?([[:space:]]*\[[a-zA-Z][a-zA-Z]\])?[[:space:]]*(\((([^()]|(\([^()]*\)))*)\))?[[:space:]]*/i)
22
- groups.each_with_index do |pieces,i|
23
- name = pieces[0]
24
- version = pieces[2]
25
- comment = pieces[5]
26
-
27
- if name =~ /(#{BROWSERS.collect{|cat,regex| regex}.join(')|(')})/i
28
- # Found the browser
29
- AgentOrange.debug " Got a browser in group #{i+1}!", 2
30
- AgentOrange.debug " Raw Name : #{name}", 2
31
- AgentOrange.debug " Raw Version: #{version}", 2
32
- AgentOrange.debug " Raw Comment: #{comment}", 2
33
- AgentOrange.debug "", 2
34
-
35
- # Determine browser type
36
- if name =~ /(#{BROWSERS[:ie]})/i
37
- self.type = "ie"
38
- elsif name =~ /(#{BROWSERS[:firefox]})/i
39
- self.type = "firefox"
40
- elsif name =~ /(#{BROWSERS[:safari]})/i
41
- self.type = "safari"
42
- elsif name =~ /(#{BROWSERS[:opera]})/i
43
- self.type = "opera"
44
- else
45
- self.type = "other"
18
+
19
+ groups = parse_user_agent_string_into_groups(user_agent)
20
+ groups.each_with_index do |content,i|
21
+ if content[:name] =~ /(#{BROWSERS.collect{|cat,regex| regex}.join(')|(')})/i
22
+ # Matched group against name
23
+ self.populate(content)
24
+ elsif content[:comment] =~ /(#{BROWSERS.collect{|cat,regex| regex}.join(')|(')})/i
25
+ # Matched group against comment
26
+ chosen_content = { :name => nil, :version => nil }
27
+ additional_groups = parse_comment(content[:comment])
28
+ additional_groups.each do |additional_content|
29
+ if additional_content[:name] =~ /(#{BROWSERS.collect{|cat,regex| regex}.join(')|(')})/i
30
+ chosen_content = additional_content
31
+ end
46
32
  end
47
-
48
- # Determine browser name
49
- self.name = name
50
-
51
- # Determine device version
52
- self.version = AgentOrange::Version.new(version)
53
-
33
+
34
+ self.populate(chosen_content)
54
35
  end
55
-
56
36
  end
57
37
 
38
+ self.analysis
39
+ end
40
+
41
+ def populate(content={})
42
+ self.debug_raw_content(content)
43
+ AgentOrange.debug "", 2
44
+
45
+ self.type = self.determine_type(BROWSERS, content[:name])
46
+ self.name = content[:name]
47
+ self.version = AgentOrange::Version.new(content[:version])
48
+ self
49
+ end
50
+
51
+ def analysis
58
52
  AgentOrange.debug "BROWSER ANALYSIS", 2
59
- AgentOrange.debug " Type: #{self.type}", 2
60
- AgentOrange.debug " Name: #{self.name}", 2
61
- AgentOrange.debug " Version: #{self.version}", 2
53
+ self.debug_content(:type => self.type, :name => self.name, :version => self.version)
62
54
  AgentOrange.debug "", 2
63
55
  end
64
56
 
@@ -1,10 +1,11 @@
1
+ require 'agent_orange/base'
1
2
  require 'agent_orange/platform'
2
3
  require 'agent_orange/operating_system'
3
4
  require 'agent_orange/engine'
4
5
  require 'agent_orange/version'
5
6
 
6
7
  module AgentOrange
7
- class Device
8
+ class Device < Base
8
9
  attr_accessor :type, :name, :version
9
10
  attr_accessor :platform
10
11
  attr_accessor :operating_system
@@ -16,58 +17,40 @@ module AgentOrange
16
17
  :bot => 'bot'
17
18
  }
18
19
 
19
- def initialize(user_agent)
20
- self.parse(user_agent)
21
- end
22
-
23
20
  def parse(user_agent)
24
21
  AgentOrange.debug "DEVICE PARSING", 2
25
- groups = user_agent.scan(/([^\/[:space:]]*)(\/([^[:space:]]*))?([[:space:]]*\[[a-zA-Z][a-zA-Z]\])?[[:space:]]*(\((([^()]|(\([^()]*\)))*)\))?[[:space:]]*/i)
26
- groups.each_with_index do |pieces,i|
27
- name = pieces[0]
28
- version = pieces[2]
29
- comment = pieces[5]
30
-
31
- if comment =~ /(#{DEVICES.collect{|cat,regex| regex}.join(')|(')})/i
32
- # Found the device
33
- AgentOrange.debug " Got a device in group #{i+1}!", 2
34
- AgentOrange.debug " Group Raw Name : #{name}", 2
35
- AgentOrange.debug " Group Raw Version: #{version}", 2
36
- AgentOrange.debug " Group Raw Comment: #{comment}", 2
37
- AgentOrange.debug "", 2
38
-
39
- # Determine device type
40
- if comment =~ /(#{DEVICES[:computer]})/i
41
- self.type = "computer"
42
- end
43
- if comment =~ /(#{DEVICES[:mobile]})/i
44
- self.type = "mobile"
45
- end
46
- if comment =~ /(#{DEVICES[:bot]})/i
47
- self.type = "bot"
48
- end
49
-
50
- # Determine device name
51
- self.name = self.type.capitalize
52
-
53
- # Determine device version
54
- self.version = nil
55
-
22
+
23
+ groups = parse_user_agent_string_into_groups(user_agent)
24
+ groups.each_with_index do |content,i|
25
+ if content[:comment] =~ /(#{DEVICES.collect{|cat,regex| regex}.join(')|(')})/i
26
+ # Matched group against name
27
+ self.populate(content)
56
28
  end
57
-
58
29
  end
59
30
 
60
- AgentOrange.debug "DEVICE ANALYSIS", 2
61
- AgentOrange.debug " Type: #{self.type}", 2
62
- AgentOrange.debug " Name: #{self.name}", 2
63
- AgentOrange.debug " Version: #{self.version}", 2
64
- AgentOrange.debug "", 2
31
+ self.analysis
65
32
 
66
33
  self.platform = AgentOrange::Platform.new(user_agent)
67
34
  self.operating_system = AgentOrange::OperatingSystem.new(user_agent)
68
35
  self.engine = AgentOrange::Engine.new(user_agent)
69
36
  end
70
37
 
38
+ def populate(content={})
39
+ self.debug_raw_content(content)
40
+ AgentOrange.debug "", 2
41
+
42
+ self.type = self.determine_type(DEVICES, content[:comment])
43
+ self.name = self.type.to_s.capitalize
44
+ self.version = nil
45
+ self
46
+ end
47
+
48
+ def analysis
49
+ AgentOrange.debug "DEVICE ANALYSIS", 2
50
+ self.debug_content(:type => self.type, :name => self.name, :version => self.version)
51
+ AgentOrange.debug "", 2
52
+ end
53
+
71
54
  def is_computer?(name=nil)
72
55
  if name
73
56
  case name
@@ -1,9 +1,10 @@
1
+ require 'agent_orange/base'
1
2
  require 'agent_orange/browser'
2
3
  require 'agent_orange/version'
3
4
  require 'pp'
4
5
 
5
6
  module AgentOrange
6
- class Engine
7
+ class Engine < Base
7
8
  attr_accessor :type, :name, :version
8
9
  attr_accessor :browser
9
10
 
@@ -15,14 +16,10 @@ module AgentOrange
15
16
  :other => 'Other'
16
17
  }
17
18
 
18
- def initialize(user_agent)
19
- self.parse(user_agent)
20
- end
21
-
22
19
  def parse(user_agent)
23
20
  AgentOrange.debug "ENGINE PARSING", 2
24
- results = user_agent.scan(/([^\/[:space:]]*)(\/([^[:space:]]*))?([[:space:]]*\[[a-zA-Z][a-zA-Z]\])?[[:space:]]*(\((([^()]|(\([^()]*\)))*)\))?[[:space:]]*/i)
25
- groups = scan_results_into_groups(results)
21
+
22
+ groups = parse_user_agent_string_into_groups(user_agent)
26
23
  groups.each_with_index do |content,i|
27
24
  if content[:name] =~ /(#{ENGINES.collect{|cat,regex| regex}.join(')|(')})/i
28
25
  # Matched group against name
@@ -45,45 +42,11 @@ module AgentOrange
45
42
  self.browser = AgentOrange::Browser.new(user_agent)
46
43
  end
47
44
 
48
- def scan_results_into_groups(results)
49
- groups = []
50
- results.each do |result|
51
- if result[0] != "" # Add the group of content if name isn't blank
52
- groups << { :name => result[0], :version => result[2], :comment => result[5] }
53
- end
54
- end
55
- groups
56
- end
57
-
58
- def parse_comment(comment)
59
- groups = []
60
- comment.split('; ').each do |piece|
61
- content = { :name => nil, :version => nil }
62
- if piece =~ /(.+)[ \/]([\w.]+)$/i
63
- chopped = piece.scan(/(.+)[ \/]([\w.]+)$/i)[0]
64
- groups << { :name => chopped[0], :version => chopped[1] }
65
- end
66
- end
67
- groups
68
- end
69
-
70
- def determine_type(content="")
71
- # Determine type
72
- type = nil
73
- ENGINES.each do |key, value|
74
- type = key if content =~ /(#{value})/i
75
- end
76
- type = "other" if type.nil?
77
- type
78
- end
79
-
80
45
  def populate(content={})
81
- AgentOrange.debug " Raw Name : #{content[:name]}", 2
82
- AgentOrange.debug " Raw Version: #{content[:version]}", 2
83
- AgentOrange.debug " Raw Comment: #{content[:comment]}", 2
46
+ self.debug_raw_content(content)
84
47
  AgentOrange.debug "", 2
85
-
86
- self.type = self.determine_type(content[:name])
48
+
49
+ self.type = self.determine_type(ENGINES, content[:name])
87
50
  self.name = ENGINES[self.type.to_sym]
88
51
  self.version = AgentOrange::Version.new(content[:version])
89
52
  self
@@ -91,9 +54,7 @@ module AgentOrange
91
54
 
92
55
  def analysis
93
56
  AgentOrange.debug "ENGINE ANALYSIS", 2
94
- AgentOrange.debug " Type: #{self.type}", 2
95
- AgentOrange.debug " Name: #{self.name}", 2
96
- AgentOrange.debug " Version: #{self.version}", 2
57
+ self.debug_content(:type => self.type, :name => self.name, :version => self.version)
97
58
  AgentOrange.debug "", 2
98
59
  end
99
60
 
@@ -1,5 +1,7 @@
1
+ require 'agent_orange/base'
2
+
1
3
  module AgentOrange
2
- class OperatingSystem
4
+ class OperatingSystem < Base
3
5
  attr_accessor :type, :name, :version
4
6
 
5
7
  OPERATING_SYSTEMS = {
@@ -21,66 +23,45 @@ module AgentOrange
21
23
  :osx => 'Mac OS X',
22
24
  :windows => 'Windows'
23
25
  }
24
-
25
- def initialize(user_agent)
26
- self.parse(user_agent)
27
- end
28
26
 
29
27
  def parse(user_agent)
30
28
  AgentOrange.debug "OPERATING SYSTEM PARSING", 2
31
- groups = user_agent.scan(/([^\/[:space:]]*)(\/([^[:space:]]*))?([[:space:]]*\[[a-zA-Z][a-zA-Z]\])?[[:space:]]*(\((([^()]|(\([^()]*\)))*)\))?[[:space:]]*/i)
32
- groups.each_with_index do |pieces,i|
33
- name = pieces[0]
34
- version = pieces[2]
35
- comment = pieces[5]
36
-
37
- if comment =~ /(#{OPERATING_SYSTEMS.collect{|cat,regex| regex}.join(')|(')})/i
38
- # Found the operating system
39
- AgentOrange.debug " Got an operating system in group #{i+1}!", 2
40
- AgentOrange.debug " Raw Name : #{name}", 2
41
- AgentOrange.debug " Raw Version: #{version}", 2
42
- AgentOrange.debug " Raw Comment: #{comment}", 2
43
- AgentOrange.debug "", 2
44
-
45
- # Determine operating system type
46
- if comment =~ /(#{OPERATING_SYSTEMS[:android]})/i
47
- self.type = "android"
48
- end
49
- if comment =~ /(#{OPERATING_SYSTEMS[:freebsd]})/i
50
- self.type = "freebsd"
51
- end
52
- if comment =~ /(#{OPERATING_SYSTEMS[:ios]})/i
53
- self.type = "ios"
54
- end
55
- if comment =~ /(#{OPERATING_SYSTEMS[:linux]})/i
56
- self.type = "linux"
57
- end
58
- if comment =~ /(#{OPERATING_SYSTEMS[:netbsd]})/i
59
- self.type = "netbsd"
60
- end
61
- if comment =~ /(#{OPERATING_SYSTEMS[:osx]})/i
62
- self.type = "osx"
63
- end
64
- if comment =~ /(#{OPERATING_SYSTEMS[:windows]})/i
65
- self.type = "windows"
29
+
30
+ groups = parse_user_agent_string_into_groups(user_agent)
31
+ groups.each_with_index do |content,i|
32
+ if content[:comment] =~ /(#{OPERATING_SYSTEMS.collect{|cat,regex| regex}.join(')|(')})/i
33
+ # Matched group against comment
34
+ chosen_content = { :name => nil, :version => nil }
35
+ additional_groups = parse_comment(content[:comment])
36
+ additional_groups.each do |additional_content|
37
+ if additional_content[:name] =~ /(#{OPERATING_SYSTEMS.collect{|cat,regex| regex}.join(')|(')})/i
38
+ chosen_content = additional_content
39
+ end
66
40
  end
67
-
68
- # Determine operating system name
69
- self.name = OPERATING_SYSTEM_NAMES[self.type.to_sym]
70
-
71
- # Determine operating system version
72
- self.version = nil
41
+
42
+ self.populate(chosen_content)
73
43
  end
74
-
75
44
  end
76
-
45
+
46
+ self.analysis
47
+ end
48
+
49
+ def populate(content={})
50
+ self.debug_raw_content(content)
51
+ AgentOrange.debug "", 2
52
+
53
+ self.type = self.determine_type(OPERATING_SYSTEMS, content[:name])
54
+ self.name = OPERATING_SYSTEM_NAMES[self.type.to_sym]
55
+ self.version = AgentOrange::Version.new(content[:version])
56
+ self
57
+ end
58
+
59
+ def analysis
77
60
  AgentOrange.debug "OPERATING SYSTEM ANALYSIS", 2
78
- AgentOrange.debug " Type: #{self.type}", 2
79
- AgentOrange.debug " Name: #{self.name}", 2
80
- AgentOrange.debug " Version: #{self.version}", 2
61
+ self.debug_content(:type => self.type, :name => self.name, :version => self.version)
81
62
  AgentOrange.debug "", 2
82
63
  end
83
-
64
+
84
65
  def to_s
85
66
  [self.name, self.version].compact.join(' ')
86
67
  end
@@ -1,5 +1,7 @@
1
+ require 'agent_orange/base'
2
+
1
3
  module AgentOrange
2
- class Platform
4
+ class Platform < Base
3
5
  attr_accessor :type, :name, :version
4
6
 
5
7
  PLATFORMS = {
@@ -16,11 +18,7 @@ module AgentOrange
16
18
  :pc => 'PC'
17
19
  }
18
20
 
19
- def initialize(user_agent)
20
- self.parse(user_agent)
21
- end
22
-
23
- def parse(user_agent)
21
+ def old_parse(user_agent)
24
22
  AgentOrange.debug "PLATFORM PARSING", 2
25
23
  groups = user_agent.scan(/([^\/[:space:]]*)(\/([^[:space:]]*))?([[:space:]]*\[[a-zA-Z][a-zA-Z]\])?[[:space:]]*(\((([^()]|(\([^()]*\)))*)\))?[[:space:]]*/i)
26
24
  groups.each_with_index do |pieces,i|
@@ -66,6 +64,36 @@ module AgentOrange
66
64
  AgentOrange.debug "", 2
67
65
  end
68
66
 
67
+ def parse(user_agent)
68
+ AgentOrange.debug "PLATFORM PARSING", 2
69
+
70
+ groups = parse_user_agent_string_into_groups(user_agent)
71
+ groups.each_with_index do |content,i|
72
+ if content[:comment] =~ /(#{PLATFORMS.collect{|cat,regex| regex}.join(')|(')})/i
73
+ # Matched group against name
74
+ self.populate(content)
75
+ end
76
+ end
77
+
78
+ self.analysis
79
+ end
80
+
81
+ def populate(content={})
82
+ self.debug_raw_content(content)
83
+ AgentOrange.debug "", 2
84
+
85
+ self.type = self.determine_type(PLATFORMS, content[:comment])
86
+ self.name = PLATFORM_NAMES[self.type.to_sym]
87
+ self.version = nil
88
+ self
89
+ end
90
+
91
+ def analysis
92
+ AgentOrange.debug "PLATFORM ANALYSIS", 2
93
+ self.debug_content(:type => self.type, :name => self.name, :version => self.version)
94
+ AgentOrange.debug "", 2
95
+ end
96
+
69
97
  def to_s
70
98
  [self.name, self.version].compact.join(' ')
71
99
  end
@@ -1,10 +1,11 @@
1
1
  module AgentOrange
2
- VERSION = "0.0.6" # This is for the gem and does not conflict with the rest of the functionality
2
+ VERSION = "0.0.7" # 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
6
6
 
7
7
  def initialize(version_string)
8
+ version_string = sanitize_version_string(version_string)
8
9
  self.major = nil
9
10
  self.minor = nil
10
11
  self.patch_level = nil
@@ -22,5 +23,11 @@ module AgentOrange
22
23
  def to_s
23
24
  [self.major, self.minor, self.patch_level, self.build_number].compact.join('.')
24
25
  end
26
+
27
+ private
28
+
29
+ def sanitize_version_string(version_string)
30
+ version_string.gsub('_','.')
31
+ end
25
32
  end
26
33
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: agent_orange
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 17
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 6
10
- version: 0.0.6
9
+ - 7
10
+ version: 0.0.7
11
11
  platform: ruby
12
12
  authors:
13
13
  - Kevin Elliott
@@ -35,6 +35,7 @@ files:
35
35
  - agent_orange.gemspec
36
36
  - bin/agent_orange_example
37
37
  - lib/agent_orange.rb
38
+ - lib/agent_orange/base.rb
38
39
  - lib/agent_orange/browser.rb
39
40
  - lib/agent_orange/device.rb
40
41
  - lib/agent_orange/engine.rb