????
Current Path : C:/opt/pgsql/pgAdmin 4/python/Lib/site-packages/user_agents/ |
Current File : C:/opt/pgsql/pgAdmin 4/python/Lib/site-packages/user_agents/parsers.py |
from collections import namedtuple from ua_parser import user_agent_parser from .compat import string_types MOBILE_DEVICE_FAMILIES = ( 'iPhone', 'iPod', 'Generic Smartphone', 'Generic Feature Phone', 'PlayStation Vita', 'iOS-Device' ) PC_OS_FAMILIES = ( 'Windows 95', 'Windows 98', 'Solaris', ) MOBILE_OS_FAMILIES = ( 'Windows Phone', 'Windows Phone OS', # Earlier versions of ua-parser returns Windows Phone OS 'Symbian OS', 'Bada', 'Windows CE', 'Windows Mobile', 'Maemo', ) MOBILE_BROWSER_FAMILIES = ( 'IE Mobile', 'Opera Mobile', 'Opera Mini', 'Chrome Mobile', 'Chrome Mobile WebView', 'Chrome Mobile iOS', ) TABLET_DEVICE_FAMILIES = ( 'iPad', 'BlackBerry Playbook', 'Blackberry Playbook', # Earlier versions of ua-parser returns "Blackberry" instead of "BlackBerry" 'Kindle', 'Kindle Fire', 'Kindle Fire HD', 'Galaxy Tab', 'Xoom', 'Dell Streak', ) TOUCH_CAPABLE_OS_FAMILIES = ( 'iOS', 'Android', 'Windows Phone', 'Windows CE', 'Windows Mobile', 'Firefox OS', 'MeeGo', ) TOUCH_CAPABLE_DEVICE_FAMILIES = ( 'BlackBerry Playbook', 'Blackberry Playbook', 'Kindle Fire', ) EMAIL_PROGRAM_FAMILIES = set(( 'Outlook', 'Windows Live Mail', 'AirMail', 'Apple Mail', 'Outlook', 'Thunderbird', 'Lightning', 'ThunderBrowse', 'Windows Live Mail', 'The Bat!', 'Lotus Notes', 'IBM Notes', 'Barca', 'MailBar', 'kmail2', 'YahooMobileMail' )) def verify_attribute(attribute): if isinstance(attribute, string_types) and attribute.isdigit(): return int(attribute) return attribute def parse_version(major=None, minor=None, patch=None, patch_minor=None): # Returns version number tuple, attributes will be integer if they're numbers major = verify_attribute(major) minor = verify_attribute(minor) patch = verify_attribute(patch) patch_minor = verify_attribute(patch_minor) return tuple( filter(lambda x: x is not None, (major, minor, patch, patch_minor)) ) Browser = namedtuple('Browser', ['family', 'version', 'version_string']) def parse_browser(family, major=None, minor=None, patch=None, patch_minor=None): # Returns a browser object version = parse_version(major, minor, patch) version_string = '.'.join([str(v) for v in version]) return Browser(family, version, version_string) OperatingSystem = namedtuple('OperatingSystem', ['family', 'version', 'version_string']) def parse_operating_system(family, major=None, minor=None, patch=None, patch_minor=None): version = parse_version(major, minor, patch) version_string = '.'.join([str(v) for v in version]) return OperatingSystem(family, version, version_string) Device = namedtuple('Device', ['family', 'brand', 'model']) def parse_device(family, brand, model): return Device(family, brand, model) class UserAgent(object): def __init__(self, user_agent_string): ua_dict = user_agent_parser.Parse(user_agent_string) self.ua_string = user_agent_string self.os = parse_operating_system(**ua_dict['os']) self.browser = parse_browser(**ua_dict['user_agent']) self.device = parse_device(**ua_dict['device']) def __str__(self): return "{device} / {os} / {browser}".format( device=self.get_device(), os=self.get_os(), browser=self.get_browser() ) def __unicode__(self): return unicode(str(self)) def _is_android_tablet(self): # Newer Android tablets don't have "Mobile" in their user agent string, # older ones like Galaxy Tab still have "Mobile" though they're not if ('Mobile Safari' not in self.ua_string and self.browser.family != "Firefox Mobile"): return True return False def _is_blackberry_touch_capable_device(self): # A helper to determine whether a BB phone has touch capabilities # Blackberry Bold Touch series begins with 99XX if 'Blackberry 99' in self.device.family: return True if 'Blackberry 95' in self.device.family: # BB Storm devices return True return False def get_device(self): return self.is_pc and "PC" or self.device.family def get_os(self): return ("%s %s" % (self.os.family, self.os.version_string)).strip() def get_browser(self): return ("%s %s" % (self.browser.family, self.browser.version_string)).strip() @property def is_tablet(self): if self.device.family in TABLET_DEVICE_FAMILIES: return True if (self.os.family == 'Android' and self._is_android_tablet()): return True if self.os.family == 'Windows' and self.os.version_string.startswith('RT'): return True if self.os.family == 'Firefox OS' and 'Mobile' not in self.browser.family: return True return False @property def is_mobile(self): # First check for mobile device and mobile browser families if self.device.family in MOBILE_DEVICE_FAMILIES: return True if self.browser.family in MOBILE_BROWSER_FAMILIES: return True # Device is considered Mobile OS is Android and not tablet # This is not fool proof but would have to suffice for now if ((self.os.family == 'Android' or self.os.family == 'Firefox OS') and not self.is_tablet): return True if self.os.family == 'BlackBerry OS' and self.device.family != 'Blackberry Playbook': return True if self.os.family in MOBILE_OS_FAMILIES: return True # TODO: remove after https://github.com/tobie/ua-parser/issues/126 is closed if 'J2ME' in self.ua_string or 'MIDP' in self.ua_string: return True # This is here mainly to detect Google's Mobile Spider if 'iPhone;' in self.ua_string: return True if 'Googlebot-Mobile' in self.ua_string: return True # Mobile Spiders should be identified as mobile if self.device.family == 'Spider' and 'Mobile' in self.browser.family: return True # Nokia mobile if 'NokiaBrowser' in self.ua_string and 'Mobile' in self.ua_string: return True return False @property def is_touch_capable(self): # TODO: detect touch capable Nokia devices if self.os.family in TOUCH_CAPABLE_OS_FAMILIES: return True if self.device.family in TOUCH_CAPABLE_DEVICE_FAMILIES: return True if self.os.family == 'Windows': if self.os.version_string.startswith(('RT', 'CE')): return True if self.os.version_string.startswith('8') and 'Touch' in self.ua_string: return True if 'BlackBerry' in self.os.family and self._is_blackberry_touch_capable_device(): return True return False @property def is_pc(self): # Returns True for "PC" devices (Windows, Mac and Linux) if 'Windows NT' in self.ua_string or self.os.family in PC_OS_FAMILIES or \ self.os.family == 'Windows' and self.os.version_string == 'ME': return True # TODO: remove after https://github.com/tobie/ua-parser/issues/127 is closed if self.os.family == 'Mac OS X' and 'Silk' not in self.ua_string: return True # Maemo has 'Linux' and 'X11' in UA, but it is not for PC if 'Maemo' in self.ua_string: return False if 'Chrome OS' in self.os.family: return True if 'Linux' in self.ua_string and 'X11' in self.ua_string: return True return False @property def is_bot(self): return True if self.device.family == 'Spider' else False @property def is_email_client(self): if self.browser.family in EMAIL_PROGRAM_FAMILIES: return True return False def parse(user_agent_string): return UserAgent(user_agent_string)