diff --git a/requirements.txt b/requirements.txt index 1d6677d..bcdafd9 100644 Binary files a/requirements.txt and b/requirements.txt differ diff --git a/src/submissions/backend/db/models/kits.py b/src/submissions/backend/db/models/kits.py index 061e32d..e8ac061 100644 --- a/src/submissions/backend/db/models/kits.py +++ b/src/submissions/backend/db/models/kits.py @@ -1499,7 +1499,7 @@ class Process(BaseClass): @setup_lookup def query(cls, name: str | None = None, - id: int = 1, + id: int | None = None, limit: int = 0) -> Process | List[Process]: """ Lookup Processes @@ -1514,7 +1514,7 @@ class Process(BaseClass): query = cls.__database_session__.query(cls) match name: case str(): - # logger.debug(f"Lookup Process with name str {name}") + logger.debug(f"Lookup Process with name str {name}") query = query.filter(cls.name == name) limit = 1 case _: diff --git a/src/submissions/backend/db/models/submissions.py b/src/submissions/backend/db/models/submissions.py index 6a0d6f1..717de4d 100644 --- a/src/submissions/backend/db/models/submissions.py +++ b/src/submissions/backend/db/models/submissions.py @@ -31,6 +31,8 @@ from dateutil.parser import parse from pathlib import Path from jinja2.exceptions import TemplateNotFound from jinja2 import Template +from docxtpl import InlineImage +from io import BytesIO logger = logging.getLogger(f"submissions.{__name__}") @@ -730,7 +732,7 @@ class BasicSubmission(BaseClass): return input_excel @classmethod - def custom_docx_writer(cls, input_dict): + def custom_docx_writer(cls, input_dict:dict, tpl_obj=None): return input_dict @@ -1493,7 +1495,7 @@ class Wastewater(BasicSubmission): # self.report.add_result(Result(msg=f"We added PCR info to {sub.rsl_plate_num}.", status='Information')) @classmethod - def custom_docx_writer(cls, input_dict): + def custom_docx_writer(cls, input_dict:dict, tpl_obj=None): from backend.excel.writer import DocxWriter input_dict = super().custom_docx_writer(input_dict) well_24 = [] @@ -1551,7 +1553,7 @@ class WastewaterArtic(BasicSubmission): if report: return output output['gel_info'] = self.gel_info - output['gel_image'] = self.gel_image + output['gel_image_path'] = self.gel_image output['dna_core_submission_number'] = self.dna_core_submission_number output['source_plates'] = self.source_plates output['artic_date'] = self.artic_date or self.submitted_date @@ -1856,7 +1858,7 @@ class WastewaterArtic(BasicSubmission): """ base_dict, template = super().get_details_template(base_dict=base_dict) base_dict['excluded'] += ['gel_info', 'gel_image', 'headers', "dna_core_submission_number", "source_plates", - "gel_controls"] + "gel_controls, gel_image_path"] base_dict['DNA Core ID'] = base_dict['dna_core_submission_number'] # check = 'gel_info' in base_dict.keys() and base_dict['gel_info'] is not None if check_key_or_attr(key='gel_info', interest=base_dict, check_none=True): @@ -1865,9 +1867,9 @@ class WastewaterArtic(BasicSubmission): base_dict['headers'] += headers # logger.debug(f"Gel info: {pformat(base_dict['headers'])}") # check = 'gel_image' in base_dict.keys() and base_dict['gel_image'] is not None - if check_key_or_attr(key='gel_image', interest=base_dict, check_none=True): + if check_key_or_attr(key='gel_image_path', interest=base_dict, check_none=True): with ZipFile(cls.__directory_path__.joinpath("submission_imgs.zip")) as zipped: - base_dict['gel_image'] = base64.b64encode(zipped.read(base_dict['gel_image'])).decode('utf-8') + base_dict['gel_image'] = base64.b64encode(zipped.read(base_dict['gel_image_path'])).decode('utf-8') return base_dict, template # def adjust_to_dict_samples(self, backup: bool = False) -> List[dict]: @@ -1935,6 +1937,20 @@ class WastewaterArtic(BasicSubmission): zipf.write(img_path, self.gel_image) self.save() + @classmethod + def custom_docx_writer(cls, input_dict:dict, tpl_obj=None): + input_dict = super().custom_docx_writer(input_dict) + if check_key_or_attr(key='gel_image_path', interest=input_dict, check_none=True): + with ZipFile(cls.__directory_path__.joinpath("submission_imgs.zip")) as zipped: + img = zipped.read(input_dict['gel_image_path']) + with tempfile.TemporaryFile(mode="wb", suffix=".jpg", delete=False) as tmp: + tmp.write(img) + logger.debug(f"Tempfile: {tmp.name}") + img = InlineImage(tpl_obj, image_descriptor=tmp.name)#, width=5.5)#, height=400) + input_dict['gel_image'] = img + return input_dict + + # Sample Classes diff --git a/src/submissions/backend/excel/writer.py b/src/submissions/backend/excel/writer.py index d65ad40..9bc8027 100644 --- a/src/submissions/backend/excel/writer.py +++ b/src/submissions/backend/excel/writer.py @@ -477,7 +477,7 @@ class DocxWriter(object): base_dict['excluded'] += ["platemap"] except KeyError: base_dict['excluded'] = ["platemap"] - base_dict = self.sub_obj.custom_docx_writer(base_dict) + base_dict = self.sub_obj.custom_docx_writer(base_dict, tpl_obj=self.template) # logger.debug(f"Base dict: {pformat(base_dict)}") self.template.render({"sub": base_dict}) diff --git a/src/submissions/backend/validators/pydant.py b/src/submissions/backend/validators/pydant.py index 2a30cce..bfa809e 100644 --- a/src/submissions/backend/validators/pydant.py +++ b/src/submissions/backend/validators/pydant.py @@ -304,7 +304,10 @@ class PydEquipment(BaseModel, extra='ignore'): value = [''] if len(value) == 0: value = [''] - value = [item.strip() for item in value] + try: + value = [item.strip() for item in value] + except AttributeError: + pass return value def toSQL(self, submission: BasicSubmission | str = None) -> Tuple[Equipment, SubmissionEquipmentAssociation]: diff --git a/src/submissions/frontend/widgets/equipment_usage.py b/src/submissions/frontend/widgets/equipment_usage.py index 8af2167..f6dc766 100644 --- a/src/submissions/frontend/widgets/equipment_usage.py +++ b/src/submissions/frontend/widgets/equipment_usage.py @@ -59,7 +59,10 @@ class EquipmentUsage(QDialog): case _: pass logger.debug(f"parsed output of Equsage form: {pformat(output)}") - return [item.strip() for item in output if item is not None] + try: + return [item.strip() for item in output if item is not None] + except AttributeError: + return [item for item in output if item is not None] class LabelRow(QWidget): @@ -131,8 +134,8 @@ class RoleComboBox(QWidget): """ Changes what tips are available when process is changed """ - process = self.process.currentText() - logger.debug(f"Checking process: {process}") + process = self.process.currentText().strip() + logger.debug(f"Checking process: {process} for equipment {self.role.name}") process = Process.query(name=process) if process.tip_roles: for iii, tip_role in enumerate(process.tip_roles): diff --git a/src/submissions/frontend/widgets/gel_checker.py b/src/submissions/frontend/widgets/gel_checker.py index a217a53..d005097 100644 --- a/src/submissions/frontend/widgets/gel_checker.py +++ b/src/submissions/frontend/widgets/gel_checker.py @@ -54,9 +54,11 @@ class GelBox(QDialog): layout = QGridLayout() layout.addWidget(QLabel("DNA Core Submission Number"),0,1) self.core_number = QLineEdit() + self.core_number.setText(self.submission.dna_core_submission_number) layout.addWidget(self.core_number, 0,2) layout.addWidget(QLabel("Gel Barcode"),0,3) self.gel_barcode = QLineEdit() + self.gel_barcode.setText(self.submission.gel_barcode) layout.addWidget(self.gel_barcode, 0, 4) # setting this layout to the widget # plot window goes on right side, spanning 3 rows diff --git a/src/submissions/frontend/widgets/submission_details.py b/src/submissions/frontend/widgets/submission_details.py index 911d76f..00065ec 100644 --- a/src/submissions/frontend/widgets/submission_details.py +++ b/src/submissions/frontend/widgets/submission_details.py @@ -10,7 +10,6 @@ from backend.db.models import BasicSubmission, BasicSample from tools import is_power_user, html_to_pdf from .functions import select_save_file from io import BytesIO -from tempfile import TemporaryFile, TemporaryDirectory from pathlib import Path import logging, base64 from getpass import getuser @@ -43,7 +42,7 @@ class SubmissionDetails(QDialog): self.layout = QVBoxLayout() self.setFixedSize(900, 500) # NOTE: button to export a pdf version - btn = QPushButton("Export PDF") + btn = QPushButton("Export DOCX") btn.setFixedWidth(875) btn.clicked.connect(self.export) self.layout.addWidget(btn) @@ -103,8 +102,6 @@ class SubmissionDetails(QDialog): logger.debug(f"Submission_details: {pformat(self.base_dict)}") self.html = self.template.render(sub=self.base_dict, signing_permission=is_power_user(), css=css) self.webview.setHtml(self.html) - with open("test.html", "w") as f: - f.write(self.html) self.setWindowTitle(f"Submission Details - {submission.rsl_plate_num}") @pyqtSlot(str)