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 -*-
import warnings
import string
import hashlib
import logging
import plugin.builtin.barcode.mixins as mixin
import plugin.integration
from stock.models import StockItem
from stock.serializers import StockItemSerializer, LocationSerializer
from part.serializers import PartSerializer
hash_barcode = mixin.hash_barcode
logger = logging.getLogger('inventree')
def hash_barcode(barcode_data):
class BarcodePlugin(mixin.BarcodeMixin, plugin.integration.IntegrationPluginBase):
"""
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!
Legacy barcode plugin definition - will be replaced
Please use the new Integration Plugin API and the BarcodeMixin
"""
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 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
# TODO @matmair remove this with InvenTree 0.7.0
def __init__(self, barcode_data=None):
warnings.warn("using the BarcodePlugin is depreceated", DeprecationWarning)
super().__init__()
self.init(barcode_data)

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.action.mixins import ActionMixin
from ..builtin.barcode.mixins import BarcodeMixin
__all__ = [
'AppMixin',
@ -12,4 +13,5 @@ __all__ = [
'SettingsMixin',
'UrlsMixin',
'ActionMixin',
'BarcodeMixin',
]