Skip to content

Commit

Permalink
migrate plugin to machine registry integration
Browse files Browse the repository at this point in the history
  • Loading branch information
simonkuehling committed Oct 17, 2024
1 parent adbb3cb commit 92ec154
Showing 1 changed file with 106 additions and 113 deletions.
219 changes: 106 additions & 113 deletions inventree_brother/brother_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,127 +10,126 @@
from brother_ql.models import ALL_MODELS
from brother_ql.labels import ALL_LABELS, FormFactor

# translation
from django.db import models
from django.utils.translation import gettext_lazy as _

# printing options
from rest_framework import serializers

from inventree_brother.version import BROTHER_PLUGIN_VERSION

# InvenTree plugin libs
from report.models import LabelTemplate
from plugin import InvenTreePlugin
from plugin.mixins import LabelPrintingMixin, SettingsMixin
from plugin.machine import BaseMachineType
from plugin.machine.machine_types import LabelPrinterBaseDriver, LabelPrinterMachine

# Image library
from PIL import ImageOps


def get_model_choices():
"""
Returns a list of available printer models
"""

return [(model.name, model.name) for model in ALL_MODELS]


def get_label_choices():
"""
Return a list of available label types
"""

return [(label.identifier, label.name) for label in ALL_LABELS]


def get_rotation_choices():
"""
Return a list of available rotation angles
"""

return [(f"{degree}", f"{degree}°") for degree in [0, 90, 180, 270]]


class BrotherLabelSerializer(serializers.Serializer):
"""Custom serializer class for BrotherLabelPlugin.
Used to specify printing parameters at runtime
"""

copies = serializers.IntegerField(
default=1,
label=_('Copies'),
help_text=_('Number of copies to print'),
)


class BrotherLabelPlugin(LabelPrintingMixin, SettingsMixin, InvenTreePlugin):
class BrotherLabelPlugin(InvenTreePlugin):
"""Brother label printer driver plugin for InvenTree."""

AUTHOR = "Oliver Walters"
DESCRIPTION = "Label printing plugin for Brother printers"
VERSION = BROTHER_PLUGIN_VERSION

# Machine registry was added in InvenTree 0.14.0, use inventree-brother-plugin 0.9.0 for older versions
# Machine driver interface was fixed with 0.16.0 to work inside of inventree workers
MIN_VERSION = "0.16.0"

NAME = "Brother Labels"
SLUG = "brother"
TITLE = "Brother Label Printer"

PrintingOptionsSerializer = BrotherLabelSerializer

# Use background printing
BLOCKING_PRINT = False


class BrotherLabelPrinterDriver(LabelPrinterBaseDriver):
"""Brother label printing driver for InvenTree."""

SLUG = "brother"
NAME = "Brother Label Printer Driver"
DESCRIPTION = "Brother label printing driver for InvenTree"

def __init__(self, *args, **kwargs):
"""Initialize the BrotherLabelPrinterDriver."""
self.MACHINE_SETTINGS = {
'MODEL': {
'name': _('Printer Model'),
'description': _('Select model of Brother printer'),
'choices': self.get_model_choices,
'default': 'PT-P750W',
'required': True,
},
'LABEL': {
'name': _('Label Media'),
'description': _('Select label media type'),
'choices': self.get_label_choices,
'default': '12',
'required': True,
},
'IP_ADDRESS': {
'name': _('IP Address'),
'description': _('IP address of the brother label printer'),
'default': '',
},
'USB_DEVICE': {
'name': _('USB Device'),
'description': _('USB device identifier of the label printer (VID:PID/SERIAL)'),
'default': '',
},
'AUTO_CUT': {
'name': _('Auto Cut'),
'description': _('Cut each label after printing'),
'validator': bool,
'default': True,
'required': True,
},
'ROTATION': {
'name': _('Rotation'),
'description': _('Rotation of the image on the label'),
'choices': self.get_rotation_choices,
'default': '0',
'required': True,
},
'COMPRESSION': {
'name': _('Compression'),
'description': _('Enable image compression option (required for some printer models)'),
'validator': bool,
'default': False,
'required': True,
},
'HQ': {
'name': _('High Quality'),
'description': _('Enable high quality option (required for some printers)'),
'validator': bool,
'default': True,
'required': True,
},
}

