friendlyfashion-useragent 0.6.1

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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 243721108c7e7564e6d19110948cd616f897fce3
4
+ data.tar.gz: 44dc0d098cc1353472584d9dccdfb901dcff93fa
5
+ SHA512:
6
+ metadata.gz: c6bde90e543a42106578c878c51dd69893b854ef03c37e013b210b4a2a9f7ca54f61eb1b926d7664430e938116724db48f3236a62a3f4fa0eac87f81a54ba209
7
+ data.tar.gz: 2fb2f050656b8101e726fe019e381ac7e5e5db6cfca7a32c825a3cee024559aa5f79b947e83ab11d35c66df57b61d477f59a246c7cff3464972b178fba311d74
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.
@@ -0,0 +1,35 @@
1
+ = UserAgent
2
+
3
+ UserAgent is a Ruby library that parses and compares HTTP User Agents.
4
+
5
+ === Installation
6
+
7
+ gem install useragent
8
+
9
+ === Examples
10
+
11
+ ==== Reporting
12
+
13
+ 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'
14
+ user_agent = UserAgent.parse(string)
15
+ user_agent.browser
16
+ # => 'Chrome'
17
+ user_agent.version
18
+ # => '19.0.1084.56'
19
+ user_agent.platform
20
+ # => 'Macintosh'
21
+
22
+ ==== Comparison
23
+
24
+ Browser = Struct.new(:browser, :version)
25
+ SupportedBrowsers = [
26
+ Browser.new("Safari", "3.1.1"),
27
+ Browser.new("Firefox", "2.0.0.14"),
28
+ Browser.new("Internet Explorer", "7.0")
29
+ ]
30
+
31
+ user_agent = UserAgent.parse(request.user_agent)
32
+ SupportedBrowsers.detect { |browser| user_agent >= browser }
33
+
34
+
35
+ Copyright (c) 2013 Joshua Peek, released under the MIT license
@@ -0,0 +1,89 @@
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
+ # http://www.texsoft.it/index.php?m=sw.php.useragent
8
+ MATCHER = %r{
9
+ ^([^/\s]+) # Product
10
+ /?([^\s]*) # Version
11
+ (\s\(([^\)]*)\))? # Comment
12
+ }x.freeze
13
+
14
+ DEFAULT_USER_AGENT = "Mozilla/4.0 (compatible)"
15
+
16
+ def self.parse(string)
17
+ if string.nil? || string == ""
18
+ string = DEFAULT_USER_AGENT
19
+ end
20
+
21
+ agents = []
22
+ while m = string.to_s.match(MATCHER)
23
+ agents << new(m[1], m[2], m[4])
24
+ string = string[m[0].length..-1].strip
25
+ end
26
+ Browsers.extend(agents)
27
+ agents
28
+ end
29
+
30
+ attr_reader :product, :version, :comment
31
+
32
+ def initialize(product, version = nil, comment = nil)
33
+ if product
34
+ @product = product
35
+ else
36
+ raise ArgumentError, "expected a value for product"
37
+ end
38
+
39
+ if version && !version.empty?
40
+ @version = Version.new(version)
41
+ else
42
+ @version = nil
43
+ end
44
+
45
+ if comment.respond_to?(:split)
46
+ @comment = comment.split("; ")
47
+ else
48
+ @comment = comment
49
+ end
50
+ end
51
+
52
+ include Comparable
53
+
54
+ # Any comparsion between two user agents with different products will
55
+ # always return false.
56
+ def <=>(other)
57
+ if @product == other.product
58
+ if @version && other.version
59
+ @version <=> other.version
60
+ else
61
+ 0
62
+ end
63
+ else
64
+ false
65
+ end
66
+ end
67
+
68
+ def eql?(other)
69
+ @product == other.product &&
70
+ @version == other.version &&
71
+ @comment == other.comment
72
+ end
73
+
74
+ def to_s
75
+ to_str
76
+ end
77
+
78
+ def to_str
79
+ if @product && @version && @comment
80
+ "#{@product}/#{@version} (#{@comment.join("; ")})"
81
+ elsif @product && @version
82
+ "#{@product}/#{@version}"
83
+ elsif @product && @comment
84
+ "#{@product} (#{@comment.join("; ")})"
85
+ else
86
+ @product
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,26 @@
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.all
16
+ [InternetExplorer, Webkit, Opera, Gecko]
17
+ end
18
+
19
+ def self.extend(array)
20
+ array.extend(All)
21
+ all.each do |extension|
22
+ return array.extend(extension) if extension.extend?(array)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,112 @@
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 os =~ /Opera Mini/
69
+ true
70
+ elsif os =~ /BlackBerry/
71
+ true
72
+ elsif browser =~ /Nokia/
73
+ true
74
+ elsif application && application.comment &&
75
+ application.comment.detect { |k, v| k =~ /^IEMobile/ }
76
+ true
77
+ else
78
+ false
79
+ end
80
+ end
81
+
82
+ def bot?
83
+ # If UA has no application type, its probably generated by a
84
+ # shitty bot.
85
+ if application.nil?
86
+ true
87
+
88
+ # Match common case when bots refer to themselves as bots in
89
+ # the application comment. There are no standards for how bots
90
+ # should call themselves so its not an exhaustive method.
91
+ #
92
+ # If you want to expand the scope, override the method and
93
+ # provide your own regexp. Any patches to future extend this
94
+ # list will be rejected.
95
+ elsif comment = application.comment
96
+ comment.any? { |c| c =~ /bot/i }
97
+ else
98
+ false
99
+ end
100
+ end
101
+
102
+ private
103
+ def detect_product(product)
104
+ detect { |useragent| useragent.product.to_s.downcase == product.to_s.downcase }
105
+ end
106
+
107
+ def detect_comment(comment)
108
+ detect { |useragent| useragent.comment && useragent.comment.include?(comment) }
109
+ end
110
+ end
111
+ end
112
+ 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,41 @@
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) || detect_blackberry(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
+
33
+ def self.detect_blackberry(os)
34
+ if os =~ /BlackBerry/ || os =~ /RIM Tablet/
35
+ "BlackBerry"
36
+ else
37
+ nil
38
+ end
39
+ end
40
+ end
41
+ 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
@@ -0,0 +1 @@
1
+ require 'user_agent'
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: friendlyfashion-useragent
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.6.1
5
+ platform: ruby
6
+ authors:
7
+ - Joshua Peek, Edvinas Bartkus, Andrius Janauskas
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-05-03 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: andrius.janauskas@gmail.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/josh/useragent
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.3
82
+ signing_key:
83
+ specification_version: 4
84
+ summary: HTTP User Agent parser
85
+ test_files: []