summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlessio Sergi <al3hex@gmail.com>2017-01-31 15:55:31 +0100
committerAlessio Sergi <al3hex@gmail.com>2017-01-31 18:04:53 +0100
commit93fbf756039c7e6f1605740c111149b2fdb35d88 (patch)
tree62eac390a8fac52758c6470086029cbff7cb9243
parent921710b0e6df5b3252199031101da53e47c4723b (diff)
Optimize config code
- Remove duplicate code (one place to rule them all) - Add SunOS support - Add a safe function for creating a directory tree - Put cache file in the cache directories
-rw-r--r--glances/config.py76
-rw-r--r--glances/globals.py19
-rw-r--r--glances/outdated.py33
-rw-r--r--glances/password.py46
4 files changed, 94 insertions, 80 deletions
diff --git a/glances/config.py b/glances/config.py
index 84595f16..c04d34c2 100644
--- a/glances/config.py
+++ b/glances/config.py
@@ -25,10 +25,64 @@ import multiprocessing
from io import open
from glances.compat import ConfigParser, NoOptionError
-from glances.globals import BSD, LINUX, MACOS, WINDOWS, sys_prefix
+from glances.globals import BSD, LINUX, MACOS, SUNOS, WINDOWS
from glances.logger import logger
+def user_config_dir():
+ r"""Return the per-user config dir (full path).
+
+ - Linux, *BSD, SunOS: ~/.config/glances
+ - macOS: ~/Library/Application Support/glances
+ - Windows: %APPDATA%\glances
+ """
+ if WINDOWS:
+ path = os.environ.get('APPDATA')
+ elif MACOS:
+ path = os.path.expanduser('~/Library/Application Support')
+ else:
+ path = os.environ.get('XDG_CONFIG_HOME') or os.path.expanduser('~/.config')
+ path = os.path.join(path, 'glances')
+
+ return path
+
+
+def user_cache_dir():
+ r"""Return the per-user cache dir (full path).
+
+ - Linux, *BSD, SunOS: ~/.cache/glances
+ - macOS: ~/Library/Caches/glances
+ - Windows: %LOCALAPPDATA%\glances\cache
+ """
+ if WINDOWS:
+ path = os.path.join(os.environ.get('LOCALAPPDATA'), 'glances', 'cache')
+ elif MACOS:
+ path = os.path.expanduser('~/Library/Caches/glances')
+ else:
+ path = os.path.join(os.environ.get('XDG_CACHE_HOME') or os.path.expanduser('~/.cache'),
+ 'glances')
+
+ return path
+
+
+def system_config_dir():
+ r"""Return the system-wide config dir (full path).
+
+ - Linux, SunOS: /etc/glances
+ - *BSD, macOS: /usr/local/etc/glances
+ - Windows: %APPDATA%\glances
+ """
+ if LINUX or SUNOS:
+ path = '/etc'
+ elif BSD or MACOS:
+ path = '/usr/local/etc'
+ else:
+ path = os.environ.get('APPDATA')
+ path = os.path.join(path, 'glances')
+
+ return path
+
+
class Config(object):
"""This class is used to access/read config file, if it exists.
@@ -51,7 +105,7 @@ class Config(object):
The list is built taking into account of the OS, priority and location.
* custom path: /path/to/glances
- * Linux: ~/.config/glances, /etc/glances
+ * Linux, SunOS: ~/.config/glances, /etc/glances
* *BSD: ~/.config/glances, /usr/local/etc/glances
* macOS: ~/Library/Application Support/glances, /usr/local/etc/glances
* Windows: %APPDATA%\glances
@@ -66,22 +120,8 @@ class Config(object):
if self.config_dir:
paths.append(self.config_dir)
- if LINUX or BSD:
- paths.append(
- os.path.join(os.environ.get('XDG_CONFIG_HOME') or
- os.path.expanduser('~/.config'),
- 'glances', self.config_filename))
- if BSD:
- paths.append(os.path.join(sys.prefix, 'etc', 'glances', self.config_filename))
- else:
- paths.append(os.path.join('/etc/glances', self.config_filename))
- elif MACOS:
- paths.append(
- os.path.join(os.path.expanduser('~/Library/Application Support/glances'),
- self.config_filename))
- paths.append(os.path.join(sys_prefix, 'etc', 'glances', self.config_filename))
- elif WINDOWS:
- paths.append(os.path.join(os.environ.get('APPDATA'), 'glances', self.config_filename))
+ paths.append(os.path.join(user_config_dir(), self.config_filename))
+ paths.append(os.path.join(system_config_dir(), self.config_filename))
return paths
diff --git a/glances/globals.py b/glances/globals.py
index c67cf3f3..f335d737 100644
--- a/glances/globals.py
+++ b/glances/globals.py
@@ -19,6 +19,7 @@
"""Common objects shared by all Glances modules."""
+import errno
import os
import sys
@@ -30,12 +31,8 @@ MACOS = sys.platform.startswith('darwin')
SUNOS = sys.platform.startswith('sunos')
WINDOWS = sys.platform.startswith('win')
-# Path definitions
-work_path = os.path.realpath(os.path.dirname(__file__))
-appname_path = os.path.split(sys.argv[0])[0]
-sys_prefix = os.path.realpath(os.path.dirname(appname_path))
-
# Set the AMPs, plugins and export modules path
+work_path = os.path.realpath(os.path.dirname(__file__))
amps_path = os.path.realpath(os.path.join(work_path, 'amps'))
plugins_path = os.path.realpath(os.path.join(work_path, 'plugins'))
exports_path = os.path.realpath(os.path.join(work_path, 'exports'))
@@ -43,3 +40,15 @@ sys_path = sys.path[:]
sys.path.insert(1, exports_path)
sys.path.insert(1, plugins_path)
sys.path.insert(1, amps_path)
+
+
+def safe_makedirs(path):
+ """A safe function for creating a directory tree."""
+ try:
+ os.makedirs(path)
+ except OSError as err:
+ if err.errno == errno.EEXIST:
+ if not os.path.isdir(path):
+ raise
+ else:
+ raise
diff --git a/glances/outdated.py b/glances/outdated.py
index f402244e..5bfd683b 100644
--- a/glances/outdated.py
+++ b/glances/outdated.py
@@ -33,7 +33,8 @@ else:
outdated_tag = True
from glances import __version__
-from glances.globals import BSD, LINUX, MACOS, WINDOWS
+from glances.config import user_cache_dir
+from glances.globals import safe_makedirs
from glances.logger import logger
@@ -51,6 +52,8 @@ class Outdated(object):
"""Init the Outdated class"""
self.args = args
self.config = config
+ self.cache_dir = user_cache_dir()
+ self.cache_file = os.path.join(self.cache_dir, 'glances-version.db')
# Set default value...
self.data = {
@@ -126,10 +129,10 @@ class Outdated(object):
# If the cached file exist, read-it
cached_data = {}
try:
- with open(os.path.join(self._cache_path(), 'glances-version.db'), 'rb') as f:
+ with open(self.cache_file, 'rb') as f:
cached_data = pickle.load(f)
except Exception as e:
- logger.debug("Cannot read the version cache file ({})".format(e))
+ logger.debug("Cannot read the version cache file: {}".format(e))
else:
logger.debug("Read the version cache file")
if cached_data['installed_version'] != self.installed_version() or \
@@ -141,25 +144,13 @@ class Outdated(object):
return cached_data
def _save_cache(self):
- """Save data to a file"""
- # If the cached file exist, read-it
- try:
- with open(os.path.join(self._cache_path(), 'glances-version.db'), 'wb') as f:
- pickle.dump(self.data, f)
- except IOError:
- return False
- return True
+ """Save data to the cache file."""
+ # Create the cache directory
+ safe_makedirs(self.cache_dir)
- def _cache_path(self):
- """Return the cached file path"""
- if LINUX or BSD:
- return os.path.join(os.environ.get('XDG_CONFIG_HOME') or
- os.path.expanduser('~/.config'),
- 'glances')
- elif MACOS:
- return os.path.expanduser('~/Library/Application Support/glances')
- elif WINDOWS:
- return os.path.join(os.environ.get('APPDATA'), 'glances')
+ # Create/overwrite the cache file
+ with open(self.cache_file, 'wb') as f:
+ pickle.dump(self.data, f)
def _update_pypi_version(self):
"""Get the latest Pypi version (as a string) via the Restful JSON API"""
diff --git a/glances/password.py b/glances/password.py
index 82c382a9..f0f9b6b1 100644
--- a/glances/password.py
+++ b/glances/password.py
@@ -27,7 +27,8 @@ import uuid
from io import open
from glances.compat import b, input
-from glances.globals import BSD, LINUX, MACOS, WINDOWS
+from glances.config import user_config_dir
+from glances.globals import safe_makedirs
from glances.logger import logger
@@ -37,30 +38,9 @@ class GlancesPassword(object):
def __init__(self, username='glances'):
self.username = username
- self.password_path = self.get_password_path()
+ self.password_dir = user_config_dir()
self.password_filename = self.username + '.pwd'
- self.password_filepath = os.path.join(self.password_path, self.password_filename)
-
- def get_password_path(self):
- r"""Get the path where the password file will be stored.
-
- * Linux and *BSD: ~/.config/glances
- * macOS: ~/Library/glances
- * Windows: %APPDATA%\glances
- """
- if LINUX or BSD:
- app_path = os.environ.get('XDG_CONFIG_HOME') or os.path.expanduser('~/.config')
- elif MACOS:
- app_path = os.path.join(os.environ.get('HOME'), 'Library')
- elif WINDOWS:
- app_path = os.environ.get('APPDATA')
- else:
- app_path = '.'
-
- # Append the Glances folder
- app_path = os.path.join(app_path, 'glances')
-
- return app_path
+ self.password_file = os.path.join(self.password_dir, self.password_filename)
def sha256_hash(self, plain_password):
"""Return the SHA-256 of the given password."""
@@ -98,9 +78,9 @@ class GlancesPassword(object):
2) the password is hashed with SHA-256 (only SHA string transit
through the network)
"""
- if os.path.exists(self.password_filepath) and not clear:
+ if os.path.exists(self.password_file) and not clear:
# If the password file exist then use it
- logger.info("Read password from file {}".format(self.password_filepath))
+ logger.info("Read password from file {}".format(self.password_file))
password = self.load_password()
else:
# password_sha256 is the plain SHA-256 password
@@ -131,23 +111,17 @@ class GlancesPassword(object):
def save_password(self, hashed_password):
"""Save the hashed password to the Glances folder."""
- # Check if the Glances folder already exists
- if not os.path.exists(self.password_path):
- # Create the Glances folder
- try:
- os.makedirs(self.password_path)
- except OSError as e:
- logger.error("Cannot create Glances directory: {}".format(e))
- return
+ # Create the glances directory
+ safe_makedirs(self.password_dir)
# Create/overwrite the password file
- with open(self.password_filepath, 'wb') as file_pwd:
+ with open(self.password_file, 'wb') as file_pwd:
file_pwd.write(b(hashed_password))
def load_password(self):
"""Load the hashed password from the Glances folder."""
# Read the password file, if it exists
- with open(self.password_filepath, 'r') as file_pwd:
+ with open(self.password_file, 'r') as file_pwd:
hashed_password = file_pwd.read()
return hashed_password