1
0
mirror of https://github.com/python-escpos/python-escpos synced 2025-09-13 09:09:58 +00:00

Match the current printer-db format.

This commit is contained in:
Michael Elsdörfer
2016-08-30 12:26:09 +02:00
parent 216184f43f
commit a07f84a5bc
6 changed files with 67 additions and 297 deletions

View File

@@ -1,40 +1,53 @@
import re
import six
from os import path
import yaml
with open(path.join(path.dirname(__file__), 'capabilities.yml')) as f:
PROFILES = yaml.load(f)
# Load external printer database
with open(path.join(path.dirname(__file__), 'capabilities.json')) as f:
CAPABILITIES = yaml.load(f)
PROFILES = CAPABILITIES['profiles']
ENCODINGS = CAPABILITIES['encodings']
class Profile(object):
class NotSupported(Exception):
pass
class BaseProfile(object):
"""This respresents a printer profile.
A printer profile knows about the number of columns, supported
features, colors and more.
"""
profile_data = {}
def __init__(self, columns=None):
self.default_columns = columns
def __getattr__(self, name):
return self.profile_data[name]
def get_font(self, font):
"""Return the escpos index for `font`. Makes sure that
the requested `font` is valid.
"""
font = {'a': 0, 'b': 1}.get(font, font)
if not six.text_type(font) in self.fonts:
raise NotSupported(
'"%s" is not a valid font in the current profile' % font)
return font
def get_columns(self, font):
""" Return the number of columns for the given font.
"""
if self.default_columns:
return self.default_columns
if 'columnConfigs' in self.profile_data:
columns_def = self.columnConfigs[self.defaultColumnConfig]
elif 'columns' in self.profile_data:
columns_def = self.columns
if isinstance(columns_def, int):
return columns_def
return columns_def[font]
font = self.get_font(font)
return self.fonts[six.text_type(font)]['columns']
def get_profile(name=None, **kwargs):
"""Get the profile by name; if no name is given, return the
default profile.
"""
if isinstance(name, Profile):
return name
@@ -42,15 +55,19 @@ def get_profile(name=None, **kwargs):
return clazz(**kwargs)
CLASS_CACHE = {}
def get_profile_class(name):
"""For the given profile name, load the data from the external
database, then generate dynamically a class.
"""
if not name in CLASS_CACHE:
profile_data = resolve_profile_data(name)
class_name = '%sProfile' % clean(name)
new_class = type(class_name, (Profile,), {'profile_data': profile_data})
profile_data = PROFILES[name]
profile_name = clean(name)
class_name = '{}{}Profile'.format(
profile_name[0].upper(), profile_name[1:])
new_class = type(class_name, (BaseProfile,), {'profile_data': profile_data})
CLASS_CACHE[name] = new_class
return CLASS_CACHE[name]
@@ -64,20 +81,20 @@ def clean(s):
return str(s)
def resolve_profile_data(name):
data = PROFILES[name]
inherits = data.get('inherits')
if not inherits:
return data
# For users, who want to provide their profile
class Profile(get_profile_class('default')):
def __init__(self, columns=None):
super(Profile, self).__init()
self.columns = columns
def get_columns(self, font):
if self.columns is not None:
return columns
return super(Profile, self).get_columns(font)
if not isinstance(inherits, (tuple, list)):
inherits = [inherits]
merged = {}
for base in reversed(inherits):
base_data = resolve_profile_data(base)
merged.update(base_data)
merged.update(data)
return merged