Coverage for adhoc-cicd-odoo-odoo / odoo / tools / _vendor / useragents.py: 33%
42 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-09 18:22 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-09 18:22 +0000
1# -*- coding: utf-8 -*-
2"""
3 werkzeug.useragents
4 ~~~~~~~~~~~~~~~~~~~
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
8 browsers.
11 :copyright: 2007 Pallets
12 :license: BSD-3-Clause
14 This package was vendored in odoo in order to prevent errors with werkzeug 2.1
15"""
16import re
19class UserAgentParser(object):
20 """A simple user agent parser. Used by the `UserAgent`."""
22 platforms = (
23 ("cros", "chromeos"),
24 ("iphone|ios", "iphone"),
25 ("ipad", "ipad"),
26 (r"darwin|mac|os\s*x", "macos"),
27 ("win", "windows"),
28 (r"android", "android"),
29 ("netbsd", "netbsd"),
30 ("openbsd", "openbsd"),
31 ("freebsd", "freebsd"),
32 ("dragonfly", "dragonflybsd"),
33 ("(sun|i86)os", "solaris"),
34 (r"x11|lin(\b|ux)?", "linux"),
35 (r"nintendo\s+wii", "wii"),
36 ("irix", "irix"),
37 ("hp-?ux", "hpux"),
38 ("aix", "aix"),
39 ("sco|unix_sv", "sco"),
40 ("bsd", "bsd"),
41 ("amiga", "amiga"),
42 ("blackberry|playbook", "blackberry"),
43 ("symbian", "symbian"),
44 )
45 browsers = (
46 ("googlebot", "google"),
47 ("msnbot", "msn"),
48 ("yahoo", "yahoo"),
49 ("ask jeeves", "ask"),
50 (r"aol|america\s+online\s+browser", "aol"),
51 ("opera", "opera"),
52 ("edge", "edge"),
53 ("chrome|crios", "chrome"),
54 ("seamonkey", "seamonkey"),
55 ("firefox|firebird|phoenix|iceweasel", "firefox"),
56 ("galeon", "galeon"),
57 ("safari|version", "safari"),
58 ("webkit", "webkit"),
59 ("camino", "camino"),
60 ("konqueror", "konqueror"),
61 ("k-meleon", "kmeleon"),
62 ("netscape", "netscape"),
63 (r"msie|microsoft\s+internet\s+explorer|trident/.+? rv:", "msie"),
64 ("lynx", "lynx"),
65 ("links", "links"),
66 ("Baiduspider", "baidu"),
67 ("bingbot", "bing"),
68 ("mozilla", "mozilla"),
69 )
71 _browser_version_re = r"(?:%s)[/\sa-z(]*(\d+[.\da-z]+)?"
72 _language_re = re.compile(
73 r"(?:;\s*|\s+)(\b\w{2}\b(?:-\b\w{2}\b)?)\s*;|"
74 r"(?:\(|\[|;)\s*(\b\w{2}\b(?:-\b\w{2}\b)?)\s*(?:\]|\)|;)"
75 )
77 def __init__(self):
78 self.platforms = tuple((b, re.compile(a, re.I)) for a, b in self.platforms)
79 self.browsers = tuple(
80 (b, re.compile(self._browser_version_re % a, re.I))
81 for a, b in self.browsers
82 )
84 def __call__(self, user_agent):
85 for platform, regex in self.platforms: # noqa: B007
86 match = regex.search(user_agent)
87 if match is not None:
88 break
89 else:
90 platform = None
91 for browser, regex in self.browsers: # noqa: B007
92 match = regex.search(user_agent)
93 if match is not None:
94 version = match.group(1)
95 break
96 else:
97 browser = version = None
98 match = self._language_re.search(user_agent)
99 if match is not None:
100 language = match.group(1) or match.group(2)
101 else:
102 language = None
103 return platform, browser, version, language
106class UserAgent(object):
107 """Represents a user agent. Pass it a WSGI environment or a user agent
108 string and you can inspect some of the details from the user agent
109 string via the attributes. The following attributes exist:
111 .. attribute:: string
113 the raw user agent string
115 .. attribute:: platform
117 the browser platform. The following platforms are currently
118 recognized:
120 - `aix`
121 - `amiga`
122 - `android`
123 - `blackberry`
124 - `bsd`
125 - `chromeos`
126 - `dragonflybsd`
127 - `freebsd`
128 - `hpux`
129 - `ipad`
130 - `iphone`
131 - `irix`
132 - `linux`
133 - `macos`
134 - `netbsd`
135 - `openbsd`
136 - `sco`
137 - `solaris`
138 - `symbian`
139 - `wii`
140 - `windows`
142 .. attribute:: browser
144 the name of the browser. The following browsers are currently
145 recognized:
147 - `aol` *
148 - `ask` *
149 - `baidu` *
150 - `bing` *
151 - `camino`
152 - `chrome`
153 - `edge`
154 - `firefox`
155 - `galeon`
156 - `google` *
157 - `kmeleon`
158 - `konqueror`
159 - `links`
160 - `lynx`
161 - `mozilla`
162 - `msie`
163 - `msn`
164 - `netscape`
165 - `opera`
166 - `safari`
167 - `seamonkey`
168 - `webkit`
169 - `yahoo` *
171 (Browsers marked with a star (``*``) are crawlers.)
173 .. attribute:: version
175 the version of the browser
177 .. attribute:: language
179 the language of the browser
180 """
182 _parser = UserAgentParser()
184 def __init__(self, environ_or_string):
185 if isinstance(environ_or_string, dict):
186 environ_or_string = environ_or_string.get("HTTP_USER_AGENT", "")
187 self.string = environ_or_string
188 self.platform, self.browser, self.version, self.language = self._parser(
189 environ_or_string
190 )
192 def to_header(self):
193 return self.string
195 def __str__(self):
196 return self.string
198 def __nonzero__(self):
199 return bool(self.browser)
201 __bool__ = __nonzero__
203 def __repr__(self):
204 return "<%s %r/%s>" % (self.__class__.__name__, self.browser, self.version)