1
0
PiggyBank/piggybank/configuration.py

92 lines
3.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""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": "..." } }
"""
from os import getenv
from os.path import exists, join
from platform import system
from typing import Union
__all__ = ["Configuration", "get_configuration_path"]
def get_configuration_path() -> str:
"""Returns a path to where configuration is stored."""
if system() == "Linux":
return getenv("XDG_CONFIG_HOME") or f"{getenv('HOME')}/.config"
elif system() == "Windows":
return getenv("APPDATA")
DEFAULT_CONFIGURATION = {
"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" } }
DEFAULT_CONFIGURATION_FILE = join(get_configuration_path(), "piggybank.conf")
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'):
if line[0] == "#" or line[0] == "\n":
continue
key, value = line[:-1].split(" = ")
if key.find(".") != -1:
k0, k1 = key.split(".")
if not k0 in self._configuration:
self._configuration[k0] = dict()
self._configuration[k0][k1] = value
else:
self._configuration[key] = value
def save(self) -> None:
with open(self._configuration_file, 'w') as cf:
for key, value in self._configuration.items():
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")
@property
def items(self) -> dict:
return self._configuration
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