drive-pipeline/drive/models.py
2020-10-24 01:21:02 -04:00

124 lines
4.6 KiB
Python

from django.db import models
from django.conf import settings
import io
from django.core import serializers
from django.templatetags.static import static
from PIL import Image, ImageDraw, ImageFont
import matplotlib.pyplot as plt
import numpy as np
# Create your models here.
class Response(models.Model):
# user data
first_name = models.CharField("First Name", max_length=50)
last_name = models.CharField("Last Name", max_length=50)
email = models.EmailField("Email", max_length=254)
# scores
decision = models.PositiveIntegerField("Decision Making")
decision_it = models.PositiveIntegerField("Decision Making - IT")
decision_legal = models.PositiveIntegerField("Decision Making - Legal/Procurement")
resources = models.PositiveIntegerField("Resources")
impact = models.PositiveIntegerField("Impact")
velocity = models.PositiveIntegerField("Velocity")
expectations = models.PositiveIntegerField("Expectations")
# self.overall
overall = models.PositiveIntegerField("Overall Score")
results = models.ImageField("Results Image", blank=True, null=True)
results_pdf = models.ImageField("Results PDF", blank=True, null=True)
class Meta:
verbose_name = "Response"
verbose_name_plural = "Responses"
def __str__(self):
return f'{self.first_name} {self.last_name}\'s Response'
def save(self, *args, **kwargs):
self.results = f'{self.id}.png'
self.results_pdf = f'{self.id}.pdf'
super().save(*args, **kwargs)
fig, ax = plt.subplots(figsize=(8, 8))
height = list(serializers.serialize("python", [self])[0]['fields'].values())[3:-2]
print(f'height {height}')
bars = tuple([field.verbose_name for field in self._meta.get_fields()][4:-2])
y_pos = np.arange(len(bars))
for i, v in enumerate(height):
if v > 10:
ax.text(int(v) - 11,
i + 0.05,
f'{v}%',
color='white',
fontweight='bold',
fontsize=14)
else:
ax.text(int(v) + 2,
i + 0.05,
f'{v}%',
color='black',
fontweight='bold',
fontsize=14)
col = []
for val in height:
if val < 50:
col.append('#FF0000')
elif val <= 75:
col.append('#FFC000')
else:
col.append('#70AD47')
ax.barh(y_pos, height, align='center', color=col)
ax.set_xlim([0,100])
ax.set_yticks(y_pos)
ax.set_yticklabels(bars)
ax.invert_yaxis() # labels read top-to-bottom
ax.set_title('Breakdown by Section:')
buf = io.BytesIO()
plt.savefig(buf, format='png', bbox_inches='tight', transparent=False)
buf.seek(0)
im = Image.open(buf)
width, height = im.size
y_offset = 200
new_height = height + y_offset
result = Image.new(im.mode, (width, new_height), color=(255,255,255))
result.paste(im, (0, y_offset))
width, height = result.size
font_path = f"{str(settings.PROJECT_PATH)}{static('font/OpenSans-Regular.ttf')}"
font = ImageFont.truetype(font_path, size=25);
top_header = 'OVERALL PROGRESS:'
draw = ImageDraw.Draw(result)
draw.text(
((width-draw.textsize(top_header, font=font)[0])/2, draw.textsize(top_header)[1]), # Coordinates
top_header, # Text
(0, 0, 0), # Color
font=font
)
font = ImageFont.truetype(font_path, size=160);
draw.text(
(((width-draw.textsize(f'{self.overall}%', font=font)[0])/2), draw.textsize(top_header)[1]), # Coordinates
f'{self.overall}%', # Text
(255, 0, 0) if self.overall < 50 else (255, 192, 0) if self.overall <= 75 else (112, 173, 71), # Color
font=font
)
result.save(f'{settings.BASE_DIR}/media/{self.id}.png')
rgba = Image.open(f'{settings.BASE_DIR}/media/{self.id}.png')
rgb = Image.new('RGB', rgba.size, (255, 255, 255))
rgb.paste(rgba, mask=rgba.split()[3])
rgb.save(f'{settings.BASE_DIR}/media/{self.id}.pdf', 'PDF', resoultion=100.0)