From e2b57282833831c3acb10d7a88ac5ae64eab07ed Mon Sep 17 00:00:00 2001 From: Chris Lane Date: Thu, 31 Jan 2019 20:03:10 -0500 Subject: [PATCH] Refactored (7) Refactored for general code-clarity, with particular focus on removing needless abstraction within `Sheet` and `Sheets` classes. --- bin/cheat | 29 ++++++++++++++++- cheat/configuration.py | 17 +++++++--- cheat/sheet.py | 9 ++--- cheat/sheets.py | 74 ++++++++++++++---------------------------- 4 files changed, 69 insertions(+), 60 deletions(-) diff --git a/bin/cheat b/bin/cheat index 80cd5f3..45524ac 100755 --- a/bin/cheat +++ b/bin/cheat @@ -41,6 +41,7 @@ from cheat.configuration import Configuration from cheat.sheet import Sheet from cheat.sheets import Sheets from docopt import docopt +import os if __name__ == '__main__': @@ -51,6 +52,32 @@ if __name__ == '__main__': config = Configuration() config.validate() + # create the CHEAT_DEFAULT_DIR if it does not exist + if not os.path.isdir(config.cheat_default_dir): + try: + os.mkdir(config.cheat_default_dir) + + except OSError: + Utils.die("%s %s %s" % ( + 'Could not create CHEAT_DEFAULT_DIR (', + config.cheat_default_dir, + ')') + ) + + # assert that the CHEAT_DEFAULT_DIR is readable and writable + if not os.access(config.cheat_default_dir, os.R_OK): + Utils.die("%s %s %s" % ( + 'The CHEAT_DEFAULT_DIR (', + config.cheat_default_dir, + ') is not readable') + ) + if not os.access(config.cheat_default_dir, os.W_OK): + Utils.die("%s %s %s" % ( + 'The CHEAT_DEFAULT_DIR (', + config.cheat_default_dir, + ') is not writeable') + ) + # bootsrap sheets = Sheets(config) sheet = Sheet(config, sheets) @@ -58,7 +85,7 @@ if __name__ == '__main__': # list directories if options['--directories']: - print("\n".join(sheets.paths())) + print("\n".join(sheets.directories())) # list cheatsheets elif options['--list']: diff --git a/cheat/configuration.py b/cheat/configuration.py index 1ad7ad4..3d8a8e5 100644 --- a/cheat/configuration.py +++ b/cheat/configuration.py @@ -6,10 +6,14 @@ class Configuration: def __init__(self): # compute the location of the config files - config_file_path_global = os.environ.get('CHEAT_GLOBAL_CONF_PATH') \ - or '/etc/cheat' - config_file_path_local = (os.environ.get('CHEAT_LOCAL_CONF_PATH') \ - or os.path.expanduser('~/.config/cheat/cheat')) + config_file_path_global = self._select([ + os.environ.get('CHEAT_GLOBAL_CONF_PATH'), + '/etc/cheat', + ]) + config_file_path_local = self._select([ + os.environ.get('CHEAT_LOCAL_CONF_PATH'), + os.path.expanduser('~/.config/cheat/cheat'), + ]) # attempt to read the global config file config = {} @@ -39,7 +43,10 @@ class Configuration: self.cheat_default_dir = self._select([ os.environ.get('CHEAT_DEFAULT_DIR'), os.environ.get('DEFAULT_CHEAT_DIR'), - '~/.cheat', + # TODO: XDG home? + os.path.expanduser( + os.path.expandvars(os.path.join('~', '.cheat')) + ), ]) # self.cheat_editor diff --git a/cheat/sheet.py b/cheat/sheet.py index e06ace0..e33df5a 100644 --- a/cheat/sheet.py +++ b/cheat/sheet.py @@ -8,8 +8,9 @@ import shutil class Sheet: def __init__(self, config, sheets): - self._sheets = sheets + self._config = config self._editor = Editor(config) + self._sheets = sheets def copy(self, current_sheet_path, new_sheet_path): """ Copies a sheet to a new path """ @@ -34,7 +35,7 @@ class Sheet: # default path before editing elif self.exists(sheet) and not self.exists_in_default_path(sheet): self.copy(self.path(sheet), - os.path.join(self._sheets.default_path(), sheet)) + os.path.join(self._config.cheat_default_dir, sheet)) self.edit(sheet) # if it exists and is in the default path, then just open it @@ -43,7 +44,7 @@ class Sheet: def create(self, sheet): """ Creates a cheatsheet """ - new_sheet_path = os.path.join(self._sheets.default_path(), sheet) + new_sheet_path = os.path.join(self._config.cheat_default_dir, sheet) self._editor.open(new_sheet_path) def edit(self, sheet): @@ -57,7 +58,7 @@ class Sheet: def exists_in_default_path(self, sheet): """ Predicate that returns true if the sheet exists in default_path""" - default_path_sheet = os.path.join(self._sheets.default_path(), sheet) + default_path_sheet = os.path.join(self._config.cheat_default_dir, sheet) return (sheet in self._sheets.get() and os.access(default_path_sheet, os.R_OK)) diff --git a/cheat/sheets.py b/cheat/sheets.py index 2816d4b..d83d832 100644 --- a/cheat/sheets.py +++ b/cheat/sheets.py @@ -10,47 +10,25 @@ class Sheets: self._config = config self._colorize = Colorize(config); - def default_path(self): - """ Returns the default cheatsheet path """ + # Assembles a dictionary of cheatsheets as name => file-path + self._sheets = {} + sheet_paths = [ + config.cheat_default_dir + ] - # determine the default cheatsheet dir - # TODO: should probably rename `CHEAT_DEFAULT_DIR` to - # `CHEAT_USER_DIR` or something for clarity. - default_sheets_dir = (self._config.cheat_default_dir or - os.path.join('~', '.cheat')) - default_sheets_dir = os.path.expanduser( - os.path.expandvars(default_sheets_dir)) + # merge the CHEAT_PATH paths into the sheet_paths + if config.cheat_path: + for path in config.cheat_path.split(os.pathsep): + if os.path.isdir(path): + sheet_paths.append(path) - # create the CHEAT_DEFAULT_DIR if it does not exist - if not os.path.isdir(default_sheets_dir): - try: - # @kludge: unclear on why this is necessary - os.umask(0000) - os.mkdir(default_sheets_dir) - - except OSError: - Utils.die('Could not create CHEAT_DEFAULT_DIR') - - # assert that the CHEAT_DEFAULT_DIR is readable and writable - if not os.access(default_sheets_dir, os.R_OK): - Utils.die('The CHEAT_DEFAULT_DIR (' - + default_sheets_dir - + ') is not readable.') - if not os.access(default_sheets_dir, os.W_OK): - Utils.die('The CHEAT_DEFAULT_DIR (' - + default_sheets_dir - + ') is not writable.') - - # return the default dir - return default_sheets_dir - - def get(self): - """ Assembles a dictionary of cheatsheets as name => file-path """ - cheats = {} + if not sheet_paths: + Utils.die('The CHEAT_DEFAULT_DIR dir does not exist ' + + 'or the CHEAT_PATH is not set.') # otherwise, scan the filesystem - for cheat_dir in reversed(self.paths()): - cheats.update( + for cheat_dir in reversed(sheet_paths): + self._sheets.update( dict([ (cheat, os.path.join(cheat_dir, cheat)) for cheat in os.listdir(cheat_dir) @@ -59,26 +37,22 @@ class Sheets: ]) ) - return cheats - - def paths(self): + def directories(self): """ Assembles a list of directories containing cheatsheets """ sheet_paths = [ - self.default_path(), + self._config.cheat_default_dir, ] - # merge the CHEAT_PATH paths into the sheet_paths - if self._config.cheat_path: - for path in self._config.cheat_path.split(os.pathsep): - if os.path.isdir(path): - sheet_paths.append(path) - - if not sheet_paths: - Utils.die('The CHEAT_DEFAULT_DIR dir does not exist ' - + 'or the CHEAT_PATH is not set.') + # merge the CHEATPATH paths into the sheet_paths + for path in self._config.cheat_path.split(os.pathsep): + sheet_paths.append(path) return sheet_paths + def get(self): + """ Returns a dictionary of cheatsheets as name => file-path """ + return self._sheets + def list(self): """ Lists the available cheatsheets """ sheet_list = ''