/glances/core/glances_config.py

https://gitlab.com/xbsd/glances · Python · 164 lines · 108 code · 13 blank · 43 comment · 9 complexity · 9a46f45240978edd567bf04aa0dc6889 MD5 · raw file

  1. # -*- coding: utf-8 -*-
  2. #
  3. # This file is part of Glances.
  4. #
  5. # Copyright (C) 2014 Nicolargo <nicolas@nicolargo.com>
  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. """Manage the configuration file."""
  20. # Import system libs
  21. import os
  22. import sys
  23. try:
  24. from configparser import RawConfigParser
  25. from configparser import NoOptionError
  26. except ImportError: # Python 2
  27. from ConfigParser import RawConfigParser
  28. from ConfigParser import NoOptionError
  29. # Import Glances lib
  30. from glances.core.glances_globals import (
  31. appname,
  32. is_bsd,
  33. is_linux,
  34. is_mac,
  35. is_py3,
  36. is_windows,
  37. logger,
  38. sys_prefix,
  39. work_path
  40. )
  41. class Config(object):
  42. """This class is used to access/read config file, if it exists.
  43. :param location: the custom path to search for config file
  44. :type location: str or None
  45. """
  46. def __init__(self, location=None):
  47. self.location = location
  48. self.config_filename = 'glances.conf'
  49. self.parser = RawConfigParser()
  50. self._loaded_config_file = None
  51. self.load()
  52. def load(self):
  53. """Load a config file from the list of paths, if it exists."""
  54. for config_file in self.get_config_paths():
  55. if os.path.isfile(config_file) and os.path.getsize(config_file) > 0:
  56. try:
  57. if is_py3:
  58. self.parser.read(config_file, encoding='utf-8')
  59. else:
  60. self.parser.read(config_file)
  61. logger.info("Read configuration file '{0}'".format(config_file))
  62. except UnicodeDecodeError as e:
  63. logger.error("Cannot decode configuration file '{0}': {1}".format(config_file, e))
  64. sys.exit(1)
  65. # Save the loaded configuration file path (issue #374)
  66. self._loaded_config_file = config_file
  67. break
  68. def get_loaded_config_file(self):
  69. """Return the loaded configuration file"""
  70. return self._loaded_config_file
  71. def get_config_paths(self):
  72. r"""Get a list of config file paths.
  73. The list is built taking into account of the OS, priority and location.
  74. * running from source: /path/to/glances/conf
  75. * per-user install: ~/.local/etc/glances (Unix-like only)
  76. * Linux: ~/.config/glances, /etc/glances
  77. * BSD: ~/.config/glances, /usr/local/etc/glances
  78. * Mac: ~/Library/Application Support/glances, /usr/local/etc/glances
  79. * Windows: %APPDATA%\glances
  80. The config file will be searched in the following order of priority:
  81. * /path/to/file (via -C flag)
  82. * /path/to/glances/conf
  83. * user's local directory (per-user install settings)
  84. * user's home directory (per-user settings)
  85. * {/usr/local,}/etc directory (system-wide settings)
  86. """
  87. paths = []
  88. conf_path = os.path.realpath(
  89. os.path.join(work_path, '..', '..', 'conf'))
  90. if self.location is not None:
  91. paths.append(self.location)
  92. if os.path.exists(conf_path):
  93. paths.append(os.path.join(conf_path, self.config_filename))
  94. if not is_windows:
  95. paths.append(os.path.join(os.path.expanduser('~/.local'), 'etc', appname, self.config_filename))
  96. if is_linux or is_bsd:
  97. paths.append(os.path.join(
  98. os.environ.get('XDG_CONFIG_HOME') or os.path.expanduser(
  99. '~/.config'),
  100. appname, self.config_filename))
  101. if hasattr(sys, 'real_prefix') or is_bsd:
  102. paths.append(
  103. os.path.join(sys.prefix, 'etc', appname, self.config_filename))
  104. else:
  105. paths.append(
  106. os.path.join('/etc', appname, self.config_filename))
  107. elif is_mac:
  108. paths.append(os.path.join(
  109. os.path.expanduser('~/Library/Application Support/'),
  110. appname, self.config_filename))
  111. paths.append(os.path.join(
  112. sys_prefix, 'etc', appname, self.config_filename))
  113. elif is_windows:
  114. paths.append(os.path.join(
  115. os.environ.get('APPDATA'), appname, self.config_filename))
  116. return paths
  117. def items(self, section):
  118. """Return the items list of a section."""
  119. return self.parser.items(section)
  120. def has_section(self, section):
  121. """Return info about the existence of a section."""
  122. return self.parser.has_section(section)
  123. def get_option(self, section, option):
  124. """Get the float value of an option, if it exists."""
  125. try:
  126. value = self.parser.getfloat(section, option)
  127. except NoOptionError:
  128. return
  129. else:
  130. return value
  131. def get_raw_option(self, section, option):
  132. """Get the raw value of an option, if it exists."""
  133. try:
  134. value = self.parser.get(section, option)
  135. except NoOptionError:
  136. return
  137. else:
  138. return value