diff --git a/README.md b/README.md index e69de29..d309e34 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,2 @@ +sendelogsls.py inherits from bdbase.sendelogframe +enumkind.py has ELogSLS enum options defined \ No newline at end of file diff --git a/sendelog.py b/sendelog.py new file mode 100644 index 0000000..9fe68f9 --- /dev/null +++ b/sendelog.py @@ -0,0 +1,365 @@ +import getpass +import inspect +import os +import time + +from qtpy.QtCore import Qt +from qtpy.QtWidgets import (QComboBox, QDialog, QFileDialog, QHBoxLayout, + QLabel, QLineEdit, QPushButton, QTextEdit, + QVBoxLayout) + +import elog # https://github.com/paulscherrerinstitute/py_elog +from pyqtacc.bdbase.enumkind import MsgSeverity + +_version = "1.0.0" +_pymodule = os.path.basename(__file__) +_appname, _appext = _pymodule.split(".") + +def _line(): + """Macro to return the current line number. + + The current line number within the file is used when + reporting messages to the message logging window. + + Returns: + int: Current line number. + """ + return inspect.currentframe().f_back.f_lineno + +class QSendToELOG(QDialog): + """ Graphical interface to elog + """ + def __init__(self, parent, logbook=None, categoryIdx=0, domainIdx=0, + systemIdx=0, sectionIdx=0, title=None, message=None, + attachFile=None, destination_folder=None): + #super(QSendToELOG, self).__init__(parent) + super().__init__() + + self.files_text = '' + self.fflag = False + self.parent = parent + if destination_folder is None: + self.destination = self.parent.elog_dest + " / " + self.parent.appname + else: + self.destination = destination_folder + self.window_title = self.parent.appname + ": " + _appname + self.pymodule = _pymodule + + self.setWindowTitle(self.window_title) + + elog_books = list(self.parent.settings.data["ElogBooks"]) + self.elog_items = QComboBox() + self.elog_items.addItems(elog_books) + self.elog_items.currentIndexChanged.connect(self.on_elog_change) + idx = 0 + + if logbook is not None: + try: + idx = elog_books.index(logbook) + except Exception: + mess = "Index not found for logbook {0}".format(logbook) + self.parent.show_log_message(MsgSeverity.WARN, self.pymodule, + _line(), mess) + else: + try: + idx = elog_books.index(self.parent.settings.data["Elog"][ + "book"]) + except Exception: + logbook = self.parent.settings.data["Elog"]["book"] + mess = "Index not found for logbook {0}".format(logbook) + self.parent.show_log_message(MsgSeverity.WARN, self.pymodule, + _line(), mess) + + print("logbook", logbook) + + self.elog_items.setCurrentIndex(idx) + self.elog_items.currentIndexChanged.emit(idx) + self.elog_items.setObjectName("Elog") + + print(self.parent.settings.data["Elog"]) + category_str = list(self.parent.settings.data["Elog"]['Projekt']) + print("logbook2", logbook) + self.category = QHBoxLayout() + self.category.addWidget(QLabel('Projekt: ')) + self.category_items = QComboBox() + self.category_items.setObjectName("Elog") + self.category_items.addItems(category_str) + self.category.addWidget(self.category_items) + self.category_items.setCurrentIndex(categoryIdx) + + domain_str = list(self.parent.settings.data["Elog"]['Eintrag']) + self.domain = QHBoxLayout() + self.domain.addWidget(QLabel('Eintrag: ')) + self.domain_items = QComboBox() + self.domain_items.setObjectName("Elog") + self.domain_items.addItems(domain_str) + self.domain.addWidget(self.domain_items) + self.domain_items.setCurrentIndex(domainIdx) + self.domain_items.currentIndexChanged.connect(self.on_domain_change) + print("logbook2", logbook) + + #self.elog_section = list(self.parent.settings.data["Elog"]['Effekt']) + self.section = QHBoxLayout() + self.section.addWidget(QLabel('Effekt: ')) + #self.section_items = QComboBox() + #self.section_items.setObjectName("Elog") + #self.section_items.addItems(self.elog_section[domainIdx]) + #self.section.addWidget(self.section_items) + #self.section_items.setCurrentIndex(sectionIdx) + self.effekt = QLineEdit() + self.effekt.setObjectName('Elog') + self.effekt.setText(str("")) + self.effekt.setFixedWidth(300) + self.effekt.setAlignment(Qt.AlignCenter) + self.section.addWidget(self.effekt) + + + self.system = QHBoxLayout() + self.system.addWidget(QLabel('System: ')) + self.system_items = QComboBox() + self.system_items.setObjectName("Elog") + self.system_items.addItems( + list(self.parent.settings.data["Elog"]['System'])) + + self.system.addWidget(self.system_items) + self.system_items.setCurrentIndex(systemIdx) + print("logbook3", logbook) + self.title_items = QHBoxLayout() + self.title_items.addWidget(QLabel('Title: ')) + self.titleline = QLineEdit() + self.titleline.setObjectName('Elog') + self.titleline.setStatusTip('elog') + if title is None: + title = self.parent.appname + self.titleline.setText(str(title)) + self.titleline.setFixedWidth(300) + self.titleline.setAlignment(Qt.AlignCenter) + self.title_items.addWidget(self.titleline) + + self.applicationbox = QHBoxLayout() + self.applicationbox.addWidget(QLabel('Application:')) + self.applicationlabel = QLabel(self.parent.pymodule) + self.applicationlabel.setObjectName("Elog") + # self.applicationbox.addStretch() + self.applicationbox.addWidget(self.applicationlabel) + + logbook = QHBoxLayout() + logbook.addWidget(QLabel('Logbook: ')) + logbook.addWidget(self.elog_items) + + authorbox = QHBoxLayout() + authorbox.addWidget(QLabel('Author: ')) + self.author = QLineEdit() + self.author.setObjectName('Elog') + self.author.setFixedWidth(195) + self.author.setStatusTip('elog') + self.author.setText(getpass.getuser()) + authorbox.addWidget(self.author) + + self.files = [] + self.attributes = {} + + self.layout = QVBoxLayout(self) + self.layout.addLayout(logbook) + self.layout.addLayout(self.applicationbox) + self.layout.addLayout(self.category) + self.layout.addLayout(self.domain) + self.layout.addLayout(self.section) + self.layout.addLayout(self.system) + self.layout.addLayout(authorbox) + self.layout.addLayout(self.title_items) + print("here4", flush=True) + report = QLabel('Report: ') + self.layout.addWidget(report) + self.message = QTextEdit(message) + self.layout.addWidget(self.message) + + filebox = QHBoxLayout() + qlfile = QLabel('Attach:') + qlfile.setAlignment(Qt.AlignTop) + filebox.addWidget(qlfile) + + self.filesE = QTextEdit() + self.filesE.setAlignment(Qt.AlignTop) + self.filesE.setFixedHeight(80) + self.filesE.setReadOnly(True) + + self.attachFile = attachFile + + if self.attachFile is not None: + _attachFile = [] + if isinstance(self.attachFile, str): + _attachFile.append(self.attachFile) + elif isinstance(self.attachFile, list): + _attachFile = self.attachFile + for i, file in enumerate(_attachFile): + _attach_base = os.path.basename(file) + if i > 0: + self.files_text += "\n" + self.files_text += str(_attach_base) + self.filesE.setText(self.files_text) + self.fflag = True + + filebox.addWidget(self.filesE) + + openCloseVBox = QVBoxLayout() + self.openBtn = QPushButton('Add') + self.openBtn.setAutoDefault(False) + self.openBtn.clicked.connect(self.openFiles) + openCloseVBox.addWidget(self.openBtn) + + closeBtn = QPushButton('Clear') + closeBtn.setAutoDefault(False) + closeBtn.clicked.connect(self.clearFiles) + openCloseVBox.addWidget(closeBtn) + + filebox.addLayout(openCloseVBox) + self.layout.addLayout(filebox) + + btnLayout = QHBoxLayout() + self.okBtn = QPushButton('Send') + self.okBtn.setAutoDefault(False) + self.okBtn.clicked.connect(self.ok) + + self.cancelBtn = QPushButton('Cancel') + self.cancelBtn.setAutoDefault(False) + self.cancelBtn.clicked.connect(self.close) + btnLayout.addWidget(self.okBtn) + btnLayout.addWidget(self.cancelBtn) + self.messagelbl = QLabel('') + self.messagelbl.setStyleSheet("QLabel { color : red; }") + self.layout.addWidget(self.messagelbl) + self.layout.addLayout(btnLayout) + print("logbook5", logbook) + self.setMinimumWidth(440) + self.exec() + + def on_elog_change(self, elog_change_val): + if "test" in self.elog_items.currentText(): + _bgcolor = "QComboBox {background: plum; color : black;}" + else: + _bgcolor = "QComboBox {background: lightblue; color : black;}" + self.elog_items.setStyleSheet(_bgcolor) + + def on_domain_change(self, i): + self.section_items.clear() + self.section_items.addItems(self.elog_section[i]) + + def ok(self): + message = self.message.document().toPlainText() + if not message: + self.messagelbl.setText('Please enter a brief Report') + return + title = self.titleline.text() + if not title: + self.messagelbl.setText('Titel attribute is required') + return + cat = self.category_items.currentText() + if not cat: + self.messagelbl.setText('Projekt attribute is required') + return + + el = self.elog_items.currentText() + + author = self.author.text() + application = self.applicationlabel.text() + self.attributes['Autor'] = author + self.attributes['Author'] = author + self.attributes['Application'] = application + # if title is not None: #!= '': + self.attributes['Titel'] = title + self.attributes['Title'] = title + self.attributes['Projekt'] = cat + if el == 'SLS': + self.attributes['Eintrag'] = self.domain_items.currentText() + self.attributes['Effekt'] = self.effekt.text() + self.attributes['System'] = self.system_items.currentText() + self.attributes['When'] = str(time.time()) + self.attributes['Wann'] = str(time.time()) + + + + if self.attachFile is not None: + _attachFile = [] + if isinstance(self.attachFile, str): + _attachFile.append(self.attachFile) + elif isinstance(self.attachFile, list): + _attachFile = self.attachFile + for i in range(0, len(_attachFile)): + if "/tmp" in _attachFile[i]: + self.files.append(str(_attachFile[i])) + elif "/afs/psi.ch" in _attachFile[i]: + self.files.append(str(_attachFile[i])) + elif "/sls/bd/data/" in _attachFile[i]: + self.files.append(str(_attachFile[i])) + else: + self.files.append(self.destination + str(_attachFile[i])) + + url = self.parent.settings.data["ElogBooks"][el]["url"] + + self.logbook = elog.open(url, user='robot', password='robot') + + print("sendelog.py: ", url, flush=True) + print(message, flush=True) + try: + if self.files: + self.logbook.post(message, attributes=self.attributes, + attachments=self.files) + else: + self.logbook.post(message, attributes=self.attributes) + + #self.trigger_elog_entry.emit(True, url, "OK") + self.receive_elog_notification(True, url, "OK") + except Exception as ex: + #self.trigger_elog_entry.emit(False, url, str(ex)) + print("Exception in sendelog.py", str(ex)) + self.receive_elog_notification(False, url, str(ex)) + + #for file in self.files: + # if os.path.exists(file): + # os.remove(file) + + self.close() + + + def clearFiles(self): + self.attachFile = [] + self.filesE.clear() + self.files = [] + self.files_text = '' + self.fflag = False + + def openFiles(self): + # Notethat openFiles also gets called when qDialog cacnel is clicked! + qFileDialog = QFileDialog() + extensions = ("Images (*.bmp *.eps *.gif *.jpeg *.jpg *.pdf *.png " + + "*.ps *.tiff *.xpm);;Text files (*.txt *.text);;" + + "JSON/XML files (*.json *.xml)") + + flocal = qFileDialog.getOpenFileNames( + self, 'Open File', self.destination, extensions)[0] + + if not flocal: + return + self.files.append(flocal[0]) + if self.fflag: + self.files_text += '\n' + self.files_text += str(flocal[0].split('/')[-1]) + self.fflag = True + self.filesE.setText(self.files_text) + + + def receive_elog_notification(self, is_accepted, logbook_url, elog_message): + '''Receive notification from ELOG, and report to log window''' + + yes_no = "made" if is_accepted else "failed" + mess = "Entry into ELOG: {0} {1}".format(logbook_url, yes_no) + + if is_accepted: + self.parent.show_log_message(MsgSeverity.INFO, self.pymodule, + _line(), mess) + else: + mess += ".\n" + elog_message + self.parent.show_log_message(MsgSeverity.WARN, self.pymodule, + _line(), mess) + self.parent.statusbar.showMessage(mess)