Before addition of tips.
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
All kit and reagent related models
|
||||
"""
|
||||
from __future__ import annotations
|
||||
from copy import copy
|
||||
from sqlalchemy import Column, String, TIMESTAMP, JSON, INTEGER, ForeignKey, Interval, Table, FLOAT, BLOB
|
||||
from sqlalchemy.orm import relationship, validates, Query
|
||||
from sqlalchemy.ext.associationproxy import association_proxy
|
||||
|
||||
@@ -8,8 +8,6 @@ from pprint import pformat
|
||||
from typing import List
|
||||
import pandas as pd
|
||||
from openpyxl import load_workbook, Workbook
|
||||
from openpyxl.worksheet.protection import SheetProtection
|
||||
import numpy as np
|
||||
from pathlib import Path
|
||||
from backend.db.models import *
|
||||
from backend.validators import PydSubmission, PydReagent, RSLNamer, PydSample, PydEquipment
|
||||
@@ -17,14 +15,12 @@ import logging, re
|
||||
from collections import OrderedDict
|
||||
from datetime import date
|
||||
from dateutil.parser import parse, ParserError
|
||||
from tools import check_not_nan, convert_nans_to_nones, row_map, row_keys, is_missing, remove_key_from_list_of_dicts
|
||||
from tools import check_not_nan, convert_nans_to_nones, is_missing, remove_key_from_list_of_dicts
|
||||
|
||||
|
||||
logger = logging.getLogger(f"submissions.{__name__}")
|
||||
|
||||
|
||||
# row_keys = {v:k for k,v in row_map.items()}
|
||||
|
||||
class SheetParser(object):
|
||||
"""
|
||||
object to pull and contain data from excel file
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import logging
|
||||
from copy import copy
|
||||
from pathlib import Path
|
||||
# from pathlib import Path
|
||||
from pprint import pformat
|
||||
from typing import List
|
||||
|
||||
from openpyxl import load_workbook, Workbook
|
||||
from tools import row_keys
|
||||
from backend.db.models import SubmissionType, KitType, BasicSample, BasicSubmission
|
||||
from backend.db.models import SubmissionType, KitType, BasicSubmission
|
||||
from backend.validators.pydant import PydSubmission
|
||||
from io import BytesIO
|
||||
from collections import OrderedDict
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
Contains pydantic models and accompanying validators
|
||||
'''
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from operator import attrgetter
|
||||
import uuid, re, logging
|
||||
|
||||
@@ -8,6 +8,7 @@ from PyQt6.QtWidgets import QMainWindow, QFileDialog
|
||||
|
||||
logger = logging.getLogger(f"submissions.{__name__}")
|
||||
|
||||
|
||||
def select_open_file(obj:QMainWindow, file_extension:str) -> Path:
|
||||
"""
|
||||
File dialog to select a file to read from
|
||||
@@ -29,6 +30,7 @@ def select_open_file(obj:QMainWindow, file_extension:str) -> Path:
|
||||
obj.last_dir = fname.parent
|
||||
return fname
|
||||
|
||||
|
||||
def select_save_file(obj:QMainWindow, default_name:str, extension:str) -> Path:
|
||||
"""
|
||||
File dialog to select a file to write to
|
||||
|
||||
@@ -5,9 +5,8 @@ from PyQt6.QtWidgets import (QWidget, QDialog, QGridLayout,
|
||||
QLabel, QLineEdit, QDialogButtonBox,
|
||||
QTextEdit
|
||||
)
|
||||
import numpy as np
|
||||
import pyqtgraph as pg
|
||||
from PyQt6.QtGui import QIcon, QFont
|
||||
from PyQt6.QtGui import QIcon
|
||||
from PIL import Image
|
||||
import numpy as np
|
||||
import logging
|
||||
@@ -18,6 +17,7 @@ from backend.db.models import WastewaterArtic
|
||||
|
||||
logger = logging.getLogger(f"submissions.{__name__}")
|
||||
|
||||
|
||||
# Main window class
|
||||
class GelBox(QDialog):
|
||||
|
||||
@@ -87,6 +87,7 @@ class GelBox(QDialog):
|
||||
values, comment = self.form.parse_form()
|
||||
return dna_core_submission_number, gel_barcode, self.img_path, values, comment
|
||||
|
||||
|
||||
class ControlsForm(QWidget):
|
||||
|
||||
def __init__(self, parent, control_info:List=None) -> None:
|
||||
|
||||
@@ -139,6 +139,7 @@ class KitAdder(QWidget):
|
||||
info[widget.objectName()] = widget.date().toPyDate()
|
||||
return info, reagents
|
||||
|
||||
|
||||
class ReagentRoleForm(QWidget):
|
||||
"""
|
||||
custom widget to add information about a new reagenttype
|
||||
|
||||
@@ -13,12 +13,12 @@ from backend.db.models import *
|
||||
import logging
|
||||
from .pop_ups import AlertPop
|
||||
from .functions import select_open_file
|
||||
from tools import Settings
|
||||
|
||||
logger = logging.getLogger(f"submissions.{__name__}")
|
||||
|
||||
env = jinja_template_loading()
|
||||
|
||||
|
||||
class AddReagentForm(QDialog):
|
||||
"""
|
||||
dialog to add gather info about new reagent
|
||||
@@ -102,6 +102,7 @@ class AddReagentForm(QDialog):
|
||||
lookup = Reagent.query(reagent_role=self.type_input.currentText())
|
||||
self.name_input.addItems(list(set([item.name for item in lookup])))
|
||||
|
||||
|
||||
class ReportDatePicker(QDialog):
|
||||
"""
|
||||
custom dialog to ask for report start/stop dates
|
||||
@@ -138,6 +139,7 @@ class ReportDatePicker(QDialog):
|
||||
"""
|
||||
return dict(start_date=self.start_date.date().toPyDate(), end_date = self.end_date.date().toPyDate())
|
||||
|
||||
|
||||
class FirstStrandSalvage(QDialog):
|
||||
|
||||
def __init__(self, ctx:Settings, submitter_id:str, rsl_plate_num:str|None=None) -> None:
|
||||
@@ -178,6 +180,7 @@ class FirstStrandSalvage(QDialog):
|
||||
"""
|
||||
return dict(plate=self.rsl_plate_num.text(), submitter_id=self.submitter_id_input.text(), well=f"{self.row_letter.currentText()}{self.column_number.currentText()}")
|
||||
|
||||
|
||||
class LogParser(QDialog):
|
||||
|
||||
def __init__(self, parent):
|
||||
@@ -197,7 +200,6 @@ class LogParser(QDialog):
|
||||
self.btn.clicked.connect(self.runsearch)
|
||||
self.setMinimumWidth(400)
|
||||
|
||||
|
||||
def filelookup(self):
|
||||
"""
|
||||
Select file to search
|
||||
|
||||
@@ -14,6 +14,7 @@ logger = logging.getLogger(f"submissions.{__name__}")
|
||||
|
||||
env = jinja_template_loading()
|
||||
|
||||
|
||||
class QuestionAsker(QDialog):
|
||||
"""
|
||||
dialog to ask yes/no questions
|
||||
@@ -33,6 +34,7 @@ class QuestionAsker(QDialog):
|
||||
self.layout.addWidget(self.buttonBox)
|
||||
self.setLayout(self.layout)
|
||||
|
||||
|
||||
class AlertPop(QMessageBox):
|
||||
"""
|
||||
Dialog to show an alert.
|
||||
@@ -45,6 +47,7 @@ class AlertPop(QMessageBox):
|
||||
self.setInformativeText(message)
|
||||
self.setWindowTitle(f"{owner} - {status.title()}")
|
||||
|
||||
|
||||
class ObjectSelector(QDialog):
|
||||
"""
|
||||
dialog to input BaseClass type manually
|
||||
@@ -79,70 +82,3 @@ class ObjectSelector(QDialog):
|
||||
str: KitType as str
|
||||
"""
|
||||
return self.widget.currentText()
|
||||
|
||||
# class KitSelector(QDialog):
|
||||
# """
|
||||
# dialog to input KitType manually
|
||||
# """
|
||||
# def __init__(self, title:str, message:str) -> QDialog:
|
||||
# super().__init__()
|
||||
# self.setWindowTitle(title)
|
||||
# self.widget = QComboBox()
|
||||
# kits = [item.name for item in KitType.query()]
|
||||
# self.widget.addItems(kits)
|
||||
# self.widget.setEditable(False)
|
||||
# # set yes/no buttons
|
||||
# QBtn = QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel
|
||||
# self.buttonBox = QDialogButtonBox(QBtn)
|
||||
# self.buttonBox.accepted.connect(self.accept)
|
||||
# self.buttonBox.rejected.connect(self.reject)
|
||||
# self.layout = QVBoxLayout()
|
||||
# # Text for the yes/no question
|
||||
# message = QLabel(message)
|
||||
# self.layout.addWidget(message)
|
||||
# self.layout.addWidget(self.widget)
|
||||
# self.layout.addWidget(self.buttonBox)
|
||||
# self.setLayout(self.layout)
|
||||
|
||||
# def getValues(self) -> str:
|
||||
# """
|
||||
# Get KitType(str) from widget
|
||||
|
||||
# Returns:
|
||||
# str: KitType as str
|
||||
# """
|
||||
# return self.widget.currentText()
|
||||
|
||||
# class SubmissionTypeSelector(QDialog):
|
||||
# """
|
||||
# dialog to input SubmissionType manually
|
||||
# """
|
||||
# def __init__(self, title:str, message:str) -> QDialog:
|
||||
# super().__init__()
|
||||
# self.setWindowTitle(title)
|
||||
# self.widget = QComboBox()
|
||||
# # sub_type = [item.name for item in lookup_submission_type(ctx=ctx)]
|
||||
# sub_type = [item.name for item in SubmissionType.query()]
|
||||
# self.widget.addItems(sub_type)
|
||||
# self.widget.setEditable(False)
|
||||
# # set yes/no buttons
|
||||
# QBtn = QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel
|
||||
# self.buttonBox = QDialogButtonBox(QBtn)
|
||||
# self.buttonBox.accepted.connect(self.accept)
|
||||
# self.buttonBox.rejected.connect(self.reject)
|
||||
# self.layout = QVBoxLayout()
|
||||
# # Text for the yes/no question
|
||||
# message = QLabel(message)
|
||||
# self.layout.addWidget(message)
|
||||
# self.layout.addWidget(self.widget)
|
||||
# self.layout.addWidget(self.buttonBox)
|
||||
# self.setLayout(self.layout)
|
||||
|
||||
# def parse_form(self) -> str:
|
||||
# """
|
||||
# Pulls SubmissionType(str) from widget
|
||||
|
||||
# Returns:
|
||||
# str: SubmissionType as str
|
||||
# """
|
||||
# return self.widget.currentText()
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
from pprint import pformat
|
||||
from typing import Tuple
|
||||
from pandas import DataFrame
|
||||
from PyQt6.QtCore import QAbstractTableModel, Qt, QEvent, QSortFilterProxyModel
|
||||
from PyQt6.QtCore import QSortFilterProxyModel
|
||||
from PyQt6.QtWidgets import (
|
||||
QLabel, QVBoxLayout, QDialog,
|
||||
QDialogButtonBox, QMessageBox, QComboBox, QTableView, QWidget, QLineEdit, QGridLayout
|
||||
QComboBox, QTableView, QWidget, QLineEdit, QGridLayout
|
||||
)
|
||||
from backend.db.models import BasicSample
|
||||
from .submission_table import pandasModel
|
||||
from .submission_details import SubmissionDetails
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(f"submissions.{__name__}")
|
||||
|
||||
@@ -21,6 +21,7 @@ from typing import List
|
||||
|
||||
logger = logging.getLogger(f"submissions.{__name__}")
|
||||
|
||||
|
||||
class SubmissionDetails(QDialog):
|
||||
"""
|
||||
a window showing text details of submission
|
||||
@@ -92,8 +93,8 @@ class SubmissionDetails(QDialog):
|
||||
self.base_dict, self.template = submission.get_details_template(base_dict=self.base_dict)
|
||||
self.html = self.template.render(sub=self.base_dict, signing_permission=is_power_user())
|
||||
self.webview.setHtml(self.html)
|
||||
with open("test.html", "w") as f:
|
||||
f.write(self.html)
|
||||
# with open("test.html", "w") as f:
|
||||
# f.write(self.html)
|
||||
self.setWindowTitle(f"Submission Details - {submission.rsl_plate_num}")
|
||||
|
||||
@pyqtSlot(str)
|
||||
@@ -125,8 +126,6 @@ class SubmissionDetails(QDialog):
|
||||
del self.base_dict['platemap']
|
||||
self.html2 = self.template.render(sub=self.base_dict)
|
||||
try:
|
||||
# with open(fname, "w+b") as f:
|
||||
# pisa.CreatePDF(self.html2, dest=f)
|
||||
html_to_pdf(html=self.html2, output_file=fname)
|
||||
except PermissionError as e:
|
||||
logger.error(f"Error saving pdf: {e}")
|
||||
@@ -136,6 +135,7 @@ class SubmissionDetails(QDialog):
|
||||
msg.setWindowTitle("Permission Error")
|
||||
msg.exec()
|
||||
|
||||
|
||||
class SubmissionComment(QDialog):
|
||||
"""
|
||||
a window for adding comment text to a submission
|
||||
@@ -174,4 +174,3 @@ class SubmissionComment(QDialog):
|
||||
full_comment = {"name":commenter, "time": dt, "text": comment}
|
||||
# logger.debug(f"Full comment: {full_comment}")
|
||||
return full_comment
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ from PyQt6.QtGui import QAction, QCursor
|
||||
from backend.db.models import BasicSubmission
|
||||
from backend.excel import make_report_html, make_report_xlsx
|
||||
from tools import Report, Result, row_map, get_first_blank_df_row, html_to_pdf
|
||||
# from xhtml2pdf import pisa
|
||||
from .functions import select_save_file, select_open_file
|
||||
from .misc import ReportDatePicker
|
||||
import pandas as pd
|
||||
@@ -17,6 +16,7 @@ from openpyxl.worksheet.worksheet import Worksheet
|
||||
|
||||
logger = logging.getLogger(f"submissions.{__name__}")
|
||||
|
||||
|
||||
class pandasModel(QAbstractTableModel):
|
||||
"""
|
||||
pandas model for inserting summary sheet into gui
|
||||
@@ -61,6 +61,7 @@ class pandasModel(QAbstractTableModel):
|
||||
return self._data.columns[col]
|
||||
return None
|
||||
|
||||
|
||||
class SubmissionsSheet(QTableView):
|
||||
"""
|
||||
presents submission summary to user in tab1
|
||||
|
||||
@@ -12,6 +12,7 @@ from .functions import select_open_file
|
||||
|
||||
logger = logging.getLogger(f"submissions.{__name__}")
|
||||
|
||||
|
||||
class SubmissionTypeAdder(QWidget):
|
||||
|
||||
def __init__(self, parent) -> None:
|
||||
@@ -80,6 +81,7 @@ class SubmissionTypeAdder(QWidget):
|
||||
self.template_path = select_open_file(obj=self, file_extension="xlsx")
|
||||
self.template_label.setText(self.template_path.__str__())
|
||||
|
||||
|
||||
class InfoWidget(QWidget):
|
||||
|
||||
def __init__(self, parent: QWidget, key) -> None:
|
||||
|
||||
@@ -4,7 +4,6 @@ Contains miscellaenous functions used by both frontend and backend.
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
import numpy as np
|
||||
import logging, re, yaml, sys, os, stat, platform, getpass, inspect, csv
|
||||
import pandas as pd
|
||||
@@ -16,7 +15,7 @@ from sqlalchemy import create_engine, text
|
||||
from pydantic import field_validator, BaseModel, Field
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
from typing import Any, Tuple, Literal, List
|
||||
from PyQt6.QtGui import QTextDocument, QPageSize
|
||||
from PyQt6.QtGui import QPageSize
|
||||
from PyQt6.QtWebEngineWidgets import QWebEngineView
|
||||
from openpyxl.worksheet.worksheet import Worksheet
|
||||
|
||||
|
||||
Reference in New Issue
Block a user