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

+ New configuration option `temperature.sensors_chipsets` - [BREAKING (?)] `sensors` sub-call won't have its STDERR redirected to `/dev/null` anymore. - It allows occurring errors to be shown, instead of silently fail in temperature computations. - This could happen if the user specifies (a) wrong chipset identifiers. - Errors/warnings may still be silenced at the Archey level using the `suppress_warnings` configuration option. - This new feature could not be unit-tested as it completely relies on the `sensors` sub-call, to which we pass chipsets identifiers.
123 lines
4.1 KiB
Python
123 lines
4.1 KiB
Python
"""Archey configuration module"""
|
|
|
|
import os
|
|
import sys
|
|
import json
|
|
|
|
from archey.singleton import Singleton
|
|
|
|
|
|
class Configuration(metaclass=Singleton):
|
|
"""
|
|
The default needed configuration which will be used by Archey is present below.
|
|
Values present in the `self.config` dictionary below are needed.
|
|
New optional values may be added with `_update_recursive()` method.
|
|
"""
|
|
def __init__(self):
|
|
self._config = {
|
|
'colors_palette': {
|
|
'use_unicode': False,
|
|
'honor_ansi_color': True
|
|
},
|
|
'default_strings': {
|
|
'no_address': 'No Address',
|
|
'not_detected': 'Not detected',
|
|
'virtual_environment': 'Virtual Environment'
|
|
},
|
|
'ip_settings': {
|
|
'lan_ip_max_count': 2,
|
|
'lan_ip_v6_support': True,
|
|
'wan_ip_v6_support': True
|
|
},
|
|
'limits': {
|
|
'ram': {
|
|
'warning': 33.3,
|
|
'danger': 66.7
|
|
},
|
|
'disk': {
|
|
'warning': 50,
|
|
'danger': 75
|
|
}
|
|
},
|
|
'temperature': {
|
|
'char_before_unit': ' ',
|
|
'sensors_chipsets': [],
|
|
'use_fahrenheit': False
|
|
},
|
|
'timeout': {
|
|
'ipv4_detection': 1,
|
|
'ipv6_detection': 1
|
|
}
|
|
}
|
|
|
|
# Let's "save" `STDERR` file descriptor for `suppress_warnings` option
|
|
self._stderr = sys.stderr
|
|
|
|
# Now, let's load each optional configuration file in a "regular" order
|
|
self.load_configuration('/etc/archey4/')
|
|
self.load_configuration(os.path.expanduser('~/.config/archey4/'))
|
|
self.load_configuration(os.path.dirname(os.path.realpath(__file__)))
|
|
|
|
def get(self, key, default=None):
|
|
"""
|
|
A binding method to imitate the `dict.get()` behavior.
|
|
"""
|
|
return self._config.get(key, default)
|
|
|
|
def load_configuration(self, path):
|
|
"""
|
|
A method handling configuration loading from a JSON file.
|
|
It will try to load any `config.json` present under `path`.
|
|
"""
|
|
# If a previous configuration file has denied overriding...
|
|
if not self._config.get('allow_overriding', True):
|
|
# ... don't load this one.
|
|
return
|
|
|
|
path = os.path.join(path, 'config.json')
|
|
|
|
try:
|
|
with open(path) as file:
|
|
self._update_recursive(self._config, json.load(file))
|
|
|
|
# If the user does not want any warning to appear : 2> /dev/null
|
|
if self._config.get('suppress_warnings', False):
|
|
# One more if statement to avoid multiple `open` calls.
|
|
if sys.stderr == self._stderr:
|
|
sys.stderr = open(os.devnull, 'w')
|
|
|
|
else:
|
|
# One more if statement to avoid useless assignments and...
|
|
# ... for closing previously opened new file descriptor.
|
|
if sys.stderr != self._stderr:
|
|
sys.stderr.close()
|
|
sys.stderr = self._stderr
|
|
|
|
except FileNotFoundError:
|
|
pass
|
|
|
|
# For backward compatibility with Python versions prior to 3.5.0
|
|
# we use `ValueError` instead of `json.JSONDecodeError`.
|
|
except ValueError as error:
|
|
print('Warning: {0} ({1})'.format(error, path), file=sys.stderr)
|
|
|
|
def _update_recursive(self, old_dict, new_dict):
|
|
"""
|
|
A method for recursively merging dictionaries as...
|
|
... `dict.update()` is not able to do this.
|
|
Original snippet taken from here :
|
|
https://gist.github.com/angstwad/bf22d1822c38a92ec0a9
|
|
"""
|
|
for key, value in new_dict.items():
|
|
if key in old_dict and isinstance(old_dict[key], dict) \
|
|
and isinstance(value, dict):
|
|
self._update_recursive(old_dict[key], value)
|
|
|
|
else:
|
|
old_dict[key] = value
|
|
|
|
def __del__(self):
|
|
if sys.stderr != self._stderr:
|
|
sys.stderr.close()
|
|
sys.stderr = self._stderr
|