commit 409c60610a42bd51d8f7e53ba483918a2fe7dd5e Author: Viktoria Polyakova Date: Sat Mar 29 17:13:06 2025 +0300 Init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1f275eb --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +dist +build +.vscode +.venv +__pycache__ diff --git a/SignGenerator.spec b/SignGenerator.spec new file mode 100644 index 0000000..9e16978 --- /dev/null +++ b/SignGenerator.spec @@ -0,0 +1,39 @@ +# -*- mode: python ; coding: utf-8 -*- + + +a = Analysis( + ['main.py'], + pathex=[], + binaries=[], + datas=[], + hiddenimports=[], + hookspath=[], + hooksconfig={}, + runtime_hooks=[], + excludes=[], + noarchive=False, + optimize=0, +) +pyz = PYZ(a.pure) + +exe = EXE( + pyz, + a.scripts, + a.binaries, + a.datas, + [], + name='SignGenerator', + debug=False, + bootloader_ignore_signals=False, + strip=False, + upx=True, + upx_exclude=[], + runtime_tmpdir=None, + console=False, + disable_windowed_traceback=False, + argv_emulation=False, + target_arch=None, + codesign_identity=None, + entitlements_file=None, + icon=['ui/sign.ico'], +) diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..e2173b6 --- /dev/null +++ b/build.sh @@ -0,0 +1 @@ +python -m PyInstaller --onefile -n "SignGenerator" --windowed --icon=ui/sign.ico main.py \ No newline at end of file diff --git a/config.ini b/config.ini new file mode 100644 index 0000000..1e6d8c9 --- /dev/null +++ b/config.ini @@ -0,0 +1,10 @@ +[General] +firstname = Сергей +lastname = Гусенков +jobtitle = Руководитель отдела продаж +gtsphone = +7 (499) 229-60-00 +gtsphoneadd = 303 +mobilephone = +7 (993) 666-52-51 +logo = logo.png +template = template.html + diff --git a/config.py b/config.py new file mode 100644 index 0000000..91ed493 --- /dev/null +++ b/config.py @@ -0,0 +1,29 @@ +from configparser import ConfigParser +from os.path import exists + +cfg = ConfigParser() +cfg['General'] = {} +cfg['General']['FirstName'] = '' +cfg['General']['LastName'] = '' +cfg['General']['JobTitle'] = '' +cfg['General']['GTSPhone'] = '' +cfg['General']['GTSPhoneAdd'] = '' +cfg['General']['MobilePhone'] = '' +cfg['General']['Logo'] = 'logo.png' +cfg['General']['Template'] = 'template.html' + + +def save_config(cfg): + with open('config.ini', 'w', encoding='utf-8') as configfile: + cfg.write(configfile) + + +def load_config(): + if not exists('config.ini'): + with open('config.ini', 'w', encoding='utf-8') as configfile: + cfg.write(configfile) + else: + cfg.read('config.ini', encoding='utf-8') + +load_config() + diff --git a/logo.png b/logo.png new file mode 100644 index 0000000..e5ed3cc Binary files /dev/null and b/logo.png differ diff --git a/main.py b/main.py new file mode 100644 index 0000000..4856438 --- /dev/null +++ b/main.py @@ -0,0 +1,136 @@ +import sys +from PyQt5 import uic +from PyQt5.QtWidgets import QApplication, QMainWindow, QDesktopWidget, QMessageBox, QFileDialog +from PyQt5.QtCore import Qt +from PyQt5.QtGui import QIcon +from config import * +from base64 import b64encode +from os.path import exists + + +class MainForm(QMainWindow): + def __init__(self, cfg): + super().__init__() + uic.loadUi('ui/MainForm.ui', self) + self.setWindowIcon(QIcon('ui/sign.ico')) + + self.cfg = cfg + self.fname_txt.setText(cfg['General']['firstname']) + self.lname_txt.setText(cfg['General']['lastname']) + self.jobtitle_txt.setText(cfg['General']['jobtitle']) + self.mgts_txt.setText(cfg['General']['gtsphone']) + self.mgtsadd_txt.setText(cfg['General']['gtsphoneadd']) + self.mobile_txt.setText(cfg['General']['mobilephone']) + self.template_txt.setText(cfg['General']['template']) + self.logo_txt.setText(cfg['General']['logo']) + + self.selecttemplate_btn.clicked.connect(self.selecttemplate_btn_clicked) + self.selectlogo_btn.clicked.connect(self.selectlogo_btn_clicked) + self.generate_btn.clicked.connect(self.generate_btn_clicked) + self.copy_btn.clicked.connect(self.copy_btn_clicked) + + + def selecttemplate_btn_clicked(self): + tmpl = QFileDialog.getOpenFileName(self, 'Выбрать файл шаблона', '', filter='Шаблон HTML (*.html)')[0] + if tmpl: + self.template_txt.setText(tmpl) + self.template_txt.setFocus() + + + def selectlogo_btn_clicked(self): + logo = QFileDialog.getOpenFileName(self, 'Выбрать файл логотипа', '', filter='Логотип PNG (*.png)')[0] + if logo: + self.logo_txt.setText(logo) + self.logo_txt.setFocus() + + + def generate_btn_clicked(self): + fname = self.fname_txt.text() + lname = self.lname_txt.text() + jobtitle = self.jobtitle_txt.text() + if self.mgts_txt.text() == '+7 () --': + mgts = '' + else: + mgts = self.mgts_txt.text() + mgtsadd = self.mgtsadd_txt.text() + if self.mobile_txt.text() == '+7 () --': + mobile = '' + else: + mobile = self.mobile_txt.text() + template = self.template_txt.text() + logo = self.logo_txt.text() + + username = fname + ' ' + lname + + if not exists(template): + alrt = QMessageBox(self) + alrt.setWindowIcon(self.windowIcon()) + alrt.setWindowTitle('Ошибка') + alrt.setText('Не найден шаблон!') + alrt.setStandardButtons(QMessageBox.Ok) + alrt.setIcon(QMessageBox.Warning) + alrt.exec_() + return + + with open(template, 'r', encoding='utf-8') as f: + text = f.read() + + if not exists(logo): + alrt = QMessageBox(self) + alrt.setWindowIcon(self.windowIcon()) + alrt.setWindowTitle('Ошибка') + alrt.setText('Не найден логотип!') + alrt.setStandardButtons(QMessageBox.Ok) + alrt.setIcon(QMessageBox.Warning) + alrt.exec_() + return + + with open(logo, 'rb') as f: + logo_b64 = 'data:image/png;base64, ' + str(b64encode(f.read()))[2:-1] + + workphone = mgts + if mgtsadd: + workphone += ' доб. ' + mgtsadd + + text = text.format(username=username, logo=logo_b64, jobtitle=jobtitle, mgts=workphone, mobile=mobile) + self.view_txt.setHtml(text) + self.html_txt.setPlainText(text) + + cfg['General']['firstname'] = fname + cfg['General']['lastname'] = lname + cfg['General']['jobtitle'] = jobtitle + cfg['General']['gtsphone'] = mgts + cfg['General']['gtsphoneadd'] = mgtsadd + cfg['General']['mobilephone'] = mobile + cfg['General']['template'] = template + cfg['General']['logo'] = logo + + save_config(cfg) + + def copy_btn_clicked(self): + self.html_txt.selectAll() + self.html_txt.copy() + alrt = QMessageBox(self) + alrt.setWindowIcon(self.windowIcon()) + alrt.setWindowTitle('Сообщение') + alrt.setText('Текст скопирован!') + alrt.setStandardButtons(QMessageBox.Ok) + alrt.setIcon(QMessageBox.Information) + alrt.exec_() + + + def center(self): + qr = self.frameGeometry() + cp = QDesktopWidget().availableGeometry().center() + qr.moveCenter(cp) + self.move(qr.topLeft()) + + +if __name__ == '__main__': + app = QApplication(sys.argv) + ex = MainForm(cfg) + ex.setWindowFlags(Qt.WindowCloseButtonHint | Qt.WindowMinimizeButtonHint) + ex.setFixedSize(680, 760) + ex.center() + ex.show() + sys.exit(app.exec_()) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..4b5a780 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,9 @@ +altgraph==0.17.4 +configparser==7.2.0 +packaging==24.2 +pyinstaller==6.12.0 +pyinstaller-hooks-contrib==2025.2 +PyQt5==5.15.11 +PyQt5-Qt5==5.15.16 +PyQt5_sip==12.17.0 +setuptools==78.1.0 diff --git a/template.html b/template.html new file mode 100644 index 0000000..9a29858 --- /dev/null +++ b/template.html @@ -0,0 +1,11 @@ +С уважением,
+{username}
+{jobtitle}
+
+Т.: {mgts}
+М.: {mobile}
+www.silart.com
+
+Используем систему электронного документооборота (ЭДО).
+Система Сбис. Оператор ЭДО Компания ТЕНЗОР.
+Наш ID 2BEc53781dc83984882a910c2486b6122a7 \ No newline at end of file diff --git a/ui/MainForm.ui b/ui/MainForm.ui new file mode 100644 index 0000000..d42e250 --- /dev/null +++ b/ui/MainForm.ui @@ -0,0 +1,322 @@ + + + ИП Полякова Виктория Валерьевна + MainWindow + + + + 0 + 0 + 680 + 760 + + + + + 0 + 0 + + + + Генератор подписи + + + + + + 20 + 530 + 641 + 171 + + + + + + + 20 + 260 + 641 + 261 + + + + + 100 + 100 + + + + true + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css"> +p, li { white-space: pre-wrap; } +hr { height: 1px; border-width: 0; } +li.unchecked::marker { content: "\2610"; } +li.checked::marker { content: "\2612"; } +</style></head><body style=" font-family:'Cantarell'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + + + + + 20 + 23 + 641 + 232 + + + + + + + 10 + + + + + + 0 + 0 + + + + Имя: + + + + + + + + + + + 0 + 0 + + + + Фамилия: + + + + + + + + + + + + 10 + + + + + + 0 + 0 + + + + Должность: + + + + + + + + + + + + 10 + + + + + Рабочий телефон: + + + + + + + +7 (000) 000-00-00;_ + + + +7 () -- + + + + + + + + 0 + 0 + + + + добавочный: + + + + + + + + 0 + 0 + + + + 000;_ + + + + + + + + + + + + 10 + + + + + + 0 + 0 + + + + Мобильный телефон: + + + + + + + + 0 + 0 + + + + +7 (000) 000-00-00;_ + + + +7 () -- + + + + + + + + + 10 + + + + + + 0 + 0 + + + + Файл шаблона: + + + + + + + + + + + 0 + 0 + + + + Выбрать + + + + + + + + + 10 + + + + + + 0 + 0 + + + + Файл логотипа: + + + + + + + + + + + 0 + 0 + + + + Выбрать + + + + + + + + + Просмотр + + + + + + + + + 400 + 710 + 261 + 31 + + + + Копировать в буфер обмена + + + + + + + diff --git a/ui/sign.ico b/ui/sign.ico new file mode 100644 index 0000000..7035e4c Binary files /dev/null and b/ui/sign.ico differ