From ff5c617a429bccf8fe7226e22d76794338ef0116 Mon Sep 17 00:00:00 2001 From: Papoteur Date: Fri, 27 Oct 2023 19:39:17 +0200 Subject: Initial commit --- form.ui | 249 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mga-advisor.py | 185 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 434 insertions(+) create mode 100644 form.ui create mode 100644 mga-advisor.py diff --git a/form.ui b/form.ui new file mode 100644 index 0000000..2663c25 --- /dev/null +++ b/form.ui @@ -0,0 +1,249 @@ + + + Widget + + + + 0 + 0 + 814 + 622 + + + + Widget + + + + + -1 + -1 + 811 + 601 + + + + + + + + 0 + 0 + + + + Mageia Advisories Editor + + + + + + + Type: + + + + + 50 + 0 + 99 + 20 + + + + Bug fix + + + true + + + + + + 230 + 0 + 99 + 20 + + + + Security + + + + + + + + + + Bug report number + + + + + + + + + + bug number + + + + + + + false + + + Retrieve info + + + + + + + + + + + + + + Subject + + + + + + + subject + + + + + + + + + Description: + + + + + + + Drescription + + + 72 + + + + + + + + + + + + + + Add source + + + + + + + Remove source + + + + + + + + + + + + + + + + + + Add reference + + + + + + + Remove reference + + + + + + + + + + + + + + + + + + Add CVE + + + + + + + Remove CVE + + + + + + + + + + + + + Cancel + + + + + + + Preview + + + + + + + Export + + + + + + + + + + + diff --git a/mga-advisor.py b/mga-advisor.py new file mode 100644 index 0000000..4869407 --- /dev/null +++ b/mga-advisor.py @@ -0,0 +1,185 @@ +# This Python file uses the following encoding: utf-8 +import os +from pathlib import Path +import sys +import yaml +import textwrap +import re + +from PySide6.QtWidgets import QApplication, QWidget, QDialog, QLineEdit, QPushButton, QVBoxLayout, QHBoxLayout, QComboBox, QTextEdit +from PySide6.QtCore import QFile, QDate, QDir +from PySide6.QtUiTools import QUiLoader + + +class LineDialog(QDialog): + def __init__(self, title, init="", parent=None): + super().__init__(parent) + self.setWindowTitle(title) + self.name_ql = QLineEdit() + self.name_ql.setText(init) + apply_bt = QPushButton("Apply") + layout = QHBoxLayout() + layout.addWidget(self.name_ql) + layout.addWidget(apply_bt) + self.setLayout(layout) + apply_bt.clicked.connect(self.apply) + + def apply(self): + self.accept() + +class SrcDialog(QDialog): + def __init__(self, parent=None): + super().__init__(parent) + self.setWindowTitle("Add source") + self.name_ql = QLineEdit() + self.release = QComboBox() + self.release.addItems(["9", "8"]) + self.repo = QComboBox() + self.repo.addItems(["core", "nonfree", "tainted"]) + apply_bt = QPushButton("Apply") + layout = QHBoxLayout() + layout.addWidget(self.release) + layout.addWidget(self.repo) + layout.addWidget(self.name_ql) + layout.addWidget(apply_bt) + self.setLayout(layout) + apply_bt.clicked.connect(self.apply) + + def apply(self): + self.accept() + +class Widget(QWidget): + def __init__(self, parent=None): + super().__init__(parent) + self.load_ui() + self.setWindowTitle("Mageia advisor") + + def load_ui(self): + loader = QUiLoader() + path = Path(__file__).resolve().parent / "form.ui" + ui_file = QFile(path) + ui_file.open(QFile.ReadOnly) + self.ui = loader.load(ui_file, self) + ui_file.close() + self.ui.retrieve_pb.clicked.connect(self.retrieve) + self.ui.add_cve_pb.clicked.connect(self.add_cve) + self.ui.remove_cve_pb.clicked.connect(self.remove_cve) + self.ui.add_src_pb.clicked.connect(self.add_src) + self.ui.remove_src_pb.clicked.connect(self.remove_src) + self.ui.add_ref_pb.clicked.connect(self.add_reference) + self.ui.remove_ref_pb.clicked.connect(self.remove_reference) + self.ui.export_pb.clicked.connect(self.export) + self.ui.cancel_pb.clicked.connect(self.cancel) + self.ui.preview_pb.clicked.connect(self.preview) + self.ui.bug_le.editingFinished.connect(self.valid_number) + + def retrieve(self): + print("Action retrieve") + + def add_src(self): + dl = SrcDialog() + name = dl.exec() + self.ui.list_src.addItem( + " ".join((dl.release.currentText(), + dl.repo.currentText(), + self.sanitize_line(dl.name_ql.text()) + )) + ) + + def remove_src(self): + self.ui.list_src.takeItem(self.ui.list_src.currentRow()) + + def add_reference(self): + dl = LineDialog("Add reference") + dl.exec() + self.ui.list_ref.addItem(self.sanitize_line(dl.name_ql.text())) + + + def remove_reference(self): + self.ui.list_ref.takeItem(self.ui.list_ref.currentRow()) + + def add_cve(self): + init_value = f"CVE-{QDate.currentDate().year()}-" + dl = LineDialog("Add CVE", init=init_value) + dl.exec() + self.ui.list_cve.addItem(self.sanitize_line(dl.name_ql.text())) + + def remove_cve(self): + self.ui.list_cve.takeItem(self.ui.list_cve.currentRow()) + + def adv_text(self): + data = {} + if self.ui.bugfix_rb.isEnabled(): + data['type'] = 'bugfix' + if self.ui.security_rb.isEnabled(): + data['type'] = 'security' + if len(self.ui.description_te.toPlainText()) != 0: + data['description'] = self.ui.description_te.toPlainText() + if self.ui.subject_le.text() != "": + data['subject'] = self.sanitize_line(self.ui.subject_le.text()) + cves = [] + n = 0 + for n in range(0, self.ui.list_cve.count()): + cves.append(self.ui.list_cve.item(n).text()) + if n != 0: + data['CVE'] = cves + srcs = {} + n = 0 + for n in range(0, self.ui.list_src.count()): + release, repo, name = self.ui.list_src.item(n).text().split(" ") + if not release in srcs.keys(): + srcs[release] = {} + srcs[release][repo] = [] + else: + if not repo in srcs[release].keys(): + srcs[release][repo] = [] + srcs[release][repo].append(name) + if n != 0: + data['src'] = srcs + refs = [] + n = 0 + for n in range(0, self.ui.list_ref.count()): + refs.append(self.ui.list_ref.item(n).text()) + if n != 0: + data['references'] = refs + return yaml.dump(data, default_flow_style=False) + + def export(self): + if QDir().mkpath(QDir().homePath() + "/mageia-advisories/advisories"): + if self.ui.bug_le.text() != "": + #TODO check that it exists + with open(f"{QDir().homePath()}/mageia-advisories/advisories/{self.ui.bug_le.text()}.adv", 'w') as f: + f.write(self.adv_text()) + + def cancel(self): + self.close() + + def preview(self): + dl = QDialog() + dl.setWindowTitle("Advisory preview") + te = QTextEdit() + te.setPlainText(self.adv_text()) + te.setReadOnly(True) + te.setMinimumSize(600, 0) + ok_bt = QPushButton("OK") + layout = QVBoxLayout() + layout.addWidget(te) + layout.addWidget(ok_bt) + dl.setLayout(layout) + ok_bt.clicked.connect(dl.close) + dl.exec() + + def sanitize_line(self, line): + if len(line) != 0: + return line.splitlines()[0].strip() + else: + return "" + + def valid_number(self): + self.ui.bug_le.setText(re.sub('\D', '', self.ui.bug_le.text())) + +if __name__ == "__main__": + app = QApplication(sys.argv) + widget = Widget() + widget.show() + sys.exit(app.exec()) -- cgit v1.2.1