mirror of
https://github.com/nicolargo/glances.git
synced 2024-12-23 09:11:49 +03:00
Merge branch 'issue2518' into develop
This commit is contained in:
commit
723e0617bc
@ -13,22 +13,9 @@ from __future__ import unicode_literals
|
||||
import os
|
||||
|
||||
from glances.timer import Timer
|
||||
from glances.globals import nativestr
|
||||
from glances.globals import nativestr, folder_size
|
||||
from glances.logger import logger
|
||||
|
||||
# Use the built-in version of scandir/walk if possible, otherwise
|
||||
# use the scandir module version
|
||||
scandir_tag = True
|
||||
try:
|
||||
# For Python 3.5 or higher
|
||||
from os import scandir
|
||||
except ImportError:
|
||||
# For others...
|
||||
try:
|
||||
from scandir import scandir
|
||||
except ImportError:
|
||||
scandir_tag = False
|
||||
|
||||
|
||||
class FolderList(object):
|
||||
|
||||
@ -62,12 +49,9 @@ class FolderList(object):
|
||||
self.first_grab = True
|
||||
|
||||
if self.config is not None and self.config.has_section('folders'):
|
||||
if scandir_tag:
|
||||
# Process monitoring list
|
||||
logger.debug("Folder list configuration detected")
|
||||
self.__set_folder_list('folders')
|
||||
else:
|
||||
logger.error('Scandir not found. Please use Python 3.5+ or install the scandir lib')
|
||||
# Process monitoring list
|
||||
logger.debug("Folder list configuration detected")
|
||||
self.__set_folder_list('folders')
|
||||
else:
|
||||
self.__folder_list = []
|
||||
|
||||
@ -132,23 +116,6 @@ class FolderList(object):
|
||||
else:
|
||||
return None
|
||||
|
||||
def __folder_size(self, path):
|
||||
"""Return the size of the directory given by path
|
||||
|
||||
path: <string>"""
|
||||
|
||||
ret = 0
|
||||
for f in scandir(path):
|
||||
if f.is_dir(follow_symlinks=False) and (f.name != '.' or f.name != '..'):
|
||||
ret += self.__folder_size(os.path.join(path, f.name))
|
||||
else:
|
||||
try:
|
||||
ret += f.stat().st_size
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
return ret
|
||||
|
||||
def update(self, key='path'):
|
||||
"""Update the command result attributed."""
|
||||
# Only continue if monitor list is not empty
|
||||
@ -163,16 +130,13 @@ class FolderList(object):
|
||||
# Set the key (see issue #2327)
|
||||
self.__folder_list[i]['key'] = key
|
||||
# Get folder size
|
||||
try:
|
||||
self.__folder_list[i]['size'] = self.__folder_size(self.path(i))
|
||||
except OSError as e:
|
||||
logger.debug('Cannot get folder size ({}). Error: {}'.format(self.path(i), e))
|
||||
if e.errno == 13:
|
||||
# Permission denied
|
||||
self.__folder_list[i]['size'] = '!'
|
||||
else:
|
||||
self.__folder_list[i]['size'] = '?'
|
||||
# Reset the timer
|
||||
self.__folder_list[i]['size'], self.__folder_list[i]['errno'] = folder_size(self.path(i))
|
||||
if self.__folder_list[i]['errno'] != 0:
|
||||
logger.debug('Folder size ({} ~ {}) may not be correct. Error: {}'.format(
|
||||
self.path(i),
|
||||
self.__folder_list[i]['size'],
|
||||
self.__folder_list[i]['errno']))
|
||||
# Reset the timer
|
||||
self.timer_folders[i].reset()
|
||||
|
||||
# It is no more the first time...
|
||||
|
@ -372,3 +372,29 @@ def string_value_to_float(s):
|
||||
def file_exists(filename):
|
||||
"""Return True if the file exists and is readable."""
|
||||
return os.path.isfile(filename) and os.access(filename, os.R_OK)
|
||||
|
||||
|
||||
def folder_size(path, errno=0):
|
||||
"""Return a tuple with the size of the directory given by path and the errno.
|
||||
If an error occurs (for example one file or subfolder is not accessible),
|
||||
errno is set to the error number.
|
||||
|
||||
path: <string>
|
||||
errno: <int> Should always be 0 when calling the function"""
|
||||
ret_size = 0
|
||||
ret_err = errno
|
||||
try:
|
||||
f_list = os.scandir(path)
|
||||
except OSError as e:
|
||||
return 0, e.errno
|
||||
for f in f_list:
|
||||
if f.is_dir(follow_symlinks=False) and (f.name != '.' or f.name != '..'):
|
||||
ret = folder_size(os.path.join(path, f.name), ret_err)
|
||||
ret_size += ret[0]
|
||||
ret_err = ret[1]
|
||||
else:
|
||||
try:
|
||||
ret_size += f.stat().st_size
|
||||
except OSError as e:
|
||||
ret_err = e.errno
|
||||
return ret_size, ret_err
|
||||
|
@ -330,6 +330,7 @@ class _GlancesCurses(object):
|
||||
'PASSWORD': curses.A_PROTECT,
|
||||
'SELECTED': self.selected_color,
|
||||
'INFO': self.ifINFO_color,
|
||||
'ERROR': self.selected_color,
|
||||
}
|
||||
|
||||
def set_cursor(self, value):
|
||||
|
@ -110,6 +110,10 @@ body {
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
.error {
|
||||
color: #EE6600;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Plugins */
|
||||
#processlist-plugin .table-cell {
|
||||
|
@ -9,6 +9,9 @@
|
||||
<div class="table-cell text-left">{{ folder.path }}</div>
|
||||
<div class="table-cell"></div>
|
||||
<div class="table-cell" :class="getDecoration(folder)">
|
||||
<span v-if="folder.errno > 0" class="visible-lg-inline">
|
||||
?
|
||||
</span>
|
||||
{{ $filters.bytes(folder.size) }}
|
||||
</div>
|
||||
</div>
|
||||
@ -31,6 +34,7 @@ export default {
|
||||
return {
|
||||
path: folderData['path'],
|
||||
size: folderData['size'],
|
||||
errno: folderData['errno'],
|
||||
careful: folderData['careful'],
|
||||
warning: folderData['warning'],
|
||||
critical: folderData['critical']
|
||||
@ -40,8 +44,8 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
getDecoration(folder) {
|
||||
if (!Number.isInteger(folder.size)) {
|
||||
return;
|
||||
if (folder.errno > 0) {
|
||||
return 'error';
|
||||
}
|
||||
if (folder.critical !== null && folder.size > folder.critical * 1000000) {
|
||||
return 'critical';
|
||||
|
6
glances/outputs/static/public/glances.js
vendored
6
glances/outputs/static/public/glances.js
vendored
File diff suppressed because one or more lines are too long
@ -64,8 +64,8 @@ class PluginModel(GlancesPluginModel):
|
||||
|
||||
def get_alert(self, stat, header=""):
|
||||
"""Manage limits of the folder list."""
|
||||
if not isinstance(stat['size'], numbers.Number):
|
||||
ret = 'DEFAULT'
|
||||
if stat['errno'] != 0:
|
||||
ret = 'ERROR'
|
||||
else:
|
||||
ret = 'OK'
|
||||
|
||||
@ -108,15 +108,15 @@ class PluginModel(GlancesPluginModel):
|
||||
ret.append(self.curse_new_line())
|
||||
if len(i['path']) > name_max_width:
|
||||
# Cut path if it is too long
|
||||
path = '_' + i['path'][-name_max_width + 1 :]
|
||||
path = '_' + i['path'][-name_max_width + 1:]
|
||||
else:
|
||||
path = i['path']
|
||||
msg = '{:{width}}'.format(nativestr(path), width=name_max_width)
|
||||
ret.append(self.curse_add_line(msg))
|
||||
try:
|
||||
if i['errno'] != 0:
|
||||
msg = '?{:>8}'.format(self.auto_unit(i['size']))
|
||||
else:
|
||||
msg = '{:>9}'.format(self.auto_unit(i['size']))
|
||||
except (TypeError, ValueError):
|
||||
msg = '{:>9}'.format(i['size'])
|
||||
ret.append(self.curse_add_line(msg, self.get_alert(i, header='folder_' + i['indice'])))
|
||||
|
||||
return ret
|
||||
|
5
setup.py
5
setup.py
@ -9,8 +9,8 @@ from io import open
|
||||
from setuptools import setup, Command
|
||||
|
||||
|
||||
if sys.version_info < (3, 4):
|
||||
print('Glances requires at least Python 3.4 to run.')
|
||||
if sys.version_info < (3, 8):
|
||||
print('Glances requires at least Python 3.8 to run.')
|
||||
sys.exit(1)
|
||||
|
||||
# Global functions
|
||||
@ -60,7 +60,6 @@ def get_install_extras_require():
|
||||
'graphitesender', 'influxdb>=1.0.0', 'influxdb-client', 'pymongo',
|
||||
'kafka-python', 'pika', 'paho-mqtt', 'potsdb', 'prometheus_client',
|
||||
'pyzmq', 'statsd'],
|
||||
'folders': ['scandir'],
|
||||
'gpu': ['py3nvml'],
|
||||
'graph': ['pygal'],
|
||||
'ip': ['netifaces'],
|
||||
|
Loading…
Reference in New Issue
Block a user