2016-03-15 21:09:45 +00:00
|
|
|
""" ESC/POS configuration manager.
|
|
|
|
|
|
|
|
This module contains the implentations of abstract base class :py:class:`Config`.
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
2016-03-15 19:00:46 +00:00
|
|
|
from __future__ import absolute_import
|
|
|
|
|
|
|
|
import os
|
|
|
|
import appdirs
|
2016-03-15 20:47:23 +00:00
|
|
|
import yaml
|
2016-03-15 19:00:46 +00:00
|
|
|
|
|
|
|
from . import printer
|
2016-03-15 19:14:12 +00:00
|
|
|
from . import exceptions
|
2016-03-15 19:00:46 +00:00
|
|
|
|
|
|
|
class Config(object):
|
2016-03-15 21:09:45 +00:00
|
|
|
""" Configuration handler class.
|
2016-03-15 19:00:46 +00:00
|
|
|
|
2016-03-15 21:09:45 +00:00
|
|
|
This class loads configuration from a default or specificed directory. It
|
|
|
|
can create your defined printer and return it to you.
|
|
|
|
"""
|
2016-03-15 19:00:46 +00:00
|
|
|
_app_name = 'python-escpos'
|
2016-03-15 20:47:23 +00:00
|
|
|
_config_file = 'config.yaml'
|
2016-03-15 19:00:46 +00:00
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
self._has_loaded = False
|
|
|
|
self._printer = None
|
|
|
|
|
|
|
|
self._printer_name = None
|
|
|
|
self._printer_config = None
|
|
|
|
|
|
|
|
def load(self, config_path=None):
|
2016-03-15 21:09:45 +00:00
|
|
|
""" Load and parse the configuration file using pyyaml
|
|
|
|
|
|
|
|
:param config_path: An optional file path, file handle, or byte string
|
|
|
|
for the configuration file.
|
|
|
|
|
|
|
|
"""
|
2016-03-15 19:00:46 +00:00
|
|
|
if not config_path:
|
|
|
|
config_path = os.path.join(
|
|
|
|
appdirs.user_config_dir(self._app_name),
|
|
|
|
self._config_file
|
|
|
|
)
|
|
|
|
|
2016-03-15 20:47:23 +00:00
|
|
|
try:
|
2016-03-15 22:05:25 +00:00
|
|
|
if isinstance(config_path, file):
|
|
|
|
config = yaml.safe_load(config_path)
|
|
|
|
else:
|
|
|
|
with open(config_path, 'rb') as f:
|
|
|
|
config = yaml.safe_load(f)
|
2016-03-16 20:47:51 +00:00
|
|
|
except EnvironmentError:
|
2016-03-16 20:29:22 +00:00
|
|
|
raise exceptions.ConfigNotFoundError('Couldn\'t read config at {config_path}'.format(
|
|
|
|
config_path=str(config_path),
|
2016-03-15 19:00:46 +00:00
|
|
|
))
|
2016-03-15 22:05:25 +00:00
|
|
|
except yaml.YAMLError as e:
|
2016-03-15 20:47:23 +00:00
|
|
|
raise exceptions.ConfigSyntaxError('Error parsing YAML')
|
2016-03-15 19:00:46 +00:00
|
|
|
|
|
|
|
if 'printer' in config:
|
2016-03-15 20:47:23 +00:00
|
|
|
self._printer_config = config['printer']
|
2016-03-15 19:00:46 +00:00
|
|
|
self._printer_name = self._printer_config.pop('type').title()
|
|
|
|
|
|
|
|
if not self._printer_name or not hasattr(printer, self._printer_name):
|
2016-03-15 19:14:12 +00:00
|
|
|
raise exceptions.ConfigSyntaxError('Printer type "{printer_name}" is invalid'.format(
|
2016-03-15 19:00:46 +00:00
|
|
|
printer_name=self._printer_name,
|
|
|
|
))
|
|
|
|
|
|
|
|
self._has_loaded = True
|
|
|
|
|
|
|
|
def printer(self):
|
2016-03-15 21:09:45 +00:00
|
|
|
""" Returns a printer that was defined in the config, or None.
|
|
|
|
|
|
|
|
This method loads the default config if one hasn't beeen already loaded.
|
|
|
|
|
|
|
|
"""
|
2016-03-15 19:00:46 +00:00
|
|
|
if not self._has_loaded:
|
|
|
|
self.load()
|
|
|
|
|
|
|
|
if not self._printer:
|
|
|
|
# We could catch init errors and make them a ConfigSyntaxError,
|
|
|
|
# but I'll just let them pass
|
|
|
|
self._printer = getattr(printer, self._printer_name)(**self._printer_config)
|
|
|
|
|
|
|
|
return self._printer
|
|
|
|
|