2020-06-06 03:00:36 +04:00
|
|
|
|
"""An implementation of a slightly advanced key=value configuration file.
|
|
|
|
|
Commentary lines are started with # symbol.
|
|
|
|
|
Keys and values are separated by ' = ' (spaces are necessary).
|
|
|
|
|
Keys with . symbol are splited and right part is a nested dictionary.
|
|
|
|
|
Example:
|
|
|
|
|
# A commentary line
|
|
|
|
|
default_something = 10
|
|
|
|
|
currency.RUB = ...
|
|
|
|
|
Above example is translated as a following dictionary:
|
|
|
|
|
{ "default_something": 10, "currency": { "RUB": "..." } }
|
|
|
|
|
"""
|
2020-06-04 03:12:31 +04:00
|
|
|
|
|
|
|
|
|
from os import getenv
|
|
|
|
|
from os.path import exists, join
|
|
|
|
|
from platform import system
|
|
|
|
|
from typing import Union
|
|
|
|
|
|
|
|
|
|
__all__ = ["Configuration", "get_configuration_path"]
|
|
|
|
|
|
|
|
|
|
|
2020-06-06 03:00:36 +04:00
|
|
|
|
def get_configuration_path() -> str:
|
|
|
|
|
"""Returns a path to where configuration is stored."""
|
2020-06-04 03:12:31 +04:00
|
|
|
|
if system() == "Linux":
|
|
|
|
|
return getenv("XDG_CONFIG_HOME") or f"{getenv('HOME')}/.config"
|
|
|
|
|
elif system() == "Windows":
|
|
|
|
|
return getenv("APPDATA")
|
|
|
|
|
|
|
|
|
|
|
2020-06-05 03:51:29 +04:00
|
|
|
|
DEFAULT_CONFIGURATION = {
|
2020-06-07 20:41:17 +04:00
|
|
|
|
"default-currency": "SRUB",
|
|
|
|
|
"currency": {
|
|
|
|
|
"RUB": "RUB;Russian ruble;Russian Federation;8;" \
|
|
|
|
|
"1к,5к,10к,50к,1₽,2₽,5₽,10₽;1,5,10,50,100,200,500,1000",
|
|
|
|
|
"SRUB": "SRUB;Russian ruble (short);No 1 and 5 kopek;6;" \
|
|
|
|
|
"10к,50к,1₽,2₽,5₽,10₽;10,50,100,200,500,1000",
|
|
|
|
|
"BYN": "BYN;Belarusian ruble;Belarus;8;" \
|
|
|
|
|
"1к,2к,5к,10к,20к,50к,1р,2р;1,2,5,10,20,50,100,200",
|
|
|
|
|
"UAH": "UAH;Ukrainian hryvnia;Ukraine;10;" \
|
|
|
|
|
"1к,2к,5к,10к,25к,50к,₴1,₴2,₴5,₴10;1,2,5,10,25,50,100,200,500,1000",
|
|
|
|
|
"USD": "USD;US Dollar;United States of America;6;" \
|
|
|
|
|
"1¢,5¢,10¢,25¢,50¢,$1;1,5,10,25,50,100",
|
|
|
|
|
"EUR": "EUR;Euro;European Union;8;" \
|
|
|
|
|
"1c,2c,5c,10c,20c,50c,€1,€2;1,2,5,10,20,50,100,200",
|
|
|
|
|
"GBP": "GBP;Pound sterling;United Kingdom;9;" \
|
|
|
|
|
"1p,2p,5p,10p,20p,25p,50p,£1,£2;1,2,5,10,20,25,50,100,200" } }
|
2020-06-06 03:00:36 +04:00
|
|
|
|
|
2020-06-05 03:51:29 +04:00
|
|
|
|
DEFAULT_CONFIGURATION_FILE = join(get_configuration_path(), "piggybank.conf")
|
|
|
|
|
|
|
|
|
|
|
2020-06-04 03:12:31 +04:00
|
|
|
|
class Configuration:
|
|
|
|
|
def __init__(self, configuration_file: str = DEFAULT_CONFIGURATION_FILE,
|
|
|
|
|
default_configuration: dict = DEFAULT_CONFIGURATION) -> None:
|
|
|
|
|
self._configuration_file = configuration_file
|
|
|
|
|
self._configuration = dict()
|
|
|
|
|
if exists(self._configuration_file):
|
|
|
|
|
self.load()
|
|
|
|
|
elif not default_configuration is None:
|
|
|
|
|
self._configuration = default_configuration
|
|
|
|
|
self.save()
|
|
|
|
|
|
|
|
|
|
def load(self) -> None:
|
|
|
|
|
for line in open(self._configuration_file, 'r'):
|
2020-06-07 20:41:17 +04:00
|
|
|
|
if line[0] == "#" or line[0] == "\n":
|
2020-06-06 03:00:36 +04:00
|
|
|
|
continue
|
2020-06-05 03:51:29 +04:00
|
|
|
|
key, value = line[:-1].split(" = ")
|
2020-06-06 03:00:36 +04:00
|
|
|
|
if key.find(".") != -1:
|
|
|
|
|
k0, k1 = key.split(".")
|
2020-06-07 20:41:17 +04:00
|
|
|
|
if not k0 in self._configuration:
|
|
|
|
|
self._configuration[k0] = dict()
|
|
|
|
|
self._configuration[k0][k1] = value
|
2020-06-06 03:00:36 +04:00
|
|
|
|
else:
|
|
|
|
|
self._configuration[key] = value
|
2020-06-04 03:12:31 +04:00
|
|
|
|
|
|
|
|
|
def save(self) -> None:
|
|
|
|
|
with open(self._configuration_file, 'w') as cf:
|
|
|
|
|
for key, value in self._configuration.items():
|
2020-06-07 20:41:17 +04:00
|
|
|
|
if type(value) is dict:
|
|
|
|
|
for subkey, subvalue in value.items():
|
|
|
|
|
cf.write(f"{key}.{subkey} = {subvalue}\n")
|
|
|
|
|
else:
|
|
|
|
|
cf.write(f"{key} = {value}\n")
|
2020-06-04 03:12:31 +04:00
|
|
|
|
|
2020-06-07 04:47:15 +04:00
|
|
|
|
@property
|
|
|
|
|
def items(self) -> dict:
|
|
|
|
|
return self._configuration
|
|
|
|
|
|
2020-06-04 03:12:31 +04:00
|
|
|
|
def __getitem__(self, key: str) -> Union[int, str, bool]:
|
|
|
|
|
return self._configuration[key]
|
|
|
|
|
|
|
|
|
|
def __setitem__(self, key: str, value: Union[int, str, bool]) -> None:
|
|
|
|
|
self._configuration[key] = value
|