# brightway2-data / bw2data / _config.py

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 # -*- coding: utf-8 -*- import codecs import json import os import platform import tempfile import warnings class Config(object): """A singleton that store configuration settings. Default data directory is brightway in the user's home directory, and is stored as config.dir. Other configuration settings can also be assigned as needed. Args: * *path* (str, optional): The path of the data directory. Must be writeable. """ version = 0.1 basic_directories = ("processed", "intermediate", "backups", "logs") _windows = platform.system() == "Windows" # TODO: Create directory if needed (and basic dirs) def __init__(self, path=None): self.is_temp_dir = False self.reset(path) self.cache = {} def check_dir(self, dir=None): """Check is directory is a directory and writeable.""" return os.path.isdir(self.dir) and os.access(dir or self.dir, os.W_OK) def reset(self, path=None): """Reset to original configuration. Useful for testing.""" try: self.dir = self.get_home_directory(path) except OSError: self.dir = tempfile.mkdtemp() self.is_temp_dir = True if not getattr(self, "dont_warn", False): warnings.warn(u"\n\tYour changes will not be saved!\n" u"\tSet a writeable directory!\n" u"\tCurrent data directory is:\n" u"\t%s" % self.dir, UserWarning ) # Has to come here, because web interface wants # to open a log ASAP self.create_basic_directories() self.load_preferences() def load_preferences(self): """Load a set of preferences from a file in the home directory. Preferences as stored as config.p.""" try: self.p = json.load(open(os.path.join( self.dir, "preferences.json"))) except: self.p = {"use_cache": True} def save_preferences(self): """Serialize preferences to disk.""" with open(os.path.join( self.dir, "preferences.json"), "w") as f: json.dump(self.p, f, indent=2) def get_home_directory(self, path=None): """Get data directory, trying in order: * Provided path (optional) * BRIGHTWAY2_DIR environment variable * .brightway2path file in user's home directory * brightway2path.txt file in user's home directory * brightway2 in user's home directory To set the environment variable: * Unix/Mac: export BRIGHTWAY2_DIR=/path/to/brightway2/directory * Windows XP: Instead of an environment variable, just create a brightway2path.txt file in your home directory (C:\Users\Your Name\) with a single line that is the directory path you want to use. * Windows 7: setx BRIGHTWAY2_DIR=\path\to\brightway2\directory """ if path: self._dir_from = u"user provided" return path user_dir = os.path.expanduser("~") envvar = os.getenv("BRIGHTWAY2_DIR") if envvar: self._dir_from = u"environment variable" return envvar for filename in (".brightway2path", "brightway2path.txt"): try: candidate = codecs.open( os.path.join(user_dir, filename), encoding='utf-8' ).readline().strip() if os.path.supports_unicode_filenames: # Leaving as unicode is OK pass else: # posix systems except for Mac OS X candidate = candidate.encode('utf-8') assert os.path.exists(candidate) self._dir_from = filename return candidate except: pass else: self._dir_from = u"default" return os.path.join(user_dir, "brightway2") def request_dir(self, dirname): """Return directory path if writable, or False.""" path = os.path.join(self.dir, dirname) if self.check_dir(path): return path else: try: os.mkdir(path) return path except: return False def create_basic_directories(self): """Create basic directory structure. Useful when first starting or for tests.""" for name in self.basic_directories: if not os.path.exists(os.path.join(self.dir, name)): os.mkdir(os.path.join(self.dir, name)) def _get_dir(self): # This is a string in the correct encoding for the filesystem return self._dir def _set_dir(self, d): self._dir = d if not self.check_dir(): raise OSError(u"This directory is not writeable") dir = property(_get_dir, _set_dir) @property def udir(self): """Return dir in Unicode""" return self.dir.decode('utf-8') config = Config()