delano-useragent 0.0.2

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,20 @@
1
+ Copyright (c) 2008 Joshua Peek
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,21 @@
1
+ UserAgent
2
+ =========
3
+
4
+ UserAgent is a Ruby library that parses and compares HTTP User Agents.
5
+
6
+
7
+ Example
8
+ =======
9
+
10
+ Browser = Struct.new(:browser, :version)
11
+ SupportedBrowsers = [
12
+ Browser.new("Safari", "3.1.1"),
13
+ Browser.new("Firefox", "2.0.0.14"),
14
+ Browser.new("Internet Explorer", "7.0")
15
+ ]
16
+
17
+ user_agent = UserAgent.parse(request.user_agent)
18
+ SupportedBrowsers.detect { |browser| user_agent >= browser }
19
+
20
+
21
+ Copyright (c) 2008 Joshua Peek, released under the MIT license
@@ -0,0 +1,83 @@
1
+ require "#{File.dirname(__FILE__)}/user_agent/comparable"
2
+ require "#{File.dirname(__FILE__)}/user_agent/browsers"
3
+ require "#{File.dirname(__FILE__)}/user_agent/operating_systems"
4
+
5
+ class UserAgent
6
+ # http://www.texsoft.it/index.php?m=sw.php.useragent
7
+ MATCHER = %r{
8
+ ^([^/\s]+) # Product
9
+ /?([^\s]*) # Version
10
+ (\s\(([^\)]*)\))? # Comment
11
+ }x.freeze unless defined? MATCHER
12
+
13
+ def self.parse(string)
14
+ agents = []
15
+ while m = string.match(MATCHER)
16
+ agent = new(m[1], m[2], m[4], string)
17
+ agents << agent
18
+ string = string.sub(agent.to_s, '').strip
19
+ end
20
+ Browsers.extend(agents)
21
+ agents
22
+ end
23
+
24
+ attr_accessor :product, :version, :comment, :original
25
+
26
+ def initialize(product, version = nil, comment = nil, original = nil)
27
+ if product
28
+ @product = product
29
+ else
30
+ raise ArgumentError, "expected a value for product"
31
+ end
32
+
33
+ if version && version.any?
34
+ @version = version
35
+ end
36
+
37
+ if comment.respond_to?(:split)
38
+ @comment = comment.split("; ")
39
+ else
40
+ @comment = comment
41
+ end
42
+
43
+ @original = original
44
+ end
45
+
46
+ include Comparable
47
+
48
+ # Any comparsion between two user agents with different products will
49
+ # always return false.
50
+ def <=>(other)
51
+ if @product == other.product
52
+ if @version && other.version
53
+ @version <=> other.version
54
+ else
55
+ 0
56
+ end
57
+ else
58
+ false
59
+ end
60
+ end
61
+
62
+ def eql?(other)
63
+ @product == other.product &&
64
+ @version == other.version &&
65
+ @comment == other.comment
66
+ end
67
+
68
+ def to_s
69
+ to_str
70
+ end
71
+
72
+ def to_str
73
+ if @product && @version && @comment
74
+ "#{@product}/#{@version} (#{@comment.join("; ")})"
75
+ elsif @product && @version
76
+ "#{@product}/#{@version}"
77
+ elsif @product && @comment
78
+ "#{@product} (#{@comment.join("; ")})"
79
+ else
80
+ @product
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,24 @@
1
+ Dir["#{File.dirname(__FILE__)}/browsers/*.rb"].each do |browser|
2
+ require browser
3
+ end
4
+
5
+ class UserAgent
6
+ module Browsers
7
+ Security = {
8
+ "N" => :none,
9
+ "U" => :strong,
10
+ "I" => :weak
11
+ }.freeze unless defined? Security
12
+
13
+ def self.all
14
+ [InternetExplorer, Webkit, Opera, Gecko]
15
+ end
16
+
17
+ def self.extend(array)
18
+ array.extend(All)
19
+ all.each do |extension|
20
+ return array.extend(extension) if extension.extend?(array)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,69 @@
1
+ class UserAgent
2
+ module Browsers
3
+ module All
4
+ include Comparable
5
+
6
+ def <=>(other)
7
+ if respond_to?(:browser) && other.respond_to?(:browser) &&
8
+ browser == other.browser
9
+ version <=> other.version
10
+ else
11
+ false
12
+ end
13
+ end
14
+
15
+ def eql?(other)
16
+ self == other
17
+ end
18
+
19
+ def to_s
20
+ to_str
21
+ end
22
+
23
+ def to_str
24
+ join(" ")
25
+ end
26
+
27
+ def application
28
+ first
29
+ end
30
+
31
+ def browser
32
+ application.product
33
+ end
34
+
35
+ def platform
36
+ "Unknown"
37
+ end
38
+
39
+ def os
40
+ "Unknown"
41
+ end
42
+
43
+ def version=(v)
44
+ application.version = v
45
+ end
46
+
47
+ def original
48
+ application.original
49
+ end
50
+
51
+ def version
52
+ application.version
53
+ end
54
+
55
+ def respond_to?(symbol)
56
+ detect_product(symbol) ? true : super
57
+ end
58
+
59
+ def method_missing(method, *args, &block)
60
+ detect_product(method) || super
61
+ end
62
+
63
+ private
64
+ def detect_product(product)
65
+ detect { |useragent| useragent.product.to_s.downcase == product.to_s.downcase }
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,43 @@
1
+ class UserAgent
2
+ module Browsers
3
+ module Gecko
4
+ def self.extend?(agent)
5
+ agent.application && agent.application.product == "Mozilla"
6
+ end
7
+
8
+ GeckoBrowsers = %w(
9
+ Firefox
10
+ Camino
11
+ ).freeze unless defined? GeckoBrowsers
12
+
13
+ def browser
14
+ GeckoBrowsers.detect { |browser| respond_to?(browser) } || super
15
+ end
16
+
17
+ def version
18
+ send(browser).version || super
19
+ end
20
+
21
+
22
+ def version=(v)
23
+ send(browser).version = v
24
+ end
25
+
26
+ def platform
27
+ application.comment[0]
28
+ end
29
+
30
+ def security
31
+ Security[application.comment[1]]
32
+ end
33
+
34
+ def os
35
+ OperatingSystems.normalize_os(application.comment[2])
36
+ end
37
+
38
+ def localization
39
+ application.comment[3]
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,40 @@
1
+ class UserAgent
2
+ module Browsers
3
+ module InternetExplorer
4
+ def self.extend?(agent)
5
+ agent.application &&
6
+ agent.application.comment &&
7
+ agent.application.comment[0] == "compatible" &&
8
+ agent.application.comment[1].match(/^MSIE/)
9
+ end
10
+
11
+ def browser
12
+ "Internet Explorer"
13
+ end
14
+
15
+ def version=(v)
16
+ application.comment[1] = "MSIE #{v}"
17
+ end
18
+
19
+ def version
20
+ application.comment[1].sub("MSIE ", "")
21
+ end
22
+
23
+ def compatibility
24
+ application.comment[0]
25
+ end
26
+
27
+ def compatible?
28
+ compatibility == "compatible"
29
+ end
30
+
31
+ def platform
32
+ "Windows"
33
+ end
34
+
35
+ def os
36
+ OperatingSystems.normalize_os(application.comment[2])
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,49 @@
1
+ class UserAgent
2
+ module Browsers
3
+ module Opera
4
+ def self.extend?(agent)
5
+ agent.application && agent.application.product == "Opera"
6
+ end
7
+
8
+ def platform
9
+ if application.comment[0] =~ /Windows/
10
+ "Windows"
11
+ else
12
+ application.comment[0]
13
+ end
14
+ end
15
+
16
+ def security
17
+ if platform == "Macintosh"
18
+ Security[application.comment[2]]
19
+ else
20
+ Security[application.comment[1]]
21
+ end
22
+ end
23
+
24
+ def version
25
+ application.version
26
+ end
27
+
28
+ def version=(v)
29
+ application.version = v
30
+ end
31
+
32
+ def os
33
+ if application.comment[0] =~ /Windows/
34
+ OperatingSystems.normalize_os(application.comment[0])
35
+ else
36
+ application.comment[1]
37
+ end
38
+ end
39
+
40
+ def localization
41
+ if platform == "Macintosh"
42
+ application.comment[3]
43
+ else
44
+ application.comment[2]
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,94 @@
1
+ class UserAgent
2
+ module Browsers
3
+ module Webkit
4
+ def self.extend?(agent)
5
+ agent.detect { |useragent| useragent.product == "Safari" }
6
+ end
7
+
8
+ def browser
9
+ if detect_product("Chrome")
10
+ "Chrome"
11
+ else
12
+ "Safari"
13
+ end
14
+ end
15
+
16
+ def build
17
+ safari.version
18
+ end
19
+
20
+ # TODO: Complete this mapping
21
+ # See: http://www.useragentstring.com/pages/Safari/
22
+ BuildVersions = {
23
+ "125.12" => "1.2.4",
24
+ "312.6" => "1.3.2",
25
+ "412.2.2" => "2.0",
26
+ "412.5" => "2.0.1",
27
+ "416.13" => "2.0.2",
28
+ "417.9.3" => "2.0.3",
29
+ "525.13" => "2.2",
30
+ "522.11.3" => "3.0",
31
+ "523.15" => "3.0",
32
+ "523.12.9" => "3.0",
33
+ "522.12.2" => "3.0.1",
34
+ "522.13.1" => "3.0.2",
35
+ "522.15.5" => "3.0.3",
36
+ "523.10" => "3.0.4",
37
+ "523.15" => "3.0.4",
38
+ "523.12" => "3.0.4",
39
+ "523.12.2" => "3.0.4",
40
+ "525.13" => "3.1",
41
+ "525.13.3" => "3.1",
42
+ "525.9" => "3.1",
43
+ "525.17" => "3.1.1",
44
+ "525.9" => "3.1.1",
45
+ "525.20" => "3.1.1",
46
+ "525.18" => "3.1.1",
47
+ "525.21" => "3.1.2",
48
+ "525.26.13" => "3.2",
49
+ "525.26.12" => "3.2",
50
+ "528.1" => "4.0"
51
+
52
+ }.freeze unless defined? BuildVersions
53
+
54
+ # Prior to Safari 3, the user agent did not include a version number
55
+ def version
56
+ if browser == "Chrome"
57
+ chrome.version
58
+ elsif product = detect_product("Version")
59
+ product.version
60
+ else
61
+ BuildVersions[build]
62
+ end
63
+ end
64
+
65
+ def version=(v)
66
+ if browser == "Chrome"
67
+ chrome.version = v
68
+ elsif product = detect_product("Version")
69
+ product.version = v
70
+ end
71
+ end
72
+
73
+ def platform
74
+ application.comment[0]
75
+ end
76
+
77
+ def webkit
78
+ detect { |useragent| useragent.product == "AppleWebKit" }
79
+ end
80
+
81
+ def security
82
+ Security[application.comment[1]]
83
+ end
84
+
85
+ def os
86
+ OperatingSystems.normalize_os(application.comment[2])
87
+ end
88
+
89
+ def localization
90
+ application.comment[3]
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,25 @@
1
+ class UserAgent
2
+ # A custom Comparable module that will always return false
3
+ # if the <=> returns false
4
+ module Comparable
5
+ def <(other)
6
+ (c = self <=> other) ? c == -1 : false
7
+ end
8
+
9
+ def <=(other)
10
+ (c = self <=> other) ? c == -1 || c == 0 : false
11
+ end
12
+
13
+ def ==(other)
14
+ (c = self <=> other) ? c == 0 : false
15
+ end
16
+
17
+ def >(other)
18
+ (c = self <=> other) ? c == 1 : false
19
+ end
20
+
21
+ def >=(other)
22
+ (c = self <=> other) ? c == 1 || c == 0 : false
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,19 @@
1
+ class UserAgent
2
+ module OperatingSystems
3
+ Windows = {
4
+ "Windows NT 6.0" => "Windows Vista",
5
+ "Windows NT 5.2" => "Windows XP x64 Edition",
6
+ "Windows NT 5.1" => "Windows XP",
7
+ "Windows NT 5.01" => "Windows 2000, Service Pack 1 (SP1)",
8
+ "Windows NT 5.0" => "Windows 2000",
9
+ "Windows NT 4.0" => "Windows NT 4.0",
10
+ "Windows 98" => "Windows 98",
11
+ "Windows 95" => "Windows 95",
12
+ "Windows CE" => "Windows CE"
13
+ }.freeze unless defined? Windows
14
+
15
+ def self.normalize_os(os)
16
+ Windows[os] || os
17
+ end
18
+ end
19
+ end
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: delano-useragent
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Joshua Peek
8
+ - Delano Mandelbaum
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2008-07-27 00:00:00 -07:00
14
+ default_executable:
15
+ dependencies: []
16
+
17
+ description: UserAgent is a Ruby library that parses and compares HTTP User Agents. This is a fork from josh-useragent with fixes for Stella (http://github.com/solutious/stella).
18
+ email: delano@solutious.com
19
+ executables: []
20
+
21
+ extensions: []
22
+
23
+ extra_rdoc_files: []
24
+
25
+ files:
26
+ - README
27
+ - MIT-LICENSE
28
+ - lib/user_agent
29
+ - lib/user_agent/browsers.rb
30
+ - lib/user_agent/operating_systems.rb
31
+ - lib/user_agent/comparable.rb
32
+ - lib/user_agent/browsers
33
+ - lib/user_agent/browsers/webkit.rb
34
+ - lib/user_agent/browsers/gecko.rb
35
+ - lib/user_agent/browsers/internet_explorer.rb
36
+ - lib/user_agent/browsers/all.rb
37
+ - lib/user_agent/browsers/opera.rb
38
+ - lib/user_agent.rb
39
+ has_rdoc: false
40
+ homepage: http://github.com/delano/useragent
41
+ post_install_message:
42
+ rdoc_options: []
43
+
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: "0"
51
+ version:
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ requirements: []
59
+
60
+ rubyforge_project:
61
+ rubygems_version: 1.2.0
62
+ signing_key:
63
+ specification_version: 2
64
+ summary: HTTP User Agent parser
65
+ test_files: []
66
+