Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Address devices marked as multiple types #108

Merged
merged 7 commits into from
Mar 16, 2021
Merged
56 changes: 55 additions & 1 deletion user_agents/devices.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,24 @@
"ua_string": "Mozilla/5.0 (Android; Mobile; rv:27.0) Gecko/27.0 Firefox/27.0",
"str": "Other / Android / Firefox Mobile 27"
},
"android_tablet_chrome_mobile": {
"is_bot": false,
"is_mobile": false,
"is_pc": false,
"is_tablet": true,
"is_touch_capable": true,
"ua_string": "Mozilla/5.0 (Linux; Android 9; SM-T820 Build/PPR1.180610.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/85.0.4183.101 Safari/537.36 ANDROID_APP",
"str": "Samsung SM-T820 / Android 9 / Chrome Mobile WebView 85.0.4183"
},
"kindle": {
"is_bot": false,
"is_mobile": false,
"is_pc": false,
"is_tablet": true,
"is_touch_capable": true,
"ua_string": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Silk/85.3.5 like Chrome/85.0.4183.126 Safari/537.36",
"str": "Kindle / Linux / Amazon Silk 85.3.5"
},
"blackberry_bold": {
"is_bot": false,
"is_mobile": true,
Expand Down Expand Up @@ -53,6 +71,24 @@
"ua_string": "Mozilla/5.0 (Linux; U; Android 2.2; en-us; SCH-I800 Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
"str": "SCH-I800 / Android 2.2 / Android 2.2"
},
"generic_android_tablet": {
"is_bot": false,
"is_mobile": false,
"is_pc": false,
"is_tablet": true,
"is_touch_capable": true,
"ua_string": "Mozilla/5.0 (Linux; Android 10.0; X116L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36",
"str": "X116L / Android 10.0 / Chrome 86.0.4240"
},
"generic_smart_phone_puffin": {
"is_bot": false,
"is_mobile": true,
"is_pc": false,
"is_tablet": false,
"is_touch_capable": true,
"ua_string": "Mozilla/5.0 (X11; U; U; Linux x86_64; nl-nl) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36 Puffin/8.4.0.42081AP",
"str": "Generic Smartphone / Linux / Puffin 8.4.0"
},
"google_bot": {
"is_bot": true,
"is_mobile": false,
Expand Down Expand Up @@ -89,6 +125,15 @@
"ua_string": "Mozilla/5.0(iPad; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B314 Safari/531.21.10",
"str": "iPad / iOS 3.2 / Mobile Safari 4.0.4"
},
"ipad_puffin": {
"is_bot": false,
"is_mobile": false,
"is_pc": false,
"is_tablet": true,
"is_touch_capable": true,
"ua_string": "Mozilla/5.0 (X11; U; Linux x86_64; nl-NL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.114 Safari/537.36 Puffin/5.2.3IT",
"str": "iPad / Linux / Puffin 5.2.3"
},
"iphone": {
"is_bot": false,
"is_mobile": true,
Expand Down Expand Up @@ -241,6 +286,15 @@
"ua_string": "Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:15.0) Gecko/20100101 Firefox/15.0.1",
"str": "PC / Ubuntu / Firefox 15.0.1"
},
"windows_chrome_mobile": {
"is_bot": false,
"is_mobile": false,
"is_pc": true,
"is_tablet": false,
"is_touch_capable": false,
"ua_string": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.64 Safari/537.36Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0",
"str": "PC / Windows 10 / Chrome Mobile WebView 70.0.3538"
},
"windows_ie": {
"is_bot": false,
"is_mobile": false,
Expand Down Expand Up @@ -317,7 +371,7 @@
"is_bot": false,
"is_mobile": true,
"is_pc": false,
"is_tablet": true,
"is_tablet": false,
"is_touch_capable": true,
"ua_string": "Opera/9.80 (Android 2.3.3; Linux; Opera Mobi/ADR-1202011015; U; en) Presto/2.9.201 Version/11.50",
"str": "Opera / Android 2.3.3 / Opera Mobile 11.50"
Expand Down
22 changes: 18 additions & 4 deletions user_agents/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@
'Dell Streak',
)

TABLET_DEVICE_BRANDS = (
'Generic_Android_Tablet',
)

