Merge branch 'master' into master
This commit is contained in:
commit
6cd35747d2
|
@ -12,7 +12,7 @@
|
||||||
"editor.formatOnPaste": true,
|
"editor.formatOnPaste": true,
|
||||||
"python.formatting.provider": "black",
|
"python.formatting.provider": "black",
|
||||||
"editor.codeActionsOnSave": {
|
"editor.codeActionsOnSave": {
|
||||||
"source.organizeImports": true
|
"source.organizeImports": "explicit"
|
||||||
},
|
},
|
||||||
"python.testing.unittestEnabled": false,
|
"python.testing.unittestEnabled": false,
|
||||||
"python.testing.pytestEnabled": true,
|
"python.testing.pytestEnabled": true,
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 375135d552e3fe65cbd1462b8b8d56c401b13ae7
|
Subproject commit e3bf6056ee75cf70ffaccb925081fffa7ad6ced5
|
|
@ -91,6 +91,7 @@ docstrings
|
||||||
ean
|
ean
|
||||||
Ean
|
Ean
|
||||||
encodable
|
encodable
|
||||||
|
Errno
|
||||||
fff
|
fff
|
||||||
fullimage
|
fullimage
|
||||||
io
|
io
|
||||||
|
@ -124,6 +125,7 @@ Todo
|
||||||
traceback
|
traceback
|
||||||
udev
|
udev
|
||||||
usb
|
usb
|
||||||
|
USBTimeoutError
|
||||||
usec
|
usec
|
||||||
virtualenvs
|
virtualenvs
|
||||||
whitespaces
|
whitespaces
|
||||||
|
|
|
@ -213,6 +213,14 @@ If something is wrong, an ``CharCodeError`` will be raised.
|
||||||
After you have manually set the codepage the printer won't change it anymore.
|
After you have manually set the codepage the printer won't change it anymore.
|
||||||
You can revert to normal behavior by setting charcode to ``AUTO``.
|
You can revert to normal behavior by setting charcode to ``AUTO``.
|
||||||
|
|
||||||
|
Resolving bus timeout issues during printing images
|
||||||
|
---------------------------------------------------
|
||||||
|
|
||||||
|
If an error message such as "USBTimeoutError: [Errno 110] Operation timed out" occurs,
|
||||||
|
setting a sleep time between printing fragments can help.
|
||||||
|
|
||||||
|
This can be done with the :meth:`.set_sleep_in_fragment()` method.
|
||||||
|
|
||||||
Advanced Usage: Print from binary blob
|
Advanced Usage: Print from binary blob
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ This module contains the abstract base class :py:class:`Escpos`.
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import textwrap
|
import textwrap
|
||||||
|
import time
|
||||||
import warnings
|
import warnings
|
||||||
from abc import ABCMeta, abstractmethod # abstract base class support
|
from abc import ABCMeta, abstractmethod # abstract base class support
|
||||||
from re import match as re_match
|
from re import match as re_match
|
||||||
|
@ -123,6 +124,9 @@ class Escpos(object, metaclass=ABCMeta):
|
||||||
# object -> The connection object (Usb(), Serial(), Network(), etc.)
|
# object -> The connection object (Usb(), Serial(), Network(), etc.)
|
||||||
_device: Union[Literal[False], Literal[None], object] = False
|
_device: Union[Literal[False], Literal[None], object] = False
|
||||||
|
|
||||||
|
# sleep time in fragments:
|
||||||
|
_sleep_in_fragment_ms: int = 0
|
||||||
|
|
||||||
def __init__(self, profile=None, magic_encode_args=None, **kwargs) -> None:
|
def __init__(self, profile=None, magic_encode_args=None, **kwargs) -> None:
|
||||||
"""Initialize ESCPOS Printer.
|
"""Initialize ESCPOS Printer.
|
||||||
|
|
||||||
|
@ -178,6 +182,21 @@ class Escpos(object, metaclass=ABCMeta):
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def set_sleep_in_fragment(self, sleep_time_ms: int) -> None:
|
||||||
|
"""Configures the currently active sleep time after sending a fragment.
|
||||||
|
|
||||||
|
If during printing an image an issue like "USBTimeoutError: [Errno 110]
|
||||||
|
Operation timed out" occurs, setting this value to roughly 300
|
||||||
|
milliseconds can help resolve the issue.
|
||||||
|
|
||||||
|
:param sleep_time_ms: sleep time in milliseconds
|
||||||
|
"""
|
||||||
|
self._sleep_in_fragment_ms = sleep_time_ms
|
||||||
|
|
||||||
|
def _sleep_in_fragment(self) -> None:
|
||||||
|
"""Sleeps the preconfigured time after sending a fragment."""
|
||||||
|
time.sleep(self._sleep_in_fragment_ms / 1000)
|
||||||
|
|
||||||
def image(
|
def image(
|
||||||
self,
|
self,
|
||||||
img_source,
|
img_source,
|
||||||
|
@ -246,6 +265,7 @@ class Escpos(object, metaclass=ABCMeta):
|
||||||
impl=impl,
|
impl=impl,
|
||||||
fragment_height=fragment_height,
|
fragment_height=fragment_height,
|
||||||
)
|
)
|
||||||
|
self._sleep_in_fragment()
|
||||||
return
|
return
|
||||||
|
|
||||||
if impl == "bitImageRaster":
|
if impl == "bitImageRaster":
|
||||||
|
|
|
@ -4,7 +4,10 @@
|
||||||
I doubt that this currently works correctly.
|
I doubt that this currently works correctly.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import types
|
||||||
|
import typing
|
||||||
|
|
||||||
|
jaconv: typing.Optional[types.ModuleType]
|
||||||
try:
|
try:
|
||||||
import jaconv
|
import jaconv
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""tests for software_columns
|
||||||
|
|
||||||
|
:author: Benito López and the python-escpos developers
|
||||||
|
:organization: `python-escpos <https://github.com/python-escpos>`_
|
||||||
|
:copyright: Copyright (c) 2024 `python-escpos <https://github.com/python-escpos>`_
|
||||||
|
:license: MIT
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
def test_rearrange_into_cols(driver) -> None:
|
||||||
|
"""
|
||||||
|
GIVEN a list of columnable text
|
||||||
|
WHEN the column width is different for each column and some strings exceed the max width
|
||||||
|
THEN check the strings are properly wrapped, truncated and rearranged into some columns
|
||||||
|
"""
|
||||||
|
|
||||||
|
output = driver._rearrange_into_cols(
|
||||||
|
text_list=["fits", "row1 row2", "truncate and wrap"], widths=[4, 5, 6]
|
||||||
|
)
|
||||||
|
assert output == [["fits", "row1", "trunc."], ["", "row2", "and"], ["", "", "wrap"]]
|
||||||
|
|
||||||
|
|
||||||
|
def test_add_padding_into_cols(driver) -> None:
|
||||||
|
"""
|
||||||
|
GIVEN a list of strings
|
||||||
|
WHEN adding padding and different alignments to each string
|
||||||
|
THEN check the strings are correctly padded and aligned
|
||||||
|
"""
|
||||||
|
|
||||||
|
output = driver._add_padding_into_cols(
|
||||||
|
text_list=["col1", "col2", "col3"],
|
||||||
|
widths=[6, 6, 6],
|
||||||
|
align=["center", "left", "right"],
|
||||||
|
)
|
||||||
|
assert output == [" col1 ", "col2 ", " col3"]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("text_list", ["", [], None])
|
||||||
|
@pytest.mark.parametrize("widths", [30.5, "30", None])
|
||||||
|
@pytest.mark.parametrize("align", ["invalid_align_name", "", None])
|
||||||
|
def test_software_columns_invalid_args(driver, text_list, widths, align) -> None:
|
||||||
|
"""
|
||||||
|
GIVEN a dummy printer object
|
||||||
|
WHEN non valid params are passed
|
||||||
|
THEN check raise exception
|
||||||
|
"""
|
||||||
|
bad_text_list = {"text_list": text_list, "widths": 5, "align": "left"}
|
||||||
|
bad_widths = {"text_list": ["valid"], "widths": widths, "align": "left"}
|
||||||
|
bad_align = {"text_list": ["valid"], "widths": 5, "align": align}
|
||||||
|
|
||||||
|
bad_args = [bad_text_list, bad_widths, bad_align]
|
||||||
|
for kwargs in bad_args:
|
||||||
|
with pytest.raises(Exception):
|
||||||
|
driver.software_columns(**kwargs)
|
||||||
|
driver.close()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"text_list",
|
||||||
|
[
|
||||||
|
["col1", "col2", "col3"],
|
||||||
|
["wrap this string", "wrap this string", "wrap this string"],
|
||||||
|
["truncate_this_string", "truncate_this_string", "truncate_this_string"],
|
||||||
|
],
|
||||||
|
)
|
||||||
|
@pytest.mark.parametrize("widths", [[10, 10, 10], [10], 30])
|
||||||
|
@pytest.mark.parametrize("align", [["center", "left", "right"], ["center"], "center"])
|
||||||
|
def test_software_columns_valid_args(driver, text_list, widths, align) -> None:
|
||||||
|
"""
|
||||||
|
GIVEN a dummy printer object
|
||||||
|
WHEN valid params are passed
|
||||||
|
THEN check no errors
|
||||||
|
"""
|
||||||
|
driver.software_columns(text_list=text_list, widths=widths, align=align)
|
||||||
|
driver.close()
|
|
@ -7,7 +7,8 @@
|
||||||
:copyright: Copyright (c) 2016 `python-escpos <https://github.com/python-escpos>`_
|
:copyright: Copyright (c) 2016 `python-escpos <https://github.com/python-escpos>`_
|
||||||
:license: MIT
|
:license: MIT
|
||||||
"""
|
"""
|
||||||
|
import types
|
||||||
|
import typing
|
||||||
|
|
||||||
import hypothesis.strategies as st
|
import hypothesis.strategies as st
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -111,6 +112,7 @@ class TestMagicEncode:
|
||||||
assert driver.output == b"\x1bt\x00? ist teuro."
|
assert driver.output == b"\x1bt\x00? ist teuro."
|
||||||
|
|
||||||
|
|
||||||
|
jaconv: typing.Optional[types.ModuleType]
|
||||||
try:
|
try:
|
||||||
import jaconv
|
import jaconv
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
|
Loading…
Reference in New Issue