Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pre commit #49

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.4.10
hooks:
- id: ruff
args: [ --fix ]
- id: ruff-format
19 changes: 9 additions & 10 deletions LEGACY.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ giving:
[--dither] [--compress] [--red] [--600dpi] [--no-cut]
[--loglevel LOGLEVEL]
image [outfile]

positional arguments:
image The image file to create a label from.
outfile The file to write the instructions to. Defaults to
stdout.

optional arguments:
-h, --help show this help message and exit
--model MODEL, -m MODEL
Expand Down Expand Up @@ -119,17 +119,17 @@ You can use the supplied tool `brother_ql_debug` to send your problematic instru
After every instruction, the printer will be given a chance to send a status response containing error information. Here is an example:

philipp@lion ~> brother_ql_debug ./720x151_monochrome.bin /dev/usb/lp0
INFO: CMD preamble FOUND. Instruction: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [...] 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
INFO: CMD init FOUND. Instruction: 1B 40
INFO: CMD status request FOUND. Instruction: 1B 69 53
INFO: CMD preamble FOUND. Instruction: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [...] 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
INFO: CMD init FOUND. Instruction: 1B 40
INFO: CMD status request FOUND. Instruction: 1B 69 53
INFO: Response from the device: 80 20 42 30 4F 30 00 00 00 00 3E 0A 00 00 15 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
INFO: Interpretation of the response: 'Reply to status request' (phase: Waiting to receive), 'Continuous length tape' 62x0 mm^2, errors: []
INFO: CMD media/quality FOUND. Instruction: 1B 69 7A CE 0A 3E 00 97 00 00 00 01 00
INFO: CMD margins FOUND. Instruction: 1B 69 64 23 00
INFO: CMD raster FOUND. Instruction: 67 00 5A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 FF FF FF 1F FF FF FF FF FF F0 00 00 00 00 00 0F FF FF 03 FF FF FF FF E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [...] 00 07 FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
INFO: CMD media/quality FOUND. Instruction: 1B 69 7A CE 0A 3E 00 97 00 00 00 01 00
INFO: CMD margins FOUND. Instruction: 1B 69 64 23 00
INFO: CMD raster FOUND. Instruction: 67 00 5A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 FF FF FF 1F FF FF FF FF FF F0 00 00 00 00 00 0F FF FF 03 FF FF FF FF E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [...] 00 07 FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
INFO: Response from the device: 80 20 42 30 4F 30 00 00 00 00 3E 0A 00 00 15 00 00 00 06 01 00 00 00 00 00 00 00 00 00 00 00 00
INFO: Interpretation of the response: 'Phase change' (phase: Printing state), 'Continuous length tape' 62x0 mm^2, errors: []
INFO: CMD print FOUND. Instruction: 1A
INFO: CMD print FOUND. Instruction: 1A
TIME 1.60
INFO: Interpretation of the response: 'Printing completed' (phase: Printing state), 'Continuous length tape' 62x0 mm^2, errors: []
TIME 1.60
Expand All @@ -139,4 +139,3 @@ Here, a command file was successfully printed. The last response should state th
If you want to confirm the sending of every single command individually, you can add the `--interactive` argument to the command line call.

If you're seeing any error there, open a new issue on Github containing the debugging output to get your device supported.

1 change: 0 additions & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -672,4 +672,3 @@ may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

