1 | # -*- coding: utf-8 -*- |
||
2 | # |
||
3 | # This file is part of Glances. |
||
4 | # |
||
5 | # Copyright (C) 2019 Nicolargo <[email protected]> |
||
6 | # |
||
7 | # Glances is free software; you can redistribute it and/or modify |
||
8 | # it under the terms of the GNU Lesser General Public License as published by |
||
9 | # the Free Software Foundation, either version 3 of the License, or |
||
10 | # (at your option) any later version. |
||
11 | # |
||
12 | # Glances is distributed in the hope that it will be useful, |
||
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
15 | # GNU Lesser General Public License for more details. |
||
16 | # |
||
17 | # You should have received a copy of the GNU Lesser General Public License |
||
18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
||
19 | |||
20 | """Manage the folder list.""" |
||
21 | from __future__ import unicode_literals |
||
22 | |||
23 | import os |
||
0 ignored issues
–
show
introduced
by
Loading history...
|
|||
24 | |||
25 | from glances.timer import Timer |
||
0 ignored issues
–
show
|
|||
26 | from glances.compat import range, nativestr |
||
0 ignored issues
–
show
|
|||
27 | from glances.logger import logger |
||
0 ignored issues
–
show
|
|||
28 | |||
29 | # Use the built-in version of scandir/walk if possible, otherwise |
||
30 | # use the scandir module version |
||
31 | scandir_tag = True |
||
0 ignored issues
–
show
The name
scandir_tag does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$ ).
This check looks for invalid names for a range of different identifiers. You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements. If your project includes a Pylint configuration file, the settings contained in that file take precedence. To find out more about Pylint, please refer to their site.
Loading history...
|
|||
32 | try: |
||
33 | # For Python 3.5 or higher |
||
34 | from os import scandir |
||
0 ignored issues
–
show
|
|||
35 | except ImportError: |
||
36 | # For others... |
||
37 | try: |
||
38 | from scandir import scandir |
||
0 ignored issues
–
show
|
|||
39 | except ImportError: |
||
40 | scandir_tag = False |
||
0 ignored issues
–
show
The name
scandir_tag does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$ ).
This check looks for invalid names for a range of different identifiers. You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements. If your project includes a Pylint configuration file, the settings contained in that file take precedence. To find out more about Pylint, please refer to their site.
Loading history...
|
|||
41 | |||
42 | |||
43 | class FolderList(object): |
||
44 | |||
45 | """This class describes the optional monitored folder list. |
||
46 | |||
47 | The folder list is a list of 'important' folder to monitor. |
||
48 | |||
49 | The list (Python list) is composed of items (Python dict). |
||
50 | An item is defined (dict keys): |
||
51 | * path: Path to the folder |
||
52 | * careful: optional careful threshold (in MB) |
||
53 | * warning: optional warning threshold (in MB) |
||
54 | * critical: optional critical threshold (in MB) |
||
55 | """ |
||
56 | |||
57 | # Maximum number of items in the list |
||
58 | __folder_list_max_size = 10 |
||
59 | # The folder list |
||
60 | __folder_list = [] |
||
61 | # Default refresh time is 30 seconds for this plugins |
||
62 | __default_refresh = 30 |
||
63 | |||
64 | def __init__(self, config): |
||
65 | """Init the folder list from the configuration file, if it exists.""" |
||
66 | self.config = config |
||
67 | |||
68 | # A list of Timer |
||
69 | # One timer per folder |
||
70 | # default timer is __default_refresh, can be overwrite by folder_1_refresh=600 |
||
0 ignored issues
–
show
|
|||
71 | self.timer_folders = [] |
||
72 | self.first_grab = True |
||
73 | |||
74 | if self.config is not None and self.config.has_section('folders'): |
||
75 | if scandir_tag: |
||
76 | # Process monitoring list |
||
77 | logger.debug("Folder list configuration detected") |
||
78 | self.__set_folder_list('folders') |
||
79 | else: |
||
80 | logger.error('Scandir not found. Please use Python 3.5+ or install the scandir lib') |
||
0 ignored issues
–
show
|
|||
81 | else: |
||
82 | self.__folder_list = [] |
||
83 | |||
84 | def __set_folder_list(self, section): |
||
85 | """Init the monitored folder list. |
||
86 | |||
87 | The list is defined in the Glances configuration file. |
||
88 | """ |
||
89 | for l in range(1, self.__folder_list_max_size + 1): |
||
0 ignored issues
–
show
The name
l does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ ).
This check looks for invalid names for a range of different identifiers. You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements. If your project includes a Pylint configuration file, the settings contained in that file take precedence. To find out more about Pylint, please refer to their site.
Loading history...
|
|||
90 | value = {} |
||
91 | key = 'folder_' + str(l) + '_' |
||
92 | |||
93 | # Path is mandatory |
||
94 | value['indice'] = str(l) |
||
95 | value['path'] = self.config.get_value(section, key + 'path') |
||
96 | if value['path'] is None: |
||
97 | continue |
||
98 | else: |
||
99 | value['path'] = nativestr(value['path']) |
||
100 | |||
101 | # Optional conf keys |
||
102 | # Refresh time |
||
103 | value['refresh'] = int(self.config.get_value(section, |
||
104 | key + 'refresh', |
||
105 | default=self.__default_refresh)) |
||
0 ignored issues
–
show
|
|||
106 | self.timer_folders.append(Timer(value['refresh'])) |
||
107 | # Thesholds |
||
108 | for i in ['careful', 'warning', 'critical']: |
||
109 | # Read threshold |
||
110 | value[i] = self.config.get_value(section, key + i) |
||
111 | if value[i] is not None: |
||
112 | logger.debug("{} threshold for folder {} is {}".format(i, value["path"], value[i])) |
||
0 ignored issues
–
show
|
|||
113 | # Read action |
||
114 | action = self.config.get_value(section, key + i + '_action') |
||
115 | if action is not None: |
||
116 | value[i + '_action'] = action |
||
117 | logger.debug("{} action for folder {} is {}".format(i, value["path"], value[i + '_action'])) |
||
0 ignored issues
–
show
|
|||
118 | |||
119 | # Add the item to the list |
||
120 | self.__folder_list.append(value) |
||
121 | |||
122 | def __str__(self): |
||
123 | return str(self.__folder_list) |
||
124 | |||
125 | def __repr__(self): |
||
126 | return self.__folder_list |
||
127 | |||
128 | def __getitem__(self, item): |
||
129 | return self.__folder_list[item] |
||
130 | |||
131 | def __len__(self): |
||
132 | return len(self.__folder_list) |
||
133 | |||
134 | def __get__(self, item, key): |
||
135 | """Meta function to return key value of item. |
||
136 | |||
137 | Return None if not defined or item > len(list) |
||
138 | """ |
||
139 | if item < len(self.__folder_list): |
||
140 | try: |
||
141 | return self.__folder_list[item][key] |
||
142 | except Exception: |
||
0 ignored issues
–
show
Catching very general exceptions such as
Exception is usually not recommended.
Generally, you would want to handle very specific errors in the exception handler. This ensure that you do not hide other types of errors which should be fixed. So, unless you specifically plan to handle any error, consider adding a more specific exception.
Loading history...
|
|||
143 | return None |
||
144 | else: |
||
145 | return None |
||
146 | |||
147 | def __folder_size(self, path): |
||
148 | """Return the size of the directory given by path |
||
149 | |||
150 | path: <string>""" |
||
151 | |||
152 | ret = 0 |
||
153 | for f in scandir(path): |
||
0 ignored issues
–
show
The name
f does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ ).
This check looks for invalid names for a range of different identifiers. You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements. If your project includes a Pylint configuration file, the settings contained in that file take precedence. To find out more about Pylint, please refer to their site.
Loading history...
|
|||
154 | if f.is_dir() and (f.name != '.' or f.name != '..'): |
||
155 | ret += self.__folder_size(os.path.join(path, f.name)) |
||
156 | else: |
||
157 | try: |
||
158 | ret += f.stat().st_size |
||
159 | except OSError: |
||
160 | pass |
||
161 | |||
162 | return ret |
||
163 | |||
164 | def update(self): |
||
165 | """Update the command result attributed.""" |
||
166 | # Only continue if monitor list is not empty |
||
167 | if len(self.__folder_list) == 0: |
||
0 ignored issues
–
show
|
|||
168 | return self.__folder_list |
||
169 | |||
170 | # Iter upon the folder list |
||
171 | for i in range(len(self.get())): |
||
172 | # Update folder size |
||
173 | if not self.first_grab and not self.timer_folders[i].finished(): |
||
174 | continue |
||
175 | # Get folder size |
||
176 | try: |
||
177 | self.__folder_list[i]['size'] = self.__folder_size(self.path(i)) |
||
178 | except OSError as e: |
||
0 ignored issues
–
show
The name
e does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ ).
This check looks for invalid names for a range of different identifiers. You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements. If your project includes a Pylint configuration file, the settings contained in that file take precedence. To find out more about Pylint, please refer to their site.
Loading history...
|
|||
179 | logger.debug('Cannot get folder size ({}). Error: {}'.format(self.path(i), e)) |
||
0 ignored issues
–
show
|
|||
180 | if e.errno == 13: |
||
181 | # Permission denied |
||
182 | self.__folder_list[i]['size'] = '!' |
||
183 | else: |
||
184 | self.__folder_list[i]['size'] = '?' |
||
185 | # Reset the timer |
||
186 | self.timer_folders[i].reset() |
||
187 | |||
188 | # It is no more the first time... |
||
189 | self.first_grab = False |
||
190 | |||
191 | return self.__folder_list |
||
192 | |||
193 | def get(self): |
||
194 | """Return the monitored list (list of dict).""" |
||
195 | return self.__folder_list |
||
196 | |||
197 | def set(self, newlist): |
||
198 | """Set the monitored list (list of dict).""" |
||
199 | self.__folder_list = newlist |
||
200 | |||
201 | def getAll(self): |
||
0 ignored issues
–
show
The name
getAll does not conform to the method naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ ).
This check looks for invalid names for a range of different identifiers. You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements. If your project includes a Pylint configuration file, the settings contained in that file take precedence. To find out more about Pylint, please refer to their site.
Loading history...
This method should have a docstring.
The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods: class SomeClass:
def some_method(self):
"""Do x and return foo."""
If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.
Loading history...
|
|||
202 | # Deprecated: use get() |
||
203 | return self.get() |
||
204 | |||
205 | def setAll(self, newlist): |
||
0 ignored issues
–
show
The name
setAll does not conform to the method naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ ).
This check looks for invalid names for a range of different identifiers. You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements. If your project includes a Pylint configuration file, the settings contained in that file take precedence. To find out more about Pylint, please refer to their site.
Loading history...
This method should have a docstring.
The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods: class SomeClass:
def some_method(self):
"""Do x and return foo."""
If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.
Loading history...
|
|||
206 | # Deprecated: use set() |
||
207 | self.set(newlist) |
||
208 | |||
209 | def path(self, item): |
||
210 | """Return the path of the item number (item).""" |
||
211 | return self.__get__(item, "path") |
||
212 | |||
213 | def careful(self, item): |
||
214 | """Return the careful threshold of the item number (item).""" |
||
215 | return self.__get__(item, "careful") |
||
216 | |||
217 | def warning(self, item): |
||
218 | """Return the warning threshold of the item number (item).""" |
||
219 | return self.__get__(item, "warning") |
||
220 | |||
221 | def critical(self, item): |
||
222 | """Return the critical threshold of the item number (item).""" |
||
223 | return self.__get__(item, "critical") |
||
224 |