knd_klinteplo/classes/create_photo.py

245 lines
9.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from datetime import datetime, timedelta
import os
import shutil
from docx import Document
from docx.text.paragraph import Paragraph
from docx.shared import Inches, Pt, RGBColor
from docx.enum.style import WD_STYLE_TYPE
import sys
import subprocess
import re
from random import randint
import random
from pathlib import Path
from pdf2image import convert_from_path
from PIL import Image, ImageFilter, ImageDraw
from PIL.ImageFilter import (
BLUR, CONTOUR, DETAIL, EDGE_ENHANCE, EDGE_ENHANCE_MORE,
EMBOSS, FIND_EDGES, SMOOTH, SMOOTH_MORE, SHARPEN
)
def convert_to(folder, source, timeout=None):
args = [libreoffice_exec(), '--headless', '--convert-to', 'pdf', '--outdir', folder, source]
process = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=timeout)
filename = re.search('-> (.*?) using filter', process.stdout.decode())
return filename.group(1)
def libreoffice_exec():
# TODO: Provide support for more platforms
if sys.platform == 'darwin':
return '/Applications/LibreOffice.app/Contents/MacOS/soffice'
elif sys.platform == 'win32':
# you need to add libreoffice to path
return 'soffice.exe'
return 'libreoffice'
def create_photo(address, user):
month = datetime.now().month
info = get_info(user)
path_to_template = os.path.join(os.path.abspath('.'), 'data', user)
template_docx = os.path.join(path_to_template, 'new_template.docx')
if len(info) > 0:
if not os.path.exists(template_docx):
# print(f"Копируем шаблоны графиков в {user}")
template_in_user = shutil.copyfile('new_template.docx', template_docx)
path_for_photo = os.path.join(path_to_template, str(month), address)
photos = get_photo(address, user)
if len(photos) > 0:
# print(len(photos))
if len(photos) > 7:
open_document(template_docx, True, info, address, path_for_photo, user)
else:
open_document(template_docx, False, info, address, path_for_photo, user)
return path_for_photo
else:
print(f"Нет фотографий по адресу {address}")
def get_info(user):
path = os.path.join(os.path.abspath('.'), 'data', user, 'img_5.txt')
if not os.path.exists(path):
print(f"Нет файла с информацией у пользователя {user}")
return []
with open(path, 'r') as f:
fd = f.readlines()
return fd
def get_photo(address, email):
photos = []
month = datetime.now().month
main_path = os.path.join(os.path.abspath('.'), 'data', email, str(month), address)
if not os.path.exists(main_path):
print(f"Нет фотографий по адресу: {address}")
return photos
else:
for images in os.listdir(main_path):
if images.endswith(".jpg") or images.endswith(".jpeg") or images.endswith(".JPG"):
photos.append(main_path + '/' + images)
return photos
def open_document(filename, lift, info, address, path_for_photo, user):
# print(f"Наличие лифта по адресу: {address} - {lift}")
# print(f"Начинаем подготавливать график для {address}, шаблон {filename}")
row_for_sign = 0
document = Document(filename)
styles = document.styles
tables = document.tables
date_now = datetime.today()
first_date = tables[0].rows[1].cells[0].text
first_date = datetime.strptime(first_date, '%d.%m.%y')
if datetime.now().date()-timedelta(12) > first_date.date():
clear_table(tables, lift, styles, info)
row_for_sign = fill_table(tables)
document.save(filename)
else:
row_for_sign = fill_table(tables)
document.save(filename)
paragraphs = document.paragraphs
fill_info(paragraphs, styles, info, address, lift)
document.save(filename)
make_png_with_sign(filename, row_for_sign, lift, path_for_photo, user)
def make_png_with_sign(filename, row_for_sign, lift, path_for_photo, user):
# print(f"Создаем картинку из графика {filename}")
horizontal = 0
if lift:
start_vertical = 780
else:
start_vertical = 680
result = convert_to('.', filename, timeout=15)
pages = convert_from_path(result, 200)
pages[0].save('template.png', 'PNG')
img2 = Image.open('template.png')
img2 = img2.convert("RGBA")
datas = img2.getdata()
newData = []
for item in datas:
if item[0] == 255 and item[1] == 255 and item[2] == 255:
newData.append((255, 255, 255, 0))
else:
# if item[0] > 120:
# newData.append((105, 105, 105, 255))
# else:
newData.append(item)
img2.putdata(newData)
while (row_for_sign+1) > 0:
# if lift:
# horizontal = randint(1320, 1450)
# else:
horizontal = randint(1320, 1450)
vertical = start_vertical + ((row_for_sign) * 100)
# clear_background('my_sign.png')
sign = Image.open(os.path.join(os.path.abspath('.'), 'data', user, 'sign.png'))
width, height = sign.size
sign = sign.resize((int(width*1.5), int(height*1.5)))
# print(horizontal)
img2.paste(sign, (horizontal, vertical), sign) # vertical step = 150
row_for_sign -= 1
img2.save('template.png', "PNG")
add_image_to_image('template.png', 'fon2.png', path_for_photo)
def add_image_to_image(filename, filename_fon, dst_folder):
# print(f"Накладываем график {filename} на фон")
left = randint(0, 140)
upper = randint(0, 85)
w_rand = random.uniform(0.8, 1)
b_rand = random.uniform(0.5, 0.8)
try:
angle = 0
# img = img.filter(ImageFilter.GaussianBlur(radius=1))
background = Image.open(filename_fon)
foreground = Image.open(filename)
width, height = foreground.size
size = int(width*0.25), int(height*0.25)
width_b, height_b = background.size
foreground = foreground.resize(size).rotate(angle)
background.paste(foreground, (195, 290), foreground)
background = background.crop((left, upper, width_b*w_rand, height_b*w_rand))
background = background.filter(ImageFilter.GaussianBlur(radius=b_rand))
background.save(os.path.join(dst_folder, 'graph.jpg'))
# print(os.path.join(dst_folder, 'graph.jpg'))
# print(os.path.dirname(dst_folder))
except IOError:
print(sys.exc_info()[0])
pass
def delete_paragraph(paragraph):
p = paragraph._element
p.getparent().remove(p)
p._p = p._element = None
def clear_table(tables, lift, styles, info):
# print(f"Очищаем таблицу в графике")
fio = info[0].split('\n')[0]
count = 0
while count < len(tables[0].rows)-1:
date_to_add = datetime.now().date()+timedelta(count)
delete_paragraph(tables[0].rows[count+1].cells[0].paragraphs[0])
delete_paragraph(tables[0].rows[count+1].cells[2].paragraphs[0])
par = tables[0].rows[count+1].cells[0].add_paragraph()
par_fio = tables[0].rows[count+1].cells[2].add_paragraph()
p = par.add_run(datetime.strftime(date_to_add, '%d.%m.%y'))
p_fio = par_fio.add_run(fio)
par_fio.alignment = 1
p_fio.bold = True
p.bold = True
font = p.font
count += 1
def fill_table(tables):
# print("Заполняем таблицу в графике")
r_count = 0
count = 0
while count < len(tables[0].rows)-1:
date_in_cell = tables[0].rows[count+1].cells[0].text
date_in_cell = datetime.strptime(date_in_cell, '%d.%m.%y')
if date_in_cell.date() == datetime.now().date():
r_count = count
count += 1
return r_count
def fill_info(paragraphs, styles, info, address, lift):
# print(f"Заполняем шапку графика в {address}")
fio = info[0].split('\n')[0]
dol = info[1].split('\n')[0]
phone_number = info[2].split('\n')[0]
for paragraph in paragraphs:
name_style = paragraph.style.name
if 'по адресу:' in paragraph.text:
# p = paragraph.insert_paragraph_before()
style = styles[name_style]
style.font.size = Pt(14)
paragraph.text = ''
p = paragraph.add_run('по адресу: '+address[:-4]+' Подъезд № ' + address[-2])
p.bold = True
font = p.font
font.color.rgb = RGBColor(128, 128, 128)
paragraph.style = styles[name_style]
elif 'Должность:' in paragraph.text:
paragraph.text = ''
if lift:
text_for_perechen = 'Перечень обрабатываемых объектов:\n - Первые этажи подъездов: полы, дверные и оконные ручки, почтовые ящики, панели домофонов и кодовых замков, перила лестничных маршей\n - Лифтовые кабины: напольные покрытия, панели управления лифтами, лифтовые вентиляционные решетки'
else:
text_for_perechen = 'Перечень обрабатываемых объектов:\n - Первые этажи подъездов: полы, дверные и оконные ручки, почтовые ящики, панели домофонов и кодовых замков, перила лестничных маршей'
run = paragraph.add_run(' Должность: ' + dol +' Ф.И.О.: ' + fio + '\n тел: ' + phone_number + '\n' + text_for_perechen)
font = run.font