user_agent_parser 0.1.0
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.
Potentially problematic release.
This version of user_agent_parser might be problematic. Click here for more details.
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'user_agent_parser/parser'
|
2
|
+
require 'user_agent_parser/user_agent'
|
3
|
+
require 'user_agent_parser/version'
|
4
|
+
require 'user_agent_parser/operating_system'
|
5
|
+
|
6
|
+
module UserAgentParser
|
7
|
+
|
8
|
+
# Path to the ua-parser regexes pattern database
|
9
|
+
def self.patterns_path
|
10
|
+
@patterns_path
|
11
|
+
end
|
12
|
+
|
13
|
+
# Sets the path to the ua-parser regexes pattern database
|
14
|
+
def self.patterns_path=(path)
|
15
|
+
@patterns_path = path
|
16
|
+
end
|
17
|
+
|
18
|
+
self.patterns_path = File.join(File.dirname(__FILE__), "../vendor/ua-parser/regexes.yaml")
|
19
|
+
|
20
|
+
# Parse the given +user_agent_string+, returning a +UserAgent+
|
21
|
+
def self.parse user_agent_string
|
22
|
+
Parser.new.parse user_agent_string
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module UserAgentParser
|
2
|
+
|
3
|
+
class OperatingSystem
|
4
|
+
|
5
|
+
attr_accessor :name, :version
|
6
|
+
|
7
|
+
def initialize(name="Other", version=nil)
|
8
|
+
self.name = name
|
9
|
+
self.version = version
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
s = name
|
14
|
+
s += " #{version}" if version
|
15
|
+
s
|
16
|
+
end
|
17
|
+
|
18
|
+
def inspect
|
19
|
+
"#<#{self.class} #{to_s}>"
|
20
|
+
end
|
21
|
+
|
22
|
+
def ==(other)
|
23
|
+
name == other.name && version == other.version
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module UserAgentParser
|
4
|
+
|
5
|
+
class Parser
|
6
|
+
|
7
|
+
def parse user_agent
|
8
|
+
ua = parse_ua(user_agent)
|
9
|
+
ua.os = parse_os(user_agent)
|
10
|
+
ua
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def all_patterns
|
16
|
+
@all_patterns ||= YAML.load(File.read(UserAgentParser.patterns_path))
|
17
|
+
end
|
18
|
+
|
19
|
+
def patterns type
|
20
|
+
@patterns ||= {}
|
21
|
+
@patterns[type] ||= begin
|
22
|
+
all_patterns[type].each do |p|
|
23
|
+
p["regex"] = Regexp.new(p["regex"])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def parse_ua user_agent
|
29
|
+
pattern, match = first_pattern_match(patterns("user_agent_parsers"), user_agent)
|
30
|
+
if match
|
31
|
+
user_agent_from_pattern_match(pattern, match)
|
32
|
+
else
|
33
|
+
UserAgent.new
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def parse_os user_agent
|
38
|
+
pattern, match = first_pattern_match(patterns("os_parsers"), user_agent)
|
39
|
+
if match
|
40
|
+
os_from_pattern_match(pattern, match)
|
41
|
+
else
|
42
|
+
OperatingSystem.new
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def first_pattern_match patterns, value
|
47
|
+
for p in patterns
|
48
|
+
if m = p["regex"].match(value)
|
49
|
+
return [p, m]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
nil
|
53
|
+
end
|
54
|
+
|
55
|
+
def user_agent_from_pattern_match pattern, match
|
56
|
+
family, v1, v2, v3 = match[1], match[2], match[3], match[4]
|
57
|
+
if pattern["family_replacement"]
|
58
|
+
family = pattern["family_replacement"].sub('$1', family || '')
|
59
|
+
end
|
60
|
+
v1 = pattern["v1_replacement"].sub('$1', v1 || '') if pattern["v1_replacement"]
|
61
|
+
v2 = pattern["v2_replacement"].sub('$1', v2 || '') if pattern["v2_replacement"]
|
62
|
+
v3 = pattern["v3_replacement"].sub('$1', v3 || '') if pattern["v3_replacement"]
|
63
|
+
ua = UserAgent.new(family)
|
64
|
+
ua.version = version_from_segments(v1, v2, v3)
|
65
|
+
ua
|
66
|
+
end
|
67
|
+
|
68
|
+
def os_from_pattern_match pattern, match
|
69
|
+
os, v1, v2, v3, v4 = match[1], match[2], match[3], match[4], match[5]
|
70
|
+
os = pattern["os_replacement"].sub('$1', os || '') if pattern["os_replacement"]
|
71
|
+
v1 = pattern["v1_replacement"].sub('$1', v1 || '') if pattern["v1_replacement"]
|
72
|
+
v2 = pattern["v2_replacement"].sub('$1', v2 || '') if pattern["v2_replacement"]
|
73
|
+
v3 = pattern["v3_replacement"].sub('$1', v3 || '') if pattern["v3_replacement"]
|
74
|
+
v4 = pattern["v3_replacement"].sub('$1', v3 || '') if pattern["v4_replacement"]
|
75
|
+
os = OperatingSystem.new(os)
|
76
|
+
os.version = version_from_segments(v1, v2, v3, v4)
|
77
|
+
os
|
78
|
+
end
|
79
|
+
|
80
|
+
def version_from_segments(*segments)
|
81
|
+
version_string = segments.compact.join(".")
|
82
|
+
version_string.empty? ? nil : Version.new(version_string)
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module UserAgentParser
|
2
|
+
|
3
|
+
class UserAgent
|
4
|
+
|
5
|
+
attr_accessor :family, :version, :os
|
6
|
+
|
7
|
+
def initialize(family="Other", version=nil, os=nil)
|
8
|
+
self.family = family
|
9
|
+
self.version = version
|
10
|
+
self.os = os
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_s
|
14
|
+
s = family
|
15
|
+
s += " #{version}" if version
|
16
|
+
s += " (#{os})" if os
|
17
|
+
s
|
18
|
+
end
|
19
|
+
|
20
|
+
def inspect
|
21
|
+
"#<#{self.class} #{to_s}>"
|
22
|
+
end
|
23
|
+
|
24
|
+
def ==(other)
|
25
|
+
family == other.family &&
|
26
|
+
version == other.version &&
|
27
|
+
os == other.os
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module UserAgentParser
|
2
|
+
|
3
|
+
class Version
|
4
|
+
|
5
|
+
attr_accessor :version
|
6
|
+
alias :to_s :version
|
7
|
+
|
8
|
+
def initialize(version)
|
9
|
+
self.version = version.to_s.strip
|
10
|
+
end
|
11
|
+
|
12
|
+
def segments
|
13
|
+
version.scan(/\d+\-\d+|\d+[a-zA-Z]+$|\d+|[A-Za-z][0-9A-Za-z-]*$/).map do |s|
|
14
|
+
/^\d+$/ =~ s ? s.to_i : s
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def [](segment)
|
19
|
+
segments[segment]
|
20
|
+
end
|
21
|
+
|
22
|
+
def inspect
|
23
|
+
"#<#{self.class} #{to_s}>"
|
24
|
+
end
|
25
|
+
|
26
|
+
def ==(other)
|
27
|
+
version == other.version
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
metadata
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: user_agent_parser
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Tim Lucas
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-05-02 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: A simple, comprehensive Ruby gem for parsing user agent strings with
|
15
|
+
the help of BrowserScope's UA database
|
16
|
+
email: t@toolmantim.com
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- lib/user_agent_parser.rb
|
22
|
+
- lib/user_agent_parser/operating_system.rb
|
23
|
+
- lib/user_agent_parser/parser.rb
|
24
|
+
- lib/user_agent_parser/user_agent.rb
|
25
|
+
- lib/user_agent_parser/version.rb
|
26
|
+
homepage: http://github.com/toolmantim/user_agent_parser
|
27
|
+
licenses:
|
28
|
+
- MIT
|
29
|
+
post_install_message:
|
30
|
+
rdoc_options: []
|
31
|
+
require_paths:
|
32
|
+
- lib
|
33
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
35
|
+
requirements:
|
36
|
+
- - ! '>='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: 1.9.2
|
39
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
segments:
|
46
|
+
- 0
|
47
|
+
hash: 2720701220446018537
|
48
|
+
requirements: []
|
49
|
+
rubyforge_project:
|
50
|
+
rubygems_version: 1.8.23
|
51
|
+
signing_key:
|
52
|
+
specification_version: 3
|
53
|
+
summary: A simple, comprehensive Ruby gem for parsing user agent strings with the
|
54
|
+
help of BrowserScope's UA database
|
55
|
+
test_files: []
|