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 150 151 152 153
|
"""Settings file exclusively for friendly -- not for friendly-traceback"""
import configparser
import locale
import os
import sys
from friendly_traceback import debug_helper
from friendly_traceback.config import session
import platformdirs
config_dir = platformdirs.user_config_dir(
appname="FriendlyTraceback", appauthor=False # noqa
)
FILENAME = os.path.join(config_dir, "friendly.ini")
# I tried to install psutil to determine the kind of terminal (if any)
# that friendly was running in, but the installation failed.
# So I resort to a simpler way of determining the terminal if possible.
# For terminals, the assumption is that a single background color will
# be used for a given terminal type.
if "TERM_PROGRAM" in os.environ: # used by VS Code
terminal_type = os.environ["TERM_PROGRAM"]
elif "TERMINAL_EMULATOR" in os.environ: # used by PyCharm
terminal_type = os.environ["TERMINAL_EMULATOR"]
elif "TERM" in os.environ: # Unix?
terminal_type = os.environ["TERM"]
elif sys.platform == "win32":
# The following might be used to distinguish between powershell and cmd.
_ps = len(os.getenv("PSModulePath", "").split(os.pathsep))
terminal_type = f"win32-{_ps}"
else:
terminal_type = "sys.platform"
ENVIRONMENT = terminal_type
# ENVIRONMENT is determined by the "flavour" of friendly.
# If a terminal type is identified, then the ENVIRONMENT variable
# would usually be a combination of the terminal_type and the flavour.
# Perhaps friendly will be used in environments where the user cannot
# create settings directories and files
def ensure_existence():
"""Ensures that a settings file exists"""
if not os.path.exists(config_dir):
os.makedirs(config_dir)
if not os.path.exists(FILENAME):
config = configparser.ConfigParser()
with open(FILENAME, "w") as config_file:
config.write(config_file)
try:
ensure_existence()
except Exception: # noqa
FILENAME = None
def read(*, option="unknown", environment=None):
"""Returns the value of a key in the current environment"""
if FILENAME is None:
return getattr(session, option) if hasattr(session, option) else None
if environment is not None:
section = environment
elif ENVIRONMENT is not None:
section = ENVIRONMENT
else:
section = "unknown"
debug_helper.log(f"Reading unknown section: {option}")
config = configparser.ConfigParser()
config.read(FILENAME)
if section in config and option in config[section]:
return config[section][option]
return
def write(*, option="unknown", value="unknown", environment=None):
"""Updates the value of a key in the current environment.
If the section does not already exist, it is created.
"""
if not isinstance(option, str):
debug_helper.log(f"option = {option} is not a string.")
return
if not isinstance(value, str):
debug_helper.log(f"value = {value} is not a string.")
return
if FILENAME is None:
setattr(session, option, value)
return
if environment is not None:
section = environment
elif ENVIRONMENT is not None:
section = ENVIRONMENT
else:
section = "unknown"
debug_helper.log(f"writing unknown for environment={environment}")
config = configparser.ConfigParser()
config.read(FILENAME)
if not config.has_section(section):
config.add_section(section)
config[section][option] = value
with open(FILENAME, "w") as config_file:
config.write(config_file)
def _remove_environment(environment=None):
"""Removes an environment (option) previously saved."""
if FILENAME is None:
return
if environment is not None:
section = environment
elif ENVIRONMENT is not None:
section = ENVIRONMENT
else:
print("No environment defined.")
return
config = configparser.ConfigParser()
config.read(FILENAME)
config.remove_section(section)
with open(FILENAME, "w") as config_file:
config.write(config_file)
def has_environment(environment=None):
"""Returns True if a section in the settings file has already been set
for this environment.
"""
if FILENAME is None:
return False
section = environment if environment is not None else ENVIRONMENT
config = configparser.ConfigParser()
config.read(FILENAME)
return config.has_section(section)
def print_settings():
"""Prints the contents of the settings file"""
config = configparser.ConfigParser()
print("Current environment: ", ENVIRONMENT)
config.read(FILENAME)
config.write(sys.stdout)
def get_lang() -> str:
lang = read(option="lang", environment="common")
if lang is None:
lang = locale.getlocale()[0]
return lang
|