1
0
mirror of https://github.com/HorlogeSkynet/archey4 synced 2025-04-30 04:00:16 +02:00

[GPU] Add multi-line GPU entry output.

With appropriate configuration options.
This commit is contained in:
Michael Bromilow 2020-05-10 22:09:15 +01:00
parent 25bf6d88b7
commit ac8eaf5f27
No known key found for this signature in database
GPG Key ID: 0F937D40CE5F9F0F
5 changed files with 68 additions and 26 deletions

@ -199,6 +199,13 @@ Below, some further explanations of each option available :
// `false` would make Archey displays only IPv4 WAN addresses.
"wan_ip_v6_support": true
},
"gpu": {
// Display all GPUs on one line if true, multiple lines if false.
"one_line": false,
// The maximum number of GPUs you want to display.
// `false` --> Unlimited.
"max_count": 4
},
"limits": {
// Some threshold values you can adjust affecting disk/ram warning/danger color (percent).
"ram": {

@ -30,6 +30,10 @@
"not_detected": "Not detected",
"virtual_environment": "Virtual Environment"
},
"gpu": {
"one_line": false,
"max_count": false
},
"ip_settings": {
"lan_ip_max_count": 2,
"lan_ip_v6_support": true,

@ -24,6 +24,7 @@ class Configuration(metaclass=Singleton):
'not_detected': 'Not detected',
'virtual_environment': 'Virtual Environment'
},
'gpu': {},
'ip_settings': {
'lan_ip_max_count': 2,
'lan_ip_v6_support': True,

@ -1,5 +1,6 @@
"""GPU information detection class"""
from itertools import islice
from subprocess import check_output, CalledProcessError
from archey.entry import Entry
@ -10,17 +11,18 @@ class GPU(Entry):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# This list will contain GPU devices detected on this system.
self.gpu_devices = []
self._max_count = self._configuration.get('gpu').get('max_count', None)
# Consistency with other entries' configuration: Infinite count if false.
if self._max_count is False:
self._max_count = None
# Let's try to run `lspci` and parse here.
self._run_lspci()
# Populate our list of devices with the `lspci`-based generator.
self.gpu_devices = list(islice(self._gpu_generator(), self._max_count))
self.value = ', '.join(self.gpu_devices) or \
self._configuration.get('default_strings')['not_detected']
def _run_lspci(self):
"""Based on `lspci` output, retrieve a list of video controllers names"""
@staticmethod
def _gpu_generator():
"""Based on `lspci` output, return a generator for video controllers names"""
try:
lspci_output = check_output(
['lspci'],
@ -34,5 +36,17 @@ class GPU(Entry):
for pci_device in lspci_output:
# If a controller type match...
if video_key in pci_device:
# ... adds its name to our final list.
self.gpu_devices.append(pci_device.partition(': ')[2])
# ... return its name on the next iteration.
yield pci_device.partition(': ')[2]
def output(self, output):
"""Writes GPUs to `output` based on preferences."""
if self.gpu_devices:
if self._configuration.get('gpu').get('one_line', False):
output.append(self.name, ', '.join(self.gpu_devices))
else:
for gpu in self.gpu_devices:
output.append(self.name, gpu)
else:
output.append(self.name, self._configuration.get('default_strings')['not_detected'])

@ -10,6 +10,12 @@ from archey.entries.gpu import GPU
class TestGPUEntry(unittest.TestCase):
"""Here, we mock the `check_output` call to `lspci` to test the logic"""
@patch(
'archey.configuration.Configuration.get',
side_effect=[
{'max_count': None}
]
)
@patch(
'archey.entries.gpu.check_output',
return_value="""\
@ -18,10 +24,16 @@ XX:YY.H SMBus: BBBBBBBBBBBBBBBB
XX:YY.H VGA compatible controller: GPU-MODEL-NAME
XX:YY.H Audio device: DDDDDDDDDDDDDDDD
""")
def test_match_vga(self, _):
def test_match_vga(self, _, __):
"""Simple 'VGA' device type matching"""
self.assertEqual(GPU().value, 'GPU-MODEL-NAME')
self.assertListEqual(GPU().gpu_devices, ['GPU-MODEL-NAME'])
@patch(
'archey.configuration.Configuration.get',
side_effect=[
{'max_count': None}
]
)
@patch(
'archey.entries.gpu.check_output',
return_value="""\
@ -31,13 +43,19 @@ XX:YY.H Display controller: ANOTHER-MATCHING-VIDEO-CONTROLLER
XX:YY.H Audio device: DDDDDDDDDDDDDDDD
XX:YY.H 3D controller: 3D GPU-MODEL-NAME TAKES ADVANTAGE
""")
def test_multi_matches(self, _):
def test_multi_matches(self, _, __):
"""Test detection when there are multiple graphical candidates"""
self.assertEqual(
GPU().value,
'3D GPU-MODEL-NAME TAKES ADVANTAGE, ANOTHER-MATCHING-VIDEO-CONTROLLER'
self.assertListEqual(
GPU().gpu_devices,
['3D GPU-MODEL-NAME TAKES ADVANTAGE', 'ANOTHER-MATCHING-VIDEO-CONTROLLER']
)
@patch(
'archey.configuration.Configuration.get',
side_effect=[
{'max_count': None}
]
)
@patch(
'archey.entries.gpu.check_output',
return_value="""\
@ -45,25 +63,23 @@ XX:YY.H IDE interface: IIIIIIIIIIIIIIII
XX:YY.H SMBus: BBBBBBBBBBBBBBBB
XX:YY.H Audio device: DDDDDDDDDDDDDDDD
""")
@patch(
'archey.configuration.Configuration.get',
return_value={'not_detected': 'Not detected'}
)
def test_no_match(self, _, __):
"""Test (non-)detection when there is not any graphical candidate"""
self.assertEqual(GPU().value, 'Not detected')
self.assertListEqual(GPU().gpu_devices, [])
@patch(
'archey.configuration.Configuration.get',
side_effect=[
{'max_count': None}
]
)
@patch(
'archey.entries.gpu.check_output',
side_effect=CalledProcessError(1, 'lspci')
)
@patch(
'archey.configuration.Configuration.get',
return_value={'not_detected': 'Not detected'}
)
def test_lspsci_crash(self, _, __):
"""Test (non-)detection due to a crashing `lspci` program"""
self.assertEqual(GPU().value, 'Not detected')
self.assertListEqual(GPU().gpu_devices, [])
if __name__ == '__main__':