update barcodes to use mixin

This commit is contained in:
Matthias 2022-01-10 01:23:48 +01:00
parent 4fc3e85a53
commit 20e712a287
No known key found for this signature in database
GPG Key ID: F50EF5741D33E076
4 changed files with 161 additions and 132 deletions

View File

@ -1,139 +1,19 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import warnings
import string import plugin.builtin.barcode.mixins as mixin
import hashlib import plugin.integration
import logging
from stock.models import StockItem hash_barcode = mixin.hash_barcode
from stock.serializers import StockItemSerializer, LocationSerializer
from part.serializers import PartSerializer
class BarcodePlugin(mixin.BarcodeMixin, plugin.integration.IntegrationPluginBase):
logger = logging.getLogger('inventree')
def hash_barcode(barcode_data):
""" """
Calculate an MD5 hash of barcode data. Legacy barcode plugin definition - will be replaced
Please use the new Integration Plugin API and the BarcodeMixin
HACK: Remove any 'non printable' characters from the hash,
as it seems browers will remove special control characters...
TODO: Work out a way around this!
""" """
# TODO @matmair remove this with InvenTree 0.7.0
barcode_data = str(barcode_data).strip() def __init__(self, barcode_data=None):
warnings.warn("using the BarcodePlugin is depreceated", DeprecationWarning)
printable_chars = filter(lambda x: x in string.printable, barcode_data) super().__init__()
self.init(barcode_data)
barcode_data = ''.join(list(printable_chars))
hash = hashlib.md5(str(barcode_data).encode())
return str(hash.hexdigest())
class BarcodePlugin:
"""
Base class for barcode handling.
Custom barcode plugins should extend this class as necessary.
"""
# Override the barcode plugin name for each sub-class
PLUGIN_NAME = ""
@property
def name(self):
return self.PLUGIN_NAME
def __init__(self, barcode_data):
"""
Initialize the BarcodePlugin instance
Args:
barcode_data - The raw barcode data
"""
self.data = barcode_data
def getStockItem(self):
"""
Attempt to retrieve a StockItem associated with this barcode.
Default implementation returns None
"""
return None
def getStockItemByHash(self):
"""
Attempt to retrieve a StockItem associated with this barcode,
based on the barcode hash.
"""
try:
item = StockItem.objects.get(uid=self.hash())
return item
except StockItem.DoesNotExist:
return None
def renderStockItem(self, item):
"""
Render a stock item to JSON response
"""
serializer = StockItemSerializer(item, part_detail=True, location_detail=True, supplier_part_detail=True)
return serializer.data
def getStockLocation(self):
"""
Attempt to retrieve a StockLocation associated with this barcode.
Default implementation returns None
"""
return None
def renderStockLocation(self, loc):
"""
Render a stock location to a JSON response
"""
serializer = LocationSerializer(loc)
return serializer.data
def getPart(self):
"""
Attempt to retrieve a Part associated with this barcode.
Default implementation returns None
"""
return None
def renderPart(self, part):
"""
Render a part to JSON response
"""
serializer = PartSerializer(part)
return serializer.data
def hash(self):
"""
Calculate a hash for the barcode data.
This is supposed to uniquely identify the barcode contents,
at least within the bardcode sub-type.
The default implementation simply returns an MD5 hash of the barcode data,
encoded to a string.
This may be sufficient for most applications, but can obviously be overridden
by a subclass.
"""
return hash_barcode(self.data)
def validate(self):
"""
Default implementation returns False
"""
return False

View File

@ -0,0 +1,147 @@
"""
Plugin mixin classes for barcode plugin
"""
import string
import hashlib
from stock.models import StockItem
from stock.serializers import StockItemSerializer, LocationSerializer
from part.serializers import PartSerializer
def hash_barcode(barcode_data):
"""
Calculate an MD5 hash of barcode data.
HACK: Remove any 'non printable' characters from the hash,
as it seems browers will remove special control characters...
TODO: Work out a way around this!
"""
barcode_data = str(barcode_data).strip()
printable_chars = filter(lambda x: x in string.printable, barcode_data)
barcode_data = ''.join(list(printable_chars))
hash = hashlib.md5(str(barcode_data).encode())
return str(hash.hexdigest())
class BarcodeMixin:
"""
Mixin that enables barcode handeling
Custom barcode plugins should use and extend this mixin as necessary.
"""
ACTION_NAME = ""
class MixinMeta:
"""
meta options for this mixin
"""
MIXIN_NAME = 'Barcode'
def __init__(self):
super().__init__()
self.add_mixin('barcode', 'has_barcode', __class__)
@property
def has_barcode(self):
"""
Does this plugin have everything needed to process a barcode
"""
return True
def init(self, barcode_data):
"""
Initialize the BarcodePlugin instance
Args:
barcode_data - The raw barcode data
"""
self.data = barcode_data
def getStockItem(self):
"""
Attempt to retrieve a StockItem associated with this barcode.
Default implementation returns None
"""
return None
def getStockItemByHash(self):
"""
Attempt to retrieve a StockItem associated with this barcode,
based on the barcode hash.
"""
try:
item = StockItem.objects.get(uid=self.hash())
return item
except StockItem.DoesNotExist:
return None
def renderStockItem(self, item):
"""
Render a stock item to JSON response
"""
serializer = StockItemSerializer(item, part_detail=True, location_detail=True, supplier_part_detail=True)
return serializer.data
def getStockLocation(self):
"""
Attempt to retrieve a StockLocation associated with this barcode.
Default implementation returns None
"""
return None
def renderStockLocation(self, loc):
"""
Render a stock location to a JSON response
"""
serializer = LocationSerializer(loc)
return serializer.data
def getPart(self):
"""
Attempt to retrieve a Part associated with this barcode.
Default implementation returns None
"""
return None
def renderPart(self, part):
"""
Render a part to JSON response
"""
serializer = PartSerializer(part)
return serializer.data
def hash(self):
"""
Calculate a hash for the barcode data.
This is supposed to uniquely identify the barcode contents,
at least within the bardcode sub-type.
The default implementation simply returns an MD5 hash of the barcode data,
encoded to a string.
This may be sufficient for most applications, but can obviously be overridden
by a subclass.
"""
return hash_barcode(self.data)
def validate(self):
"""
Default implementation returns False
"""
return False

View File

@ -4,6 +4,7 @@ Utility class to enable simpler imports
from ..builtin.integration.mixins import AppMixin, SettingsMixin, ScheduleMixin, UrlsMixin, NavigationMixin from ..builtin.integration.mixins import AppMixin, SettingsMixin, ScheduleMixin, UrlsMixin, NavigationMixin
from ..builtin.action.mixins import ActionMixin from ..builtin.action.mixins import ActionMixin
from ..builtin.barcode.mixins import BarcodeMixin
__all__ = [ __all__ = [
'AppMixin', 'AppMixin',
@ -12,4 +13,5 @@ __all__ = [
'SettingsMixin', 'SettingsMixin',
'UrlsMixin', 'UrlsMixin',
'ActionMixin', 'ActionMixin',
'BarcodeMixin',
] ]