From c28089ae478388d28e375113a8f84b0924fbce2e Mon Sep 17 00:00:00 2001 From: nicolargo Date: Sun, 26 Nov 2023 22:40:36 +0100 Subject: First step of the migration --- README.rst | 4 +++- glances/globals.py | 14 +++++++++++--- glances/main.py | 2 +- glances/plugins/plugin/model.py | 26 ++++++++++++++++++++++---- optional-requirements.txt | 2 ++ setup.py | 4 +++- snap/snapcraft.yaml | 22 ++++++++++++++++++++++ tox.ini | 2 ++ webui-requirements.txt | 2 ++ 9 files changed, 68 insertions(+), 10 deletions(-) diff --git a/README.rst b/README.rst index 50c9c0f3..5192ae9c 100644 --- a/README.rst +++ b/README.rst @@ -101,8 +101,10 @@ Optional dependencies: - ``hddtemp`` (for HDD temperature monitoring support) [Linux-only] - ``influxdb`` (for the InfluxDB version 1 export module) - ``influxdb-client`` (for the InfluxDB version 2 export module) +- ``jinja2`` (for templating, used under the hood by FastAPI) - ``kafka-python`` (for the Kafka export module) - ``netifaces`` (for the IP plugin) +- ``orjson`` (fast JSON library, used under the hood by FastAPI) - ``py3nvml`` (for the GPU plugin) - ``pycouchdb`` (for the CouchDB export module) - ``pika`` (for the RabbitMQ/ActiveMQ export module) @@ -319,7 +321,7 @@ Start Termux on your device and enter: $ apt update $ apt upgrade $ apt install clang python - $ pip install fastapi uvicorn + $ pip install fastapi uvicorn orjson jinja2 $ pip install glances And start Glances: diff --git a/glances/globals.py b/glances/globals.py index 87a48817..ccf3f5be 100644 --- a/glances/globals.py +++ b/glances/globals.py @@ -315,10 +315,10 @@ def json_dumps(data): return ujson.dumps(data, ensure_ascii=False) -def json_dumps_dictlist(data, item): +def dictlist(data, item): if isinstance(data, dict): try: - return json_dumps({item: data[item]}) + return {item: data[item]} except (TypeError, IndexError, KeyError): return None elif isinstance(data, list): @@ -326,13 +326,21 @@ def json_dumps_dictlist(data, item): # Source: # http://stackoverflow.com/questions/4573875/python-get-index-of-dictionary-item-in-list # But https://github.com/nicolargo/glances/issues/1401 - return json_dumps({item: list(map(itemgetter(item), data))}) + return {item: list(map(itemgetter(item), data))} except (TypeError, IndexError, KeyError): return None else: return None +def json_dumps_dictlist(data, item): + dl = dictlist(data, item) + if dl is None: + return None + else: + return json_dumps(dl) + + def string_value_to_float(s): """Convert a string with a value and an unit to a float. Example: diff --git a/glances/main.py b/glances/main.py index 85db14aa..52c9439f 100644 --- a/glances/main.py +++ b/glances/main.py @@ -363,7 +363,7 @@ Examples of use: action='store_true', default=False, dest='webserver', - help='run Glances in web server mode (FastAPI and Uvicorn lib needed)', + help='run Glances in web server mode (FastAPI, Uvicorn, Jinja2 and OrJsonLib needed)', ) parser.add_argument( '--cached-time', diff --git a/glances/plugins/plugin/model.py b/glances/plugins/plugin/model.py index aa67bcb0..b25c2174 100644 --- a/glances/plugins/plugin/model.py +++ b/glances/plugins/plugin/model.py @@ -16,7 +16,7 @@ I am your father... import re import copy -from glances.globals import iterkeys, itervalues, listkeys, mean, nativestr, json_dumps, json_dumps_dictlist +from glances.globals import iterkeys, itervalues, listkeys, mean, nativestr, json_dumps, json_dumps_dictlist, dictlist from glances.actions import GlancesActions from glances.history import GlancesHistory from glances.logger import logger @@ -395,6 +395,13 @@ class GlancesPluginModel(object): """Return the stats object in JSON format.""" return self.get_stats() + def get_raw_stats_item(self, item): + """Return the stats object for a specific item in RAW format. + + Stats should be a list of dict (processlist, network...) + """ + return dictlist(self.stats, item) + def get_stats_item(self, item): """Return the stats object for a specific item in JSON format. @@ -402,8 +409,8 @@ class GlancesPluginModel(object): """ return json_dumps_dictlist(self.stats, item) - def get_stats_value(self, item, value): - """Return the stats object for a specific item=value in JSON format. + def get_raw_stats_value(self, item, value): + """Return the stats object for a specific item=value. Stats should be a list of dict (processlist, network...) """ @@ -413,11 +420,22 @@ 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 {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 + def get_stats_value(self, item, value): + """Return the stats object for a specific item=value in JSON format. + + Stats should be a list of dict (processlist, network...) + """ + rsv = self.get_raw_stats_value(item, value) + if rsv is None: + return None + else: + return json_dumps(rsv) + def update_views_hidden(self): """Update the hidden views diff --git a/optional-requirements.txt b/optional-requirements.txt index ef1cb735..5d9ba5e3 100644 --- a/optional-requirements.txt +++ b/optional-requirements.txt @@ -12,8 +12,10 @@ graphitesender hddtemp influxdb>=1.0.0 # For InfluxDB < 1.8 influxdb-client; python_version >= "3.7" # For InfluxDB >= 1.8 +jinja2 kafka-python netifaces +orjson; python_version >= "3.8" packaging; python_version >= "3.7" paho-mqtt pika diff --git a/setup.py b/setup.py index 6049b513..c32e6e86 100755 --- a/setup.py +++ b/setup.py @@ -46,6 +46,8 @@ def get_install_requires(): if sys.platform.startswith('win'): requires.append('fastapi') requires.append('uvicorn') + requires.append('orjson') + requires.append('jinja2') requires.append('requests') return requires @@ -68,7 +70,7 @@ def get_install_extras_require(): 'smart': ['pySMART.smartx'], 'snmp': ['pysnmp'], 'sparklines': ['sparklines'], - 'web': ['fastapi', 'uvicorn', 'requests'], + 'web': ['fastapi', 'uvicorn', 'jinja2', 'orjson', 'requests'], 'wifi': ['wifi'] } if sys.platform.startswith('linux'): diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 7185846c..b230edaa 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -76,6 +76,28 @@ parts: organize: uvicorn-dist: uvicorn/dist + orjson: + plugin: python + source: https://github.com/ijl/orjson.git + source-tag: '3.9.10' + source-depth: 1 + override-build: | + mkdir -p $SNAPCRAFT_PART_BUILD/dist + cp -r $SNAPCRAFT_PART_BUILD/dist $SNAPCRAFT_PART_INSTALL/orjson-dist + organize: + orjson-dist: orjson/dist + + jinja2: + plugin: python + source: https://github.com/pallets/jinja.git + source-tag: '3.1.2' + source-depth: 1 + override-build: | + mkdir -p $SNAPCRAFT_PART_BUILD/dist + cp -r $SNAPCRAFT_PART_BUILD/dist $SNAPCRAFT_PART_INSTALL/jinja2-dist + organize: + jinja2-dist: jinja2/dist + docker: plugin: python source: https://github.com/docker/docker-py.git diff --git a/tox.ini b/tox.ini index 30a67b06..f214f405 100644 --- a/tox.ini +++ b/tox.ini @@ -21,6 +21,8 @@ deps = ujson fastapi uvicorn + orjson + jinja2 requests commands = python unitest.py diff --git a/webui-requirements.txt b/webui-requirements.txt index 309e06cf..e24c83a0 100644 --- a/webui-requirements.txt +++ b/webui-requirements.txt @@ -3,3 +3,5 @@ fastapi; python_version >= "3.8" uvicorn; python_version >= "3.8" +orjson; python_version >= "3.8" +jinja2 \ No newline at end of file -- cgit v1.2.3