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

1# -*- coding: utf-8 -*- 

2""" 

3 werkzeug.useragents 

4 ~~~~~~~~~~~~~~~~~~~ 

5 

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. 

9 

10 

11 :copyright: 2007 Pallets 

12 :license: BSD-3-Clause 

13 

14 This package was vendored in odoo in order to prevent errors with werkzeug 2.1 

15""" 

16import re 

17 

18 

19class UserAgentParser(object): 

20 """A simple user agent parser. Used by the `UserAgent`.""" 

21 

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 ) 

70 

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 ) 

76 

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 ) 

83 

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 

104 

105 

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: 

110 

111 .. attribute:: string 

112 

113 the raw user agent string 

114 

115 .. attribute:: platform 

116 

117 the browser platform. The following platforms are currently 

118 recognized: 

119 

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` 

141 

142 .. attribute:: browser 

143 

144 the name of the browser. The following browsers are currently 

145 recognized: 

146 

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` * 

170 

171 (Browsers marked with a star (``*``) are crawlers.) 

172 

173 .. attribute:: version 

174 

175 the version of the browser 

176 

177 .. attribute:: language 

178 

179 the language of the browser 

180 """ 

181 

182 _parser = UserAgentParser() 

183 

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 ) 

191 

192 def to_header(self): 

193 return self.string 

194 

195 def __str__(self): 

196 return self.string 

197 

198 def __nonzero__(self): 

199 return bool(self.browser) 

200 

201 __bool__ = __nonzero__ 

202 

203 def __repr__(self): 

204 return "<%s %r/%s>" % (self.__class__.__name__, self.browser, self.version)