filebased.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import os.path
  2. from copy import deepcopy
  3. from ..config import Configuration
  4. from .base import Source
  5. __all__ = ("HomeDirectory", "ConfigDirectory", "FileBasedSource")
  6. class DirectoryModifier(object):
  7. def __init__(self, target_file):
  8. self.target_file = target_file
  9. def __call__(self):
  10. raise NotImplementedError()
  11. class HomeDirectory(DirectoryModifier):
  12. def __call__(self):
  13. return os.path.expanduser(os.path.join("~", self.target_file))
  14. class ConfigDirectory(DirectoryModifier):
  15. def __call__(self):
  16. config_dir = os.getenv("XDG_CONFIG_HOME") or os.path.expanduser(
  17. os.path.join("~", ".config")
  18. )
  19. return os.path.join(config_dir, self.target_file)
  20. class FileBasedSource(Source):
  21. def __init__(self, files, base_path=None, combine=False):
  22. super(FileBasedSource, self).__init__()
  23. if isinstance(files, (str, DirectoryModifier)):
  24. files = [files]
  25. elif not isinstance(files, (tuple, list)):
  26. raise TypeError("files must be a string or list of strings")
  27. self.files = []
  28. for target in files:
  29. if isinstance(target, str):
  30. self.files.append(target)
  31. elif isinstance(target, DirectoryModifier):
  32. self.files.append(target())
  33. else:
  34. raise TypeError("files must be a string or list of strings")
  35. self.base_path = base_path or os.getcwd()
  36. self.combine = combine
  37. def get_config(self, settings, manager=None, parent=None):
  38. parsed_settings = []
  39. for file_source in self.files:
  40. if os.path.isabs(file_source):
  41. file_path = file_source
  42. else:
  43. file_path = os.path.join(self.base_path, file_source)
  44. if os.path.exists(file_path):
  45. file_settings = self.get_settings_from_file(
  46. file_path, deepcopy(settings), manager=manager
  47. )
  48. if file_settings:
  49. parsed_settings.append(file_settings)
  50. if not self.combine:
  51. # No need to gather any more, we only want one.
  52. break
  53. if parsed_settings:
  54. config = parent
  55. for parsed_setting in reversed(parsed_settings):
  56. config = Configuration(settings=parsed_setting, parent=config)
  57. else:
  58. config = Configuration(settings=settings, parent=parent)
  59. return config
  60. def get_settings_from_file(self, file_path, settings, manager=None):
  61. raise NotImplementedError()