Some errors...

This commit is contained in:
nicolargo 2023-05-18 19:41:40 +02:00
parent 4fb509009c
commit 1f03b03aa1
2 changed files with 88 additions and 50 deletions

View File

@ -26,7 +26,7 @@ import sys
from glances.logger import logger
from glances.keyboard import KBHit
from glances.timer import Timer
from glances.compat import nativestr, u
from glances.globals import nativestr, u
from glances.processes import glances_processes, sort_processes_key_list
# Import curses library for "normal" operating system

View File

@ -14,11 +14,12 @@ I am your father...
"""
import re
import json
import copy
import numbers
from operator import itemgetter
from glances.globals import iterkeys, itervalues, listkeys, mean, nativestr, json_dumps, json_dumps_dictlist
from glances.globals import iterkeys, itervalues, listkeys, mean, nativestr
from glances.actions import GlancesActions
from glances.history import GlancesHistory
from glances.logger import logger
@ -169,6 +170,16 @@ class GlancesPluginModel(object):
"""Return true if plugin is disabled."""
return not self.is_enabled(plugin_name=plugin_name)
def _json_dumps(self, d):
"""Return the object 'd' in a JSON format.
Manage the issue #815 for Windows OS
"""
try:
return json.dumps(d)
except UnicodeDecodeError:
return json.dumps(d, ensure_ascii=False)
def history_enable(self):
return self.args is not None and not self.args.disable_history and self.get_items_history_list() is not None
@ -188,13 +199,13 @@ class GlancesPluginModel(object):
def update_stats_history(self):
"""Update stats history."""
# If the plugin data is a dict, the dict's key should be used
if self.get_key() is None:
item_name = ''
else:
item_name = self.get_key()
# Build the history
if self.get_export() and self.history_enable():
# If the plugin data is a dict, the dict's key should be used
if self.get_key() is None:
item_name = ''
else:
item_name = self.get_key()
for i in self.get_items_history_list():
if isinstance(self.get_export(), list):
# Stats is a list of data
@ -262,9 +273,24 @@ class GlancesPluginModel(object):
s = self.get_json_history(nb=nb)
if item is None:
return json_dumps(s)
return self._json_dumps(s)
return json_dumps_dictlist(s, item)
if isinstance(s, dict):
try:
return self._json_dumps({item: s[item]})
except KeyError as e:
logger.error("Cannot get item history {} ({})".format(item, e))
return None
elif isinstance(s, list):
try:
# Source:
# http://stackoverflow.com/questions/4573875/python-get-index-of-dictionary-item-in-list
return self._json_dumps({item: map(itemgetter(item), s)})
except (KeyError, ValueError) as e:
logger.error("Cannot get item history {} ({})".format(item, e))
return None
else:
return None
def get_trend(self, item, nb=6):
"""Get the trend regarding to the last nb values.
@ -397,7 +423,7 @@ class GlancesPluginModel(object):
def get_stats(self):
"""Return the stats object in JSON format."""
return json_dumps(self.stats)
return self._json_dumps(self.stats)
def get_json(self):
"""Return the stats object in JSON format."""
@ -408,7 +434,23 @@ class GlancesPluginModel(object):
Stats should be a list of dict (processlist, network...)
"""
return json_dumps_dictlist(self.stats, item)
if isinstance(self.stats, dict):
try:
return self._json_dumps({item: self.stats[item]})
except KeyError as e:
logger.error("Cannot get item {} ({})".format(item, e))
return None
elif isinstance(self.stats, list):
try:
# Source:
# http://stackoverflow.com/questions/4573875/python-get-index-of-dictionary-item-in-list
# But https://github.com/nicolargo/glances/issues/1401
return self._json_dumps({item: list(map(itemgetter(item), self.stats))})
except (KeyError, ValueError) as e:
logger.error("Cannot get item {} ({})".format(item, e))
return None
else:
return None
def get_stats_value(self, item, value):
"""Return the stats object for a specific item=value in JSON format.
@ -421,7 +463,7 @@ class GlancesPluginModel(object):
if not isinstance(value, int) and value.isdigit():
value = int(value)
try:
return json_dumps({value: [i for i in self.stats if i[item] == value]})
return self._json_dumps({value: [i for i in self.stats if i[item] == value]})
except (KeyError, ValueError) as e:
logger.error("Cannot get item({})=value({}) ({})".format(item, value, e))
return None
@ -548,7 +590,7 @@ class GlancesPluginModel(object):
def get_json_views(self, item=None, key=None, option=None):
"""Return the views (in JSON)."""
return json_dumps(self.get_views(item, key, option))
return self._json_dumps(self.get_views(item, key, option))
def load_limits(self, config):
"""Load limits from the configuration file, if it exists."""
@ -839,10 +881,11 @@ class GlancesPluginModel(object):
Example for diskio:
show=sda.*
"""
# @TODO: possible optimisation: create a re.compile list
return any(
j for j in [re.fullmatch(i.lower(), value.lower()) for i in self.get_conf_value('show', header=header)]
)
# TODO: possible optimisation: create a re.compile list
if self.get_conf_value('show', header=header) == []:
return True
else:
return any(j for j in [re.match(i, value) for i in self.get_conf_value('show', header=header)])
def is_hide(self, value, header=""):
"""Return True if the value is in the hide configuration list.
@ -852,17 +895,8 @@ class GlancesPluginModel(object):
Example for diskio:
hide=sda2,sda5,loop.*
"""
# @TODO: possible optimisation: create a re.compile list
return any(
j for j in [re.fullmatch(i.lower(), value.lower()) for i in self.get_conf_value('hide', header=header)]
)
def is_display(self, value, header=""):
"""Return True if the value should be displayed in the UI"""
if self.get_conf_value('show', header=header) != []:
return self.is_show(value, header=header)
else:
return not self.is_hide(value, header=header)
# TODO: possible optimisation: create a re.compile list
return any(j for j in [re.match(i, value) for i in self.get_conf_value('hide', header=header)])
def has_alias(self, header):
"""Return the alias name for the relative header it it exists otherwise None."""
@ -1045,7 +1079,7 @@ class GlancesPluginModel(object):
"""Go to a new line."""
return self.curse_add_line('\n')
def curse_add_stat(self, key, width=None, header='', display_key=True, separator='', trailer=''):
def curse_add_stat(self, key, width=None, header='', separator='', trailer=''):
"""Return a list of dict messages with the 'key: value' result
<=== width ===>
@ -1053,8 +1087,8 @@ class GlancesPluginModel(object):
| | | | |_ trailer
| | | |_ self.stats[key]
| | |_ separator
| |_ 'short_name' description or key or nothing if display_key is True
|_ header
| |_ key
|_ trailer
Instead of:
msg = ' {:8}'.format('idle:')
@ -1070,9 +1104,7 @@ class GlancesPluginModel(object):
return []
# Check if a shortname is defined
if not display_key:
key_name = ''
elif key in self.fields_description and 'short_name' in self.fields_description[key]:
if key in self.fields_description and 'short_name' in self.fields_description[key]:
key_name = self.fields_description[key]['short_name']
else:
key_name = key
@ -1111,28 +1143,33 @@ class GlancesPluginModel(object):
if width is None:
msg_item = header + '{}'.format(key_name) + separator
msg_template_float = '{:.1f}{}'
msg_template = '{}{}'
if unit_type == 'float':
msg_value = '{:.1f}{}'.format(value, unit_short) + trailer
elif 'min_symbol' in self.fields_description[key]:
msg_value = (
'{}{}'.format(
self.auto_unit(int(value), min_symbol=self.fields_description[key]['min_symbol']), unit_short
)
+ trailer
)
else:
msg_value = '{}{}'.format(int(value), unit_short) + trailer
else:
# Define the size of the message
# item will be on the left
# value will be on the right
msg_item = header + '{:{width}}'.format(key_name, width=width - 7) + separator
msg_template_float = '{:5.1f}{}'
msg_template = '{:>5}{}'
if unit_type == 'float':
msg_value = msg_template_float.format(value, unit_short) + trailer
elif 'min_symbol' in self.fields_description[key]:
msg_value = (
msg_template.format(
self.auto_unit(int(value), min_symbol=self.fields_description[key]['min_symbol']), unit_short
if unit_type == 'float':
msg_value = '{:5.1f}{}'.format(value, unit_short) + trailer
elif 'min_symbol' in self.fields_description[key]:
msg_value = (
'{:>5}{}'.format(
self.auto_unit(int(value), min_symbol=self.fields_description[key]['min_symbol']), unit_short
)
+ trailer
)
+ trailer
)
else:
msg_value = msg_template.format(int(value), unit_short) + trailer
else:
msg_value = '{:>5}{}'.format(int(value), unit_short) + trailer
decoration = self.get_views(key=key, option='decoration')
optional = self.get_views(key=key, option='optional')
@ -1268,3 +1305,4 @@ class GlancesPluginModel(object):
# Mandatory to call the decorator in child classes
_check_decorator = staticmethod(_check_decorator)
_log_result_decorator = staticmethod(_log_result_decorator)