104 lines
3.2 KiB
Python
104 lines
3.2 KiB
Python
import argparse
|
|
import configparser
|
|
import datetime
|
|
import os.path
|
|
import pathlib
|
|
|
|
from . import loaders
|
|
|
|
HOME_PATH = pathlib.Path(os.path.expanduser('~'))
|
|
CONFFILE_SEED = """
|
|
[Historical]
|
|
base=USD
|
|
"""
|
|
|
|
def currency_code(s):
|
|
if not (len(s) == 3) and s.isalpha():
|
|
raise ValueError("bad currency code: {!r}".format(s))
|
|
return s.upper()
|
|
|
|
def date_from(fmt_s):
|
|
def date_from_fmt(s):
|
|
return datetime.datetime.strptime(s, fmt_s).date
|
|
return date_from_fmt
|
|
|
|
class Configuration:
|
|
DEFAULT_CONFIG_PATH = pathlib.Path(HOME_PATH, '.config', 'oxrlib.ini')
|
|
|
|
def __init__(self, arglist):
|
|
argparser = self._build_argparser()
|
|
self.error = argparser.error
|
|
self.args = argparser.parse_args(arglist)
|
|
|
|
if self.args.config_file is None:
|
|
self.args.config_file = [self.DEFAULT_CONFIG_PATH]
|
|
self.conffile = self._build_conffile()
|
|
conffile_paths = [path.as_posix() for path in self.args.config_file]
|
|
read_files = self.conffile.read(conffile_paths)
|
|
for expected_path, read_path in zip(conffile_paths, read_files):
|
|
if read_path != expected_path:
|
|
self.error("failed to read configuration file {!r}".format(expected_path))
|
|
|
|
try:
|
|
post_hook = getattr(self, '_post_hook_' + self.args.command)
|
|
except AttributeError:
|
|
pass
|
|
else:
|
|
post_hook()
|
|
|
|
def _build_argparser(self):
|
|
prog_parser = argparse.ArgumentParser()
|
|
prog_parser.add_argument(
|
|
'--config-file', '-c',
|
|
action='append', type=pathlib.Path,
|
|
help="Path of a configuration file to read",
|
|
)
|
|
subparsers = prog_parser.add_subparsers()
|
|
|
|
hist_parser = subparsers.add_parser('historical', aliases=['hist'])
|
|
hist_parser.set_defaults(command='historical')
|
|
hist_parser.add_argument(
|
|
'--base',
|
|
help="Base currency (default USD)",
|
|
)
|
|
hist_parser.add_argument(
|
|
'date',
|
|
type=date_from('%Y-%m-%d'), metavar='YYYY-MM-DD',
|
|
)
|
|
|
|
return prog_parser
|
|
|
|
def _build_conffile(self):
|
|
conffile = configparser.ConfigParser()
|
|
conffile.read_string(CONFFILE_SEED)
|
|
return conffile
|
|
|
|
def _post_hook_historical(self):
|
|
if self.args.base is None:
|
|
self.args.base = self.conffile.get('Historical', 'base')
|
|
|
|
def _build_cache_loader(self):
|
|
kwargs = dict(self.conffile.items('Cache'))
|
|
try:
|
|
kwargs['dir_path'] = kwargs.pop('directory')
|
|
except KeyError:
|
|
pass
|
|
return loaders.FileCache(**kwargs)
|
|
|
|
def _build_oxrapi_loader(self):
|
|
kwargs = dict(self.conffile.items('OXR'))
|
|
return loaders.OXRAPIRequest(**kwargs)
|
|
|
|
def get_loaders(self):
|
|
loader_chain = loaders.LoaderChain()
|
|
for build_func in [
|
|
self._build_cache_loader,
|
|
self._build_oxrapi_loader,
|
|
]:
|
|
try:
|
|
loader = build_func()
|
|
except (TypeError, ValueError, configparser.NoSectionError):
|
|
pass
|
|
else:
|
|
loader_chain.add_loader(loader)
|
|
return loader_chain
|