Skip to content

Commit

Permalink
Merge pull request #15 from k01ek/develop
Browse files Browse the repository at this point in the history
Allow text location to be customised
  • Loading branch information
k01ek authored Jun 21, 2021
2 parents 71229bb + 7b8052d commit d4195d4
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 20 deletions.
11 changes: 10 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
PYTHON_VER?=3.7
NETBOX_VER?=v2.10.6
NETBOX_VER?=v2.11.6


NAME=netbox-qrcode

Expand Down Expand Up @@ -64,3 +65,11 @@ endif
git commit -am 'bump ver'
git push origin release-$(NEWVER)
git checkout develop

pbuild:
python3 -m pip install --upgrade build
python3 -m build

pypipub:
python3 -m pip install --upgrade twine
python3 -m twine upload dist/*
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,13 @@ The following options are available:
* `with_text`: Boolean (default True). Text label will be added to QR code image if enabled.
* `text_fields`: List of String (default ['name']). Text fields of an object that will be added as text label to QR image. It's possible to use custom field values.
* `font`: String (default TahomaBold) Font name for text label ( Some font include in package, see fonts dir).
* `text_location`: Where to render the text, relative to the QR code. Valid values are `"right"` (default), `"left"`", `"up"`, and `"down"`.
* `custom_text`: String or None (default None) additional text label to QR code image (will be added after text_fields).
* `qr_version`: Integer (default 1) parameter is an integer from 1 to 40 that controls the size of
the QR Code (the smallest, version 1, is a 21x21 matrix).
* `qr_error_correction`: Integer (default 0), controls the error correction used for the
QR Code. The following values are available:

1 - About 7% or less errors can be corrected.
0 - About 15% or less errors can be corrected.
2 - About 30% or less errors can be corrected.
Expand All @@ -60,6 +61,7 @@ PLUGINS_CONFIG = {
'text_fields': ['name', 'serial'],
'font': 'ArialMT',
'custom_text': 'Property of SomeCompany\ntel.8.800333554-CALL',
'text_location': 'up',
'qr_version': 1,
'qr_error_correction': 0,
'qr_box_size': 4,
Expand Down Expand Up @@ -97,4 +99,4 @@ Rack QR code
![Rack QR Code](docs/img/qrcode_rack.png)

Cable QR code
![Cable QR Code](docs/img/qrcode_cable.png)
![Cable QR Code](docs/img/qrcode_cable.png)
3 changes: 2 additions & 1 deletion netbox_qrcode/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class QRCodeConfig(PluginConfig):
'text_fields': ['name', 'serial'],
'font': 'TahomaBold',
'custom_text': None,
'text_location': 'right',
'qr_version': 1,
'qr_error_correction': 0,
'qr_box_size': 6,
Expand All @@ -35,4 +36,4 @@ class QRCodeConfig(PluginConfig):
}
}

config = QRCodeConfig # noqa E305
config = QRCodeConfig # noqa E305
3 changes: 2 additions & 1 deletion netbox_qrcode/template_content.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ def x_page(self):
text.append(custom_text)
text = '\n'.join(text)
text_img = get_qr_text(qr_img.size, text, config.get('font'))
qr_with_text = get_concat(qr_img, text_img)
qr_with_text = get_concat(qr_img, text_img, config.get('text_location', 'right'))

img = get_img_b64(qr_with_text)
else:
img = get_img_b64(qr_img)
Expand Down
76 changes: 62 additions & 14 deletions netbox_qrcode/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,29 +28,77 @@ def get_img_b64(img):
return str(base64.b64encode(stream.getvalue()), encoding='ascii')


def get_qr_text(size, text, font='TahomaBold'):
img = Image.new('L', size, 'white')
def get_qr_text(max_size, text, font='TahomaBold'):
font_size = 56
flag = True
while flag:
tmpimg = Image.new('L', max_size, 'white')
text_too_large = True
while text_too_large:
file_path = resource_stream(__name__, 'fonts/{}.ttf'.format(font))
try:
fnt = ImageFont.truetype(file_path, font_size)
except Exception:
fnt = ImageFont.load_default()
flag = False
draw = ImageDraw.Draw(img)

draw = ImageDraw.Draw(tmpimg)
w, h = draw.textsize(text, font=fnt)
if w < size[0] - 4 and h < size[1] - 4:
flag = False
if w < max_size[0] - 4 and h < max_size[1] - 4:
text_too_large = False
font_size -= 1
W, H = size
draw.text(((W-w)/2, (H-h)/2), text, font=fnt, fill='black')

img = Image.new('L', (w, h), 'white')
draw = ImageDraw.Draw(img)
draw.text((0, 0), text, font=fnt, fill='black')
return img


def get_concat(im1, im2):
dst = Image.new('L', (im1.width + im2.width, im1.height))
dst.paste(im1, (0, 0))
dst.paste(im2, (im1.width, 0))
def get_concat(im1, im2, direction='right'):
if direction == 'right' or direction == 'left':
width = im1.width + im2.width
height = max(im1.height, im2.height)
elif direction == 'down' or direction == 'up':
width = max(im1.width, im2.width)
height = im1.height + im2.height
else:
raise ValueError(
'Invalid direction "{}" (must be one of "left", "right", "up", or "down")'.format(direction)
)

dst = Image.new('L', (width, height), 'white')

if direction == 'right' or direction == 'left':
if im1.height > im2.height:
im1_y = 0
im2_y = abs(im1.height-im2.height) // 2
else:
im1_y = abs(im1.height-im2.height) // 2
im2_y = 0

if direction == 'right':
im1_x = 0
im2_x = im1.width
else:
im1_x = im2.width
im2_x = 0
elif direction == 'up' or direction == 'down':
if im1.width > im2.width:
im1_x = 0
im2_x = abs(im1.width-im2.width) // 2
else:
im1_x = abs(im1.width-im2.width) // 2
im2_x = 0

if direction == 'down':
im1_y = 0
im2_y = im1.height
else:
im1_y = im2.height
im2_y = 0
else:
raise ValueError(
'Invalid direction "{}" (must be one of "left", "right", "up", or "down")'.format(direction)
)

dst.paste(im1, (im1_x, im1_y))
dst.paste(im2, (im2_x, im2_y))

return dst
2 changes: 1 addition & 1 deletion netbox_qrcode/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.0.5"
__version__ = "0.0.6"

0 comments on commit d4195d4

Please sign in to comment.