12 changes: 6 additions & 6 deletions OLD_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ On those systems, extending the path variable via `export PATH="${PATH}:~/.local
The main user interface of this package is the command line tool `brother_ql`.

Usage: brother_ql [OPTIONS] COMMAND [ARGS]...

Command line interface for the brother_ql Python package.

Options:
-b, --backend [pyusb|network|linux_kernel]
-m, --model [QL-500|QL-550|QL-560|QL-570|QL-580N|QL-650TD|QL-700|QL-710W|QL-720NW|QL-800|QL-810W|QL-820NWB|QL-1050|QL-1060N]
Expand All @@ -79,7 +79,7 @@ The main user interface of this package is the command line tool `brother_ql`.
--debug
--version Show the version and exit.
--help Show this message and exit.

Commands:
analyze interpret a binary file containing raster...
discover find connected label printers
Expand All @@ -94,9 +94,9 @@ The global options are followed by a command such as `info` or `print`.
The most important command is the `print` command and here is its CLI signature:

Usage: brother_ql print [OPTIONS] IMAGE [IMAGE] ...

Print a label of the provided IMAGE.

Options:
-l, --label [12|29|38|50|54|62|102|17x54|17x87|23x23|29x42|29x90|39x90|39x48|52x29|62x29|62x100|102x51|102x152|d12|d24|d58]
The label (size, type - die-cut or endless).
Expand Down Expand Up @@ -203,7 +203,7 @@ removed in a future release.
This software package was written by Philipp Klaus based on Brother's documentation
of its raster language and based on additinal reverse engineering efforts.

* Philipp Klaus
* Philipp Klaus
<[email protected]>

Many more have contributed by raising issues, helping to solve them,
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,3 @@ v1.0:
- Added label support for DK-1234 https://github.com/matmair/brother_ql-inventree/pull/22 , 54x29 https://github.com/matmair/brother_ql-inventree/pull/19 , DK22246 https://github.com/matmair/brother_ql-inventree/pull/20, ...

Read the full old Readme [here](https://github.com/matmair/brother_ql-inventree/blob/cleanup/OLD_README.md).

2 changes: 0 additions & 2 deletions brother_ql/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@

from .exceptions import *

from .raster import BrotherQLRaster

from .brother_ql_create import create_label

55 changes: 32 additions & 23 deletions brother_ql/backends/__init__.py
Original file line number Diff line number Diff line change
@@ -1,40 +1,49 @@

from .generic import BrotherQLBackendGeneric


available_backends = [
'pyusb',
'network',
'linux_kernel',
"pyusb",
"network",
"linux_kernel",
]


def guess_backend(identifier):
""" guess the backend from a given identifier string for the device """
if identifier.startswith('usb://') or identifier.startswith('0x'):
return 'pyusb'
elif identifier.startswith('file://') or identifier.startswith('/dev/usb/') or identifier.startswith('lp'):
return 'linux_kernel'
elif identifier.startswith('tcp://'):
return 'network'
"""guess the backend from a given identifier string for the device"""
if identifier.startswith("usb://") or identifier.startswith("0x"):
return "pyusb"
elif (
identifier.startswith("file://")
or identifier.startswith("/dev/usb/")
or identifier.startswith("lp")
):
return "linux_kernel"
elif identifier.startswith("tcp://"):
return "network"
else:
raise ValueError('Cannot guess backend for given identifier: %s' % identifier)
raise ValueError("Cannot guess backend for given identifier: %s" % identifier)


def backend_factory(backend_name):
if backend_name == "pyusb":
from . import pyusb as pyusb_backend

if backend_name == 'pyusb':
from . import pyusb as pyusb_backend
list_available_devices = pyusb_backend.list_available_devices
backend_class = pyusb_backend.BrotherQLBackendPyUSB
elif backend_name == 'linux_kernel':
backend_class = pyusb_backend.BrotherQLBackendPyUSB
elif backend_name == "linux_kernel":
from . import linux_kernel as linux_kernel_backend

list_available_devices = linux_kernel_backend.list_available_devices
backend_class = linux_kernel_backend.BrotherQLBackendLinuxKernel
elif backend_name == 'network':
from . import network as network_backend
backend_class = linux_kernel_backend.BrotherQLBackendLinuxKernel
elif backend_name == "network":
from . import network as network_backend

list_available_devices = network_backend.list_available_devices
backend_class = network_backend.BrotherQLBackendNetwork
backend_class = network_backend.BrotherQLBackendNetwork
else:
raise NotImplementedError('Backend %s not implemented.' % backend_name)
raise NotImplementedError("Backend %s not implemented." % backend_name)

return {'list_available_devices': list_available_devices, 'backend_class': backend_class}
return {
"list_available_devices": list_available_devices,
"backend_class": backend_class,
}
14 changes: 7 additions & 7 deletions brother_ql/backends/generic.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@

from builtins import bytes

import logging

logger = logging.getLogger(__name__)


def list_available_devices():
""" List all available devices for the respective backend """
"""List all available devices for the respective backend"""
# returns a list of dictionaries with the keys 'identifier' and 'instance':
# [ {'identifier': '/dev/usb/lp0', 'instance': os.open('/dev/usb/lp0', os.O_RDWR)}, ]
raise NotImplementedError()


class BrotherQLBackendGeneric(object):

def __init__(self, device_specifier):
"""
device_specifier can be either a string or an instance
of the required class type.
"""
self.write_dev = None
self.read_dev = None
self.read_dev = None
raise NotImplementedError()

def _write(self, data):
Expand All @@ -30,16 +29,17 @@ def _read(self, length=32):
return bytes(self.read_dev.read(length))

def write(self, data):
logger.debug('Writing %d bytes.', len(data))
logger.debug("Writing %d bytes.", len(data))
self._write(data)

def read(self, length=32):
try:
ret_bytes = self._read(length)
if ret_bytes: logger.debug('Read %d bytes.', len(ret_bytes))
if ret_bytes:
logger.debug("Read %d bytes.", len(ret_bytes))
return ret_bytes
except Exception as e:
logger.debug('Error reading... %s', e)
logger.debug("Error reading... %s", e)
raise

def dispose(self):
Expand Down
77 changes: 44 additions & 33 deletions brother_ql/backends/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,24 @@
* printing
"""

import logging, time
import logging
import time

from brother_ql.backends import backend_factory, guess_backend
from brother_ql.reader import interpret_response

logger = logging.getLogger(__name__)

def discover(backend_identifier='linux_kernel'):

def discover(backend_identifier="linux_kernel"):
be = backend_factory(backend_identifier)
list_available_devices = be['list_available_devices']
BrotherQLBackend = be['backend_class']
list_available_devices = be["list_available_devices"]
BrotherQLBackend = be["backend_class"]

available_devices = list_available_devices()
return available_devices


def send(instructions, printer_identifier=None, backend_identifier=None, blocking=True):
"""
Send instruction bytes to a printer.
Expand All @@ -34,11 +36,11 @@ def send(instructions, printer_identifier=None, backend_identifier=None, blockin
"""

status = {
'instructions_sent': True, # The instructions were sent to the printer.
'outcome': 'unknown', # String description of the outcome of the sending operation like: 'unknown', 'sent', 'printed', 'error'
'printer_state': None, # If the selected backend supports reading back the printer state, this key will contain it.
'did_print': False, # If True, a print was produced. It defaults to False if the outcome is uncertain (due to a backend without read-back capability).
'ready_for_next_job': False, # If True, the printer is ready to receive the next instructions. It defaults to False if the state is unknown.
"instructions_sent": True, # The instructions were sent to the printer.
"outcome": "unknown", # String description of the outcome of the sending operation like: 'unknown', 'sent', 'printed', 'error'
"printer_state": None, # If the selected backend supports reading back the printer state, this key will contain it.
"did_print": False, # If True, a print was produced. It defaults to False if the outcome is uncertain (due to a backend without read-back capability).
"ready_for_next_job": False, # If True, the printer is ready to receive the next instructions. It defaults to False if the state is unknown.
}
selected_backend = None
if backend_identifier:
Expand All @@ -47,23 +49,27 @@ def send(instructions, printer_identifier=None, backend_identifier=None, blockin
try:
selected_backend = guess_backend(printer_identifier)
except:
logger.info("No backend stated. Selecting the default linux_kernel backend.")
selected_backend = 'linux_kernel'
logger.info(
"No backend stated. Selecting the default linux_kernel backend."
)
selected_backend = "linux_kernel"

be = backend_factory(selected_backend)
list_available_devices = be['list_available_devices']
BrotherQLBackend = be['backend_class']
list_available_devices = be["list_available_devices"]
BrotherQLBackend = be["backend_class"]

printer = BrotherQLBackend(printer_identifier)

start = time.time()
logger.info('Sending instructions to the printer. Total: %d bytes.', len(instructions))
logger.info(
"Sending instructions to the printer. Total: %d bytes.", len(instructions)
)
printer.write(instructions)
status['outcome'] = 'sent'
status["outcome"] = "sent"

if not blocking:
return status
if selected_backend == 'network':
if selected_backend == "network":
""" No need to wait for completion. The network backend doesn't support readback. """
return status

Expand All @@ -75,29 +81,34 @@ def send(instructions, printer_identifier=None, backend_identifier=None, blockin
try:
result = interpret_response(data)
except ValueError:
logger.error("TIME %.3f - Couln't understand response: %s", time.time()-start, data)
logger.error(
"TIME %.3f - Couln't understand response: %s", time.time() - start, data
)
continue
status['printer_state'] = result
logger.debug('TIME %.3f - result: %s', time.time()-start, result)
if result['errors']:
logger.error('Errors occured: %s', result['errors'])
status['outcome'] = 'error'
status["printer_state"] = result
logger.debug("TIME %.3f - result: %s", time.time() - start, result)
if result["errors"]:
logger.error("Errors occured: %s", result["errors"])
status["outcome"] = "error"
break
if result['status_type'] == 'Printing completed':
status['did_print'] = True
status['outcome'] = 'printed'
if result['status_type'] == 'Phase change' and result['phase_type'] == 'Waiting to receive':
status['ready_for_next_job'] = True
if status['did_print'] and status['ready_for_next_job']:
if result["status_type"] == "Printing completed":
status["did_print"] = True
status["outcome"] = "printed"
if (
result["status_type"] == "Phase change"
and result["phase_type"] == "Waiting to receive"
):
status["ready_for_next_job"] = True
if status["did_print"] and status["ready_for_next_job"]:
break

if not status['did_print']:
if not status["did_print"]:
logger.warning("'printing completed' status not received.")
if not status['ready_for_next_job']:
if not status["ready_for_next_job"]:
logger.warning("'waiting to receive' status not received.")
if (not status['did_print']) or (not status['ready_for_next_job']):
logger.warning('Printing potentially not successful?')
if status['did_print'] and status['ready_for_next_job']:
if (not status["did_print"]) or (not status["ready_for_next_job"]):
logger.warning("Printing potentially not successful?")
if status["did_print"] and status["ready_for_next_job"]:
logger.info("Printing was successful. Waiting for the next job.")

return status
Loading