cengal.web_tools.detect_browsers_host_device_type.by_http_headers.versions.v_0.by_http_headers
1#!/usr/bin/env python 2# coding=utf-8 3 4# Copyright © 2012-2024 ButenkoMS. All rights reserved. Contacts: <gtalk@butenkoms.space> 5# 6# Licensed under the Apache License, Version 2.0 (the "License"); 7# you may not use this file except in compliance with the License. 8# You may obtain a copy of the License at 9# 10# http://www.apache.org/licenses/LICENSE-2.0 11# 12# Unless required by applicable law or agreed to in writing, software 13# distributed under the License is distributed on an "AS IS" BASIS, 14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15# See the License for the specific language governing permissions and 16# limitations under the License. 17 18 19__all__ = ['UAProf', 'is_wap_browser', 'BrowserViewState', 'browser_view_state', 'ClientDevicePlatform', 20 'client_device_platform', 'client_device_platform_version', 'client_device_model', 'client_device_arch', 21 'MobileDeviceType', 'mobile_device_type_by_user_agent', 'ClientDeviceType', 'client_device_type', 22 'ClientViewType', 'client_view_type'] 23 24 25""" 26Module Docstring 27Docstrings: http://www.python.org/dev/peps/pep-0257/ 28""" 29 30__author__ = "ButenkoMS <gtalk@butenkoms.space>" 31__copyright__ = "Copyright © 2012-2024 ButenkoMS. All rights reserved. Contacts: <gtalk@butenkoms.space>" 32__credits__ = ["ButenkoMS <gtalk@butenkoms.space>", ] 33__license__ = "Apache License, Version 2.0" 34__version__ = "4.4.1" 35__maintainer__ = "ButenkoMS <gtalk@butenkoms.space>" 36__email__ = "gtalk@butenkoms.space" 37# __status__ = "Prototype" 38__status__ = "Development" 39# __status__ = "Production" 40 41 42from enum import Enum, IntEnum 43from typing import Mapping, Optional 44from cengal.web_tools.detect_browsers_host_device_type.by_http_user_agent import is_mobile_or_tablet_browser 45 46 47UAProf = { 48 'x-wap-profile'.casefold(), 49 '19-Profile'.casefold(), 50 'WAP-Profile'.casefold(), 51} 52 53 54def is_wap_browser(headers: Mapping) -> bool: 55 return bool(UAProf.intersection(headers.keys())) 56 57 58class BrowserViewState(str, Enum): 59 desktop = '?0' 60 mobile = '?1' 61 unknown = 'unknown' 62 63 64def browser_view_state(headers: Mapping) -> BrowserViewState: 65 return BrowserViewState(headers.get('Sec-CH-UA-Mobile'.casefold(), 'unknown')) 66 67 68class ClientDevicePlatform(str, Enum): 69 unknown = 'unknown' 70 windows = 'Windows' 71 macos = 'macOS' 72 linux = 'Linux' 73 ios = 'iOS' 74 chromiumos = 'Chromium OS' 75 chromeos = 'Chrome OS' 76 android = 'Android' 77 78 79def client_device_platform(headers: Mapping) -> ClientDevicePlatform: 80 return ClientDevicePlatform(headers.get('Sec-CH-UA-Platform'.casefold(), 'unknown')) 81 82 83def client_device_platform_version(headers: Mapping) -> Optional[str]: 84 return headers.get('Sec-CH-UA-Platform-Version'.casefold(), None) 85 86 87def client_device_model(headers: Mapping) -> Optional[str]: 88 return headers.get('Sec-CH-UA-Model'.casefold(), None) 89 90 91def client_device_arch(headers: Mapping) -> Optional[str]: 92 return headers.get('Sec-CH-UA-Arch'.casefold(), None) 93 94 95class MobileDeviceType(str, Enum): 96 unknown = 'unknown' 97 mobile = 'mobile' 98 tablet = 'tablet' 99 100 101def mobile_device_type_by_user_agent(headers: Mapping) -> MobileDeviceType: 102 mobile, tablet = is_mobile_or_tablet_browser(headers.get('User-Agent'.casefold(), '')) 103 if tablet: 104 return MobileDeviceType.tablet 105 elif mobile: 106 return MobileDeviceType.mobile 107 else: 108 return MobileDeviceType.unknown 109 110 111class ClientDeviceType(str, Enum): 112 desktop = 'desktop' 113 laptop = 'laptop' 114 tablet = 'tablet' 115 mobile = 'mobile' 116 117 118def client_device_type(headers: Mapping) -> ClientDeviceType: 119 if is_wap_browser(headers): 120 return ClientDeviceType.mobile 121 else: 122 cdp: ClientDevicePlatform = client_device_platform(headers) 123 if ClientDevicePlatform.unknown == cdp: 124 mdt: MobileDeviceType = mobile_device_type_by_user_agent(headers) 125 if MobileDeviceType.tablet == mdt: 126 return ClientDeviceType.tablet 127 elif MobileDeviceType.mobile == mdt: 128 return ClientDeviceType.mobile 129 else: 130 return ClientDeviceType.desktop 131 elif cdp in {ClientDevicePlatform.ios, ClientDevicePlatform.android}: 132 mdt: MobileDeviceType = mobile_device_type_by_user_agent(headers) 133 if MobileDeviceType.tablet == mdt: 134 return ClientDeviceType.tablet 135 else: 136 return ClientDeviceType.mobile 137 else: 138 return ClientDeviceType.desktop 139 140 141class ClientViewType(str, Enum): 142 desktop = 'desktop' 143 laptop = 'laptop' 144 tablet = 'tablet' 145 mobile = 'mobile' 146 147 148def client_view_type(headers: Mapping) -> ClientViewType: 149 bvs: BrowserViewState = browser_view_state(headers) 150 if BrowserViewState.desktop == bvs: 151 return ClientViewType.desktop 152 elif BrowserViewState.mobile == bvs: 153 mdt: MobileDeviceType = mobile_device_type_by_user_agent(headers) 154 if MobileDeviceType.tablet == mdt: 155 return ClientViewType.tablet 156 else: 157 return ClientViewType.mobile 158 elif BrowserViewState.unknown == bvs: 159 if is_wap_browser(headers): 160 return ClientDeviceType.mobile 161 else: 162 mdt: MobileDeviceType = mobile_device_type_by_user_agent(headers) 163 if MobileDeviceType.tablet == mdt: 164 return ClientViewType.tablet 165 elif MobileDeviceType.mobile == mdt: 166 return ClientViewType.mobile 167 else: 168 return ClientViewType.desktop 169 else: 170 raise ValueError(f'Unknown BrowserViewState: {bvs}')
UAProf =
{'19-profile', 'wap-profile', 'x-wap-profile'}
def
is_wap_browser(headers: Mapping) -> bool:
class
BrowserViewState(builtins.str, enum.Enum):
An enumeration.
desktop =
<BrowserViewState.desktop: '?0'>
mobile =
<BrowserViewState.mobile: '?1'>
unknown =
<BrowserViewState.unknown: 'unknown'>
Inherited Members
- enum.Enum
- name
- value
- builtins.str
- encode
- replace
- split
- rsplit
- join
- capitalize
- casefold
- title
- center
- count
- expandtabs
- find
- partition
- index
- ljust
- lower
- lstrip
- rfind
- rindex
- rjust
- rstrip
- rpartition
- splitlines
- strip
- swapcase
- translate
- upper
- startswith
- endswith
- isascii
- islower
- isupper
- istitle
- isspace
- isdecimal
- isdigit
- isnumeric
- isalpha
- isalnum
- isidentifier
- isprintable
- zfill
- format
- format_map
- maketrans
class
ClientDevicePlatform(builtins.str, enum.Enum):
69class ClientDevicePlatform(str, Enum): 70 unknown = 'unknown' 71 windows = 'Windows' 72 macos = 'macOS' 73 linux = 'Linux' 74 ios = 'iOS' 75 chromiumos = 'Chromium OS' 76 chromeos = 'Chrome OS' 77 android = 'Android'
An enumeration.
unknown =
<ClientDevicePlatform.unknown: 'unknown'>
windows =
<ClientDevicePlatform.windows: 'Windows'>
macos =
<ClientDevicePlatform.macos: 'macOS'>
linux =
<ClientDevicePlatform.linux: 'Linux'>
ios =
<ClientDevicePlatform.ios: 'iOS'>
chromiumos =
<ClientDevicePlatform.chromiumos: 'Chromium OS'>
chromeos =
<ClientDevicePlatform.chromeos: 'Chrome OS'>
android =
<ClientDevicePlatform.android: 'Android'>
Inherited Members
- enum.Enum
- name
- value
- builtins.str
- encode
- replace
- split
- rsplit
- join
- capitalize
- casefold
- title
- center
- count
- expandtabs
- find
- partition
- index
- ljust
- lower
- lstrip
- rfind
- rindex
- rjust
- rstrip
- rpartition
- splitlines
- strip
- swapcase
- translate
- upper
- startswith
- endswith
- isascii
- islower
- isupper
- istitle
- isspace
- isdecimal
- isdigit
- isnumeric
- isalpha
- isalnum
- isidentifier
- isprintable
- zfill
- format
- format_map
- maketrans
def
client_device_platform_version(headers: Mapping) -> Union[str, NoneType]:
def
client_device_model(headers: Mapping) -> Union[str, NoneType]:
def
client_device_arch(headers: Mapping) -> Union[str, NoneType]:
class
MobileDeviceType(builtins.str, enum.Enum):
96class MobileDeviceType(str, Enum): 97 unknown = 'unknown' 98 mobile = 'mobile' 99 tablet = 'tablet'
An enumeration.
unknown =
<MobileDeviceType.unknown: 'unknown'>
mobile =
<MobileDeviceType.mobile: 'mobile'>
tablet =
<MobileDeviceType.tablet: 'tablet'>
Inherited Members
- enum.Enum
- name
- value
- builtins.str
- encode
- replace
- split
- rsplit
- join
- capitalize
- casefold
- title
- center
- count
- expandtabs
- find
- partition
- index
- ljust
- lower
- lstrip
- rfind
- rindex
- rjust
- rstrip
- rpartition
- splitlines
- strip
- swapcase
- translate
- upper
- startswith
- endswith
- isascii
- islower
- isupper
- istitle
- isspace
- isdecimal
- isdigit
- isnumeric
- isalpha
- isalnum
- isidentifier
- isprintable
- zfill
- format
- format_map
- maketrans
102def mobile_device_type_by_user_agent(headers: Mapping) -> MobileDeviceType: 103 mobile, tablet = is_mobile_or_tablet_browser(headers.get('User-Agent'.casefold(), '')) 104 if tablet: 105 return MobileDeviceType.tablet 106 elif mobile: 107 return MobileDeviceType.mobile 108 else: 109 return MobileDeviceType.unknown
class
ClientDeviceType(builtins.str, enum.Enum):
112class ClientDeviceType(str, Enum): 113 desktop = 'desktop' 114 laptop = 'laptop' 115 tablet = 'tablet' 116 mobile = 'mobile'
An enumeration.
desktop =
<ClientDeviceType.desktop: 'desktop'>
laptop =
<ClientDeviceType.laptop: 'laptop'>
tablet =
<ClientDeviceType.tablet: 'tablet'>
mobile =
<ClientDeviceType.mobile: 'mobile'>
Inherited Members
- enum.Enum
- name
- value
- builtins.str
- encode
- replace
- split
- rsplit
- join
- capitalize
- casefold
- title
- center
- count
- expandtabs
- find
- partition
- index
- ljust
- lower
- lstrip
- rfind
- rindex
- rjust
- rstrip
- rpartition
- splitlines
- strip
- swapcase
- translate
- upper
- startswith
- endswith
- isascii
- islower
- isupper
- istitle
- isspace
- isdecimal
- isdigit
- isnumeric
- isalpha
- isalnum
- isidentifier
- isprintable
- zfill
- format
- format_map
- maketrans
119def client_device_type(headers: Mapping) -> ClientDeviceType: 120 if is_wap_browser(headers): 121 return ClientDeviceType.mobile 122 else: 123 cdp: ClientDevicePlatform = client_device_platform(headers) 124 if ClientDevicePlatform.unknown == cdp: 125 mdt: MobileDeviceType = mobile_device_type_by_user_agent(headers) 126 if MobileDeviceType.tablet == mdt: 127 return ClientDeviceType.tablet 128 elif MobileDeviceType.mobile == mdt: 129 return ClientDeviceType.mobile 130 else: 131 return ClientDeviceType.desktop 132 elif cdp in {ClientDevicePlatform.ios, ClientDevicePlatform.android}: 133 mdt: MobileDeviceType = mobile_device_type_by_user_agent(headers) 134 if MobileDeviceType.tablet == mdt: 135 return ClientDeviceType.tablet 136 else: 137 return ClientDeviceType.mobile 138 else: 139 return ClientDeviceType.desktop
class
ClientViewType(builtins.str, enum.Enum):
142class ClientViewType(str, Enum): 143 desktop = 'desktop' 144 laptop = 'laptop' 145 tablet = 'tablet' 146 mobile = 'mobile'
An enumeration.
desktop =
<ClientViewType.desktop: 'desktop'>
laptop =
<ClientViewType.laptop: 'laptop'>
tablet =
<ClientViewType.tablet: 'tablet'>
mobile =
<ClientViewType.mobile: 'mobile'>
Inherited Members
- enum.Enum
- name
- value
- builtins.str
- encode
- replace
- split
- rsplit
- join
- capitalize
- casefold
- title
- center
- count
- expandtabs
- find
- partition
- index
- ljust
- lower
- lstrip
- rfind
- rindex
- rjust
- rstrip
- rpartition
- splitlines
- strip
- swapcase
- translate
- upper
- startswith
- endswith
- isascii
- islower
- isupper
- istitle
- isspace
- isdecimal
- isdigit
- isnumeric
- isalpha
- isalnum
- isidentifier
- isprintable
- zfill
- format
- format_map
- maketrans
149def client_view_type(headers: Mapping) -> ClientViewType: 150 bvs: BrowserViewState = browser_view_state(headers) 151 if BrowserViewState.desktop == bvs: 152 return ClientViewType.desktop 153 elif BrowserViewState.mobile == bvs: 154 mdt: MobileDeviceType = mobile_device_type_by_user_agent(headers) 155 if MobileDeviceType.tablet == mdt: 156 return ClientViewType.tablet 157 else: 158 return ClientViewType.mobile 159 elif BrowserViewState.unknown == bvs: 160 if is_wap_browser(headers): 161 return ClientDeviceType.mobile 162 else: 163 mdt: MobileDeviceType = mobile_device_type_by_user_agent(headers) 164 if MobileDeviceType.tablet == mdt: 165 return ClientViewType.tablet 166 elif MobileDeviceType.mobile == mdt: 167 return ClientViewType.mobile 168 else: 169 return ClientViewType.desktop 170 else: 171 raise ValueError(f'Unknown BrowserViewState: {bvs}')