useragent-no-extends 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d48b50d3a1469dc8126b326ce8eefbbfc86a5867
4
+ data.tar.gz: 2f59350ea745b69a399085e3adc049987ea7c392
5
+ SHA512:
6
+ metadata.gz: f94b8d409b9580fa551d774f8aa43916602d38c25c195d7a2558b798bf1f8d7f86b2ce3e2dcbbf34bed0fa4828d00f88b1de63d0c0afb72b13db5999ba49cc62
7
+ data.tar.gz: 294e86a5068a9fd25a0ecbc9066337112bd8b647bb3e3ef6d3e1aaf4bbf6395acece7263b550ab621bf6b97a532980ded9c66616ed110c2975624e64cb13f3f1
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013 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.rdoc ADDED
@@ -0,0 +1,37 @@
1
+ = UserAgent
2
+
3
+ UserAgent is a Ruby library that parses and compares HTTP User Agents.
4
+
5
+ This fork removes all of the class extends and replaces them with subclass includes. This results in a performance improvement that is noticed when calling .parse tens of thousands of times.
6
+
7
+ === Installation
8
+
9
+ gem install useragent-no-extends
10
+
11
+ === Examples
12
+
13
+ ==== Reporting
14
+
15
+ string = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.56 Safari/536.5'
16
+ user_agent = UserAgent.parse(string)
17
+ user_agent.browser
18
+ # => 'Chrome'
19
+ user_agent.version
20
+ # => '19.0.1084.56'
21
+ user_agent.platform
22
+ # => 'Macintosh'
23
+
24
+ ==== Comparison
25
+
26
+ Browser = Struct.new(:browser, :version)
27
+ SupportedBrowsers = [
28
+ Browser.new("Safari", "3.1.1"),
29
+ Browser.new("Firefox", "2.0.0.14"),
30
+ Browser.new("Internet Explorer", "7.0")
31
+ ]
32
+
33
+ user_agent = UserAgent.parse(request.user_agent)
34
+ SupportedBrowsers.detect { |browser| user_agent >= browser }
35
+
36
+
37
+ Copyright (c) 2013 Joshua Peek, released under the MIT license
data/lib/user_agent.rb ADDED
@@ -0,0 +1,90 @@
1
+ require 'user_agent/comparable'
2
+ require 'user_agent/browsers'
3
+ require 'user_agent/operating_systems'
4
+ require 'user_agent/version'
5
+
6
+ class UserAgent
7
+
8
+ # http://www.texsoft.it/index.php?m=sw.php.useragent
9
+ MATCHER = %r{
10
+ ^([^/\s]+) # Product
11
+ /?([^\s]*) # Version
12
+ (\s\(([^\)]*)\))? # Comment
13
+ }x.freeze
14
+
15
+ DEFAULT_USER_AGENT = "Mozilla/4.0 (compatible)"
16
+
17
+ def self.parse(string)
18
+ if string.nil? || string == ""
19
+ string = DEFAULT_USER_AGENT
20
+ end
21
+
22
+ agents = BrowserArray.new
23
+ while m = string.to_s.match(MATCHER)
24
+ agents << new(m[1], m[2], m[4])
25
+ string = string[m[0].length..-1].strip
26
+ end
27
+ agents = Browsers.extend(agents)
28
+ agents
29
+ end
30
+
31
+ attr_reader :product, :version, :comment
32
+
33
+ def initialize(product, version = nil, comment = nil)
34
+ if product
35
+ @product = product
36
+ else
37
+ raise ArgumentError, "expected a value for product"
38
+ end
39
+
40
+ if version && !version.empty?
41
+ @version = Version.new(version)
42
+ else
43
+ @version = nil
44
+ end
45
+
46
+ if comment.respond_to?(:split)
47
+ @comment = comment.split("; ")
48
+ else
49
+ @comment = comment
50
+ end
51
+ end
52
+
53
+ include Comparable
54
+
55
+ # Any comparsion between two user agents with different products will
56
+ # always return false.
57
+ def <=>(other)
58
+ if @product == other.product
59
+ if @version && other.version
60
+ @version <=> other.version
61
+ else
62
+ 0
63
+ end
64
+ else
65
+ false
66
+ end
67
+ end
68
+
69
+ def eql?(other)
70
+ @product == other.product &&
71
+ @version == other.version &&
72
+ @comment == other.comment
73
+ end
74
+
75
+ def to_s
76
+ to_str
77
+ end
78
+
79
+ def to_str
80
+ if @product && @version && @comment
81
+ "#{@product}/#{@version} (#{@comment.join("; ")})"
82
+ elsif @product && @version
83
+ "#{@product}/#{@version}"
84
+ elsif @product && @comment
85
+ "#{@product} (#{@comment.join("; ")})"
86
+ else
87
+ @product
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,45 @@
1
+ require 'user_agent/browsers/all'
2
+ require 'user_agent/browsers/gecko'
3
+ require 'user_agent/browsers/internet_explorer'
4
+ require 'user_agent/browsers/opera'
5
+ require 'user_agent/browsers/webkit'
6
+
7
+ class UserAgent
8
+ module Browsers
9
+ Security = {
10
+ "N" => :none,
11
+ "U" => :strong,
12
+ "I" => :weak
13
+ }.freeze
14
+
15
+ def self.extend(array)
16
+
17
+ return InternetExplorerBrowsers.new(array) if InternetExplorer.extend?(array)
18
+ return WebkitBrowsers.new(array) if Webkit.extend?(array)
19
+ return OperaBrowsers.new(array) if Opera.extend?(array)
20
+ return GeckoBrowsers.new(array) if Gecko.extend?(array)
21
+ return array
22
+
23
+ end
24
+ end
25
+
26
+ class BrowserArray < Array
27
+ include Browsers::All
28
+ end
29
+
30
+ class WebkitBrowsers < BrowserArray
31
+ include Browsers::Webkit
32
+ end
33
+
34
+ class InternetExplorerBrowsers < BrowserArray
35
+ include Browsers::InternetExplorer
36
+ end
37
+
38
+ class OperaBrowsers < BrowserArray
39
+ include Browsers::Opera
40
+ end
41
+
42
+ class GeckoBrowsers < BrowserArray
43
+ include Browsers::Gecko
44
+ end
45
+ end
@@ -0,0 +1,106 @@
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 <=> Version.new(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 && application.product
33
+ end
34
+
35
+ def version
36
+ application && application.version
37
+ end
38
+
39
+ def platform
40
+ nil
41
+ end
42
+
43
+ def os
44
+ nil
45
+ end
46
+
47
+ def respond_to?(symbol)
48
+ detect_product(symbol) ? true : super
49
+ end
50
+
51
+ def method_missing(method, *args, &block)
52
+ detect_product(method) || super
53
+ end
54
+
55
+ def webkit?
56
+ false
57
+ end
58
+
59
+ def mobile?
60
+ if browser == 'webOS'
61
+ true
62
+ elsif platform == 'Symbian'
63
+ true
64
+ elsif detect_product('Mobile') || detect_comment('Mobile')
65
+ true
66
+ elsif os =~ /Android/
67
+ true
68
+ elsif application && application.comment &&
69
+ application.comment.detect { |k, v| k =~ /^IEMobile/ }
70
+ true
71
+ else
72
+ false
73
+ end
74
+ end
75
+
76
+ def bot?
77
+ # If UA has no application type, its probably generated by a
78
+ # shitty bot.
79
+ if application.nil?
80
+ true
81
+
82
+ # Match common case when bots refer to themselves as bots in
83
+ # the application comment. There are no standards for how bots
84
+ # should call themselves so its not an exhaustive method.
85
+ #
86
+ # If you want to expand the scope, override the method and
87
+ # provide your own regexp. Any patches to future extend this
88
+ # list will be rejected.
89
+ elsif comment = application.comment
90
+ comment.any? { |c| c =~ /bot/i }
91
+ else
92
+ false
93
+ end
94
+ end
95
+
96
+ private
97
+ def detect_product(product)
98
+ detect { |useragent| useragent.product.to_s.downcase == product.to_s.downcase }
99
+ end
100
+
101
+ def detect_comment(comment)
102
+ detect { |useragent| useragent.comment && useragent.comment.include?(comment) }
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,60 @@
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
+ Iceweasel
12
+ Seamonkey
13
+ ).freeze
14
+
15
+ def browser
16
+ GeckoBrowsers.detect { |browser| respond_to?(browser) } || super
17
+ end
18
+
19
+ def version
20
+ send(browser).version || super
21
+ end
22
+
23
+ def platform
24
+ if comment = application.comment
25
+ if comment[0] == 'compatible'
26
+ nil
27
+ elsif /^Windows / =~ comment[0]
28
+ 'Windows'
29
+ else
30
+ comment[0]
31
+ end
32
+ end
33
+ end
34
+
35
+ def security
36
+ Security[application.comment[1]] || :strong
37
+ end
38
+
39
+ def os
40
+ if comment = application.comment
41
+ i = if comment[1] == 'U'
42
+ 2
43
+ elsif /^Windows / =~ comment[0]
44
+ 0
45
+ else
46
+ 1
47
+ end
48
+
49
+ OperatingSystems.normalize_os(comment[i])
50
+ end
51
+ end
52
+
53
+ def localization
54
+ if comment = application.comment
55
+ comment[3]
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,50 @@
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] =~ /MSIE/
9
+ end
10
+
11
+ def browser
12
+ "Internet Explorer"
13
+ end
14
+
15
+ def version
16
+ Version.new(application.comment[1].sub("MSIE ", ""))
17
+ end
18
+
19
+ def compatibility
20
+ application.comment[0]
21
+ end
22
+
23
+ def compatible?
24
+ compatibility == "compatible"
25
+ end
26
+
27
+ def compatibility_view?
28
+ version == "7.0" && application.comment.detect { |c| c['Trident/'] }
29
+ end
30
+
31
+ # Before version 4.0, Chrome Frame declared itself (unversioned) in a comment;
32
+ # as of 4.0 it can declare itself versioned in a comment
33
+ # or as a separate product with a version
34
+ def chromeframe
35
+ cf = application.comment.include?("chromeframe") || detect_product("chromeframe")
36
+ return cf if cf
37
+ cf_comment = application.comment.detect { |c| c['chromeframe/'] }
38
+ cf_comment ? UserAgent.new(*cf_comment.split('/', 2)) : nil
39
+ end
40
+
41
+ def platform
42
+ "Windows"
43
+ end
44
+
45
+ def os
46
+ OperatingSystems.normalize_os(application.comment[2])
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,57 @@
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 version
9
+ if product = detect_product('Version')
10
+ product.version
11
+ else
12
+ super
13
+ end
14
+ end
15
+
16
+ def platform
17
+ if application.comment.nil?
18
+ nil
19
+ elsif application.comment[0] =~ /Windows/
20
+ "Windows"
21
+ else
22
+ application.comment[0]
23
+ end
24
+ end
25
+
26
+ def security
27
+ if application.comment.nil?
28
+ :strong
29
+ elsif platform == "Macintosh"
30
+ Security[application.comment[2]]
31
+ else
32
+ Security[application.comment[1]]
33
+ end
34
+ end
35
+
36
+ def os
37
+ if application.comment.nil?
38
+ nil
39
+ elsif application.comment[0] =~ /Windows/
40
+ OperatingSystems.normalize_os(application.comment[0])
41
+ else
42
+ application.comment[1]
43
+ end
44
+ end
45
+
46
+ def localization
47
+ if application.comment.nil?
48
+ nil
49
+ elsif platform == "Macintosh"
50
+ application.comment[3]
51
+ else
52
+ application.comment[2]
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,135 @@
1
+ class UserAgent
2
+ module Browsers
3
+ module Webkit
4
+ def self.extend?(agent)
5
+ agent.detect { |useragent| useragent.product == 'AppleWebKit' }
6
+ end
7
+
8
+ def webkit?
9
+ true
10
+ end
11
+
12
+ def browser
13
+ if detect_product('Chrome')
14
+ 'Chrome'
15
+ elsif os =~ /Android/
16
+ 'Android'
17
+ elsif platform == 'webOS' || platform == 'BlackBerry' || platform == 'Symbian'
18
+ platform
19
+ else
20
+ 'Safari'
21
+ end
22
+ end
23
+
24
+ def build
25
+ webkit.version
26
+ end
27
+
28
+ BuildVersions = {
29
+ "85.7" => "1.0",
30
+ "85.8.5" => "1.0.3",
31
+ "85.8.2" => "1.0.3",
32
+ "124" => "1.2",
33
+ "125.2" => "1.2.2",
34
+ "125.4" => "1.2.3",
35
+ "125.5.5" => "1.2.4",
36
+ "125.5.6" => "1.2.4",
37
+ "125.5.7" => "1.2.4",
38
+ "312.1.1" => "1.3",
39
+ "312.1" => "1.3",
40
+ "312.5" => "1.3.1",
41
+ "312.5.1" => "1.3.1",
42
+ "312.5.2" => "1.3.1",
43
+ "312.8" => "1.3.2",
44
+ "312.8.1" => "1.3.2",
45
+ "412" => "2.0",
46
+ "412.6" => "2.0",
47
+ "412.6.2" => "2.0",
48
+ "412.7" => "2.0.1",
49
+ "416.11" => "2.0.2",
50
+ "416.12" => "2.0.2",
51
+ "417.9" => "2.0.3",
52
+ "418" => "2.0.3",
53
+ "418.8" => "2.0.4",
54
+ "418.9" => "2.0.4",
55
+ "418.9.1" => "2.0.4",
56
+ "419" => "2.0.4",
57
+ "425.13" => "2.2",
58
+ "534.52.7" => "5.1.2"
59
+ }.freeze
60
+
61
+ # Prior to Safari 3, the user agent did not include a version number
62
+ def version
63
+ str = if os =~ /CPU (?:iPhone |iPod )?OS ([\d_]+) like Mac OS X/
64
+ $1.gsub(/_/, '.')
65
+ elsif product = detect_product('Version')
66
+ product.version
67
+ elsif browser == 'Chrome'
68
+ chrome.version
69
+ else
70
+ BuildVersions[build.to_s]
71
+ end
72
+
73
+ Version.new(str) if str
74
+ end
75
+
76
+ def application
77
+ self.reject { |agent| agent.comment.nil? || agent.comment.empty? }.first
78
+ end
79
+
80
+ def platform
81
+ if application.nil?
82
+ nil
83
+ elsif application.comment[0] =~ /Symbian/
84
+ 'Symbian'
85
+ elsif application.comment[0] =~ /webOS/
86
+ 'webOS'
87
+ elsif application.comment[0] =~ /Windows/
88
+ 'Windows'
89
+ elsif application.comment[0] == 'BB10'
90
+ 'BlackBerry'
91
+ else
92
+ application.comment[0]
93
+ end
94
+ end
95
+
96
+ def webkit
97
+ detect { |useragent| useragent.product == "AppleWebKit" }
98
+ end
99
+
100
+ def security
101
+ Security[application.comment[1]]
102
+ end
103
+
104
+ def os
105
+ if platform == 'webOS'
106
+ "Palm #{last.product} #{last.version}"
107
+ elsif platform == 'Symbian'
108
+ application.comment[0]
109
+ elsif application
110
+ if application.comment[0] =~ /Windows NT/
111
+ OperatingSystems.normalize_os(application.comment[0])
112
+ elsif application.comment[2].nil?
113
+ OperatingSystems.normalize_os(application.comment[1])
114
+ elsif application.comment[1] =~ /Android/
115
+ OperatingSystems.normalize_os(application.comment[1])
116
+ else
117
+ OperatingSystems.normalize_os(application.comment[2])
118
+ end
119
+ else
120
+ nil
121
+ end
122
+ end
123
+
124
+ def localization
125
+ if application.nil?
126
+ nil
127
+ elsif platform == 'webOS'
128
+ application.comment[2]
129
+ else
130
+ application.comment[3]
131
+ end
132
+ end
133
+ end
134
+ end
135
+ 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,33 @@
1
+ class UserAgent
2
+ module OperatingSystems
3
+ Windows = {
4
+ "Windows NT 6.2" => "Windows 8",
5
+ "Windows NT 6.1" => "Windows 7",
6
+ "Windows NT 6.0" => "Windows Vista",
7
+ "Windows NT 5.2" => "Windows XP x64 Edition",
8
+ "Windows NT 5.1" => "Windows XP",
9
+ "Windows NT 5.01" => "Windows 2000, Service Pack 1 (SP1)",
10
+ "Windows NT 5.0" => "Windows 2000",
11
+ "Windows NT 4.0" => "Windows NT 4.0",
12
+ "Windows 98" => "Windows 98",
13
+ "Windows 95" => "Windows 95",
14
+ "Windows CE" => "Windows CE"
15
+ }.freeze
16
+
17
+ def self.normalize_os(os)
18
+ Windows[os] || normalize_mac_os_x(os) || os
19
+ end
20
+
21
+ private
22
+ def self.normalize_mac_os_x(os)
23
+ if os =~ /(?:Intel|PPC) Mac OS X\s*([0-9_\.]+)?/
24
+ if $1.nil?
25
+ "OS X"
26
+ else
27
+ version = $1.gsub('_', '.')
28
+ "OS X #{version}"
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,90 @@
1
+ class UserAgent
2
+ class Version
3
+ include ::Comparable
4
+
5
+ def self.new(obj)
6
+ case obj
7
+ when Version
8
+ obj
9
+ when String
10
+ super
11
+ else
12
+ raise ArgumentError, "invalid value for Version: #{obj.inspect}"
13
+ end
14
+ end
15
+
16
+ def initialize(str)
17
+ @str = str
18
+
19
+ if str =~ /^\d+$/ || str =~ /^\d+\./
20
+ @sequences = str.scan(/\d+|[A-Za-z][0-9A-Za-z-]*$/).map { |s| s =~ /^\d+$/ ? s.to_i : s }
21
+ @comparable = true
22
+ else
23
+ @sequences = [str]
24
+ @comparable = false
25
+ end
26
+ end
27
+
28
+ def to_a
29
+ @sequences.dup
30
+ end
31
+
32
+ def to_str
33
+ @str.dup
34
+ end
35
+
36
+ def eql?(other)
37
+ other.is_a?(self.class) && to_s == other.to_s
38
+ end
39
+
40
+ def ==(other)
41
+ case other
42
+ when Version
43
+ eql?(other)
44
+ when String
45
+ eql?(self.class.new(other))
46
+ else
47
+ false
48
+ end
49
+ end
50
+
51
+ def <=>(other)
52
+ case other
53
+ when Version
54
+ if @comparable
55
+ ([0]*6).zip(to_a, other.to_a).each do |dump, a, b|
56
+ a ||= 0
57
+ b ||= 0
58
+
59
+ if a.is_a?(String) && b.is_a?(Integer)
60
+ return -1
61
+ elsif a.is_a?(Integer) && b.is_a?(String)
62
+ return 1
63
+ elsif a == b
64
+ next
65
+ else
66
+ return a <=> b
67
+ end
68
+ end
69
+ 0
70
+ elsif to_s == other.to_s
71
+ return 0
72
+ else
73
+ return -1
74
+ end
75
+ when String
76
+ self <=> self.class.new(other)
77
+ else
78
+ nil
79
+ end
80
+ end
81
+
82
+ def to_s
83
+ to_str
84
+ end
85
+
86
+ def inspect
87
+ "#<#{self.class} #{to_s}>"
88
+ end
89
+ end
90
+ end
data/lib/useragent.rb ADDED
@@ -0,0 +1 @@
1
+ require 'user_agent'
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: useragent-no-extends
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.6.1
5
+ platform: ruby
6
+ authors:
7
+ - Joshua Peek
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-08-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: ! ' HTTP User Agent parser
42
+
43
+ '
44
+ email: josh@joshpeek.com
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - lib/user_agent.rb
50
+ - lib/user_agent/browsers.rb
51
+ - lib/user_agent/browsers/all.rb
52
+ - lib/user_agent/browsers/gecko.rb
53
+ - lib/user_agent/browsers/internet_explorer.rb
54
+ - lib/user_agent/browsers/opera.rb
55
+ - lib/user_agent/browsers/webkit.rb
56
+ - lib/user_agent/comparable.rb
57
+ - lib/user_agent/operating_systems.rb
58
+ - lib/user_agent/version.rb
59
+ - lib/useragent.rb
60
+ - LICENSE
61
+ - README.rdoc
62
+ homepage: http://github.com/jpwinans/useragent-no-extends
63
+ licenses: []
64
+ metadata: {}
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ! '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubyforge_project:
81
+ rubygems_version: 2.0.7
82
+ signing_key:
83
+ specification_version: 4
84
+ summary: HTTP User Agent parser without extends
85
+ test_files: []