-
-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
572 additions
and
70 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,298 @@ | ||
|
||
import os | ||
from io import StringIO | ||
import base64 | ||
import tempfile | ||
|
||
from io import BytesIO | ||
from datetime import datetime | ||
|
||
from pypdf import PdfFileWriter, PdfFileReader | ||
from reportlab.pdfgen import canvas | ||
from reportlab.lib.utils import ImageReader | ||
from reportlab.lib.pagesizes import A4 | ||
from reportlab.graphics import renderPDF | ||
|
||
from reportlab.pdfbase import pdfmetrics | ||
from reportlab.pdfbase.ttfonts import TTFont | ||
from svglib.svglib import svg2rlg | ||
|
||
from logging import info | ||
|
||
abs_path = os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir)) | ||
font_path = abs_path + "/static/font/opensans.ttf" | ||
pdfmetrics.registerFont(TTFont('OpenSans', font_path)) | ||
|
||
default_font_size = 15 | ||
form_image_path = "/static/images/formular-2021.jpg" | ||
|
||
|
||
def format_ngo_account(ngo_account): | ||
# remove white spaces from account | ||
ngo_account = ngo_account.replace(' ', '') | ||
|
||
account = '' | ||
for i, l in enumerate(ngo_account): | ||
account += l | ||
if (i + 1) % 4 == 0: | ||
account += " " | ||
|
||
return account | ||
|
||
def add_donor_data(c, person): | ||
|
||
donor_block_x = 681 | ||
|
||
# the first name | ||
if len(person["first_name"]) > 18: | ||
c.setFontSize(12) | ||
|
||
c.drawString(75, donor_block_x, person["first_name"]) | ||
c.setFontSize(default_font_size) | ||
|
||
# father's first letter | ||
c.drawString(300, donor_block_x, person["father"]) | ||
|
||
# the last name | ||
last_name = person["last_name"] | ||
if len(last_name) > 34: | ||
c.setFontSize(10) | ||
|
||
c.drawString(75, donor_block_x - 22, last_name) | ||
|
||
|
||
# ======================================= | ||
# THIRD ROW | ||
# | ||
third_row_x = donor_block_x - 45 | ||
|
||
# the street | ||
street = person["street"] | ||
|
||
if len(street) > 40: | ||
c.setFontSize(8) | ||
elif len(street) in range(36, 41): | ||
c.setFontSize(10) | ||
elif len(street) in range(24, 36): | ||
c.setFontSize(11) | ||
|
||
c.drawString(67, third_row_x, street) | ||
c.setFontSize(default_font_size) | ||
|
||
# numar | ||
if len(person["number"]) > 5: | ||
c.setFontSize(8) | ||
elif len(person["number"]) > 3: | ||
c.setFontSize(10) | ||
|
||
c.drawString(289, third_row_x, person["number"]) | ||
c.setFontSize(default_font_size) | ||
|
||
# | ||
# ======================================= | ||
|
||
# ======================================= | ||
# FOURTH ROW | ||
fourth_row_x = donor_block_x - 67 | ||
|
||
c.setFontSize(14) | ||
# bloc | ||
c.drawString(49, fourth_row_x, person["bl"]) | ||
# scara | ||
c.drawString(108, fourth_row_x, person["sc"]) | ||
|
||
# etaj | ||
c.drawString(150, fourth_row_x, person["et"]) | ||
|
||
# apartament | ||
c.drawString(185, fourth_row_x, person["ap"]) | ||
|
||
# judet | ||
if len(person["county"]) <= 12: | ||
c.setFontSize(12) | ||
else: | ||
c.setFontSize(8) | ||
|
||
c.drawString(255, fourth_row_x, person["county"]) | ||
c.setFontSize(default_font_size) | ||
# | ||
# ======================================= | ||
|
||
|
||
# oras | ||
c.drawString(69, donor_block_x - 90, person["city"]) | ||
|
||
c.setFontSize(16) | ||
|
||
# cnp | ||
start_x = 336 | ||
for letter in person["cnp"]: | ||
c.drawString(start_x, donor_block_x - 10, letter) | ||
start_x += 18.5 | ||
|
||
|
||
start_email_x = 368 | ||
if person['email']: | ||
if len(person['email']) < 32: | ||
c.setFontSize(12) | ||
elif len(person['email']) < 40: | ||
c.setFontSize(10) | ||
else: | ||
c.setFontSize(8) | ||
|
||
c.drawString(start_email_x, third_row_x + 14, person['email']) | ||
|
||
# telephone | ||
if person['tel']: | ||
c.setFontSize(12) | ||
c.drawString(start_email_x, third_row_x - 15, person['tel']) | ||
|
||
|
||
c.setFontSize(default_font_size) | ||
|
||
def add_ngo_data(c, ong): | ||
start_ong_y = 449 | ||
|
||
# the x mark | ||
c.drawString(219, start_ong_y, "x") | ||
|
||
if ong.get('two_years'): | ||
c.drawString(325, start_ong_y - 21, "x") | ||
|
||
# the cif code | ||
c.setFontSize(9) | ||
c.drawString(250, start_ong_y - 41, ong["cif"]) | ||
|
||
# the name | ||
org_name = ong["name"] | ||
if len(org_name) > 79: | ||
c.setFontSize(9) | ||
elif len(org_name) > 65: | ||
c.setFontSize(12) | ||
|
||
c.drawString(186, start_ong_y - 64, org_name.encode('utf-8')) | ||
|
||
c.setFontSize(11) | ||
|
||
# the bank account | ||
account = format_ngo_account(ong["account"]) | ||
c.drawString(110, start_ong_y - 86, account) | ||
|
||
if ong.get('percent'): | ||
c.drawString(146, start_ong_y - 108, ong.get('percent')) | ||
|
||
def create_pdf(person = {}, ong = {}): | ||
"""method used to create the pdf | ||
person: dict with the person's data | ||
first_name | ||
father | ||
last_name | ||
tel | ||
street | ||
number | ||
bl | ||
sc | ||
et | ||
ap | ||
county | ||
city | ||
cnp | ||
ong: dict with the ngo's data | ||
name | ||
cif | ||
account | ||
""" | ||
|
||
# packet = StringIO.StringIO() | ||
# we could also use StringIO | ||
packet = tempfile.TemporaryFile(mode='w+b') | ||
|
||
c = canvas.Canvas(packet, A4) | ||
width, height = A4 | ||
|
||
# add the image as background | ||
background = ImageReader( abs_path + form_image_path ) | ||
c.drawImage(background, 0, 0, width=width, height=height) | ||
|
||
c.setFont('OpenSans', default_font_size) | ||
c.setFontSize(default_font_size) | ||
|
||
# the year | ||
# this is the previous year | ||
year = str( datetime.now().year - 1 ) | ||
start_x = 305 | ||
for letter in year: | ||
c.drawString(start_x, 736, letter) | ||
start_x += 18 | ||
|
||
# DRAW DONOR DATA | ||
if person.get('first_name'): | ||
add_donor_data(c, person) | ||
|
||
add_ngo_data(c, ong) | ||
|
||
c.save() | ||
|
||
# go to the beginning of the file | ||
packet.seek(0) | ||
# packet.type = "application/pdf" | ||
|
||
return packet | ||
|
||
def add_signature(pdf, image): | ||
|
||
pdf_string = StringIO.StringIO(pdf) | ||
existing_pdf = PdfFileReader(pdf_string) | ||
|
||
packet = tempfile.TemporaryFile(mode='w+b') | ||
|
||
# init pdf canvas | ||
c = canvas.Canvas(packet, A4) | ||
|
||
# add the image as background | ||
# remove the header added by javascript | ||
image = image.split(',')[1] | ||
# make sure the string has the right padding | ||
image = image + '=' * (-len(image) % 4) | ||
base_image = base64.b64decode(image) | ||
byte_image = BytesIO(base_image) | ||
# make this a svg2rlg object | ||
drawing = svg2rlg(byte_image) | ||
|
||
# we used to use width for scaling down but we move to height | ||
# new_width = 90 | ||
|
||
new_height = 30 | ||
scaled_down = (new_height / drawing.height) | ||
|
||
# we want to scale the image down and stil keep it's aspect ratio | ||
# the image might have dimensions of 750 x 200 | ||
drawing.scale(scaled_down, scaled_down) | ||
|
||
# add it to the PDF | ||
renderPDF.draw(drawing, c, 166, 134) | ||
|
||
c.save() | ||
packet.seek(0) | ||
|
||
new_pdf = PdfFileReader(packet) | ||
|
||
page = existing_pdf.getPage(0) | ||
page.mergePage(new_pdf.getPage(0)) | ||
|
||
output = PdfFileWriter() | ||
output.addPage(page) | ||
|
||
outputStream = tempfile.TemporaryFile(mode='w+b') | ||
output.write(outputStream) | ||
|
||
outputStream.seek(0) | ||
|
||
packet.close() | ||
|
||
return outputStream |
Oops, something went wrong.