new user agent, thananks Angelo

This commit is contained in:
Massimo DiPierro
2011-12-02 16:16:30 -06:00
parent 3b017cb0e9
commit 32b0ff3289
2 changed files with 210 additions and 108 deletions
+1 -1
View File
@@ -1 +1 @@
Version 1.99.3 (2011-11-30 22:36:21) dev Version 1.99.3 (2011-12-02 16:16:28) dev
+209 -107
View File
@@ -9,6 +9,9 @@ Aim is
Taken from http://pypi.python.org/pypi/httpagentparser (MIT license) Taken from http://pypi.python.org/pypi/httpagentparser (MIT license)
Modified my Ross Peoples for web2py to better support iPhone and iPad. Modified my Ross Peoples for web2py to better support iPhone and iPad.
Modified by Angelo Compagnucci <angelo.compagnucci@gmail.com> to better support a wide ringe of mobile devices.
Now it supports: tablet device (is_tablet), BlackBerry, BlackBerry PlayBook, Android Tablets, Windows Mobile,
Symbian.
""" """
import sys import sys
@@ -52,13 +55,14 @@ class DetectorsHub(dict):
class DetectorBase(object): class DetectorBase(object):
name = "" # "to perform match in DetectorsHub object" name = "" # "to perform match in DetectorsHub object"
info_type = "override me" info_type = '' #override me
result_key = "override me" result_key = '' #override me
order = 10 # 0 is highest order = 10 # 0 is highest
look_for = "string to look for" look_for = [] # list of words to look for
skip_if_found = [] # strings if present stop processin skip_if_found = [] # strings if present stop processin
can_register = False can_register = False
is_mobile = False is_mobile = False
is_tablet = False
prefs = dict() # dict(info_type = [name1, name2], ..) prefs = dict() # dict(info_type = [name1, name2], ..)
version_splitters = ["/", " "] version_splitters = ["/", " "]
_suggested_detectors = None _suggested_detectors = None
@@ -71,9 +75,16 @@ class DetectorBase(object):
def detect(self, agent, result): def detect(self, agent, result):
if agent and self.checkWords(agent): if agent and self.checkWords(agent):
result[self.info_type] = dict(name=self.name) result[self.info_type] = dict(name=self.name)
result[self.info_type]['is_mobile'] = self.is_mobile is_mobile=self.is_mobile
if not result.get('is_mobile',None): is_tablet=self.is_tablet
result['is_mobile'] = result[self.info_type]['is_mobile'] if result.get('is_mobile') is None:
result['is_mobile'] = False
if is_mobile:
result['is_mobile'] = is_mobile
if result.get('is_tablet') is None:
result['is_tablet'] = False
if is_tablet:
result['is_tablet'] = is_tablet
version = self.getVersion(agent) version = self.getVersion(agent)
if version: if version:
@@ -86,14 +97,18 @@ class DetectorBase(object):
for w in self.skip_if_found: for w in self.skip_if_found:
if w in agent: if w in agent:
return False return False
if self.look_for in agent: for w in self.look_for:
return True if not w in agent:
return False return False
return True
# It get the version correctly only if the words list
# contains only one element, alternatively, you have to
# override this method
def getVersion(self, agent): def getVersion(self, agent):
# -> version string /None # -> version string /None
vs = self.version_splitters vs = self.version_splitters
return agent.split(self.look_for + vs[0])[-1].split(vs[1])[0].strip() return agent.split(self.look_for[0] + vs[0])[1].split(vs[1])[0].strip()
class OS(DetectorBase): class OS(DetectorBase):
@@ -118,85 +133,128 @@ class Browser(DetectorBase):
class Macintosh(OS): class Macintosh(OS):
look_for = 'Macintosh' look_for = ['Macintosh']
prefs = dict(dist=None) prefs = dict(dist=None)
def getVersion(self, agent): def getVersion(self, agent):
pass pass
class Firefox(Browser): class Firefox(Browser):
look_for = "Firefox" look_for = ["Firefox"]
class Konqueror(Browser): class Konqueror(Browser):
look_for = "Konqueror" look_for = ["Konqueror"]
version_splitters = ["/", ";"] version_splitters = ["/", ";"]
class Opera(Browser): class Opera(Browser):
look_for = "Opera" look_for = ["Opera"]
def getVersion(self, agent): def getVersion(self, agent):
return agent.split(self.look_for)[1][1:].split(' ')[0] return agent.split(self.look_for[0])[1][1:].split(' ')[0]
class Netscape(Browser): class Netscape(Browser):
look_for = "Netscape" look_for = ["Netscape"]
class MSIE(Browser): class MSIE(Browser):
look_for = "MSIE" look_for = ["MSIE"]
skip_if_found = ["Opera"] skip_if_found = ["Opera"]
name = "Microsoft Internet Explorer" name = "Microsoft Internet Explorer"
version_splitters = [" ", ";"] version_splitters = [" ", ";"]
class Galeon(Browser): class Galeon(Browser):
look_for = "Galeon" look_for = ["Galeon"]
class Safari(Browser): class Safari(Browser):
look_for = "Safari" look_for = ["Safari"]
skip_if_found = ["Chrome", "OmniWeb", "Mobile", "iPad", 'Android']
def checkWords(self, agent):
unless_list = ["Chrome", "OmniWeb"]
if self.look_for in agent:
for word in unless_list:
if word in agent:
return False
return True
def getVersion(self, agent): def getVersion(self, agent):
if "Version/" in agent: if "Version/" in agent:
return agent.split('Version/')[-1].split(' ')[0].strip() return agent.split('Version/')[1].split(' ')[0].strip()
else:
# Mobile Safari class SafariTablet(Browser):
return agent.split('Safari ')[-1].split(' ')[0].strip() name = "Safari"
look_for = ['Safari', 'Android']
skip_if_found = ["Chrome", "OmniWeb", "Mobile", "iPad"]
is_mobile = True
is_tablet = True
def getVersion(self, agent):
if "Version/" in agent:
return agent.split('Version/')[1].split(' ')[0].strip()
class SafariMobile(Browser):
name = "Safari"
look_for = ["Safari", "Mobile"]
is_mobile = True
def getVersion(self, agent):
if "Version/" in agent:
return agent.split('Version/')[1].split(' ')[0].strip()
class SafariNokia(Browser):
name = "Safari"
look_for = ["Safari", "SymbianOS"]
is_mobile = True
def getVersion(self, agent):
pass
class SafariiPad(Browser):
name = "Safari"
look_for = ["Safari", "iPad"]
skip_if_found = ["Chrome", "OmniWeb"]
is_mobile = True
is_tablet = True
def getVersion(self, agent):
if "Version/" in agent:
return agent.split('Version/')[1].split(' ')[0].strip()
class Linux(OS): class Linux(OS):
look_for = 'Linux' look_for = ["Linux"]
prefs = dict(browser=["Firefox"], prefs = dict(dist=["Ubuntu", "Android", "Debian"], flavor=None)
dist=["Ubuntu", "Android"], flavor=None)
def getVersion(self, agent): def getVersion(self, agent):
pass pass
class RIM(OS): class BlackBerry(OS):
look_for = 'BlackBerry' look_for = ['BlackBerry']
prefs = dict(dist=[None], flavor=None) prefs = dict( flavor=['PlayBook'])
is_mobile = True
# Manual check for tablet
def checkWords(self, agent):
if 'BlackBerry' in agent or 'PlayBook' in agent:
return True
return False
def getVersion(self, agent): def getVersion(self, agent):
pass pass
class PlayBook(Flavor):
look_for = ['PlayBook']
is_mobile=True
is_tablet=True
def getVersion(self, agent):
return agent.partition('Tablet OS')[2].partition(';')[0].strip()
class Macintosh(OS): class Macintosh(OS):
look_for = 'Macintosh' look_for = ['Macintosh']
prefs = dict(dist=None, flavor=['MacOS']) prefs = dict(dist=None, flavor=['MacOS'])
def getVersion(self, agent): def getVersion(self, agent):
pass pass
class MacOS(Flavor): class MacOS(Flavor):
look_for = 'Mac OS' look_for = ['Mac OS']
prefs = dict(browser=['Firefox', 'Opera', "Microsoft Internet Explorer"]) prefs = dict(browser=['Safari','SafariMobile', 'SafariIpad', 'Firefox', 'Opera', "Microsoft Internet Explorer"])
def getVersion(self, agent): def getVersion(self, agent):
version_end_chars = [';', ')'] version_end_chars = [';', ')']
@@ -209,63 +267,81 @@ class MacOS(Flavor):
class Windows(OS): class Windows(OS):
look_for = 'Windows' look_for = ['Windows', 'NT']
prefs = dict(browser=["Microsoft Internet Explorer", 'Firefox'], prefs = dict(browser=["Microsoft Internet Explorer", 'Firefox'],
dist=['WindowsMobile'], flavor=None) dist=['WindowsMobile'], flavor=None)
def getVersion(self, agent): def getVersion(self, agent):
v = agent.split('Windows')[-1].split(';')[0].strip() v = agent.partition('NT')
if ')' in v: return v[1]+' '+v[2].replace(')',';').partition(';')[0].strip()
v = v.split(')')[0]
return v
class WindowsMobile(Dist):
name = 'Phone'
look_for = ['Windows', 'Phone']
is_mobile = True
def getVersion(self, agent):
return agent.partition('Windows Phone')[2].replace(')','').partition(';')[0].strip()
class Ubuntu(Dist): class Ubuntu(Dist):
look_for = 'Ubuntu' look_for = ['Ubuntu']
version_splitters = ["/", " "] version_splitters = ["/", " "]
prefs = dict(browser=['Firefox']) prefs = dict(browser=['Firefox'])
class Debian(Dist): class Debian(Dist):
look_for = 'Debian' look_for = ['Debian']
version_splitters = ["/", " "] version_splitters = ["/", " "]
prefs = dict(browser=['Firefox']) prefs = dict(browser=['Firefox'])
class Chrome(Browser): class Chrome(Browser):
look_for = "Chrome" look_for = ['Chrome']
version_splitters = ["/", " "] version_splitters = ["/", " "]
class ChromeOS(OS): class ChromeOS(OS):
look_for = "CrOS" look_for = ['CrOS']
version_splitters = [" ", " "] version_splitters = [" ", " "]
prefs = dict(browser=['Chrome']) prefs = dict(browser=['Chrome'])
def getVersion(self, agent): def getVersion(self, agent):
vs = self.version_splitters vs = self.version_splitters
return agent.split(self.look_for+vs[0])[-1].split(vs[1])[1].strip()[:-1] return agent.split(self.look_for[0]+vs[0])[1].split(vs[1])[1].strip()[:-1]
class WindowsMobile(Dist):
look_for = 'Windows Phone'
is_mobile = True
def getVersion(self, agent):
return agent.split('Windows Phone')[-1].split(';')[0].strip().split(' ')[-1]
class Android(Dist): class Android(Dist):
look_for = 'Android' look_for = ['Android']
prefs = dict(browser=['SafariTablet', 'SafariMobile'])
is_mobile = True is_mobile = True
def getVersion(self, agent): def getVersion(self, agent):
return agent.split('Android')[-1].split(';')[0].strip() return agent.split('Android')[1].split(';')[0].strip()
class SymbianOS(OS):
look_for = ['SymbianOS']
prefs = dict(dist = ['Series'], browser = ['Safari', 'Opera'])
is_mobile = True
version_splitters = ['/', '; ']
class Series(Flavor):
look_for = ['SymbianOS', 'Series']
version_splitters = ['/', ';']
def getVersion(self, agent):
return agent.partition('Series')[2].partition(' ')[0].replace('/',' ')
class BrowserNG(Browser):
look_for = ['BrowserNG']
version_splitters = ['/', ';']
class iPhone(Dist): class iPhone(Dist):
look_for = 'iPhone' look_for = ['iPhone']
is_mobile = True is_mobile = True
prefs = dict(browser=['SafariMobile'])
def getVersion(self, agent): def getVersion(self, agent):
version_end_chars = ['like', ';', ')'] version_end_chars = ['like', ';', ')']
part = agent.split('CPU OS')[-1].strip() if (not 'CPU iPhone OS' in agent) and (not 'CPU OS' in agent):
return 'X'
part = agent.split('OS')[1].strip()
for c in version_end_chars: for c in version_end_chars:
if c in part: if c in part:
version = 'iOS ' + part.split(c)[0].strip() version = 'iOS ' + part.split(c)[0].strip()
@@ -273,12 +349,15 @@ class iPhone(Dist):
return version.replace('_', '.') return version.replace('_', '.')
class iPad(Dist): class iPad(Dist):
look_for = 'iPad' look_for = ['iPad']
is_mobile = True is_mobile = True
is_tablet = True
def getVersion(self, agent): def getVersion(self, agent):
version_end_chars = ['like', ';', ')'] version_end_chars = ['like', ';', ')']
part = agent.split('CPU OS')[-1].strip() if not 'OS' in agent:
return ''
part = agent.split('OS')[1].strip()
for c in version_end_chars: for c in version_end_chars:
if c in part: if c in part:
version = 'iOS ' + part.split(c)[0].strip() version = 'iOS ' + part.split(c)[0].strip()
@@ -290,21 +369,13 @@ detectorshub = DetectorsHub()
def detect(agent): def detect(agent):
result = dict() result = dict()
prefs = dict() prefs = dict()
_suggested_detectors = []
for info_type in detectorshub: for info_type in detectorshub:
if not _suggested_detectors: detectors = detectorshub[info_type]
detectors = detectorshub[info_type] _d_prefs = prefs.get(info_type, [])
_d_prefs = prefs.get(info_type, []) detectors = detectorshub.reorderByPrefs(detectors, _d_prefs)
detectors = detectorshub.reorderByPrefs(detectors, _d_prefs)
if "detector" in locals():
detector._suggested_detectors = detectors
else:
detectors = _suggested_detectors
for detector in detectors: for detector in detectors:
# print "detector name: ", detector.name
if detector.detect(agent, result): if detector.detect(agent, result):
prefs = detector.prefs prefs = detector.prefs
_suggested_detectors = detector._suggested_detectors
break break
return result return result
@@ -327,8 +398,7 @@ def simple_detect(agent):
os_version = os_list and ('flavor' in result and result['flavor'] and result['flavor'].get( os_version = os_list and ('flavor' in result and result['flavor'] and result['flavor'].get(
'version')) or ('dist' in result and result['dist'] and result['dist'].get('version')) \ 'version')) or ('dist' in result and result['dist'] and result['dist'].get('version')) \
or ('os' in result and result['os'] and result['os'].get('version')) or "" or ('os' in result and result['os'] and result['os'].get('version')) or ""
browser = 'browser' in result and result['browser']['name'] \ browser = 'browser' in result and result['browser']['name'] or 'Unknown Browser'
or 'Unknown Browser'
browser_version = 'browser' in result \ browser_version = 'browser' in result \
and result['browser'].get('version') or "" and result['browser'].get('version') or ""
if browser_version: if browser_version:
@@ -336,7 +406,7 @@ def simple_detect(agent):
if os_version: if os_version:
os = " ".join((os, os_version)) os = " ".join((os, os_version))
#is_mobile = ('dist' in result and result.dist.is_mobile) or ('os' in result and result.os.is_mobile) or False #is_mobile = ('dist' in result and result.dist.is_mobile) or ('os' in result and result.os.is_mobile) or False
return os, browser, result.is_mobile return os, browser, result['is_mobile']
if __name__ == '__main__': if __name__ == '__main__':
@@ -344,38 +414,70 @@ if __name__ == '__main__':
import unittest import unittest
data = ( data = (
("Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-GB; rv:1.9.0.10) Gecko/2009042315 Firefox/3.0.10",
('MacOS Macintosh X 10.5', 'Firefox 3.0.10'),
{'flavor': {'version': 'X 10.5', 'name': 'MacOS'}, 'os': {'name': 'Macintosh'}, 'browser': {'version': '3.0.10', 'name': 'Firefox'}},), ('Mozilla/5.0 (SymbianOS/9.2; U; Series60/3.1 Nokia6120c/3.83; Profile/MIDP-2.0 Configuration/CLDC-1.1) AppleWebKit/413 (KHTML, like Gecko) Safari/413',
("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_6) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.3 Safari/534.24,gzip(gfe)", ('Series SymbianOS 60 3.1', 'Safari', True),
('MacOS Macintosh X 10.6.6', 'Chrome 11.0.696.3'), {'is_mobile': True, 'is_tablet': False, 'flavor': {'name': 'Series', 'version': '60 3.1'}, 'os': {'name': 'SymbianOS', 'version': '9.2'}, 'browser': {'name': 'Safari'}},),
{'flavor': {'version': 'X 10.6.6', 'name': 'MacOS'}, 'os': {'name': 'Macintosh'}, 'browser': {'version': '11.0.696.3', 'name': 'Chrome'}},), ('Mozilla/5.0 (SymbianOS/9.4; Series60/5.0 NokiaN97-1/20.0.019; Profile/MIDP-2.1 Configuration/CLDC-1.1) AppleWebKit/525 (KHTML, like Gecko) BrowserNG/7.1.18124',
("Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2) Gecko/20100308 Ubuntu/10.04 (lucid) Firefox/3.6 GTB7.1", ('Series SymbianOS 60 5.0', 'BrowserNG 7.1.18124', True),
('Ubuntu Linux 10.04', 'Firefox 3.6'), {'is_mobile': True, 'is_tablet': False, 'flavor': {'name': 'Series', 'version': '60 5.0'}, 'os': {'name': 'SymbianOS', 'version': '9.4'}, 'browser': {'name': 'BrowserNG', 'version': '7.1.18124'}},),
{'dist': {'version': '10.04', 'name': 'Ubuntu'}, 'os': {'name': 'Linux'}, 'browser': {'version': '3.6', 'name': 'Firefox'}},), ('Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; Windows Phone 6.5.3.5)',
("Mozilla/5.0 (Linux; U; Android 2.2.1; fr-ch; A43 Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", ('Phone Windows 6.5.3.5', 'Microsoft Internet Explorer 6.0', True),
('Android Linux 2.2.1', 'Safari 4.0'), {'is_mobile': True, 'is_tablet': False, 'dist': {'name': 'Phone', 'version': '6.5.3.5'}, 'os': {'name': 'Windows', 'version': 'NT 5.1'}, 'browser': {'name': 'Microsoft Internet Explorer', 'version': '6.0'}},),
{'dist': {'version': '2.2.1', 'name': 'Android'}, 'os': {'name': 'Linux'}, 'browser': {'version': '4.0', 'name': 'Safari'}},), ('Mozilla/5.0 (PlayBook; U; RIM Tablet OS 1.0.0; en-US) AppleWebKit/534.8+ (KHTML, like Gecko) Version/0.0.1 Safari/534.8+',
("Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3", ('PlayBook BlackBerry 1.0.0', 'Safari 0.0.1', True),
('MacOS IPhone X', 'Safari 3.0'), {'is_mobile': True, 'is_tablet': True, 'flavor': {'name': 'PlayBook', 'version': '1.0.0'}, 'os': {'name': 'BlackBerry'}, 'browser': {'name': 'Safari', 'version': '0.0.1'}},),
{'flavor': {'version': 'X', 'name': 'MacOS'}, 'dist': {'version': 'X', 'name': 'IPhone'}, 'browser': {'version': '3.0', 'name': 'Safari'}},), ('Mozilla/5.0 (BlackBerry; U; BlackBerry 9800; en-US) AppleWebKit/534.1+ (KHTML, like Gecko) Version/6.0.0.246 Mobile Safari/534.1+',
("Mozilla/5.0 (X11; CrOS i686 0.0.0) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.27 Safari/534.24,gzip(gfe)", ('BlackBerry', 'Safari 6.0.0.246', True),
('ChromeOS 0.0.0', 'Chrome 11.0.696.27'), {'is_mobile': True, 'is_tablet': False, 'os': {'name': 'BlackBerry'}, 'browser': {'name': 'Safari', 'version': '6.0.0.246'}},),
{'os': {'name': 'ChromeOS', 'version': '0.0.0'}, 'browser': {'name': 'Chrome', 'version': '11.0.696.27'}},), ('Mozilla/5.0 (BlackBerry; U; BlackBerry 9800; en-US) AppleWebKit/534.8+ (KHTML, like Gecko) Version/6.0.0.600 Mobile Safari/534.8+',
("Mozilla/4.0 (compatible; MSIE 6.0; MSIE 5.5; Windows NT 5.1) Opera 7.02 [en]", ('BlackBerry', 'Safari 6.0.0.600', True),
('Windows NT 5.1', 'Opera 7.02'), {'is_mobile': True, 'is_tablet': False, 'os': {'name': 'BlackBerry'}, 'browser': {'name': 'Safari', 'version': '6.0.0.600'}},),
{'os': {'name': 'Windows', 'version': 'NT 5.1'}, 'browser': {'name': 'Opera', 'version': '7.02'}},), ('Mozilla/5.0 (iPad; U; CPU OS 4_2_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5',
("Opera/9.80 (X11; Linux i686; U; en) Presto/2.9.168 Version/11.50", ('MacOS iPad X', 'Safari 5.0.2', True),
("Linux", "Opera 9.80"), {'is_mobile': True, 'is_tablet': True, 'flavor': {'version': 'X', 'name': 'MacOS'}, 'dist': {'version': 'iOS 4.2.1', 'name': 'iPad'}, 'browser': {'name': 'Safari', 'version': '5.0.2'}},),
{"os": {"name": "Linux"}, "browser": {"name": "Opera", "version": "9.80"}},), ('Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5) Gecko/20060127 Netscape/8.1',
("Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5) Gecko/20060127 Netscape/8.1", ('Windows NT 5.1', 'Netscape 8.1', False),
("Windows NT 5.1", "Netscape 8.1"), {'is_mobile': False, 'is_tablet': False, 'os': {'name': 'Windows', 'version': 'NT 5.1'}, 'browser': {'name': 'Netscape', 'version': '8.1'}},),
{'os': {'name': 'Windows', 'version': 'NT 5.1'}, 'browser': {'name': 'Netscape', 'version': '8.1'}},), ('Mozilla/5.0 (Linux; U; Android 3.0.1; en-us; A500 Build/HRI66) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13',
('Android Linux 3.0.1', 'Safari 4.0', True),
{'is_mobile': True, 'is_tablet': True, 'dist': {'version': '3.0.1', 'name': 'Android'}, 'os': {'name': 'Linux'}, 'browser': {'version': '4.0', 'name': 'Safari'}},),
('Mozilla/5.0 (Linux; U; Android 2.3.7; it-it; Dream/Sapphire Build/FRG83) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1',
('Android Linux 2.3.7', 'Safari 4.0', True),
{'is_mobile': True, 'is_tablet': False, 'dist': {'version': '2.3.7', 'name': 'Android'}, 'os': {'name': 'Linux'}, 'browser': {'version': '4.0', 'name': 'Safari'}},),
('Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-GB; rv:1.9.0.10) Gecko/2009042315 Firefox/3.0.10',
('MacOS Macintosh X 10.5', 'Firefox 3.0.10', False),
{ 'is_mobile': False, 'is_tablet': False, 'flavor': {'version': 'X 10.5', 'name': 'MacOS'}, 'os': {'name': 'Macintosh'}, 'browser': {'version': '3.0.10', 'name': 'Firefox'}},),
('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_6) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.3 Safari/534.24,gzip(gfe)',
('MacOS Macintosh X 10.6.6', 'Chrome 11.0.696.3', False),
{'is_mobile': False, 'is_tablet': False, 'flavor': {'version': 'X 10.6.6', 'name': 'MacOS'}, 'os': {'name': 'Macintosh'}, 'browser': {'version': '11.0.696.3', 'name': 'Chrome'}},),
('Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2) Gecko/20100308 Ubuntu/10.04 (lucid) Firefox/3.6 GTB7.1',
('Ubuntu Linux 10.04', 'Firefox 3.6', False),
{'is_mobile': False, 'is_tablet': False, 'dist': {'version': '10.04', 'name': 'Ubuntu'}, 'os': {'name': 'Linux'}, 'browser': {'version': '3.6', 'name': 'Firefox'}},),
('Mozilla/5.0 (Linux; U; Android 2.2.1; fr-ch; A43 Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1',
('Android Linux 2.2.1', 'Safari 4.0', True),
{'is_mobile': True, 'is_tablet': False, 'dist': {'version': '2.2.1', 'name': 'Android'}, 'os': {'name': 'Linux'}, 'browser': {'version': '4.0', 'name': 'Safari'}},),
('Mozilla/5.0 (Linux; U; Android 2.3.4; it-it; LG-P990 Build/GRJ22) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1 MMS/LG-Android-MMS-V1.0/1.2',
('Android Linux 2.3.4', 'Safari 4.0', True),
{'is_mobile': True, 'is_tablet': False, 'dist': {'version': '2.3.4', 'name': 'Android'}, 'os': {'name': 'Linux'}, 'browser': {'version': '4.0', 'name': 'Safari'}},),
('Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3',
('MacOS iPhone X', 'Safari 3.0', True),
{'is_mobile': True, 'is_tablet': False, 'flavor': {'version': 'X', 'name': 'MacOS'}, 'dist': {'version': 'X', 'name': 'iPhone'}, 'browser': {'version': '3.0', 'name': 'Safari'}},),
('Mozilla/5.0 (X11; CrOS i686 0.0.0) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.27 Safari/534.24,gzip(gfe)',
('ChromeOS 0.0.0', 'Chrome 11.0.696.27', False),
{'is_mobile': False, 'is_tablet': False, 'os': {'name': 'ChromeOS', 'version': '0.0.0'}, 'browser': {'name': 'Chrome', 'version': '11.0.696.27'}},),
('Mozilla/4.0 (compatible; MSIE 6.0; MSIE 5.5; Windows NT 5.1) Opera 7.02 [en]',
('Windows NT 5.1', 'Opera 7.02', False),
{'is_mobile': False, 'is_tablet': False, 'os': {'name': 'Windows', 'version': 'NT 5.1'}, 'browser': {'name': 'Opera', 'version': '7.02'}},),
('Opera/9.80 (X11; Linux i686; U; en) Presto/2.9.168 Version/11.50',
('Linux', 'Opera 9.80', False),
{'is_mobile': False, 'is_tablet': False, 'os': {'name': 'Linux'}, 'browser': {'name': 'Opera', 'version': '9.80'}},),
) )
class TestHAP(unittest.TestCase): class TestHAP(unittest.TestCase):
def setUp(self): def setUp(self):
self.harass_repeat = 1000 self.harass_repeat = 100
self.data = data self.data = data
def test_simple_detect(self): def test_simple_detect(self):