mdrs-client-python/mdrsclient/config.py

84 lines
2.7 KiB
Python
Raw Permalink Normal View History

2023-05-01 20:00:32 +09:00
import configparser
import os
from typing import Final
import validators # type: ignore
2023-05-01 20:00:32 +09:00
from mdrsclient.exceptions import IllegalArgumentException
2023-05-10 14:46:08 +09:00
from mdrsclient.settings import CONFIG_DIRNAME
2023-05-23 11:48:09 +09:00
from mdrsclient.utils import FileLock
2023-05-01 20:00:32 +09:00
class ConfigFile:
OPTION_URL: Final[str] = "url"
2023-05-10 14:46:08 +09:00
CONFIG_FILENAME: Final[str] = "config.ini"
2023-05-01 20:00:32 +09:00
remote: str
2023-05-10 14:46:08 +09:00
__serial: int
__config_dirname: str
__config_path: str
__config: configparser.ConfigParser
2023-05-01 20:00:32 +09:00
def __init__(self, remote: str) -> None:
self.remote = remote
2023-05-10 14:46:08 +09:00
self.__serial = -1
self.__config_dirname = CONFIG_DIRNAME
self.__config_path = os.path.join(CONFIG_DIRNAME, self.CONFIG_FILENAME)
self.__config = configparser.ConfigParser()
2023-05-01 20:00:32 +09:00
def list(self) -> list[tuple[str, str]]:
ret: list[tuple[str, str]] = []
self.__load()
2023-05-10 14:46:08 +09:00
for remote in self.__config.sections():
url = self.__config.get(remote, self.OPTION_URL)
2023-05-01 20:00:32 +09:00
ret.append((remote, url))
return ret
@property
def url(self) -> str | None:
if not self.__exists(self.remote):
return None
2023-05-10 14:46:08 +09:00
return self.__config.get(self.remote, self.OPTION_URL)
2023-05-01 20:00:32 +09:00
@url.setter
def url(self, url: str) -> None:
if not validators.url(url): # type: ignore
raise IllegalArgumentException("malformed URI sequence")
self.__load()
2023-05-10 14:46:08 +09:00
if self.__config.has_section(self.remote):
self.__config.remove_section(self.remote)
self.__config.add_section(self.remote)
self.__config.set(self.remote, self.OPTION_URL, url)
2023-05-01 20:00:32 +09:00
self.__save()
@url.deleter
def url(self) -> None:
if self.__exists(self.remote):
2023-05-10 14:46:08 +09:00
self.__config.remove_section(self.remote)
2023-05-01 20:00:32 +09:00
self.__save()
def __exists(self, section: str) -> bool:
self.__load()
2023-05-10 14:46:08 +09:00
return self.__config.has_option(section, self.OPTION_URL)
2023-05-01 20:00:32 +09:00
def __load(self) -> None:
2023-05-10 14:46:08 +09:00
if os.path.isfile(self.__config_path):
stat = os.stat(self.__config_path)
2023-05-01 20:00:32 +09:00
serial = hash(stat)
2023-05-10 14:46:08 +09:00
if self.__serial != serial:
self.__config.read(self.__config_path, encoding="utf8")
self.__serial = serial
2023-05-01 20:00:32 +09:00
def __save(self) -> None:
self.__ensure_cache_dir()
2023-05-10 14:46:08 +09:00
with open(self.__config_path, "w") as f:
2023-05-23 11:48:09 +09:00
FileLock.lock(f)
2023-05-10 14:46:08 +09:00
self.__config.write(f)
2023-05-23 11:48:09 +09:00
FileLock.unlock(f)
2023-05-10 14:46:08 +09:00
os.chmod(self.__config_path, 0o600)
2023-05-01 20:00:32 +09:00
def __ensure_cache_dir(self) -> None:
2023-05-10 14:46:08 +09:00
if not os.path.exists(self.__config_dirname):
os.makedirs(self.__config_dirname)
2023-05-01 20:00:32 +09:00
# ensure directory is secure.
2023-05-10 14:46:08 +09:00
os.chmod(self.__config_dirname, 0o700)