Merge branch 'master' into master

This commit is contained in:
Patrick Kanzler 2024-08-25 00:51:50 +02:00 committed by GitHub
commit 6cd35747d2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 118 additions and 3 deletions

View File

@ -12,7 +12,7 @@
"editor.formatOnPaste": true,
"python.formatting.provider": "black",
"editor.codeActionsOnSave": {
"source.organizeImports": true
"source.organizeImports": "explicit"
},
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true,

@ -1 +1 @@
Subproject commit 375135d552e3fe65cbd1462b8b8d56c401b13ae7
Subproject commit e3bf6056ee75cf70ffaccb925081fffa7ad6ced5

View File

@ -91,6 +91,7 @@ docstrings
ean
Ean
encodable
Errno
fff
fullimage
io
@ -124,6 +125,7 @@ Todo
traceback
udev
usb
USBTimeoutError
usec
virtualenvs
whitespaces

View File

@ -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.
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
--------------------------------------

View File

@ -12,6 +12,7 @@ This module contains the abstract base class :py:class:`Escpos`.
from __future__ import annotations
import textwrap
import time
import warnings
from abc import ABCMeta, abstractmethod # abstract base class support
from re import match as re_match
@ -123,6 +124,9 @@ class Escpos(object, metaclass=ABCMeta):
# object -> The connection object (Usb(), Serial(), Network(), etc.)
_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:
"""Initialize ESCPOS Printer.
@ -178,6 +182,21 @@ class Escpos(object, metaclass=ABCMeta):
"""
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(
self,
img_source,
@ -246,6 +265,7 @@ class Escpos(object, metaclass=ABCMeta):
impl=impl,
fragment_height=fragment_height,
)
self._sleep_in_fragment()
return
if impl == "bitImageRaster":

View File

@ -4,7 +4,10 @@
I doubt that this currently works correctly.
"""
import types
import typing
jaconv: typing.Optional[types.ModuleType]
try:
import jaconv
except ImportError:

View File

@ -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()

View File

@ -7,7 +7,8 @@
:copyright: Copyright (c) 2016 `python-escpos <https://github.com/python-escpos>`_
:license: MIT
"""
import types
import typing
import hypothesis.strategies as st
import pytest
@ -111,6 +112,7 @@ class TestMagicEncode:
assert driver.output == b"\x1bt\x00? ist teuro."
jaconv: typing.Optional[types.ModuleType]
try:
import jaconv
except ImportError: