Compare commits

..

No commits in common. "main" and "0.9" have entirely different histories.
main ... 0.9

8 changed files with 105 additions and 267 deletions

View File

@ -7,7 +7,7 @@ workspace:
steps: steps:
- name: build - name: build
image: git.quertex.com/quertex/docker-win-pyinstaller64:latest image: git.argideli.com/quertex/docker-win-pyinstaller64:latest
pull: always pull: always
commands: commands:
# prepare output directory # prepare output directory
@ -16,7 +16,7 @@ steps:
# add dependancies # add dependancies
- pacman -Syu --noconfirm - pacman -Syu --noconfirm
#- pacman -Sy --noconfirm --needed wget lib32-gnutls libunwind lib32-expat python3 python-pip python-pipenv gcc-fortran base-devel python-numpy python-pandas gcc-libs gnutls wine-staging #- pacman -Sy --noconfirm --needed wget lib32-gnutls libunwind lib32-expat python3 python-pip python-pipenv gcc-fortran base-devel python-numpy python-pandas gcc-libs gnutls wine-staging
- pacman -Sy --noconfirm at-spi2-core gtk3 lib32-gdk-pixbuf2 qt6-base qt6-declarative shiboken6 qt6-3d qt6-charts qt6-connectivity qt6-datavis3d qt6-graphs qt6-httpserver qt6-location qt6-multimedia qt6-networkauth qt6-positioning qt6-quick3d qt6-remoteobjects qt6-scxml qt6-sensors qt6-serialbus qt6-serialport qt6-speech qt6-svg qt6-tools qt6-webchannel qt6-webengine qt6-websockets libxkbcommon lib32-libxkbcommon python-xkbcommon python-cryptography python-pillow python-pycryptodome python-typing_extensions python-build python-flit-core python-installer python-setuptools python-wheel wget lib32-gnutls libunwind lib32-expat python3 python-pip gcc-fortran base-devel gcc-libs gnutls - pacman -Sy --noconfirm at-spi2-core gtk3 lib32-gdk-pixbuf2 qt6-base qt6-declarative shiboken6 qt6-3d qt6-charts qt6-connectivity qt6-datavis3d qt6-graphs qt6-httpserver qt6-location qt6-multimedia qt6-networkauth qt6-positioning qt6-quick3d qt6-remoteobjects qt6-scxml qt6-sensors qt6-serialbus qt6-serialport qt6-speech qt6-svg qt6-tools qt6-webchannel qt6-webengine qt6-websockets libxkbcommon lib32-libxkbcommon python-xkbcommon python-cryptography python-pillow python-pycryptodome python-typing_extensions python-build python-flit-core python-installer python-setuptools python-wheel wget lib32-gnutls libunwind lib32-expat python3 python-pip gcc-fortran base-devel gcc-libs gnutls wine-staging
# linux build # linux build
- cd /drone/src/ - cd /drone/src/
- python --version - python --version
@ -29,7 +29,7 @@ steps:
- pip3 config set global.trusted-host "pypi.org files.pythonhosted.org pypi.python.org" --trusted-host=pypi.python.org --trusted-host=pypi.org --trusted-host=files.pythonhosted.org - pip3 config set global.trusted-host "pypi.org files.pythonhosted.org pypi.python.org" --trusted-host=pypi.python.org --trusted-host=pypi.org --trusted-host=files.pythonhosted.org
- pip3 install --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host files.pythonhosted.org pip setuptools - pip3 install --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host files.pythonhosted.org pip setuptools
- pip3 install --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host files.pythonhosted.org --ignore-installed -r requirements.txt - pip3 install --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host files.pythonhosted.org --ignore-installed -r requirements.txt
- pyinstaller --onefile --copy-metadata msoffice2pdf --collect-submodules --name akmi-utils.bin -y --distpath /drone/src/out/ /drone/src/widget.py - pyinstaller --onefile --name akmi-utils.bin -y --distpath /drone/src/out/ /drone/src/widget.py
- deactivate - deactivate
- cp -v out/akmi-utils.bin dist/ - cp -v out/akmi-utils.bin dist/
# clean up # clean up
@ -37,15 +37,15 @@ steps:
- rm -rf /drone/src/out - rm -rf /drone/src/out
- mkdir -p /drone/src/out/ - mkdir -p /drone/src/out/
# windows build # windows build
- wine64 c:/python/python.exe -m pip config --user set global.progress_bar off - wine c:/python/python.exe -m pip config --user set global.progress_bar off
- wine64 c:/python/python.exe -m pip install --prefer-binary -r z:/drone/src/requirements.txt - wine c:/python/python.exe -m pip install --prefer-binary -r z:/drone/src/requirements.txt
- wine64 c:/python/Scripts/pyinstaller.exe --onefile --copy-metadata msoffice2pdf --collect-submodules --name akmi-utils -y --distpath z:/drone/src/out z:/drone/src/widget.py - wine c:/python/Scripts/pyinstaller.exe --onefile --name akmi-utils -y --distpath z:/drone/src/out z:/drone/src/widget.py
- cp -v out/akmi-utils.exe dist/ - cp -v out/akmi-utils.exe dist/
- name: gitea_release - name: gitea_release
image: plugins/gitea-release image: plugins/gitea-release
settings: settings:
base_url: https://git.quertex.com base_url: https://git.argideli.com
api_key: api_key:
from_secret: gitea_token from_secret: gitea_token
files: /drone/src/dist/* files: /drone/src/dist/*

0
=6.7.2, Normal file
View File

84
form.ui
View File

@ -9,8 +9,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>706</width> <width>742</width>
<height>534</height> <height>336</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -26,13 +26,13 @@
</rect> </rect>
</property> </property>
<property name="text"> <property name="text">
<string>Επιλογή δεδομένων Excel</string> <string>Επιλογή Αρχείου CSV</string>
</property> </property>
</widget> </widget>
<widget class="QLabel" name="label"> <widget class="QLabel" name="label">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>140</x> <x>150</x>
<y>20</y> <y>20</y>
<width>61</width> <width>61</width>
<height>61</height> <height>61</height>
@ -51,7 +51,7 @@
<widget class="QLabel" name="label_2"> <widget class="QLabel" name="label_2">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>230</x> <x>240</x>
<y>10</y> <y>10</y>
<width>431</width> <width>431</width>
<height>81</height> <height>81</height>
@ -83,7 +83,7 @@
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="text"> <property name="text">
<string>Επιλέξτε το αρχείο δεδομένων σε μορφή Excel</string> <string>Επιλέξτε το αρχείο δεδομένων σε μορφή .csv</string>
</property> </property>
</widget> </widget>
<widget class="QPushButton" name="create_button"> <widget class="QPushButton" name="create_button">
@ -92,14 +92,14 @@
</property> </property>
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>480</x> <x>310</x>
<y>250</y> <y>290</y>
<width>211</width> <width>111</width>
<height>61</height> <height>34</height>
</rect> </rect>
</property> </property>
<property name="text"> <property name="text">
<string>Δημιουργία πιστοποιητικών</string> <string>Δημιουργία pdf</string>
</property> </property>
</widget> </widget>
<widget class="QPushButton" name="file_template"> <widget class="QPushButton" name="file_template">
@ -112,7 +112,7 @@
</rect> </rect>
</property> </property>
<property name="text"> <property name="text">
<string>Επιλογή προσχέδιου Word</string> <string>Επιλογή Αρχείου PDF</string>
</property> </property>
</widget> </widget>
<widget class="QLabel" name="label_4"> <widget class="QLabel" name="label_4">
@ -131,65 +131,7 @@
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="text"> <property name="text">
<string>Επιλέξτε το αρχείο του προτύπου (Word)</string> <string>Επιλέξτε το PDF αρχείο του προτύπου</string>
</property>
</widget>
<widget class="QPlainTextEdit" name="oauth2_token">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>20</x>
<y>320</y>
<width>341</width>
<height>41</height>
</rect>
</property>
</widget>
<widget class="QCheckBox" name="enable_email">
<property name="geometry">
<rect>
<x>20</x>
<y>260</y>
<width>131</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>Αποστολή email</string>
</property>
</widget>
<widget class="QLabel" name="label_5">
<property name="geometry">
<rect>
<x>120</x>
<y>290</y>
<width>131</width>
<height>31</height>
</rect>
</property>
<property name="whatsThis">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Το αρχείο που έχουμε επιλέξει&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="text">
<string>Microsoft OAuth2 Token</string>
</property>
</widget>
<widget class="QPlainTextEdit" name="log_output">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>10</x>
<y>390</y>
<width>681</width>
<height>131</height>
</rect>
</property> </property>
</widget> </widget>
</widget> </widget>

View File

@ -1,20 +0,0 @@
chardet==5.2.0
pillow==10.4.0
PyPDF2==3.0.1
PySide6>=6.7.2
PySide6_Addons>=6.7.2
PySide6_Essentials>=6.7.2
python-dateutil==2.9.0.post0
pytz==2024.1
reportlab==4.2.2
shiboken6>=6.7.2
six==1.16.0
tzdata==2024.1
altgraph==0.17.4
packaging==24.1
pyinstaller==6.9.0
pyinstaller-hooks-contrib==2024.7
setuptools==70.3.0
python-docx==1.1.2
python-docx==1.1.2
msoffice2pdf==1.0.0

View File

@ -1,30 +1,17 @@
altgraph==0.17.4
certifi==2024.12.14
chardet==5.2.0 chardet==5.2.0
charset-normalizer==3.4.1
et_xmlfile==2.0.0
idna==3.10
lxml==5.3.0
msoffice2pdf>=0.9.0
numpy==2.2.1
openpyxl==3.1.5
packaging==24.1
pandas==2.2.3
pillow==10.4.0 pillow==10.4.0
pyinstaller==6.10.0
pyinstaller-hooks-contrib==2024.11
PyPDF2==3.0.1 PyPDF2==3.0.1
PySide6==6.8.1 PySide6>=6.7.2
PySide6_Addons==6.8.1 PySide6_Addons>=6.7.2
PySide6_Essentials==6.8.1 PySide6_Essentials>=6.7.2
python-dateutil==2.9.0.post0 python-dateutil==2.9.0.post0
python-docx==1.1.2
pytz==2024.1 pytz==2024.1
reportlab==4.2.2 reportlab==4.2.2
requests==2.32.3 shiboken6>=6.7.2
setuptools==70.3.0
shiboken6==6.8.1
six==1.16.0 six==1.16.0
typing_extensions==4.12.2
tzdata==2024.1 tzdata==2024.1
urllib3==2.3.0 altgraph==0.17.4
packaging==24.1
pyinstaller==6.9.0
pyinstaller-hooks-contrib==2024.7
setuptools==70.3.0

View File

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
################################################################################ ################################################################################
## Form generated from reading UI file 'formrmZXPO.ui' ## Form generated from reading UI file 'form.ui'
## ##
## Created by: Qt User Interface Compiler version 6.8.1 ## Created by: Qt User Interface Compiler version 6.7.2
## ##
## WARNING! All changes made in this file will be lost when recompiling UI file! ## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################ ################################################################################
@ -15,27 +15,27 @@ from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
QFont, QFontDatabase, QGradient, QIcon, QFont, QFontDatabase, QGradient, QIcon,
QImage, QKeySequence, QLinearGradient, QPainter, QImage, QKeySequence, QLinearGradient, QPainter,
QPalette, QPixmap, QRadialGradient, QTransform) QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QApplication, QCheckBox, QLabel, QPlainTextEdit, from PySide6.QtWidgets import (QApplication, QLabel, QPushButton, QSizePolicy,
QPushButton, QSizePolicy, QWidget) QWidget)
import resources_rc import rc_resources
class Ui_Widget(object): class Ui_Widget(object):
def setupUi(self, Widget): def setupUi(self, Widget):
if not Widget.objectName(): if not Widget.objectName():
Widget.setObjectName(u"Widget") Widget.setObjectName(u"Widget")
Widget.setEnabled(True) Widget.setEnabled(True)
Widget.resize(706, 534) Widget.resize(742, 336)
self.file_selector = QPushButton(Widget) self.file_selector = QPushButton(Widget)
self.file_selector.setObjectName(u"file_selector") self.file_selector.setObjectName(u"file_selector")
self.file_selector.setGeometry(QRect(20, 140, 151, 34)) self.file_selector.setGeometry(QRect(20, 140, 151, 34))
self.label = QLabel(Widget) self.label = QLabel(Widget)
self.label.setObjectName(u"label") self.label.setObjectName(u"label")
self.label.setGeometry(QRect(140, 20, 61, 61)) self.label.setGeometry(QRect(150, 20, 61, 61))
self.label.setPixmap(QPixmap(u":/images/logo.png")) self.label.setPixmap(QPixmap(u":/images/logo.png"))
self.label.setScaledContents(True) self.label.setScaledContents(True)
self.label_2 = QLabel(Widget) self.label_2 = QLabel(Widget)
self.label_2.setObjectName(u"label_2") self.label_2.setObjectName(u"label_2")
self.label_2.setGeometry(QRect(230, 10, 431, 81)) self.label_2.setGeometry(QRect(240, 10, 431, 81))
font = QFont() font = QFont()
font.setPointSize(26) font.setPointSize(26)
font.setBold(True) font.setBold(True)
@ -47,7 +47,7 @@ class Ui_Widget(object):
self.create_button = QPushButton(Widget) self.create_button = QPushButton(Widget)
self.create_button.setObjectName(u"create_button") self.create_button.setObjectName(u"create_button")
self.create_button.setEnabled(False) self.create_button.setEnabled(False)
self.create_button.setGeometry(QRect(480, 250, 211, 61)) self.create_button.setGeometry(QRect(310, 290, 111, 34))
self.file_template = QPushButton(Widget) self.file_template = QPushButton(Widget)
self.file_template.setObjectName(u"file_template") self.file_template.setObjectName(u"file_template")
self.file_template.setGeometry(QRect(20, 190, 151, 34)) self.file_template.setGeometry(QRect(20, 190, 151, 34))
@ -55,21 +55,6 @@ class Ui_Widget(object):
self.label_4.setObjectName(u"label_4") self.label_4.setObjectName(u"label_4")
self.label_4.setGeometry(QRect(180, 190, 561, 31)) self.label_4.setGeometry(QRect(180, 190, 561, 31))
self.label_4.setAutoFillBackground(False) self.label_4.setAutoFillBackground(False)
self.oauth2_token = QPlainTextEdit(Widget)
self.oauth2_token.setObjectName(u"oauth2_token")
self.oauth2_token.setEnabled(False)
self.oauth2_token.setGeometry(QRect(20, 320, 341, 41))
self.enable_email = QCheckBox(Widget)
self.enable_email.setObjectName(u"enable_email")
self.enable_email.setGeometry(QRect(20, 260, 131, 20))
self.label_5 = QLabel(Widget)
self.label_5.setObjectName(u"label_5")
self.label_5.setGeometry(QRect(120, 290, 131, 31))
self.label_5.setAutoFillBackground(False)
self.log_output = QPlainTextEdit(Widget)
self.log_output.setObjectName(u"log_output")
self.log_output.setEnabled(False)
self.log_output.setGeometry(QRect(10, 390, 681, 131))
self.retranslateUi(Widget) self.retranslateUi(Widget)
@ -78,23 +63,18 @@ class Ui_Widget(object):
def retranslateUi(self, Widget): def retranslateUi(self, Widget):
Widget.setWindowTitle(QCoreApplication.translate("Widget", u"Widget", None)) Widget.setWindowTitle(QCoreApplication.translate("Widget", u"Widget", None))
self.file_selector.setText(QCoreApplication.translate("Widget", u"\u0395\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03c9\u03bd Excel", None)) self.file_selector.setText(QCoreApplication.translate("Widget", u"\u0395\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \u0391\u03c1\u03c7\u03b5\u03af\u03bf\u03c5 CSV", None))
self.label.setText("") self.label.setText("")
self.label_2.setText(QCoreApplication.translate("Widget", u"AKMI Certificate creator", None)) self.label_2.setText(QCoreApplication.translate("Widget", u"AKMI Certificate creator", None))
#if QT_CONFIG(whatsthis) #if QT_CONFIG(whatsthis)
self.label_3.setWhatsThis(QCoreApplication.translate("Widget", u"<html><head/><body><p>\u03a4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \u03c0\u03bf\u03c5 \u03ad\u03c7\u03bf\u03c5\u03bc\u03b5 \u03b5\u03c0\u03b9\u03bb\u03ad\u03be\u03b5\u03b9</p></body></html>", None)) self.label_3.setWhatsThis(QCoreApplication.translate("Widget", u"<html><head/><body><p>\u03a4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \u03c0\u03bf\u03c5 \u03ad\u03c7\u03bf\u03c5\u03bc\u03b5 \u03b5\u03c0\u03b9\u03bb\u03ad\u03be\u03b5\u03b9</p></body></html>", None))
#endif // QT_CONFIG(whatsthis) #endif // QT_CONFIG(whatsthis)
self.label_3.setText(QCoreApplication.translate("Widget", u"\u0395\u03c0\u03b9\u03bb\u03ad\u03be\u03c4\u03b5 \u03c4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03c9\u03bd \u03c3\u03b5 \u03bc\u03bf\u03c1\u03c6\u03ae Excel", None)) self.label_3.setText(QCoreApplication.translate("Widget", u"\u0395\u03c0\u03b9\u03bb\u03ad\u03be\u03c4\u03b5 \u03c4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03c9\u03bd \u03c3\u03b5 \u03bc\u03bf\u03c1\u03c6\u03ae .csv", None))
self.create_button.setText(QCoreApplication.translate("Widget", u"\u0394\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03af\u03b1 \u03c0\u03b9\u03c3\u03c4\u03bf\u03c0\u03bf\u03b9\u03b7\u03c4\u03b9\u03ba\u03ce\u03bd", None)) self.create_button.setText(QCoreApplication.translate("Widget", u"\u0394\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03af\u03b1 pdf", None))
self.file_template.setText(QCoreApplication.translate("Widget", u"\u0395\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \u03c0\u03c1\u03bf\u03c3\u03c7\u03ad\u03b4\u03b9\u03bf\u03c5 Word", None)) self.file_template.setText(QCoreApplication.translate("Widget", u"\u0395\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \u0391\u03c1\u03c7\u03b5\u03af\u03bf\u03c5 PDF", None))
#if QT_CONFIG(whatsthis) #if QT_CONFIG(whatsthis)
self.label_4.setWhatsThis(QCoreApplication.translate("Widget", u"<html><head/><body><p>\u03a4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \u03c0\u03bf\u03c5 \u03ad\u03c7\u03bf\u03c5\u03bc\u03b5 \u03b5\u03c0\u03b9\u03bb\u03ad\u03be\u03b5\u03b9</p></body></html>", None)) self.label_4.setWhatsThis(QCoreApplication.translate("Widget", u"<html><head/><body><p>\u03a4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \u03c0\u03bf\u03c5 \u03ad\u03c7\u03bf\u03c5\u03bc\u03b5 \u03b5\u03c0\u03b9\u03bb\u03ad\u03be\u03b5\u03b9</p></body></html>", None))
#endif // QT_CONFIG(whatsthis) #endif // QT_CONFIG(whatsthis)
self.label_4.setText(QCoreApplication.translate("Widget", u"\u0395\u03c0\u03b9\u03bb\u03ad\u03be\u03c4\u03b5 \u03c4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \u03c4\u03bf\u03c5 \u03c0\u03c1\u03bf\u03c4\u03cd\u03c0\u03bf\u03c5 (Word)", None)) self.label_4.setText(QCoreApplication.translate("Widget", u"\u0395\u03c0\u03b9\u03bb\u03ad\u03be\u03c4\u03b5 \u03c4\u03bf PDF \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \u03c4\u03bf\u03c5 \u03c0\u03c1\u03bf\u03c4\u03cd\u03c0\u03bf\u03c5", None))
self.enable_email.setText(QCoreApplication.translate("Widget", u"\u0391\u03c0\u03bf\u03c3\u03c4\u03bf\u03bb\u03ae email", None))
#if QT_CONFIG(whatsthis)
self.label_5.setWhatsThis(QCoreApplication.translate("Widget", u"<html><head/><body><p>\u03a4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \u03c0\u03bf\u03c5 \u03ad\u03c7\u03bf\u03c5\u03bc\u03b5 \u03b5\u03c0\u03b9\u03bb\u03ad\u03be\u03b5\u03b9</p></body></html>", None))
#endif // QT_CONFIG(whatsthis)
self.label_5.setText(QCoreApplication.translate("Widget", u"Microsoft OAuth2 Token", None))
# retranslateUi # retranslateUi

175
widget.py
View File

@ -2,22 +2,23 @@
import os import os
import io import io
import sys import sys
import csv
import shutil import shutil
import base64 from PyPDF2 import PdfReader, PdfWriter
from docx import Document from reportlab.pdfgen import canvas
from msoffice2pdf import convert from reportlab.lib.pagesizes import A4
import pandas as pd from reportlab.pdfbase import pdfmetrics
import requests from reportlab.pdfbase.ttfonts import TTFont
from PySide6.QtWidgets import QApplication, QWidget, QFileDialog from PySide6.QtWidgets import QApplication, QWidget, QFileDialog
from PySide6.QtCore import QFile, QIODevice from PySide6.QtCore import QFile, QIODevice
# NOTE: # Important:
# You need to run the following command to generate the ui_form.py file # You need to run the following command to generate the ui_form.py file
# pyside6-uic form.ui -o ui_form.py, or # pyside6-uic form.ui -o ui_form.py, or
# pyside2-uic form.ui -o ui_form.py # pyside2-uic form.ui -o ui_form.py
from ui_form import Ui_Widget from ui_form import Ui_Widget
import resources_rc import rc_resources
class Widget(QWidget): class Widget(QWidget):
@ -29,7 +30,6 @@ class Widget(QWidget):
self.ui.file_selector.clicked.connect(self.file_selector) self.ui.file_selector.clicked.connect(self.file_selector)
self.ui.file_template.clicked.connect(self.file_template) self.ui.file_template.clicked.connect(self.file_template)
self.ui.create_button.clicked.connect(self.create_button) self.ui.create_button.clicked.connect(self.create_button)
self.ui.enable_email.clicked.connect(self.enable_token)
self.selected_file = False self.selected_file = False
self.selected_template = False self.selected_template = False
self.filepath_template = "" self.filepath_template = ""
@ -49,141 +49,90 @@ class Widget(QWidget):
if self.selected_file and self.selected_template: if self.selected_file and self.selected_template:
self.ui.create_button.setEnabled(True) self.ui.create_button.setEnabled(True)
def enable_token(self):
print(self.ui.oauth2_token.isEnabled())
if self.ui.oauth2_token.isEnabled():
self.ui.oauth2_token.setEnabled(False)
else:
self.ui.oauth2_token.setEnabled(True)
def file_selector(self): def file_selector(self):
self.filepath = QFileDialog.getOpenFileName(self, "Επιλογή Αρχείου") self.filepath = QFileDialog.getOpenFileName(self, "Επιλογή Αρχείου")
if self.filepath[0]: if self.filepath[0]:
ext = os.path.splitext(self.filepath[0])[-1].lower() ext = os.path.splitext(self.filepath[0])[-1].lower()
if ext in [".xlsx", ".xls"]: if ext != ".csv":
self.ui.log_output.appendPlainText("Επιλέχθηκε το αρχείο δεδομενων: {}".format(self.filepath[0])) self.ui.label_3.setText("Το αρχείο πρέπει να είναι της μορφής .csv")
self.selected_file = False
else:
self.ui.label_3.setText("{}".format(self.filepath[0])) self.ui.label_3.setText("{}".format(self.filepath[0]))
self.selected_file = True self.selected_file = True
self.in_file = self.filepath[0] self.in_file = self.filepath[0]
self.file_path = os.path.dirname(self.filepath[0]) self.file_path = os.path.dirname(self.filepath[0])
else:
self.ui.label_3.setText("Το αρχείο πρέπει να είναι της μορφής .xlsx ή .xls")
self.selected_file = False
self.enable_create() self.enable_create()
def file_template(self): def file_template(self):
self.filepath_template = QFileDialog.getOpenFileName(self, "Επιλογή Αρχείου") self.filepath_template = QFileDialog.getOpenFileName(self, "Επιλογή Αρχείου")
if self.filepath_template[0]: if self.filepath_template[0]:
ext = os.path.splitext(self.filepath_template[0])[-1].lower() ext = os.path.splitext(self.filepath_template[0])[-1].lower()
if ext in [".docx", ".doc"]: if ext != ".pdf":
self.ui.log_output.appendPlainText("Επιλέχθηκε το προσχέδιο: {}".format(self.filepath_template[0])) self.ui.label_4.setText("Το αρχείο πρέπει να είναι της μορφής .pdf")
self.selected_template = False
else:
self.ui.label_4.setText("{}".format(self.filepath_template[0])) self.ui.label_4.setText("{}".format(self.filepath_template[0]))
self.selected_template = True self.selected_template = True
self.in_template = self.filepath_template[0] self.in_template = self.filepath_template[0]
self.template_path = os.path.dirname(self.filepath_template[0]) self.template_path = os.path.dirname(self.filepath_template[0])
else:
self.ui.label_4.setText("Το αρχείο πρέπει να είναι της μορφής .docx ή .doc")
self.selected_template = False
self.enable_create() self.enable_create()
def create_button(self): def create_button(self):
df = pd.read_excel("{}".format(self.filepath[0])) with open(self.in_file, encoding='utf-8') as fin:
doc = Document("{}".format(self.filepath_template[0])) csvin = csv.DictReader(fin)
self.create_certificates(df, doc) self.create_certificates(csvin)
def replace_text_styled(self, paragraph, key, value): def create_certificates(self, csv_dict):
if key in paragraph.text: count = 0
inline = paragraph.runs shutil.copyfile(
for i in range(len(inline)): "{}".format(self.filepath_template[0]),
if key in inline[i].text: "{}/RESULT.pdf".format(self.file_path),
text = inline[i].text.replace(key, value) )
inline[i].text = text for in_row in csv_dict:
count += 1
packet = io.BytesIO()
pdfmetrics.registerFont(
TTFont("NotoMedium", self.qrc_to_bytes(":/FONTS/NotoSans-Medium.ttf"))
)
pdfmetrics.registerFont(
TTFont(
"NotoSemiMedium",
self.qrc_to_bytes(":/FONTS/NotoSans-SemiCondensedMedium.ttf"),
)
)
# pdfmetrics.registerFont(TTFont('NotoRegular', '{}/NotoSans-Regular.ttf'.format(self.font_dir)))
# pdfmetrics.registerFont(TTFont('NotoBold', '{}/NotoSans-Bold.ttf'.format(self.font_dir)))
# pdfmetrics.registerFont(TTFont('NotoSemi', '{}/NotoSans-SemiCondensed.ttf'.format(self.font_dir)))
# pdfmetrics.registerFont(TTFont('NotoSemiMedium', '{}/NotoSans-SemiCondensedMedium.ttf'.format(self.font_dir)))
def send_email(self, data_row, attachement): can = canvas.Canvas(packet, pagesize=A4)
endpoint = "https://graph.microsoft.com/v1.0/me/sendMail" can.setFont("NotoMedium", 22)
headers = { x = can._pagesize[0] / 2
"Authorization": "{}".format(self.ui.oauth2_token.toPlainText()), can.drawString(x, 315, "{} {}".format(in_row["SURNAME"], in_row["NAME"]))
"Content-Type": "application/json" can.setFont("NotoSemiMedium", 18)
} can.drawString(x, 250, "{}".format(in_row["DEPARTMENT"]))
can.save()
cert_file = open("./OUTPUT/{}".format(attachement), "rb")
data = cert_file.read()
email_data = {
"message": {
"subject": "ΠΙΣΤΟΠΟΙΗΤΙΚΟ ΠΑΡΑΚΟΛΟΥΘΗΣΗΣ ΣΕΜΙΝΑΡΙΟΥ: {}".format(data_row['ΘΕΜΑ ΣΕΜΙΝΑΡΙΟΥ']),
"body": {
"contentType": "Text",
"content": "Χαίρετε,\nΣτο παρόν email επισυνάπτεται το πιστοποιητικό παρακολούθησης του σεμιναρίου {} που παρακολουθήσατε στη δομή {} το μήνα {}".format(data_row['ΘΕΜΑ ΣΕΜΙΝΑΡΙΟΥ'], data_row['CAMPUS'], data_row['DATE'])
},
"toRecipients": [
{
"emailAddress": {
"address": "{}".format(data_row['EMAIL'])
}
}
],
"attachments": [
{
"@odata.type": "#microsoft.graph.fileAttachment",
"name": "{}".format(attachement),
"contentType": "application/pdf",
"contentBytes": base64.b64encode(data).decode('utf-8')
}
]
},
"saveToSentItems": "true"
}
response = requests.post(endpoint, headers=headers, json=email_data) packet.seek(0)
cert_file.close() new_pdf = PdfReader(packet)
if response.status_code == 202: existing_pdf = PdfReader(open("{}/RESULT.pdf".format(self.file_path), "rb"))
self.ui.log_output.appendPlainText("Email στάλθηκε: {}".format(data_row['EMAIL'])) output = PdfWriter()
else:
self.ui.log_output.appendPlainText(f"Αποτυχία αποστολής. Status code: {response.status_code}, Error: {response.text}")
def create_certificates(self, in_df, in_doc):
if not os.path.exists("./OUTPUT"):
os.makedirs("./OUTPUT")
for index, row in in_df.iterrows():
if row['ΟΝΟΜΑΤΕΠΩΝΥΜΟ'] in ['EMPTY', None] or pd.isna(row['ΟΝΟΜΑΤΕΠΩΝΥΜΟ']):
student_name = "{} {} του {}".format(row['ΕΠΩΝΥΜΟ'],row['ΟΝΟΜΑ'], row['ΠΑΤΡΩΝΥΜΟ'])
else:
student_name = "{} {} του {}".format(row['ΟΝΟΜΑΤΕΠΩΝΥΜΟ'], row['ΠΑΤΡΩΝΥΜΟ'])
mock_data = { for page in existing_pdf.pages:
'ΟΝΟΜΑΤΕΠΩΝΥΜΟ': student_name, output.add_page(page)
'ΘΕΜΑΕΜΙΝΑΡΙΟΥ': row['ΘΕΜΑ ΣΕΜΙΝΑΡΙΟΥ'], page = existing_pdf.pages[0]
'DATE': row['DATE'], page.merge_page(new_pdf.pages[0])
'CAMPUS': row['CAMPUS'], output.add_page(page)
'EMAIL': row['EMAIL']
}
for paragraph in in_doc.paragraphs: outputStream = open("{}/RESULT.pdf".format(self.file_path), "wb")
for key in mock_data: output.write(outputStream)
self.replace_text_styled(paragraph, key, mock_data[key]) outputStream.close()
if os.path.exists("./edit.docx"):
os.remove("./edit.docx")
in_doc.save('edit.docx')
output = convert(source="edit.docx", output_dir="./", soft=0)
fname = output.rsplit('/')[-1]
shutil.move("./{}".format(fname), "./OUTPUT/{}.pdf".format(student_name.replace(" ", "_")))
print("PDF created: {}.pdf".format(student_name.replace(" ", "_")))
if self.ui.enable_email.isChecked():
self.send_email(row, attachement="{}.pdf".format(student_name.replace(" ", "_")))
self.ui.label_4.setText( self.ui.label_4.setText(
"Τα αρχείο PDF δημιουργήθηκαν εντός του φακέλου OUTPUT." "Το αρχείο PDF δημιουργήθηκε εντός του φακέλου του .csv"
) )
self.ui.create_button.setEnabled(False) self.ui.create_button.setEnabled(False)
if os.path.exists("./edit.docx"):
os.remove("./edit.docx")
if __name__ == "__main__": if __name__ == "__main__":
app = QApplication(sys.argv) app = QApplication(sys.argv)