from . import m_print import requests import time from datetime import datetime from flask import render_template from flask import redirect from flask import request from flask import session from reportlab.pdfgen import canvas from reportlab.lib.pagesizes import A4 from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase.ttfonts import TTFont from io import BytesIO from app._tools.decorators import auth_required from app._tools.database import DataManager from app._tools.database import SessionManager from app._tools.database import ConfigManager RENDER_TEMPLATE = { "$root$" : "print/print_code_a.html", "$tutor$" : "print/print_code_t.html" } pdfmetrics.registerFont(TTFont('webprint', ConfigManager.get_config()['font-path'])) def watermark_gen(p : canvas.Canvas, config, user, page) -> None: REPLACEMENTS = { "$time$": datetime.now().strftime('%d.%m.%Y %H:%M'), "$team$": getattr(user, 'team', 'Unknown Team'), "$loc$": getattr(user, 'loc', 'Unknown Location'), "$page$": str(page) } wm_format = str(config['print']['watermark']) for key, value in REPLACEMENTS.items(): wm_format = wm_format.replace(key, value) p.setFont("webprint", 13) p.setFillColorRGB(0.5, 0.5, 0.5) p.rotate(45) p.drawString(200, 200, wm_format * 10) p.rotate(-45) @m_print.route('/') @auth_required def print_code(): user = DataManager.get_user(SessionManager.get_session(session["token"]).user_id) render = 'print/print_code.html' if user.team in RENDER_TEMPLATE: render = RENDER_TEMPLATE[user.team] return render_template( f'{render}', user = user ) @m_print.route('/printcode', methods=['POST']) @auth_required def print_proc(): user_text = request.form.get('code') lines = user_text.split('\n') if len(lines) < 4: return render_template("error.html", error = "Код, в котором так мало строк, можно запомнить и без печати :)") user = DataManager.get_user(SessionManager.get_session(session["token"]).user_id) config = ConfigManager.get_config() timedelta = int(time.time()) - user.lastprint_ts timedelta = config['print']['limits']['seconds-per-request'] - timedelta if timedelta > 0: return render_template("error.html", error = f"Пожалуйста, подождите ещё {timedelta} с. перед повторным запросом!") DataManager.edit_user(user.id, "lastprint_ts", int(time.time())) buffer = BytesIO() proc_pdf = canvas.Canvas(buffer, pagesize = A4) width, height = A4 left_margin = 15 top_margin = height - 30 line_height = 15 y = top_margin pages = 1 watermark_gen(proc_pdf, config, user, pages) proc_pdf.setFillColorRGB(0, 0, 0, 1) proc_pdf.setFont("webprint", 9) for line in lines: line = line.replace('\r', '') if y < 30: pages += 1 if (pages > config['print']['limits']['pages-per-request']): return render_template( "error.html", error = f"Достигнут лимит на генерацию в {config['print']['limits']['pages-per-request']} страниц за запрос!" ) proc_pdf.showPage() watermark_gen(proc_pdf, config, user, pages) proc_pdf.setFillColorRGB(0, 0, 0, 1) proc_pdf.setFont("webprint", 9) y = top_margin proc_pdf.drawString(left_margin, y, line) y -= line_height proc_pdf.showPage() proc_pdf.save() buffer.seek(0) proc_pdf = buffer.getvalue() try: DataManager.edit_user( user.id, "pages", user.pages + pages ) response = requests.post( f"http://{config['server']['ip']}:{config['server']['port']}/printfile", files = { 'file' : (f"wp_{user.username}_{user.lastprint_ts}.pdf", proc_pdf) }, data = { 'secret-key' : config['server']['secret'] }, timeout = 10 ) if response.status_code == 200: return redirect("/") else: return render_template( "error.html", error = "Ошибка при отправке PDF файла на печать. Обратитесь к Администратору." ) except Exception as e: return render_template( "error.html", error = f"Ошибка при подключении к серверу печати: {str(e)}" ) @m_print.route('/printpdf', methods=['POST']) @auth_required def print_pdf_proc(): user = DataManager.get_user(SessionManager.get_session(session["token"]).user_id) config = ConfigManager.get_config() if user.team not in RENDER_TEMPLATE: return redirect("/") samples = 1 file = request.files.get('file') if file.filename == '': return render_template("error.html", error = "Не был прикреплён файл!") if 'samples' in request.form: samples = int(request.form.get('samples')) if samples not in range(1, 16): return render_template( "error.html", error = "Допустимый диапазон копий составляет 1..15!" ) DataManager.edit_user(user.id, "lastprint_ts", int(time.time())) try: response = requests.post( f"http://{config['server']['ip']}:{config['server']['port']}/printfile", files = { 'file' : (f"wp_{user.username}_{user.lastprint_ts}.pdf", file) }, data = { 'secret-key' : config['server']['secret'], 'samples' : samples }, timeout = 10 ) if response.status_code == 200: return redirect("/") else: return render_template( "error.html", error = "Ошибка при отправке PDF файла на печать. Обратитесь к Администратору." ) except Exception as e: return render_template( "error.html", error = f"Ошибка при подключении к серверу печати: {str(e)}" )