brewery-website/config/extras.py

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)