SETTINGS = {
'MODEL': {
'name': _('Printer Model'),
'description': _('Select model of Brother printer'),
'choices': get_model_choices,
'default': 'PT-P750W',
},
'LABEL': {
'name': _('Label Media'),
'description': _('Select label media type'),
'choices': get_label_choices,
'default': '12',
},
'IP_ADDRESS': {
'name': _('IP Address'),
'description': _('IP address of the brother label printer'),
'default': '',
},
'USB_DEVICE': {
'name': _('USB Device'),
'description': _('USB device identifier of the label printer (VID:PID/SERIAL)'),
'default': '',
},
'AUTO_CUT': {
'name': _('Auto Cut'),
'description': _('Cut each label after printing'),
'validator': bool,
'default': True,
},
'ROTATION': {
'name': _('Rotation'),
'description': _('Rotation of the image on the label'),
'choices': get_rotation_choices,
'default': '0',
},
'COMPRESSION': {
'name': _('Compression'),
'description': _('Enable image compression option (required for some printer models)'),
'validator': bool,
'default': False,
},
'HQ': {
'name': _('High Quality'),
'description': _('Enable high quality option (required for some printers)'),
'validator': bool,
'default': True,
},
}

def print_label(self, **kwargs):
"""
Send the label to the printer
"""
super().__init__(*args, **kwargs)

def get_model_choices(self, **kwargs):
""" Returns a list of available printer models """
return [(model.name, model.name) for model in ALL_MODELS]

def get_label_choices(self, **kwargs):
""" Return a list of available label types """
return [(label.identifier, label.name) for label in ALL_LABELS]

def get_rotation_choices(self, **kwargs):
""" Return a list of available rotation angles """
return [(f"{degree}", f"{degree}°") for degree in [0, 90, 180, 270]]

def init_machine(self, machine: BaseMachineType):
"""Machine initialize hook."""
# static dummy setting for now, should probably be actively checked for USB printers
# and maybe by running a simple ping test or similar for networked printers
machine.set_status(LabelPrinterMachine.MACHINE_STATUS.CONNECTED)

def print_label(self, machine: LabelPrinterMachine, label: LabelTemplate, item: models.Model, **kwargs) -> None:
""" Send the label to the printer """

# TODO: Add padding around the provided image, otherwise the label does not print correctly
# ^ Why? The wording in the underlying brother_ql library ('dots_printable') seems to suggest
Expand All @@ -148,27 +147,21 @@ def print_label(self, **kwargs):
options = kwargs.get('printing_options', {})
n_copies = int(options.get('copies', 1))

# Look for png data in kwargs (if provided)
label_image = kwargs.get('png_file', None)

if not label_image:
# Convert PDF to PNG
pdf_data = kwargs['pdf_data']
label_image = self.render_to_png(label=None, pdf_data=pdf_data)
label_image = self.render_to_png(label, item)

# Read settings
model = self.get_setting('MODEL')
ip_address = self.get_setting('IP_ADDRESS')
usb_device = self.get_setting('USB_DEVICE')
media_type = self.get_setting('LABEL')
model = machine.get_setting('MODEL', 'D')
ip_address = machine.get_setting('IP_ADDRESS', 'D')
usb_device = machine.get_setting('USB_DEVICE', 'D')
media_type = machine.get_setting('LABEL', 'D')

# Get specifications of media type
media_specs = None
for label_specs in ALL_LABELS:
if label_specs.identifier == media_type:
media_specs = label_specs

rotation = int(self.get_setting('ROTATION')) + 90
rotation = int(machine.get_setting('ROTATION', 'D')) + 90
rotation = rotation % 360

if rotation in [90, 180, 270]:
Expand Down Expand Up @@ -204,10 +197,10 @@ def print_label(self, **kwargs):
'qlr': printer,
'images': [printable_image],
'label': media_type,
'cut': self.get_setting('AUTO_CUT'),
'cut': machine.get_setting('AUTO_CUT', 'D'),
'rotate': 0,
'compress': self.get_setting('COMPRESSION'),
'hq': self.get_setting('HQ'),
'compress': machine.get_setting('COMPRESSION', 'D'),
'hq': machine.get_setting('HQ', 'D'),
'red': red,
}

Expand Down

0 comments on commit 92ec154

Please sign in to comment.