TOUCH_CAPABLE_OS_FAMILIES = (
'iOS',
'Android',
Expand All @@ -63,7 +67,10 @@
TOUCH_CAPABLE_DEVICE_FAMILIES = (
'BlackBerry Playbook',
'Blackberry Playbook',
'Generic Smartphone',
'iPad',
'Kindle Fire',
'Kindle'
)

EMAIL_PROGRAM_FAMILIES = set((
Expand Down Expand Up @@ -179,6 +186,10 @@ def get_browser(self):
def is_tablet(self):
if self.device.family in TABLET_DEVICE_FAMILIES:
return True
if self.device.brand in TABLET_DEVICE_BRANDS:
return True
if self.device.family in MOBILE_DEVICE_FAMILIES:
return False
if (self.os.family == 'Android' and self._is_android_tablet()):
return True
if self.os.family == 'Windows' and self.os.version_string.startswith('RT'):
Expand All @@ -192,14 +203,13 @@ 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.is_tablet or self.is_pc:
return False
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':
if self.os.family in ['Android', 'Firefox OS', 'BlackBerry OS']:
return True
if self.os.family in MOBILE_OS_FAMILIES:
return True
Expand Down Expand Up @@ -237,6 +247,10 @@ def is_touch_capable(self):

@property
def is_pc(self):
if self.device.family in MOBILE_DEVICE_FAMILIES or \
self.device.family in TABLET_DEVICE_FAMILIES or \
self.device.brand in TABLET_DEVICE_BRANDS:
return False
# 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':
Expand Down
8 changes: 8 additions & 0 deletions user_agents/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

iphone_ua_string = 'Mozilla/5.0 (iPhone; CPU iPhone OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B179 Safari/7534.48.3'
ipad_ua_string = 'Mozilla/5.0(iPad; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B314 Safari/531.21.10'
ipad_mobile_chrome_ua_string = 'Mozilla/5.0 (iPad; CPU OS 13_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/86.0.4240.93 Mobile/15E148 Safari/604.1'
galaxy_tab_ua_string = 'Mozilla/5.0 (Linux; U; Android 2.2; en-us; SCH-I800 Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1'
galaxy_s3_ua_string = 'Mozilla/5.0 (Linux; U; Android 4.0.4; en-gb; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30'
kindle_fire_ua_string = 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-us; Silk/1.1.0-80) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16 Silk-Accelerated=true'
Expand All @@ -34,6 +35,7 @@

iphone_ua = parse(iphone_ua_string)
ipad_ua = parse(ipad_ua_string)
ipad_mobile_chrome_ua = parse(ipad_mobile_chrome_ua_string)
galaxy_tab = parse(galaxy_tab_ua_string)
galaxy_s3_ua = parse(galaxy_s3_ua_string)
kindle_fire_ua = parse(kindle_fire_ua_string)
Expand Down Expand Up @@ -100,6 +102,7 @@ def test_is_tablet_property(self):
self.assertFalse(nokia_n97_ua.is_tablet)
self.assertTrue(windows_rt_ua.is_tablet)
self.assertTrue(ipad_ua.is_tablet)
self.assertTrue(ipad_mobile_chrome_ua.is_tablet)
self.assertTrue(playbook_ua.is_tablet)
self.assertTrue(kindle_fire_ua.is_tablet)
self.assertTrue(nexus_7_ua.is_tablet)
Expand All @@ -115,6 +118,7 @@ def test_is_mobile_property(self):
self.assertTrue(nokia_n97_ua.is_mobile)
self.assertFalse(windows_rt_ua.is_mobile)
self.assertFalse(ipad_ua.is_mobile)
self.assertFalse(ipad_mobile_chrome_ua.is_mobile)
self.assertFalse(playbook_ua.is_mobile)
self.assertFalse(kindle_fire_ua.is_mobile)
self.assertFalse(nexus_7_ua.is_mobile)
Expand All @@ -130,6 +134,7 @@ def test_is_touch_property(self):
self.assertTrue(iphone_ua.is_touch_capable)
self.assertTrue(galaxy_s3_ua.is_touch_capable)
self.assertTrue(ipad_ua.is_touch_capable)
self.assertTrue(ipad_mobile_chrome_ua.is_touch_capable)
self.assertTrue(playbook_ua.is_touch_capable)
self.assertTrue(kindle_fire_ua.is_touch_capable)
self.assertTrue(nexus_7_ua.is_touch_capable)
Expand All @@ -151,6 +156,7 @@ def test_is_pc(self):
self.assertFalse(iphone_ua.is_pc)
self.assertFalse(galaxy_s3_ua.is_pc)
self.assertFalse(ipad_ua.is_pc)
self.assertFalse(ipad_mobile_chrome_ua.is_pc)
self.assertFalse(playbook_ua.is_pc)
self.assertFalse(kindle_fire_ua.is_pc)
self.assertFalse(nexus_7_ua.is_pc)
Expand All @@ -174,6 +180,7 @@ def test_is_bot(self):
self.assertFalse(iphone_ua.is_bot)
self.assertFalse(galaxy_s3_ua.is_bot)
self.assertFalse(ipad_ua.is_bot)
self.assertFalse(ipad_mobile_chrome_ua.is_bot)
self.assertFalse(playbook_ua.is_bot)
self.assertFalse(kindle_fire_ua.is_bot)
self.assertFalse(nexus_7_ua.is_bot)
Expand Down Expand Up @@ -213,6 +220,7 @@ def test_is_email_client(self):
def test_strings(self):
self.assertEqual(str(iphone_ua), "iPhone / iOS 5.1 / Mobile Safari 5.1")
self.assertEqual(str(ipad_ua), "iPad / iOS 3.2 / Mobile Safari 4.0.4")
self.assertEqual(str(ipad_mobile_chrome_ua), "iPad / iOS 13.3 / Chrome Mobile iOS 86.0.4240")
self.assertEqual(str(galaxy_tab), "Samsung SCH-I800 / Android 2.2 / Android 2.2")
self.assertEqual(str(galaxy_s3_ua), "Samsung GT-I9300 / Android 4.0.4 / Android 4.0.4")
self.assertEqual(str(kindle_fire_ua), "Kindle / Android / Amazon Silk 1.1.0-80")
Expand Down