From f0e81b35ecdf05f2727a31ce0a0771ed30eaa25a Mon Sep 17 00:00:00 2001 From: iamdual <imduual@gmail.com> Date: Sat, 18 May 2024 00:43:19 +0300 Subject: [PATCH] make the raw values of client hints public --- src/ua_generator/client_hints.py | 47 ++++++++++++++++++-------------- tests/test_client_hints.py | 34 +++++++++++++++++++++++ 2 files changed, 60 insertions(+), 21 deletions(-) diff --git a/src/ua_generator/client_hints.py b/src/ua_generator/client_hints.py index 1be2322..8e2cc0f 100644 --- a/src/ua_generator/client_hints.py +++ b/src/ua_generator/client_hints.py @@ -3,7 +3,9 @@ Copyright: 2022-2024 Ekin Karadeniz (github.com/iamdual) License: Apache License 2.0 """ -from . import formats, serialization, utils +from random import Random + +from . import formats, serialization from .data import platforms_mobile from .data import generator @@ -26,10 +28,10 @@ def __init__(self, gen: generator.Generator): self.__generator = gen self.__cache = {} - def __mobile(self): + def get_mobile(self): return self.__generator.platform in platforms_mobile - def __platform(self): + def get_platform(self): platform = self.__generator.platform if platform == 'ios': @@ -41,13 +43,14 @@ def __platform(self): return platform - def __platform_version(self): + def get_platform_version(self): if self.__generator.platform == 'windows' and formats.major_version(self.__generator.platform_version) == '10': - return utils.choice(('10.0.0', '13.0.0')) + _random = Random(self.__generator.user_agent) + return _random.choice(('10.0.0', '13.0.0')) return formats.version(self.__generator.platform_version) - def __brands(self, full_version_list: bool = False): + def get_brands(self, full_version_list: bool = False): brand_list = [{'brand': 'Not A(Brand', 'version': '99'}] if full_version_list: @@ -64,27 +67,29 @@ def __brands(self, full_version_list: bool = False): return brand_list - def __bitness(self): + def get_bitness(self): if self.__generator.platform == 'android': - return utils.choice(('32', '64', '32', '32')) + _random = Random(self.__generator.user_agent) + return _random.choice(('32', '64', '32', '32')) return '64' - def __architecture(self): + def get_architecture(self): if self.__generator.platform == 'android' or self.__generator.platform == 'ios': return 'arm' elif self.__generator.platform == 'macos': - return utils.choice(('arm', 'x86', 'arm', 'arm')) + _random = Random(self.__generator.user_agent) + return _random.choice(('arm', 'x86', 'arm', 'arm')) return 'x86' - def __model(self): + def get_model(self): if 'platform_model' in self.__generator.platform_version: return self.__generator.platform_version['platform_model'] return '' - def __wow64(self): + def get_wow64(self): return self.__generator.platform == 'windows' def __getattr__(self, name): @@ -92,23 +97,23 @@ def __getattr__(self, name): return self.__cache[name] if name == 'mobile': - self.__cache[name] = serialization.ch_bool(self.__mobile()) + self.__cache[name] = serialization.ch_bool(self.get_mobile()) elif name == 'platform': - self.__cache[name] = serialization.ch_string(self.__platform()) + self.__cache[name] = serialization.ch_string(self.get_platform()) elif name == 'platform_version': - self.__cache[name] = serialization.ch_string(self.__platform_version()) + self.__cache[name] = serialization.ch_string(self.get_platform_version()) elif name == 'brands': - self.__cache[name] = serialization.ch_brand_list(self.__brands()) + self.__cache[name] = serialization.ch_brand_list(self.get_brands()) elif name == 'brands_full_version_list': - self.__cache[name] = serialization.ch_brand_list(self.__brands(full_version_list=True)) + self.__cache[name] = serialization.ch_brand_list(self.get_brands(full_version_list=True)) elif name == 'bitness': - self.__cache[name] = serialization.ch_string(self.__bitness()) + self.__cache[name] = serialization.ch_string(self.get_bitness()) elif name == 'architecture': - self.__cache[name] = serialization.ch_string(self.__architecture()) + self.__cache[name] = serialization.ch_string(self.get_architecture()) elif name == 'model': - self.__cache[name] = serialization.ch_string(self.__model()) + self.__cache[name] = serialization.ch_string(self.get_model()) elif name == 'wow64': - self.__cache[name] = serialization.ch_bool(self.__wow64()) + self.__cache[name] = serialization.ch_bool(self.get_wow64()) return self.__cache[name] diff --git a/tests/test_client_hints.py b/tests/test_client_hints.py index 79eefff..db21fc9 100644 --- a/tests/test_client_hints.py +++ b/tests/test_client_hints.py @@ -6,6 +6,7 @@ import unittest import src.ua_generator as ua_generator +from src.ua_generator import serialization from src.ua_generator.data import browsers_support_ch @@ -14,13 +15,17 @@ def test_ch_platform(self): for i in range(0, 100): ua = ua_generator.generate(browser=browsers_support_ch, platform='macos') self.assertIsNotNone(ua.ch) + self.assertTrue(type(ua.ch.platform) is str) self.assertEqual(ua.ch.platform, '"macOS"') + self.assertEqual(ua.ch.get_platform(), 'macOS') def test_ch_platform_2(self): for i in range(0, 100): ua = ua_generator.generate(browser=browsers_support_ch, platform='linux') self.assertIsNotNone(ua.ch) + self.assertTrue(type(ua.ch.platform) is str) self.assertEqual(ua.ch.platform, '"Linux"') + self.assertEqual(ua.ch.get_platform(), 'Linux') def test_ch_platform_version(self): for i in range(0, 100): @@ -28,6 +33,7 @@ def test_ch_platform_version(self): self.assertIsNotNone(ua.ch) self.assertTrue(type(ua.ch.platform_version) is str) self.assertTrue(len(ua.ch.platform_version) > 0) + self.assertEqual(ua.ch.platform_version, serialization.ch_string(ua.ch.get_platform_version())) def test_ch_platform_version_windows(self): for i in range(0, 100): @@ -35,71 +41,99 @@ def test_ch_platform_version_windows(self): self.assertIsNotNone(ua.ch) self.assertTrue(type(ua.ch.platform_version) is str) self.assertEqual(len(ua.ch.platform_version.split('.')), 3) + self.assertEqual(ua.ch.platform_version, serialization.ch_string(ua.ch.get_platform_version())) def test_ch_mobile(self): for i in range(0, 100): ua = ua_generator.generate(browser=browsers_support_ch, platform='android') self.assertIsNotNone(ua.ch) + self.assertTrue(type(ua.ch.mobile) is str) self.assertEqual(ua.ch.mobile, '?1') + self.assertTrue(type(ua.ch.get_mobile()) is bool) + self.assertEqual(ua.ch.get_mobile(), True) def test_ch_non_mobile(self): for i in range(0, 100): ua = ua_generator.generate(browser=browsers_support_ch, platform='windows') self.assertIsNotNone(ua.ch) + self.assertTrue(type(ua.ch.mobile) is str) self.assertEqual(ua.ch.mobile, '?0') + self.assertTrue(type(ua.ch.get_mobile()) is bool) + self.assertEqual(ua.ch.get_mobile(), False) def test_ch_brands(self): for i in range(0, 100): ua = ua_generator.generate(browser='chrome', platform='windows') self.assertIsNotNone(ua.ch) + self.assertTrue(type(ua.ch.brands) is str) self.assertTrue(ua.ch.brands.startswith('"Not A(Brand";v="99"')) self.assertTrue('Chromium' in ua.ch.brands) self.assertTrue('Google Chrome' in ua.ch.brands) + self.assertTrue(type(ua.ch.get_brands()) is list) + self.assertEqual(ua.ch.brands, serialization.ch_brand_list(ua.ch.get_brands())) def test_ch_brands_full_version_list(self): for i in range(0, 100): ua = ua_generator.generate(browser='edge', platform='windows') self.assertIsNotNone(ua.ch) + self.assertTrue(type(ua.ch.brands_full_version_list) is str) self.assertTrue(ua.ch.brands_full_version_list.startswith('"Not A(Brand";v="99"')) self.assertTrue('Chromium' in ua.ch.brands_full_version_list) self.assertTrue('Microsoft Edge' in ua.ch.brands_full_version_list) + self.assertTrue(type(ua.ch.get_brands(full_version_list=True)) is list) + self.assertEqual(ua.ch.brands_full_version_list, + serialization.ch_brand_list(ua.ch.get_brands(full_version_list=True))) def test_ch_bitness(self): for i in range(0, 100): ua = ua_generator.generate(browser=browsers_support_ch) self.assertIsNotNone(ua.ch) + self.assertTrue(type(ua.ch.bitness) is str) self.assertIn(ua.ch.bitness, ('"32"', '"64"')) + self.assertIn(ua.ch.get_bitness(), ('32', '64')) def test_ch_architecture(self): for i in range(0, 100): ua = ua_generator.generate(browser=browsers_support_ch) self.assertIsNotNone(ua.ch) + self.assertTrue(type(ua.ch.architecture) is str) self.assertIn(ua.ch.architecture, ('"arm"', '"x86"')) + self.assertIn(ua.ch.get_architecture(), ('arm', 'x86')) def test_ch_model(self): for i in range(0, 100): ua = ua_generator.generate(platform='android', browser='chrome') self.assertIsNotNone(ua.ch) + self.assertTrue(type(ua.ch.model) is str) self.assertTrue(ua.ch.model != '""') self.assertTrue(len(ua.ch.model) > 2) + self.assertEqual(ua.ch.model, serialization.ch_string(ua.ch.get_model())) def test_ch_model_2(self): for i in range(0, 100): ua = ua_generator.generate(platform='linux', browser='firefox') self.assertIsNotNone(ua.ch) + self.assertTrue(type(ua.ch.model) is str) self.assertTrue(ua.ch.model == '""') + self.assertEqual(ua.ch.model, serialization.ch_string(ua.ch.get_model())) def test_ch_wow64(self): for i in range(0, 100): ua = ua_generator.generate(platform='windows') self.assertIsNotNone(ua.ch) + self.assertTrue(type(ua.ch.wow64) is str) self.assertEqual(ua.ch.wow64, '?1') + self.assertTrue(type(ua.ch.get_wow64()) is bool) + self.assertEqual(ua.ch.get_wow64(), True) def test_ch_wow64_2(self): for i in range(0, 100): ua = ua_generator.generate(platform='linux') self.assertIsNotNone(ua.ch) + self.assertTrue(type(ua.ch.wow64) is str) self.assertEqual(ua.ch.wow64, '?0') + self.assertTrue(type(ua.ch.get_wow64()) is bool) + self.assertEqual(ua.ch.get_wow64(), False) if __name__ == '__main__':