active_device 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +41 -0
- data/lib/active_device.rb +48 -0
- data/lib/active_device/agent_spec.rb +181 -0
- data/lib/active_device/bot.rb +76 -0
- data/lib/active_device/brand.rb +237 -0
- data/lib/active_device/handset.rb +40 -0
- data/lib/active_device/model.rb +87 -0
- data/lib/active_device/user_agent.rb +117 -0
- data/lib/active_device_rails.rb +93 -0
- metadata +68 -0
data/README.rdoc
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
|
2
|
+
= Active Device
|
3
|
+
|
4
|
+
Handsets and Device Detector.
|
5
|
+
|
6
|
+
== Example
|
7
|
+
|
8
|
+
agent = Agent.new 'Mozilla/5.0 (Windows; U; Windows NT 6.0; en-us) AppleWebKit/531.9 (KHTML, like Gecko) Version/4.0.3 Safari/531.9'
|
9
|
+
agent.name # => :Safari
|
10
|
+
agent.version # => '4.0.3'
|
11
|
+
agent.engine # => :webkit
|
12
|
+
agent.os # => :'Windows Vista'
|
13
|
+
agent.engine_version # => '531.9'
|
14
|
+
|
15
|
+
== Supported Agents
|
16
|
+
|
17
|
+
|
18
|
+
== License:
|
19
|
+
|
20
|
+
(The MIT License)
|
21
|
+
|
22
|
+
Copyright (c) 2009 Shenouda Bertel <sbertel@mobithought.com>
|
23
|
+
|
24
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
25
|
+
a copy of this software and associated documentation files (the
|
26
|
+
'Software'), to deal in the Software without restriction, including
|
27
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
28
|
+
distribute, sublicense, an d/or sell copies of the Software, and to
|
29
|
+
permit persons to whom the Software is furnished to do so, subject to
|
30
|
+
the following conditions:
|
31
|
+
|
32
|
+
The above copyright notice and this permission notice shall be
|
33
|
+
included in all copies or substantial portions of the Software.
|
34
|
+
|
35
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
36
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
37
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
38
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
39
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
40
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
41
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,48 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2009 Shenouda Bertel <sbertel@mobithought.com>
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
require 'active_device/user_agent'
|
25
|
+
require 'active_device/agent_spec'
|
26
|
+
require 'active_device/brand'
|
27
|
+
require 'active_device/model'
|
28
|
+
require 'active_device/handset'
|
29
|
+
|
30
|
+
#user_agent = 'Mozilla/5.0 (SymbianOS/9.3; U; Series60/3.2 NokiaE75-1/110.48.125 Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/413 (KHTML, like Gecko) Safari/413'
|
31
|
+
#agent = UserAgent.new user_agent
|
32
|
+
#puts agent
|
33
|
+
#puts "Name:#{agent.name}"
|
34
|
+
#puts "Version:#{agent.version}"
|
35
|
+
#puts "Engine:#{agent.engine}"
|
36
|
+
#puts "EVersion:#{agent.engine_version}"
|
37
|
+
#puts "OS:#{agent.os}"
|
38
|
+
#puts "OSVersion:#{agent.os_version}"
|
39
|
+
#if agent.os == :SymbianOS
|
40
|
+
# puts "OSS:#{agent.os_series}"
|
41
|
+
#end
|
42
|
+
#puts "Brand:#{agent.brand}"
|
43
|
+
#puts "Model:#{agent.model}"
|
44
|
+
#puts "================================="
|
45
|
+
#
|
46
|
+
#puts agent.is_mobile?
|
47
|
+
#puts '============================'
|
48
|
+
#puts agent.is_handset? 'e75'
|
@@ -0,0 +1,181 @@
|
|
1
|
+
class AgentSpec
|
2
|
+
|
3
|
+
##
|
4
|
+
# User agent user_agent.
|
5
|
+
|
6
|
+
attr_reader :user_agent
|
7
|
+
|
8
|
+
##
|
9
|
+
# Initialize with user agent _user_agent_.
|
10
|
+
|
11
|
+
def initialize user_agent
|
12
|
+
@user_agent = user_agent.strip
|
13
|
+
end
|
14
|
+
|
15
|
+
##
|
16
|
+
# Return engine version for user agent _user_agent_.
|
17
|
+
|
18
|
+
def self.engine_version_for_user_agent user_agent
|
19
|
+
engine = engine_for_user_agent(user_agent)
|
20
|
+
case engine
|
21
|
+
when :Webkit;
|
22
|
+
if user_agent =~ /#{engine}[\/ ]([\d\w\.\-]+)/i
|
23
|
+
$1
|
24
|
+
elsif user_agent =~ /#{engine}([0-9\.\-]+)/i
|
25
|
+
$1
|
26
|
+
end
|
27
|
+
when :NetFront;
|
28
|
+
if user_agent =~ /#{engine}[\/ ]([\d\w\.\-]+)/i
|
29
|
+
$1
|
30
|
+
elsif user_agent =~ /#{engine}([0-9\.\-]+)/i
|
31
|
+
$1
|
32
|
+
end
|
33
|
+
when :'UP.Browser';
|
34
|
+
if user_agent =~ /#{engine}[\/ ]([\d\w\.\-]+)/i
|
35
|
+
$1
|
36
|
+
elsif user_agent =~ /#{engine}([0-9\.\-]+)/i
|
37
|
+
$1
|
38
|
+
end
|
39
|
+
else $1 if user_agent =~ /#{engine_for_user_agent(user_agent)}[\/ ]([\d\w\.\-]+)/i
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
##
|
44
|
+
# Return version for user agent _user_agent_.
|
45
|
+
|
46
|
+
def self.version_for_user_agent user_agent
|
47
|
+
name = name_for_user_agent(user_agent)
|
48
|
+
case name
|
49
|
+
when :Chrome ; $1 if user_agent =~ /chrome\/([\d\w\.\-]+)/i
|
50
|
+
when :Safari ;
|
51
|
+
if user_agent =~ /version\/([\d\w\.\-]+)/i
|
52
|
+
$1
|
53
|
+
elsif user_agent =~ /Safari([0-9\.\-]+)/i
|
54
|
+
$1
|
55
|
+
else user_agent =~ /Safari\/([0-9\.\-]+)/i
|
56
|
+
$1
|
57
|
+
end
|
58
|
+
when :PS3 ; $1 if user_agent =~ /([\d\w\.\-]+)\)\s*$/i
|
59
|
+
when :PSP ; $1 if user_agent =~ /([\d\w\.\-]+)\)?\s*$/i
|
60
|
+
# when :SymbianOS ; $1 if user_agent =~ /\/([\d\w\.\-]+)/i #\)?\s*$
|
61
|
+
# when :Symbian ; $1 if user_agent =~ /\ ([0-9\d\w\.\-]+)\)?\s*$/i
|
62
|
+
# when :iPhone ; $1 if user_agent =~ /([\d\w\.\-]+)\)?\s*$/i
|
63
|
+
#when name[/safari([0-9\-\.\_]+)/i] ; $1 if name =~ /([0-9\-\.\_]+)/i
|
64
|
+
else $1 if user_agent =~ /#{name.to_s}[\/ ]([\d\w\.\-]+)/i
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
#when /safari([\d\w\.\- ]+)/i ; :"#{user_agent[/[\w\-\.\_]*/i]}"
|
69
|
+
#when /#{name}([\d\w\.\- ]+)/i ; $1 if user_agent =~ /#{name}([\d\w\.\- ]+)/i
|
70
|
+
|
71
|
+
##
|
72
|
+
# Return version for user agent _user_agent_.
|
73
|
+
|
74
|
+
def self.os_version_for_user_agent user_agent
|
75
|
+
os = os_for_user_agent(user_agent)
|
76
|
+
case os
|
77
|
+
when :Chrome ; $1 if user_agent =~ /chrome\/([\d\w\.\-]+)/i
|
78
|
+
when :Safari;
|
79
|
+
if user_agent =~ /version\/([\d\w\.\-]+)/i
|
80
|
+
$1
|
81
|
+
elsif user_agent =~ /Safari([\d0-9\.\-]+)/i
|
82
|
+
$1
|
83
|
+
elsif user_agent =~ /Safari\/([\d0-9\.\-]+)/i
|
84
|
+
$1
|
85
|
+
end
|
86
|
+
when :PS3 ; $1 if user_agent =~ /([\d\w\.\-]+)\)\s*$/i
|
87
|
+
when :PSP ; $1 if user_agent =~ /([\d\w\.\-]+)\)?\s*$/i
|
88
|
+
when :SymbianOS;
|
89
|
+
if user_agent =~ /symbianos\/([\d\w\.\-]+)/i
|
90
|
+
$1
|
91
|
+
elsif user_agent =~ /SymbianOS([\d0-9\.\-]+)/i
|
92
|
+
$1
|
93
|
+
end
|
94
|
+
when :Symbian ; $1 if user_agent =~ /\ ([0-9\d\w\.\-]+)\)?\s*$/i
|
95
|
+
when :iPhone ; $1 if user_agent =~ /OS\ ([0-9\.\-\_]+)/i
|
96
|
+
when :IE ; $1 if user_agent =~ /IEMobile[\/ ]([\d\w\.\-]+)/i
|
97
|
+
else $1 if user_agent =~ /#{os}[\/ ]([\d\w\.\-]+)/i
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.os_series_for_user_agent user_agent
|
102
|
+
case os_for_user_agent(user_agent)
|
103
|
+
when :SymbianOS ; :"#{user_agent[/series[\w\-\.\/]*/i]}" if user_agent =~ /series[\w\-\.\/]*/i
|
104
|
+
when :Symbian ; $1 if user_agent =~ /\ ([0-9\d\w\.\-]+)\)?\s*$/i
|
105
|
+
else $1 if user_agent =~ /[\/ ]([\d\w\.\-]+)/i
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
##
|
110
|
+
# Return engine symbol for user agent _user_agent_.
|
111
|
+
|
112
|
+
def self.engine_for_user_agent user_agent
|
113
|
+
case user_agent
|
114
|
+
when /webkit/i ; :Webkit
|
115
|
+
when /khtml/i ; :khtml
|
116
|
+
when /konqueror/i ; :Konqueror
|
117
|
+
when /chrome/i ; :Chrome
|
118
|
+
when /presto/i ; :Presto
|
119
|
+
when /gecko/i ; :Gecko
|
120
|
+
when /msie/i ; :MSIE
|
121
|
+
when /NetFront/i ; :NetFront
|
122
|
+
when /UP.Browser/i; :'UP.Browser'
|
123
|
+
else :Unknown
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
##
|
128
|
+
# Return the os for user agent _user_agent_.
|
129
|
+
|
130
|
+
def self.os_for_user_agent user_agent
|
131
|
+
case user_agent
|
132
|
+
when /windows ce/i ; :'Windows CE'
|
133
|
+
when /windows nt 6\.0/i ; :'Windows Vista'
|
134
|
+
when /windows nt 6\.\d+/i ; :'Windows 7'
|
135
|
+
when /windows nt 5\.2/i ; :'Windows 2003'
|
136
|
+
when /windows nt 5\.1/i ; :'Windows XP'
|
137
|
+
when /windows nt 5\.0/i ; :'Windows 2000'
|
138
|
+
when /windows nt 4\.0/i ; :Windows
|
139
|
+
when /os x (\d+)[._](\d+)/i ; :"OS X #{$1}.#{$2}"
|
140
|
+
when /linux/i ; :Linux
|
141
|
+
when /wii/i ; :Wii
|
142
|
+
when /playstation 3/i ; :Playstation
|
143
|
+
when /playstation portable/i ; :Playstation
|
144
|
+
when /SymbianOS/i ; :SymbianOS
|
145
|
+
when /Symbian/i ; :Symbian
|
146
|
+
when /Palm/i ; :Palm
|
147
|
+
when /iPhone/i ; :iPhone
|
148
|
+
else ; :Unknown
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
|
154
|
+
##
|
155
|
+
# Return name for user agent _user_agent_.
|
156
|
+
|
157
|
+
def self.name_for_user_agent user_agent
|
158
|
+
case user_agent
|
159
|
+
when /konqueror/i ; :Konqueror
|
160
|
+
when /chrome/i ; :Chrome
|
161
|
+
when /safari/i ; :Safari
|
162
|
+
when /msie/i ; :IE
|
163
|
+
when /opera/i ; :Opera
|
164
|
+
when /playstation 3/i ; :PS3
|
165
|
+
when /playstation portable/i ; :PSP
|
166
|
+
when /SymbianOS/i ; :SymbianOS
|
167
|
+
when /Symbian/i ; :Symbian
|
168
|
+
when /iPhone/i ; :iPhone
|
169
|
+
else ; :Unknown
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
@agents = []
|
174
|
+
|
175
|
+
##
|
176
|
+
# Map agent _name_ to _options_.
|
177
|
+
|
178
|
+
def self.map name, options = {}
|
179
|
+
@agents << [name, options]
|
180
|
+
end
|
181
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module ActiveDevice
|
2
|
+
class Bot
|
3
|
+
PREFIX = {
|
4
|
+
# Common prefixes (mozilla not included)
|
5
|
+
:common => %w(opera),
|
6
|
+
# Mobile browser prefixes
|
7
|
+
:embedded => %w(blackberry docomo waptiger winwap),
|
8
|
+
# Textmode browser prefixes
|
9
|
+
:text => %w(elinks lynx retawq w3m/) << "links ",
|
10
|
+
# Uncommon browser prefixes
|
11
|
+
:rare => %w(advanced amaya amiga aplix cyberdog dillo galaxy genius
|
12
|
+
hotjava ibm ibrowse icab ice klondike ncsa netsurf openwave
|
13
|
+
reqwirelessweb sunrise worldwideweb),
|
14
|
+
# These usually are not prefixes in their normal UA string
|
15
|
+
:odd => %w(android avant firefox k-meleon konqueror netscape safari
|
16
|
+
seamonkey) }
|
17
|
+
|
18
|
+
ID = {
|
19
|
+
:mobile => %w(^sec blackberry midp mmp netfront opera safari semc
|
20
|
+
sonyericsson symbian up\\.browser up\\.link) << "windows ce",
|
21
|
+
:moz_compatible => %w(amigavoyager antfresco aol applewebkit avant
|
22
|
+
blackberry elaine gecko ibrowse icab khtml konqueror msie netfront netp
|
23
|
+
netscape omniweb opera teleca voyager),
|
24
|
+
:moz_platform => %w(amiga beos brew bsd danger dreamcast iphone ipod linux
|
25
|
+
mac os/2 palm pda playstation ps2 ps3 psp risc star-blade sunos syllable
|
26
|
+
symbian win x11 zx),
|
27
|
+
:bot => %w(<a <script bot butterfly checker crawl daumoa del\\.icio\\.us
|
28
|
+
depspid flycast heritrix httrack indexing ktxn larbin links-sql
|
29
|
+
me\\.dium miro mozshot nutch odp-entries oneriot pbwf planetwide slurp
|
30
|
+
spider survey thunderbird vermut) << "black widow" }
|
31
|
+
|
32
|
+
REGEXP = {
|
33
|
+
:prefix => /^#{PREFIX.values.flatten! * "|^"}/,
|
34
|
+
:mobile => /#{ID[:mobile] * "|"}/,
|
35
|
+
:moz_compatible => /#{ID[:moz_compatible] * "|"}/,
|
36
|
+
:moz_platform => /#{ID[:moz_platform] * "|"}/,
|
37
|
+
:bot => /#{ID[:bot] * "|"}/ }
|
38
|
+
|
39
|
+
def robot?(user_agent)
|
40
|
+
!browser?(user_agent)
|
41
|
+
end
|
42
|
+
|
43
|
+
def browser?(user_agent)
|
44
|
+
# Empty string might be an anonymized browser
|
45
|
+
return true if user_agent.nil? || user_agent =~ /^\s*$/
|
46
|
+
ua_lc = user_agent.downcase
|
47
|
+
if ua_lc[0,7] == "mozilla"
|
48
|
+
is_browser = ua_lc =~ REGEXP[:moz_compatible] || ua_lc =~ REGEXP[:moz_platform]
|
49
|
+
else
|
50
|
+
is_browser = ua_lc =~ REGEXP[:prefix] || ua_lc =~ REGEXP[:mobile]
|
51
|
+
end
|
52
|
+
is_browser = ua_lc[REGEXP[:bot]].nil? if is_browser
|
53
|
+
return is_browser
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
module BotHelper
|
58
|
+
def robot?(user_agent)
|
59
|
+
self.class.urobot.robot?(user_agent)
|
60
|
+
end
|
61
|
+
|
62
|
+
def browser?(user_agent)
|
63
|
+
self.class.urobot.browser?(user_agent)
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.included(base)
|
67
|
+
base.extend(ClassMethods)
|
68
|
+
end
|
69
|
+
|
70
|
+
module ClassMethods
|
71
|
+
def bot
|
72
|
+
@bot ||= ActiveDevice::BOT.new
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,237 @@
|
|
1
|
+
class Brand
|
2
|
+
|
3
|
+
##
|
4
|
+
# User agent string.
|
5
|
+
|
6
|
+
attr_reader :user_agent
|
7
|
+
|
8
|
+
##
|
9
|
+
# Initialize with user agent _string_.
|
10
|
+
|
11
|
+
def initialize user_agent
|
12
|
+
@user_agent = user_agent.strip
|
13
|
+
end
|
14
|
+
|
15
|
+
##
|
16
|
+
# Return the brand for user agent _string_.
|
17
|
+
|
18
|
+
def self.mobile_brand user_agent
|
19
|
+
case user_agent
|
20
|
+
when /SonyEricsson/i ; :SonyEricsson
|
21
|
+
when /Nokia/i ; :Nokia
|
22
|
+
when /HTC/i ; :HTC
|
23
|
+
when /iPhone/i ; :Apple
|
24
|
+
when /iTouch/i ; :Apple
|
25
|
+
when /iPod/i ; :Apple
|
26
|
+
## ==================================== ##
|
27
|
+
when /Acer/i ; :Acer
|
28
|
+
when /Ahong/i ; :Ahong
|
29
|
+
when /Aiko/i ; :Aiko
|
30
|
+
when /Airness/i ; :Airness
|
31
|
+
when /Alcatel/i ; :Alcatel
|
32
|
+
when /Alphacell/i ; :Alphacell
|
33
|
+
when /Amazon/i ; :Amazon
|
34
|
+
when /Amoi/i ; :Amoi
|
35
|
+
when /Android/i ; :Android
|
36
|
+
when /AnexTek/i ; :AnexTek
|
37
|
+
when /Arcelik/i ; :Arcelik
|
38
|
+
when /ASMOBILE/i ; :ASMOBILE
|
39
|
+
when /Asus/i ; :Asus
|
40
|
+
when /Audiovox/i ; :Audiovox
|
41
|
+
when /B-Mobile/i ; :'B-Mobile'
|
42
|
+
when /BEKO/i ; :BEKO
|
43
|
+
when /Bellwave/i ; :Bellwave
|
44
|
+
when /Benefon/i ; :Benefon
|
45
|
+
when /BenQ/i ; :BenQ
|
46
|
+
when /BenQ-Siemens/i ; :'BenQ-Siemens'
|
47
|
+
#when /Bird/ ; :Bird
|
48
|
+
when /Bleu/i ; :Bleu
|
49
|
+
when /BlackBerry/i ; :BlackBerry
|
50
|
+
when /Capitel/i ; :Capitel
|
51
|
+
when /Casio/i ; :Casio
|
52
|
+
when /CDM/i ; :CDM
|
53
|
+
when /CECT/i ; :CECT
|
54
|
+
when /Cingular/i ; :Cingular
|
55
|
+
when /Cking/i ; :Cking
|
56
|
+
when /Compal/i ; :Compal
|
57
|
+
when /Cricket/i ; :Cricket
|
58
|
+
when /Curitel/i ; :Curitel
|
59
|
+
when /Dai Telecom/i ; :'Dai Telecom'
|
60
|
+
when /Dallab/i ; :Dallab
|
61
|
+
when /Danger/i ; :Danger
|
62
|
+
when /Daxian/i ; :Daxian
|
63
|
+
when /DBTEL/i ; :DBTEL
|
64
|
+
when /Denso/i ; :Denso
|
65
|
+
when /Dicam/i ; :Dicam
|
66
|
+
when /DMOBO/i ; :DMOBO
|
67
|
+
when /DoCoMo/i ; :DoCoMo
|
68
|
+
when /Dopod/i ; :Dopod
|
69
|
+
when /Dreamphone/i ; :Dreamphone
|
70
|
+
when /EDL/i ; :EDL
|
71
|
+
when /Elite/i ; :Elite
|
72
|
+
when /Elson/i ; :Elson
|
73
|
+
when /Emblaze/i ; :Emblaze
|
74
|
+
when /Emobile/i ; :Emobile
|
75
|
+
when /Enteos/i ; :Enteos
|
76
|
+
when /Ericsson/i ; :Ericsson
|
77
|
+
when /Ericy/i ; :Ericy
|
78
|
+
when /ETEN/i ; :ETEN
|
79
|
+
when /Ezio/i ; :Ezio
|
80
|
+
when /Ezze/i ; :Ezze
|
81
|
+
when /^Fly/i ; :Fly
|
82
|
+
when /Fujitsu/i ; :Fujitsu
|
83
|
+
when /Gigabyte/i ; :Gigabyte
|
84
|
+
when /Gionee/i ; :Gionee
|
85
|
+
when /Gradiente/i ; :Gradiente
|
86
|
+
when /Grundig/i ; :Grundig
|
87
|
+
when /Haier/i ; :Haier
|
88
|
+
when /Handspring/i ; :Handspring
|
89
|
+
when /Hedy/i ; :Hedy
|
90
|
+
when /Hei/i ; :Hei
|
91
|
+
when /Hewlett Packard/i ; :'Hewlett Packard'
|
92
|
+
when /Hisense/i ; :Hisense
|
93
|
+
when /Hitachi/i ; :Hitachi
|
94
|
+
when /^HP/ ; :HP
|
95
|
+
when /HTC/i ; :HTC
|
96
|
+
when /HTIL/i ; :HTIL
|
97
|
+
when /Huawei/i ; :Huawei
|
98
|
+
when /Hummer/i ; :Hummer
|
99
|
+
when /i-mate/i ; :'i-mate'
|
100
|
+
when /i-mobile/i ; :'i-mobile'
|
101
|
+
when /iKoMo/i ; :iKoMo
|
102
|
+
when /IM/ ; :IM
|
103
|
+
when /iMate/i ; :iMate
|
104
|
+
when /Innostream/i ; :Innostream
|
105
|
+
when /INQ Mobile/i ; :'INQ Mobile'
|
106
|
+
when /Itelco/i ; :Itelco
|
107
|
+
when /IXI/i ; :IXI
|
108
|
+
when /KDDI-Casio/i ; :'KDDI-Casio'
|
109
|
+
when /KDDI-Hitachi/i ; :'KDDI-Hitachi'
|
110
|
+
when /KDDI-Kiocera/i ; :'KDDI-Kiocera'
|
111
|
+
when /KDDI-Panasonic/i ; :'KDDI-Panasonic'
|
112
|
+
when /KDDI-Pantech/i ; :'KDDI-Pantech'
|
113
|
+
when /KDDI-Sanyo/i ; :'KDDI-Sanyo'
|
114
|
+
when /KDDI-Sharp/i ; :'KDDI-Sharp'
|
115
|
+
when /KDDI/i ; :KDDI
|
116
|
+
when /Kejian/i ; :Kejian
|
117
|
+
when /Kenwood/i ; :Kenwood
|
118
|
+
when /Kisen/i ; :Kisen
|
119
|
+
when /Kokusai/i ; :Kokusai
|
120
|
+
when /Konka/i ; :Konka
|
121
|
+
when /Kozi/i ; :Kozi
|
122
|
+
when /KPT/i ; :KPT
|
123
|
+
when /Kyocera/i ; :Kyocera
|
124
|
+
when /LCT/i ; :LCT
|
125
|
+
when /Lenovo/i ; :Lenovo
|
126
|
+
when /Lexibook/i ; :Lexibook
|
127
|
+
when /Lexus/i ; :Lexus
|
128
|
+
when /LG/i ; :LG
|
129
|
+
when /Lobster/i ; :Lobster
|
130
|
+
when /Longcos/i ; :Longcos
|
131
|
+
#when /LT/ ; :LT
|
132
|
+
when /LXE/i ; :LXE
|
133
|
+
when /Malata/i ; :Malata
|
134
|
+
when /Maxon/i ; :Maxon
|
135
|
+
when /Medion/i ; :Medion
|
136
|
+
when /MicroMax/i ; :MicroMax
|
137
|
+
when /Microsoft/i ; :Microsoft
|
138
|
+
when /Mio/i ; :Mio
|
139
|
+
when /Miracle/i ; :Miracle
|
140
|
+
when /Mitac/i ; :Mitac
|
141
|
+
when /Mitsubishi/i ; :Mitsubishi
|
142
|
+
when /Mobile Wireless Group/i ; :'Mobile Wireless Group'
|
143
|
+
when /MOBISTEL/i ; :MOBISTEL
|
144
|
+
when /Modelabs/i ; :Modelabs
|
145
|
+
when /ModelLabs/i ; :ModelLabs
|
146
|
+
when /Modottel/i ; :Modottel
|
147
|
+
when /MOMO Design/i ; :'MOMO Design'
|
148
|
+
when /Motorola/i ; :'Motorola'
|
149
|
+
when /Movistar/i ; :Movistar
|
150
|
+
when /MyPhone/i ; :MyPhone
|
151
|
+
when /NEC/ ; :NEC
|
152
|
+
when /Neonode/i ; :Neonode
|
153
|
+
when /Newgen/i ; :Newgen
|
154
|
+
when /Nexian/i ; :Nexian
|
155
|
+
#when /Nintendo/i ; :Nintendo
|
156
|
+
when /Nokia/i ; :Nokia
|
157
|
+
when /NTT DoCoMo/i ; :'NTT DoCoMo'
|
158
|
+
when /O2/ ; :O2
|
159
|
+
when /OKWap/i ; :OKWap
|
160
|
+
when /Onda/i ; :Onda
|
161
|
+
#when /Opera/i ; :Opera
|
162
|
+
when /Optimay/i ; :Optimay
|
163
|
+
when /Orange/i ; :Orange
|
164
|
+
when /PalmOne/i ; :PalmOne
|
165
|
+
when /Palm/i ; :Palm
|
166
|
+
when /Panasonic/i ; :Panasonic
|
167
|
+
when /Panda/i ; :Panda
|
168
|
+
when /Pantech/i ; :Pantech
|
169
|
+
when /PCD/i ; :PCD
|
170
|
+
when /Philips/i ; :Philips
|
171
|
+
when /PhoneOne/i ; :PhoneOne
|
172
|
+
when /Pioneer/i ; :Pioneer
|
173
|
+
when /Pirelli-Arcor/i ; :'Pirelli-Arcor'
|
174
|
+
when /Porsche Design/i ; :'Porsche Design'
|
175
|
+
when /Psion/i ; :Psion
|
176
|
+
when /QCI/i ; :QCI
|
177
|
+
when /QMobile/i ; :QMobile
|
178
|
+
when /Qtek/i ; :Qtek
|
179
|
+
when /Raks/i ; :Raks
|
180
|
+
when /RIM/i ; :RIM
|
181
|
+
when /Ron/ ; :Ron
|
182
|
+
when /Sagem/i ; :Sagem
|
183
|
+
when /SAMART/i ; :SAMART
|
184
|
+
when /Samsung/i ; :Samsung
|
185
|
+
when /SGH/i ; :Samsung
|
186
|
+
when /Sanyo/i ; :Sanyo
|
187
|
+
when /SavaJe/i ; :SavaJe
|
188
|
+
when /Sendo/i ; :Sendo
|
189
|
+
when /SFR/i ; :SFR
|
190
|
+
when /Sharp/i ; :Sharp
|
191
|
+
when /Siemens/i ; :Siemens
|
192
|
+
when /Skyspring/i ; :Skyspring
|
193
|
+
when /Skyworth/i ; :Skyworth
|
194
|
+
when /SmartTrust/i ; :SmartTrust
|
195
|
+
when /Smile/i ; :Smile
|
196
|
+
when /SoftBank/i ; :SoftBank
|
197
|
+
when /SonyEricsson/i ; :SonyEricsson
|
198
|
+
when /Sony/i ; :Sony
|
199
|
+
when /Spice/i ; :Spice
|
200
|
+
when /T-Mobile/i ; :'T-Mobile'
|
201
|
+
when /TCL/ ; :TCL
|
202
|
+
when /Techfaith/i ; :Techfaith
|
203
|
+
when /Tel.Me/i ; :'Tel.Me'
|
204
|
+
when /Telit/i ; :Telit
|
205
|
+
when /Tianyu/i ; :Tianyu
|
206
|
+
when /Toplux/i ; :Toplux
|
207
|
+
when /Toshiba/i ; :Toshiba
|
208
|
+
when /TTPCom/i ; :TTPCom
|
209
|
+
when /tvCompass/i ; :tvCompass
|
210
|
+
when /Ubiquam/i ; :Ubiquam
|
211
|
+
when /Uniscope/i ; :Uniscope
|
212
|
+
when /Unistar/i ; :Unistar
|
213
|
+
when /Uriver/i ; :Uriver
|
214
|
+
when /Usha Lexus/i ; :'Usha Lexus'
|
215
|
+
when /Utec/i ; :Utec
|
216
|
+
when /UTStarcom/i ; :UTStarcom
|
217
|
+
when /Vacom/i ; :Vacom
|
218
|
+
when /Velocity Mobile/i ; :'Velocity Mobile'
|
219
|
+
when /Verizon/i ; :Verizon
|
220
|
+
when /Vertu/i ; :Vertu
|
221
|
+
when /VERZIOWORLD/i ; :VERZIOWORLD
|
222
|
+
when /Virgin/i ; :Virgin
|
223
|
+
when /Vitelcom/i ; :Vitelcom
|
224
|
+
when /VK/i ; :VK
|
225
|
+
when /Vodafone/i ; :Vodafone
|
226
|
+
when /Voxtel/i ; :Voxtel
|
227
|
+
when /W3C/i ; :W3C
|
228
|
+
when /WellcoM/i ; :WellcoM
|
229
|
+
when /Wonu/i ; :Wonu
|
230
|
+
when /XDA/i ; :XDA
|
231
|
+
when /YAS/i ; :YAS
|
232
|
+
when /ZT/i ; :ZT
|
233
|
+
when /ZTE/i ; :ZTE
|
234
|
+
else ; :UnknownMobile
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'active_device/brand'
|
2
|
+
require 'active_device/model'
|
3
|
+
|
4
|
+
class Handset
|
5
|
+
|
6
|
+
##
|
7
|
+
# User agent string.
|
8
|
+
|
9
|
+
attr_reader :user_agent
|
10
|
+
|
11
|
+
##
|
12
|
+
# Initialize with user agent _string_.
|
13
|
+
|
14
|
+
def initialize user_agent
|
15
|
+
@user_agent = user_agent.strip
|
16
|
+
end
|
17
|
+
|
18
|
+
##
|
19
|
+
# Is _string_. Mobile Device
|
20
|
+
|
21
|
+
def self.is_mobile? user_agent
|
22
|
+
mobi = Brand.mobile_brand user_agent
|
23
|
+
if mobi == :UnknownMobile
|
24
|
+
false
|
25
|
+
else
|
26
|
+
true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# Is _string_. Device
|
32
|
+
|
33
|
+
def self.is_handset? user_agent, model
|
34
|
+
model_sym = Model.brand_model user_agent
|
35
|
+
model_sym = model_sym.to_s.downcase
|
36
|
+
model = model.to_s.downcase
|
37
|
+
model_sym.include? model
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
class Model
|
2
|
+
##
|
3
|
+
# User agent user_agent.
|
4
|
+
|
5
|
+
attr_reader :user_agent
|
6
|
+
|
7
|
+
##
|
8
|
+
# Initialize with user agent _user_agent_.
|
9
|
+
|
10
|
+
def initialize user_agent
|
11
|
+
@user_agent = user_agent.strip
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.brand_model user_agent
|
15
|
+
case user_agent
|
16
|
+
when /iPhone/i ; :iPhone
|
17
|
+
when /SAMSUNG[\w\-\.\_\ ]*/i ; samsung_models user_agent
|
18
|
+
when /Nokia[\w\.\_\ ]*/i ; nokia_models user_agent
|
19
|
+
when /HTC[\w\-\.\_\ ]*/i ; htc_models user_agent
|
20
|
+
when /SonyEricsson[\w\-\.\_\ ]*/i ; sonyericsson_models user_agent
|
21
|
+
when /^Mozilla[0-9\-\.\_\ ]*/i ; :'Unknown Yet'
|
22
|
+
else ; :"#{user_agent[/[\w\-\.\_]*/i]}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
##
|
27
|
+
# Return the Nokia model for user agent _user_agent_.
|
28
|
+
# Note: Nokia Models Include "Nokia" Returend Value.
|
29
|
+
|
30
|
+
def self.nokia_models user_agent
|
31
|
+
if user_agent =~ /^Nokia[\w\.\_\ ]*/i
|
32
|
+
model = user_agent[/Nokia[\w\.\_\ ]*/i]
|
33
|
+
else
|
34
|
+
model = user_agent[/Nokia[\w\.\_\ ]*/i]
|
35
|
+
end
|
36
|
+
model_clear model
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.htc_models user_agent
|
40
|
+
if user_agent =~ /^HTC[\w\-\.\_\ ]*/i
|
41
|
+
model = user_agent[/[\w\-\.\_\ ]*/i]
|
42
|
+
elsif user_agent =~ /Vodafone[\w\-\.\_\ ]*/i
|
43
|
+
model = user_agent[/Vodafone[\w\-\.\_\ ]*/i]
|
44
|
+
else
|
45
|
+
model = user_agent[/HTC[\w\-\.\_\ ]*/i]
|
46
|
+
end
|
47
|
+
model_clear model
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.sonyericsson_models user_agent
|
51
|
+
if user_agent =~ /^SonyEricsson[\w\.\_]*/i
|
52
|
+
model = user_agent[/SonyEricsson[\w\.\_]*/i]
|
53
|
+
else
|
54
|
+
model = user_agent[/SonyEricsson[\w\.\_]*/i]
|
55
|
+
end
|
56
|
+
model_clear model
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.samsung_models user_agent
|
60
|
+
if user_agent =~ /^Samsung[\w\.\_\-]*/i
|
61
|
+
model = user_agent[/Samsung[\w\.\_\-]*/i]
|
62
|
+
else
|
63
|
+
model = user_agent[/Samsung[\w\.\_\-]*/i]
|
64
|
+
end
|
65
|
+
model_clear model
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.model_clear model
|
69
|
+
model = model.to_s
|
70
|
+
if model.include?("Profile")
|
71
|
+
model = model.gsub(/Profile[\w\.\_\ ]*/i, "")
|
72
|
+
elsif model.include?("Mozilla")
|
73
|
+
model = model.gsub(/Mozilla[\w\.\_\ ]*/i, "")
|
74
|
+
end
|
75
|
+
:"#{model.chomp("-").strip}"
|
76
|
+
end
|
77
|
+
##
|
78
|
+
# Return the model reselution for user agent _user_agent_.
|
79
|
+
|
80
|
+
def self.model_reselution user_agent
|
81
|
+
case user_agent
|
82
|
+
when /([0-9]+x+[0-9]*)/i ; :"#{user_agent[/([0-9]+x+[0-9]*)/i]}"
|
83
|
+
else ; :'Not Recognized'
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
class UserAgent
|
2
|
+
##
|
3
|
+
# User agent user_agent.
|
4
|
+
|
5
|
+
attr_reader :user_agent
|
6
|
+
|
7
|
+
##
|
8
|
+
# Initialize with user agent _user_agent_.
|
9
|
+
|
10
|
+
def initialize user_agent
|
11
|
+
@user_agent = user_agent.strip
|
12
|
+
end
|
13
|
+
|
14
|
+
#--
|
15
|
+
# Instance methods
|
16
|
+
#++
|
17
|
+
|
18
|
+
##
|
19
|
+
# User agent name symbol.
|
20
|
+
|
21
|
+
def name
|
22
|
+
AgentSpec.name_for_user_agent user_agent
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# User agent version.
|
27
|
+
|
28
|
+
def version
|
29
|
+
AgentSpec.version_for_user_agent user_agent
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# User agent engine symbol.
|
34
|
+
|
35
|
+
def engine
|
36
|
+
AgentSpec.engine_for_user_agent user_agent
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# User agent engine version user_agent.
|
41
|
+
|
42
|
+
def engine_version
|
43
|
+
AgentSpec.engine_version_for_user_agent user_agent
|
44
|
+
end
|
45
|
+
|
46
|
+
##
|
47
|
+
# User agent os symbol.
|
48
|
+
|
49
|
+
def os
|
50
|
+
AgentSpec.os_for_user_agent user_agent
|
51
|
+
end
|
52
|
+
|
53
|
+
##
|
54
|
+
# User agent engine version user_agent.
|
55
|
+
|
56
|
+
def os_version
|
57
|
+
AgentSpec.os_version_for_user_agent user_agent
|
58
|
+
end
|
59
|
+
|
60
|
+
##
|
61
|
+
# User agent engine version user_agent.
|
62
|
+
|
63
|
+
def os_series
|
64
|
+
AgentSpec.os_series_for_user_agent user_agent
|
65
|
+
end
|
66
|
+
|
67
|
+
##
|
68
|
+
# User agent model symbol.
|
69
|
+
|
70
|
+
def model
|
71
|
+
Model.brand_model user_agent
|
72
|
+
end
|
73
|
+
|
74
|
+
##
|
75
|
+
# User agent model Reselution symbol.
|
76
|
+
|
77
|
+
def model_reselution
|
78
|
+
Model.model_reselution user_agent
|
79
|
+
end
|
80
|
+
|
81
|
+
##
|
82
|
+
# User agent brand symbol.
|
83
|
+
|
84
|
+
def brand
|
85
|
+
Brand.mobile_brand user_agent
|
86
|
+
end
|
87
|
+
|
88
|
+
def is_mobile?
|
89
|
+
Handset.is_mobile? user_agent
|
90
|
+
end
|
91
|
+
|
92
|
+
def is_handset? model
|
93
|
+
Handset.is_handset? user_agent, model
|
94
|
+
end
|
95
|
+
|
96
|
+
##
|
97
|
+
# User agent user_agent.
|
98
|
+
|
99
|
+
def to_s
|
100
|
+
user_agent
|
101
|
+
end
|
102
|
+
|
103
|
+
##
|
104
|
+
# Inspect.
|
105
|
+
|
106
|
+
def inspect
|
107
|
+
"#<Agent:#{name} version:#{version.inspect} engine:\"#{engine.to_s}:#{engine_version}\" os:#{os.to_s.inspect}>"
|
108
|
+
end
|
109
|
+
|
110
|
+
##
|
111
|
+
# Check if the agent is the same as _other_ agent.
|
112
|
+
|
113
|
+
def == other
|
114
|
+
user_agent == other.user_agent
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
module ActionController
|
2
|
+
module ActiveDevice
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
|
10
|
+
# Add this to one of your controllers to use ActiveDevice.
|
11
|
+
#
|
12
|
+
# class ApplicationController < ActionController::Base
|
13
|
+
# has_active_handset
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# You can also force mobile mode by passing in 'true'
|
17
|
+
#
|
18
|
+
# class ApplicationController < ActionController::Base
|
19
|
+
# has_active_handset(true)
|
20
|
+
# end
|
21
|
+
|
22
|
+
def has_active_handset(test_mode = false)
|
23
|
+
include ActionController::ActiveDevice::InstanceMethods
|
24
|
+
|
25
|
+
if test_mode
|
26
|
+
before_filter :force_mobile_format
|
27
|
+
else
|
28
|
+
before_filter :set_mobile_format
|
29
|
+
end
|
30
|
+
|
31
|
+
helper_method :is_mobile_device?
|
32
|
+
helper_method :in_mobile_view?
|
33
|
+
helper_method :is_device?
|
34
|
+
end
|
35
|
+
|
36
|
+
def is_mobile_device?
|
37
|
+
@@is_mobile_device
|
38
|
+
end
|
39
|
+
|
40
|
+
def in_mobile_view?
|
41
|
+
@@in_mobile_view
|
42
|
+
end
|
43
|
+
|
44
|
+
def is_device?(type)
|
45
|
+
@@is_device
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
module InstanceMethods
|
50
|
+
|
51
|
+
# Forces the request format to be :mobile
|
52
|
+
|
53
|
+
def force_mobile_format
|
54
|
+
request.format = :mobile
|
55
|
+
session[:mobile_view] = true if session[:mobile_view].nil?
|
56
|
+
end
|
57
|
+
|
58
|
+
# Determines the request format based on whether the device is mobile or if
|
59
|
+
# the user has opted to use either the 'Standard' view or 'Mobile' view.
|
60
|
+
|
61
|
+
def set_mobile_format
|
62
|
+
if is_mobile_device?
|
63
|
+
request.format = session[:mobile_view] == false ? :html : :mobile
|
64
|
+
session[:mobile_view] = true if session[:mobile_view].nil?
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Returns either true or false depending on whether or not the format of the
|
69
|
+
# request is either :mobile or not.
|
70
|
+
|
71
|
+
def in_mobile_view?
|
72
|
+
request.format.to_sym == :mobile
|
73
|
+
end
|
74
|
+
|
75
|
+
# Returns either true or false depending on whether or not the user agent of
|
76
|
+
# the device making the request is matched to a device in our regex.
|
77
|
+
|
78
|
+
def is_mobile_device?
|
79
|
+
Handset.is_mobile? request.user_agent
|
80
|
+
end
|
81
|
+
|
82
|
+
# Can check for a specific user agent
|
83
|
+
# e.g., is_device?('iphone') or is_device?('mobileexplorer')
|
84
|
+
|
85
|
+
def is_device?(type)
|
86
|
+
request.user_agent.to_s.downcase.include?(type.to_s.downcase)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
ActionController::Base.send(:include, ActionController::ActiveDevice)
|
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: active_device
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Shenouda Bertel
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-11-20 00:00:00 +02:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Device UserAgent Detector
|
17
|
+
email: sbertel@mobithought.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.rdoc
|
24
|
+
files:
|
25
|
+
- lib/active_device/model.rb
|
26
|
+
- lib/active_device/agent_spec.rb
|
27
|
+
- lib/active_device/brand.rb
|
28
|
+
- lib/active_device/bot.rb
|
29
|
+
- lib/active_device/handset.rb
|
30
|
+
- lib/active_device/user_agent.rb
|
31
|
+
- lib/active_device_rails.rb
|
32
|
+
- lib/active_device.rb
|
33
|
+
- README.rdoc
|
34
|
+
has_rdoc: true
|
35
|
+
homepage: ""
|
36
|
+
licenses: []
|
37
|
+
|
38
|
+
post_install_message:
|
39
|
+
rdoc_options:
|
40
|
+
- --line-numbers
|
41
|
+
- --inline-source
|
42
|
+
- --title
|
43
|
+
- User-agent
|
44
|
+
- --main
|
45
|
+
- README.rdoc
|
46
|
+
require_paths:
|
47
|
+
- lib
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: "0"
|
53
|
+
version:
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: "0"
|
59
|
+
version:
|
60
|
+
requirements: []
|
61
|
+
|
62
|
+
rubyforge_project: active_device
|
63
|
+
rubygems_version: 1.3.5
|
64
|
+
signing_key:
|
65
|
+
specification_version: 3
|
66
|
+
summary: Device UserAgent Detector
|
67
|
+
test_files: []
|
68
|
+
|