163 lines
5.3 KiB
Python
163 lines
5.3 KiB
Python
import labels
|
|
import datetime
|
|
from random import randint
|
|
from django.db.models import BigIntegerField
|
|
|
|
|
|
from django.urls import reverse
|
|
|
|
from reportlab.graphics import shapes
|
|
from reportlab.graphics.barcode.qr import QrCodeWidget
|
|
from reportlab.lib.pagesizes import LETTER
|
|
from config.settings import DEBUG
|
|
|
|
BREWFATHER_APP_ROOT = 'https://web.brewfather.app'
|
|
|
|
|
|
def random_with_n_digits(n):
|
|
range_start = 10**(n-1)
|
|
range_end = (10**n)-1
|
|
return randint(range_start, range_end)
|
|
|
|
|
|
class AveryLabel:
|
|
""" Class to generate page of averty labels. """
|
|
|
|
AVERY = {
|
|
18294: (4, 15, LETTER, (44.45, 16.764), (7.62, 13.97)),
|
|
5263: (2, 5, LETTER, (101.6, 50.8), (3.95, 12.7)),
|
|
}
|
|
|
|
def __init__(self, label, **kwargs):
|
|
data = self.AVERY[label]
|
|
self.across = data[0]
|
|
self.down = data[1]
|
|
self.pagesize = data[2]
|
|
self.labelsize = data[3]
|
|
self.margins = data[4]
|
|
self.topDown = True
|
|
self.debug = False
|
|
self.position = 0
|
|
self.previous_used = 0
|
|
self.corner_radius = 2
|
|
self.__dict__.update(kwargs)
|
|
|
|
self.specs = labels.Specification(
|
|
self.pagesize[0]*0.352778, self.pagesize[1] *
|
|
0.352778, # Convert from PostScript points to mm
|
|
self.across, self.down,
|
|
self.labelsize[0], self.labelsize[1],
|
|
corner_radius=self.corner_radius,
|
|
left_margin=self.margins[0],
|
|
right_margin=self.margins[0],
|
|
top_margin=self.margins[1],
|
|
left_padding=2, right_padding=1, top_padding=1, bottom_padding=0,
|
|
row_gap=0)
|
|
|
|
def draw(self, label, width, height, obj):
|
|
if not obj['blank']:
|
|
obj['path'] = reverse(
|
|
"{}:{}".format(obj['ns'], obj['template']),
|
|
kwargs={"{}_id".format(obj['template']): obj['id']}
|
|
)
|
|
|
|
# Barcode
|
|
if DEBUG:
|
|
qrw = QrCodeWidget(
|
|
'https://brewery.giacofei.org/{path}'.format(**obj))
|
|
else:
|
|
qrw = QrCodeWidget('https://{host}/{path}'.format(**obj))
|
|
|
|
num_lines = max(len(obj['data']) + 1, 6)
|
|
font = height/num_lines
|
|
|
|
b = qrw.getBounds()
|
|
w = b[2]-b[0]
|
|
h = b[3]-b[1]
|
|
ps_size = (self.labelsize[1]/0.352778)
|
|
d = shapes.Drawing(
|
|
w, h, transform=[(ps_size/w), 0, 0, (ps_size/h), 0, 0])
|
|
d.add(qrw)
|
|
label.add(d)
|
|
|
|
# Line
|
|
line_pos = (num_lines - 1) * height / num_lines
|
|
label.add(shapes.Line(height, line_pos, width, line_pos))
|
|
|
|
# Title
|
|
label.add(shapes.String(
|
|
height, # Left Position
|
|
line_pos * 1.05, # Bottom Position
|
|
'{title}'.format(**obj), # Text
|
|
fontName="Helvetica",
|
|
fontSize=font
|
|
))
|
|
|
|
for x, line in enumerate(obj['data']):
|
|
x = x+1
|
|
label.add(shapes.String(
|
|
height, # Left Position
|
|
line_pos - font * x, # Bottom Position
|
|
line, # Text
|
|
fontName="Helvetica",
|
|
fontSize=font
|
|
))
|
|
|
|
def render(self, objects, render_file, labels_used=0):
|
|
""" Create the HttpResponse object with the appropriate PDF headers."""
|
|
|
|
# Create the sheet.
|
|
# if render_type == 'sample':
|
|
# sheet = labels.Sheet(self.specs, self.draw_sample, border=self.debug)
|
|
|
|
sheet = labels.Sheet(self.specs, self.draw, border=self.debug)
|
|
|
|
# Add a couple of labels.
|
|
for i in range(int(labels_used)):
|
|
sheet.add_label({'blank': True})
|
|
|
|
for entry in objects:
|
|
sheet.add_label(entry)
|
|
|
|
# Save the file and we are done.
|
|
sheet.save(render_file)
|
|
|
|
|
|
class DateUUIDField(BigIntegerField):
|
|
"""
|
|
A field which stores a Short UUID value with prepended date.
|
|
This may also have the Boolean attribute 'auto' which will set the value
|
|
on initial save to a new UUID value (calculated using shortuuid's default
|
|
(uuid4)). Note that while all UUIDs are expected to be unique we enforce
|
|
this with a DB constraint.
|
|
"""
|
|
|
|
def __init__(self, auto=True, *args, **kwargs):
|
|
self.auto = auto
|
|
if auto:
|
|
# Do not let the user edit UUIDs if they are auto-assigned.
|
|
kwargs['editable'] = False
|
|
kwargs['blank'] = True
|
|
kwargs['unique'] = True
|
|
|
|
super(DateUUIDField, self).__init__(*args, **kwargs)
|
|
|
|
def pre_save(self, model_instance, add):
|
|
"""
|
|
This is used to ensure that we auto-set values if required.
|
|
See CharField.pre_save
|
|
"""
|
|
value = super(DateUUIDField, self).pre_save(model_instance, add)
|
|
if self.auto and not value:
|
|
# Assign a new value for this attribute if required.
|
|
x = datetime.datetime.now()
|
|
front = x.strftime("%Y%m%d")
|
|
value = int('{}{}'.format(front, random_with_n_digits(6)))
|
|
setattr(model_instance, self.attname, value)
|
|
return value
|
|
|
|
def formfield(self, **kwargs):
|
|
if self.auto:
|
|
return None
|
|
return super(DateUUIDField, self).formfield(**kwargs)
|