1
2
3 """
4 @copyright:
5 Copyright (c) 2014 by mTLD Top Level Domain Limited. All rights reserved.\n
6 Portions copyright (c) 2008 by Argo Interactive Limited.\n
7 Portions copyright (c) 2008 by Nokia Inc.\n
8 Portions copyright (c) 2008 by Telecom Italia Mobile S.p.A.\n
9 Portions copyright (c) 2008 by Volantis Systems Limited.\n
10 Portions copyright (c) 2002-2008 by Andreas Staeding.\n
11 Portions copyright (c) 2008 by Zandan.\n
12 @author: dotMobi
13 """
14
15 import datetime
16
17 from mobi.mtld.da.exception.invalid_property_name_exception import InvalidPropertyNameException
18 from mobi.mtld.da.exception.data_file_exception import DataFileException
19 from mobi.mtld.da.exception.client_properties_exception import ClientPropertiesException
20 from mobi.mtld.da.exception.incorrect_property_type_exception import IncorrectPropertyTypeException
21
22 from mobi.mtld.da.data_type import DataType
23
24 from mobi.mtld.da.device.config import Config
25 from mobi.mtld.da.device.device_api import DeviceApi
28 """
29 UnknownPropertyException is thrown by the API class when there is an
30 attempt to fetch a property that is unknown for the supplied user agent or
31 tree.
32
33 @deprecated: Please use the new interface and exception classes through
34 DeviceApi instead.
35 """
36 pass
37
39 """
40 InvalidPropertyException is thrown by the API class when there is an
41 attempt to fetch a property that is unknown for the supplied user agent,
42 tree and client side property set.
43
44 @deprecated: Please use the new interface and exception classes through
45 DeviceApi instead.
46 """
47 pass
48
50 """
51 JsonException is thrown when there is an error loading the data file.
52
53 @deprecated: Please use the new interface and exception classes through
54 DeviceApi instead.
55 """
56 pass
57
59 """
60 Used to load the recognition tree and perform lookups of all properties, or
61 get individual properties. Typical usage is as follows:
62
63 >>> deviceAtlas = DaApi()
64 >>> path = 'data_file/sample.json'
65 >>> tree = mobi.mtld.da.getTreeFromFile(path)
66 >>> properties = mobi.mtld.da.getProperties(tree, "Nokia6680...")
67 >>> property = mobi.mtld.da.getProperty(tree, "Nokia6680...", "displayWidth")
68
69 Note that you should normally use the user-agent that was received in
70 the device's HTTP request. In a BaseHTTPServer environment, you would do this
71 as follows:
72
73 >>> userAgent = self.headers['user-agent']
74 >>> displayWidth = mobi.mtld.da.getPropertyAsInteger(tree, userAgent,
75 >>> "displayWidth")
76
77 Third-party Browsers:
78
79 In some contexts, the user-agent you want to recognise may have been provided
80 in a different header. Opera's mobile browser, for example, makes requests via
81 an HTTP proxy, which rewrites the headers. in that case, the original device's
82 user-agent is in the "X-OperaMini-Phone-UA" header, and the following code
83 could be used:
84
85 >>> operaHeader = "X-OperaMini-Phone-UA"
86 >>> if operaHeader in request.headers:
87 >>> userAgent = self.headers[operaHeader]
88 >>> else:
89 >>> userAgent = self.headers['user-agent']
90 >>> displayWidth = mobi.mtld.da.getPropertyAsInteger(tree, userAgent,
91 >>> "displayWidth")
92
93 See here for more information:
94 https://mobi.mtld.da.com/resources/side-loaded-browser-handling
95
96 Client side properties:
97
98 Client side properties can be collected and merged into the results by using
99 the DeviceAtlas Javascript detection file. The results from the client side
100 are sent to the server inside a cookie. The contents of this cookie can be
101 passed to the DeviceAtlas getProperty and getProperties methods. The client
102 side properties over-ride any data file properties and also serve as an input
103 into additional logic to determine other properties such as the iPhone models
104 that are otherwise not detectable. The following code shows how this can be
105 done in BaseHTTPServer:
106
107 >>> userAgent = self.headers['user-agent']
108 >>> cookieContents = # method call to get the 'DAPROPS' cookie content
109 >>> properties = mobi.mtld.da.getPropertiesAsTyped(tree, userAgent,
110 >>> cookieContents)
111
112 @deprecated: Please use the new interface with DeviceApi instead.
113 """
114
115 @staticmethod
116 - def getTreeFromFile(filename, includeChangeableUserAgentProperties = True):
117 """
118 Return a tree from a JSON file. The loaded tree is stored in a static cache
119 to avoid multiple reloads if this method is repeatedly called. To reload
120 from the JSON file set "reload" to true.
121
122 Some properties cannot be known before runtime and can change from
123 user-agent to user-agent. The most common of these are the OS Version and
124 the Browser Version. This API is able to dynamically detect these changing
125 properties but introduces a small overhead to do so. To disable returning
126 these extra properties set "includeChangeableUserAgentProperties" to false.
127
128 @param filename: is the location of the file to read in. Use an absolute path
129 name to be sure of success if the current working directory is not clear.
130 @param includeChangeableUserAgentProperties: is to detect changeable
131 user-agent properties.
132
133 @deprecated: Please use DeviceApi.load_data_from_file() instead.
134 """
135
136
137
138 if not includeChangeableUserAgentProperties:
139 config = Config()
140 config.include_ua_props = False
141 device_api = DeviceApi(config)
142 else:
143 device_api = DeviceApi()
144
145 device_api.load_data_from_file(filename)
146
147 return {'api': device_api}
148
149 @staticmethod
151 """
152 Return a loaded JSON tree from a string of JSON data.
153
154 Some properties cannot be known before runtime and can change from
155 user-agent to user-agent. The most common of these are the OS Version and
156 the Browser Version. This API is able to dynamically detect these changing
157 properties but introduces a small overhead to do so. To disable returning
158 these extra properties set "includeChangeableUserAgentProperties" to false.
159
160 This method does not use the built in static cache.
161
162 @param json: is the string of json data.
163 @param includeChangeableUserAgentProperties: Also detect changeable user-agent
164 properties.
165
166 @deprecated: Please use DeviceApi.load_data_from_string() instead.
167 """
168
169
170
171 if not includeChangeableUserAgentProperties:
172 config = Config()
173 config.include_ua_props = False
174 device_api = DeviceApi(config)
175 else:
176 device_api = DeviceApi()
177
178 device_api.load_data_from_string(json)
179
180 return {'api': device_api}
181
182 @staticmethod
184 """
185 Get the generation date for this tree.
186 @param tree: is a dict object with the tree.
187 It returns the date and time the tree was generated.
188
189 @deprecated: Please use DeviceApi.get_data_creation_timestamp() instead.
190 """
191
192 time = tree['api'].get_data_creation_timestamp()
193 return datetime.datetime.utcfromtimestamp(time).strftime("%Y-%m-%d %H:%M:%S")
194
195 @staticmethod
197 """
198 Get the generation date for this tree as a UNIX timestamp.
199 @param tree: is a dict object with the tree.
200 It returns a timestamp the tree was generated.
201
202 @deprecated: Please use DeviceApi.get_data_creation_timestamp() instead.
203 """
204 return tree['api'].get_data_creation_timestamp()
205
206 @staticmethod
214
215 @staticmethod
221
222 @staticmethod
237
238 @staticmethod
239 - def getProperties(tree, userAgent, cookie = None, typedValues = False,
240 sought = None, uaPropsNeeded = True):
241 """
242 Return a associative array of known properties merged with properties from
243 the client side JavaScript. The client side JavaScript sets a cookie with
244 collected properties. The contents of this cookie must be passed to this
245 method for it to work. The client properties over-ride any properties
246 discovered from the main JSON data file.
247
248 @param tree: is the previously generated associative array tree.
249 @param userAgent: is the device's User-Agent header string.
250 @param cookie: is the content of the cookie containing the client side
251 properties.
252 @param typedValues: whether values in the results are typed.
253 @param sought: is a set of properties to return values for.
254 @param uaPropsNeeded: whether the extra properties from the UA String are
255 needed.
256
257 @deprecated: Please use DeviceApi.get_properties() instead.
258 """
259 return DaApi.__get_props_as_hash(tree['api'].get_properties(userAgent, cookie))
260
261 @staticmethod
263 """
264 Return an associative array of known properties merged with properties from
265 the client side JavaScript. The client side JavaScript sets a cookie with
266 collected properties. The contents of this cookie must be passed to this
267 method for it to work. The client properties over-ride any properties
268 discovered from the main JSON data file.
269
270 @param tree: is the previously generated associative array tree.
271 @param userAgent: is the device's User-Agent header string.
272 @param cookie: is the content of the cookie containing the client side
273 properties.
274
275 @deprecated: Please use DeviceApi.get_properties() instead.
276 """
277 properties_out = {}
278 properties_in = tree['api'].get_properties(userAgent, cookie)
279 for name, property_in in properties_in.items():
280 if property_in.data_type_id == DataType.BOOLEAN:
281 properties_out[name] = int(property_in.value) == 1
282 elif property_in.data_type_id == DataType.STRING:
283 properties_out[name] = str(property_in.value)
284 elif property_in.data_type_id == DataType.INTEGER:
285 properties_out[name] = int(property_in.value)
286 elif property_in.data_type_id == DataType.FLOAT:
287 properties_out[name] = float(property_in.value)
288 else:
289 properties_out[name] = property_in.value
290 return properties_out
291
292 @staticmethod
293 - def getProperty(tree, userAgent, property, cookie = None, typedValue = False):
294 """
295 Return a value for the named property for this user agent.
296
297 @param tree: Previously generated associative array tree.
298 @param userAgent: The device's User-Agent header string.
299 @param property: The name of the property to return.
300 @param cookie: The contents of the cookie containing the client side
301 properties.
302 @param typedValue: Whether value in the associative array are typed.
303
304 @deprecated: Please use DeviceApi.get_properties instead.
305 """
306 return DaApi.__get_property_object(tree, userAgent, property, cookie).value
307
308 @staticmethod
330
331 @staticmethod
333 """
334 Strongly typed property access.
335 Returns a date property (or throws an exception if the property is actually of
336 another type).
337
338 @param tree: Previously generated associative array tree.
339 @param userAgent: The device's User-Agent header string.
340 @param property: The name of the property to return.
341
342 @deprecated: Date data type is not supported anymore.
343 """
344 raise IncorrectPropertyTypeException("Date data type is not supported " +
345 "anymore as there are no Date device properties.")
346
347 @staticmethod
367
368 @staticmethod
388
389
390
391 @staticmethod
397
398 @staticmethod
409
410 @staticmethod
432
433 @staticmethod
435 return int(keyword.replace("$","")[5:].strip())
436