1
# -*- coding: utf-8 -*-
6
This module provides a helper to inspect user agent strings. This module
7
is far from complete but should work for most of the currently available
11
:copyright: (c) 2009 by the Werkzeug Team, see AUTHORS for more details.
12
:license: BSD, see LICENSE for more details.
17
class UserAgentParser(object):
18
"""A simple user agent parser. Used by the `UserAgent`."""
22
(r'darwin|mac|os\s*x', 'macos'),
24
(r'android', 'android'),
25
(r'x11|lin(\b|ux)?', 'linux'),
26
('(sun|i86)os', 'solaris'),
27
(r'nintendo\s+wii', 'wii'),
31
('sco|unix_sv', 'sco'),
36
('googlebot', 'google'),
39
('ask jeeves', 'ask'),
40
(r'aol|america\s+online\s+browser', 'aol'),
43
('firefox|firebird|phoenix|iceweasel', 'firefox'),
48
('konqueror', 'konqueror'),
49
('k-meleon', 'kmeleon'),
50
('netscape', 'netscape'),
51
(r'msie|microsoft\s+internet\s+explorer', 'msie'),
54
('seamonkey|mozilla', 'seamonkey')
57
_browser_version_re = r'(?:%s)[/\sa-z(]*(\d+[.\da-z]+)?(?i)'
58
_language_re = re.compile(
59
r'(?:;\s*|\s+)(\b\w{2}\b(?:-\b\w{2}\b)?)\s*;|'
60
r'(?:\(|\[|;)\s*(\b\w{2}\b(?:-\b\w{2}\b)?)\s*(?:\]|\)|;)'
64
self.platforms = [(b, re.compile(a, re.I)) for a, b in self.platforms]
65
self.browsers = [(b, re.compile(self._browser_version_re % a))
66
for a, b in self.browsers]
68
def __call__(self, user_agent):
69
for platform, regex in self.platforms:
70
match = regex.search(user_agent)
75
for browser, regex in self.browsers:
76
match = regex.search(user_agent)
78
version = match.group(1)
81
browser = version = None
82
match = self._language_re.search(user_agent)
84
language = match.group(1) or match.group(2)
87
return platform, browser, version, language
90
class UserAgent(object):
91
"""Represents a user agent. Pass it a WSGI environment or a user agent
92
string and you can inspect some of the details from the user agent
93
string via the attributes. The following attributes exist:
97
the raw user agent string
99
.. attribute:: platform
101
the browser platform. The following platforms are currently
118
.. attribute:: browser
120
the name of the browser. The following browsers are currently
143
(Browsers maked with a star (``*``) are crawlers.)
145
.. attribute:: version
147
the version of the browser
149
.. attribute:: language
151
the language of the browser
153
_parser = UserAgentParser()
155
def __init__(self, environ_or_string):
156
if isinstance(environ_or_string, dict):
157
environ_or_string = environ_or_string.get('HTTP_USER_AGENT', '')
158
self.string = environ_or_string
159
self.platform, self.browser, self.version, self.language = \
160
self._parser(environ_or_string)
168
def __nonzero__(self):
169
return bool(self.browser)
172
return '<%s %r/%s>' % (
173
self.__class__.__name__,
179
# conceptionally this belongs in this module but because we want to lazily
180
# load the user agent module (which happens in wrappers.py) we have to import
181
# it afterwards. The class itself has the module set to this module so
182
# pickle, inspect and similar modules treat the object as if it was really
184
from werkzeug.wrappers import UserAgentMixin