Bug fixes and speed-ups
This commit is contained in:
@@ -369,7 +369,7 @@ def lookup_regent_by_type_name_and_kit_name(ctx:Settings, type_name:str, kit_nam
|
|||||||
output = rt_types.instances
|
output = rt_types.instances
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def lookup_all_submissions_by_type(ctx:Settings, sub_type:str|None=None, chronologic:bool=False) -> list[models.BasicSubmission]:
|
def lookup_all_submissions_by_type(ctx:Settings, sub_type:str|None=None, chronologic:bool=False, limit:int=None) -> list[models.BasicSubmission]:
|
||||||
"""
|
"""
|
||||||
Get all submissions, filtering by type if given
|
Get all submissions, filtering by type if given
|
||||||
|
|
||||||
@@ -386,6 +386,8 @@ def lookup_all_submissions_by_type(ctx:Settings, sub_type:str|None=None, chronol
|
|||||||
else:
|
else:
|
||||||
# subs = ctx['database_session'].query(models.BasicSubmission).filter(models.BasicSubmission.submission_type==sub_type.lower().replace(" ", "_")).all()
|
# subs = ctx['database_session'].query(models.BasicSubmission).filter(models.BasicSubmission.submission_type==sub_type.lower().replace(" ", "_")).all()
|
||||||
subs = ctx.database_session.query(models.BasicSubmission).filter(models.BasicSubmission.submission_type_name==sub_type)
|
subs = ctx.database_session.query(models.BasicSubmission).filter(models.BasicSubmission.submission_type_name==sub_type)
|
||||||
|
if limit != None:
|
||||||
|
subs.limit(limit)
|
||||||
if chronologic:
|
if chronologic:
|
||||||
subs.order_by(models.BasicSubmission.submitted_date)
|
subs.order_by(models.BasicSubmission.submitted_date)
|
||||||
return subs.all()
|
return subs.all()
|
||||||
@@ -418,7 +420,7 @@ def lookup_org_by_name(ctx:Settings, name:str|None) -> models.Organization:
|
|||||||
# return ctx['database_session'].query(models.Organization).filter(models.Organization.name.startswith(name)).first()
|
# return ctx['database_session'].query(models.Organization).filter(models.Organization.name.startswith(name)).first()
|
||||||
return ctx.database_session.query(models.Organization).filter(models.Organization.name.startswith(name)).first()
|
return ctx.database_session.query(models.Organization).filter(models.Organization.name.startswith(name)).first()
|
||||||
|
|
||||||
def submissions_to_df(ctx:Settings, sub_type:str|None=None) -> pd.DataFrame:
|
def submissions_to_df(ctx:Settings, sub_type:str|None=None, limit:int=None) -> pd.DataFrame:
|
||||||
"""
|
"""
|
||||||
Convert submissions looked up by type to dataframe
|
Convert submissions looked up by type to dataframe
|
||||||
|
|
||||||
@@ -429,9 +431,10 @@ def submissions_to_df(ctx:Settings, sub_type:str|None=None) -> pd.DataFrame:
|
|||||||
Returns:
|
Returns:
|
||||||
pd.DataFrame: dataframe constructed from retrieved submissions
|
pd.DataFrame: dataframe constructed from retrieved submissions
|
||||||
"""
|
"""
|
||||||
logger.debug(f"Type: {sub_type}")
|
logger.debug(f"Querying Type: {sub_type}")
|
||||||
# use lookup function to create list of dicts
|
# use lookup function to create list of dicts
|
||||||
subs = [item.to_dict() for item in lookup_all_submissions_by_type(ctx=ctx, sub_type=sub_type, chronologic=True)]
|
subs = [item.to_dict() for item in lookup_all_submissions_by_type(ctx=ctx, sub_type=sub_type, chronologic=True, limit=100)]
|
||||||
|
logger.debug(f"Got {len(subs)} results.")
|
||||||
# make df from dicts (records) in list
|
# make df from dicts (records) in list
|
||||||
df = pd.DataFrame.from_records(subs)
|
df = pd.DataFrame.from_records(subs)
|
||||||
# Exclude sub information
|
# Exclude sub information
|
||||||
|
|||||||
@@ -55,7 +55,10 @@ class Control(Base):
|
|||||||
dict: output dictionary containing: Name, Type, Targets, Top Kraken results
|
dict: output dictionary containing: Name, Type, Targets, Top Kraken results
|
||||||
"""
|
"""
|
||||||
# load json string into dict
|
# load json string into dict
|
||||||
kraken = json.loads(self.kraken)
|
try:
|
||||||
|
kraken = json.loads(self.kraken)
|
||||||
|
except TypeError:
|
||||||
|
kraken = {}
|
||||||
# calculate kraken count total to use in percentage
|
# calculate kraken count total to use in percentage
|
||||||
kraken_cnt_total = sum([kraken[item]['kraken_count'] for item in kraken])
|
kraken_cnt_total = sum([kraken[item]['kraken_count'] for item in kraken])
|
||||||
new_kraken = []
|
new_kraken = []
|
||||||
@@ -91,7 +94,10 @@ class Control(Base):
|
|||||||
"""
|
"""
|
||||||
output = []
|
output = []
|
||||||
# load json string for mode (i.e. contains, matches, kraken2)
|
# load json string for mode (i.e. contains, matches, kraken2)
|
||||||
data = json.loads(getattr(self, mode))
|
try:
|
||||||
|
data = json.loads(getattr(self, mode))
|
||||||
|
except TypeError:
|
||||||
|
data = {}
|
||||||
logger.debug(f"Length of data: {len(data)}")
|
logger.debug(f"Length of data: {len(data)}")
|
||||||
# dict keys are genera of bacteria, e.g. 'Streptococcus'
|
# dict keys are genera of bacteria, e.g. 'Streptococcus'
|
||||||
for genus in data:
|
for genus in data:
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ class BasicSubmission(Base):
|
|||||||
"""
|
"""
|
||||||
return f"{self.rsl_plate_num} - {self.submitter_plate_num}"
|
return f"{self.rsl_plate_num} - {self.submitter_plate_num}"
|
||||||
|
|
||||||
def to_dict(self) -> dict:
|
def to_dict(self, full_data:bool=False) -> dict:
|
||||||
"""
|
"""
|
||||||
dictionary used in submissions summary
|
dictionary used in submissions summary
|
||||||
|
|
||||||
@@ -82,6 +82,7 @@ class BasicSubmission(Base):
|
|||||||
dict: dictionary used in submissions summary
|
dict: dictionary used in submissions summary
|
||||||
"""
|
"""
|
||||||
# get lab from nested organization object
|
# get lab from nested organization object
|
||||||
|
logger.debug(f"Converting {self.rsl_plate_num} to dict...")
|
||||||
try:
|
try:
|
||||||
sub_lab = self.submitting_lab.name
|
sub_lab = self.submitting_lab.name
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
@@ -104,16 +105,20 @@ class BasicSubmission(Base):
|
|||||||
ext_info = None
|
ext_info = None
|
||||||
logger.debug(f"Json error in {self.rsl_plate_num}: {e}")
|
logger.debug(f"Json error in {self.rsl_plate_num}: {e}")
|
||||||
# Updated 2023-09 to use the extraction kit to pull reagents.
|
# Updated 2023-09 to use the extraction kit to pull reagents.
|
||||||
try:
|
if full_data:
|
||||||
reagents = [item.to_sub_dict(extraction_kit=self.extraction_kit) for item in self.reagents]
|
try:
|
||||||
except Exception as e:
|
reagents = [item.to_sub_dict(extraction_kit=self.extraction_kit) for item in self.reagents]
|
||||||
logger.error(f"We got an error retrieving reagents: {e}")
|
except Exception as e:
|
||||||
|
logger.error(f"We got an error retrieving reagents: {e}")
|
||||||
|
reagents = None
|
||||||
|
samples = [item.sample.to_sub_dict(submission_rsl=self.rsl_plate_num) for item in self.submission_sample_associations]
|
||||||
|
else:
|
||||||
reagents = None
|
reagents = None
|
||||||
samples = []
|
samples = None
|
||||||
# Updated 2023-09 to get sample association with plate number
|
# Updated 2023-09 to get sample association with plate number
|
||||||
for item in self.submission_sample_associations:
|
# for item in self.submission_sample_associations:
|
||||||
sample = item.sample.to_sub_dict(submission_rsl=self.rsl_plate_num)
|
# sample = item.sample.to_sub_dict(submission_rsl=self.rsl_plate_num)
|
||||||
samples.append(sample)
|
# samples.append(sample)
|
||||||
try:
|
try:
|
||||||
comments = self.comment
|
comments = self.comment
|
||||||
except:
|
except:
|
||||||
@@ -240,15 +245,16 @@ class BacterialCulture(BasicSubmission):
|
|||||||
controls = relationship("Control", back_populates="submission", uselist=True) #: A control sample added to submission
|
controls = relationship("Control", back_populates="submission", uselist=True) #: A control sample added to submission
|
||||||
__mapper_args__ = {"polymorphic_identity": "Bacterial Culture", "polymorphic_load": "inline"}
|
__mapper_args__ = {"polymorphic_identity": "Bacterial Culture", "polymorphic_load": "inline"}
|
||||||
|
|
||||||
def to_dict(self) -> dict:
|
def to_dict(self, full_data:bool=False) -> dict:
|
||||||
"""
|
"""
|
||||||
Extends parent class method to add controls to dict
|
Extends parent class method to add controls to dict
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dict: dictionary used in submissions summary
|
dict: dictionary used in submissions summary
|
||||||
"""
|
"""
|
||||||
output = super().to_dict()
|
output = super().to_dict(full_data=full_data)
|
||||||
output['controls'] = [item.to_sub_dict() for item in self.controls]
|
if full_data:
|
||||||
|
output['controls'] = [item.to_sub_dict() for item in self.controls]
|
||||||
return output
|
return output
|
||||||
|
|
||||||
class Wastewater(BasicSubmission):
|
class Wastewater(BasicSubmission):
|
||||||
@@ -260,14 +266,14 @@ class Wastewater(BasicSubmission):
|
|||||||
pcr_technician = Column(String(64))
|
pcr_technician = Column(String(64))
|
||||||
__mapper_args__ = {"polymorphic_identity": "Wastewater", "polymorphic_load": "inline"}
|
__mapper_args__ = {"polymorphic_identity": "Wastewater", "polymorphic_load": "inline"}
|
||||||
|
|
||||||
def to_dict(self) -> dict:
|
def to_dict(self, full_data:bool=False) -> dict:
|
||||||
"""
|
"""
|
||||||
Extends parent class method to add controls to dict
|
Extends parent class method to add controls to dict
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dict: dictionary used in submissions summary
|
dict: dictionary used in submissions summary
|
||||||
"""
|
"""
|
||||||
output = super().to_dict()
|
output = super().to_dict(full_data=full_data)
|
||||||
try:
|
try:
|
||||||
output['pcr_info'] = json.loads(self.pcr_info)
|
output['pcr_info'] = json.loads(self.pcr_info)
|
||||||
except TypeError as e:
|
except TypeError as e:
|
||||||
|
|||||||
@@ -335,7 +335,7 @@ class SampleParser(object):
|
|||||||
return df
|
return df
|
||||||
|
|
||||||
def create_basic_dictionaries_from_plate_map(self):
|
def create_basic_dictionaries_from_plate_map(self):
|
||||||
invalids = [0, "0"]
|
invalids = [0, "0", "EMPTY"]
|
||||||
new_df = self.plate_map.dropna(axis=1, how='all')
|
new_df = self.plate_map.dropna(axis=1, how='all')
|
||||||
columns = new_df.columns.tolist()
|
columns = new_df.columns.tolist()
|
||||||
for _, iii in new_df.iterrows():
|
for _, iii in new_df.iterrows():
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ from backend.db import (
|
|||||||
)
|
)
|
||||||
# from .main_window_functions import *
|
# from .main_window_functions import *
|
||||||
from .all_window_functions import extract_form_info
|
from .all_window_functions import extract_form_info
|
||||||
from tools import check_if_app
|
from tools import check_if_app, Settings
|
||||||
from frontend.custom_widgets import SubmissionsSheet, AlertPop, AddReagentForm, KitAdder, ControlsDatePicker
|
from frontend.custom_widgets import SubmissionsSheet, AlertPop, AddReagentForm, KitAdder, ControlsDatePicker
|
||||||
import logging
|
import logging
|
||||||
from datetime import date
|
from datetime import date
|
||||||
@@ -27,8 +27,8 @@ logger.info("Hello, I am a logger")
|
|||||||
|
|
||||||
class App(QMainWindow):
|
class App(QMainWindow):
|
||||||
|
|
||||||
def __init__(self, ctx: dict = {}):
|
def __init__(self, ctx: Settings = {}):
|
||||||
|
logger.debug(f"Initializing main window...")
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ctx = ctx
|
self.ctx = ctx
|
||||||
# indicate version and connected database in title bar
|
# indicate version and connected database in title bar
|
||||||
@@ -59,6 +59,7 @@ class App(QMainWindow):
|
|||||||
"""
|
"""
|
||||||
adds items to menu bar
|
adds items to menu bar
|
||||||
"""
|
"""
|
||||||
|
logger.debug(f"Creating menu bar...")
|
||||||
menuBar = self.menuBar()
|
menuBar = self.menuBar()
|
||||||
fileMenu = menuBar.addMenu("&File")
|
fileMenu = menuBar.addMenu("&File")
|
||||||
# Creating menus using a title
|
# Creating menus using a title
|
||||||
@@ -79,6 +80,7 @@ class App(QMainWindow):
|
|||||||
"""
|
"""
|
||||||
adds items to toolbar
|
adds items to toolbar
|
||||||
"""
|
"""
|
||||||
|
logger.debug(f"Creating toolbar...")
|
||||||
toolbar = QToolBar("My main toolbar")
|
toolbar = QToolBar("My main toolbar")
|
||||||
self.addToolBar(toolbar)
|
self.addToolBar(toolbar)
|
||||||
toolbar.addAction(self.addReagentAction)
|
toolbar.addAction(self.addReagentAction)
|
||||||
@@ -89,6 +91,7 @@ class App(QMainWindow):
|
|||||||
"""
|
"""
|
||||||
creates actions
|
creates actions
|
||||||
"""
|
"""
|
||||||
|
logger.debug(f"Creating actions...")
|
||||||
self.importAction = QAction("&Import Submission", self)
|
self.importAction = QAction("&Import Submission", self)
|
||||||
self.importPCRAction = QAction("&Import PCR Results", self)
|
self.importPCRAction = QAction("&Import PCR Results", self)
|
||||||
self.addReagentAction = QAction("Add Reagent", self)
|
self.addReagentAction = QAction("Add Reagent", self)
|
||||||
@@ -106,6 +109,7 @@ class App(QMainWindow):
|
|||||||
"""
|
"""
|
||||||
connect menu and tool bar item to functions
|
connect menu and tool bar item to functions
|
||||||
"""
|
"""
|
||||||
|
logger.debug(f"Connecting actions...")
|
||||||
self.importAction.triggered.connect(self.importSubmission)
|
self.importAction.triggered.connect(self.importSubmission)
|
||||||
self.importPCRAction.triggered.connect(self.importPCRResults)
|
self.importPCRAction.triggered.connect(self.importPCRResults)
|
||||||
self.addReagentAction.triggered.connect(self.add_reagent)
|
self.addReagentAction.triggered.connect(self.add_reagent)
|
||||||
@@ -126,7 +130,7 @@ class App(QMainWindow):
|
|||||||
"""
|
"""
|
||||||
Show the 'about' message
|
Show the 'about' message
|
||||||
"""
|
"""
|
||||||
output = f"Version: {self.ctx['package'].__version__}\n\nAuthor: {self.ctx['package'].__author__['name']} - {self.ctx['package'].__author__['email']}\n\nCopyright: {self.ctx['package'].__copyright__}"
|
output = f"Version: {self.ctx.package.__version__}\n\nAuthor: {self.ctx.package.__author__['name']} - {self.ctx.package.__author__['email']}\n\nCopyright: {self.ctx.package.__copyright__}"
|
||||||
about = AlertPop(message=output, status="information")
|
about = AlertPop(message=output, status="information")
|
||||||
about.exec()
|
about.exec()
|
||||||
|
|
||||||
@@ -289,6 +293,7 @@ class App(QMainWindow):
|
|||||||
class AddSubForm(QWidget):
|
class AddSubForm(QWidget):
|
||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
|
logger.debug(f"Initializating subform...")
|
||||||
super(QWidget, self).__init__(parent)
|
super(QWidget, self).__init__(parent)
|
||||||
self.layout = QVBoxLayout(self)
|
self.layout = QVBoxLayout(self)
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ from PyQt6.QtCore import Qt, QAbstractTableModel, QSortFilterProxyModel
|
|||||||
from PyQt6.QtGui import QAction, QCursor, QPixmap, QPainter
|
from PyQt6.QtGui import QAction, QCursor, QPixmap, QPainter
|
||||||
from backend.db import submissions_to_df, lookup_submission_by_id, delete_submission_by_id, lookup_submission_by_rsl_num, hitpick_plate
|
from backend.db import submissions_to_df, lookup_submission_by_id, delete_submission_by_id, lookup_submission_by_rsl_num, hitpick_plate
|
||||||
from backend.excel import make_hitpicks
|
from backend.excel import make_hitpicks
|
||||||
from tools import check_if_app
|
from tools import check_if_app, Settings
|
||||||
from tools import jinja_template_loading
|
from tools import jinja_template_loading
|
||||||
from xhtml2pdf import pisa
|
from xhtml2pdf import pisa
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -78,7 +78,7 @@ class SubmissionsSheet(QTableView):
|
|||||||
"""
|
"""
|
||||||
presents submission summary to user in tab1
|
presents submission summary to user in tab1
|
||||||
"""
|
"""
|
||||||
def __init__(self, ctx:dict) -> None:
|
def __init__(self, ctx:Settings) -> None:
|
||||||
"""
|
"""
|
||||||
initialize
|
initialize
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ class SubmissionsSheet(QTableView):
|
|||||||
"""
|
"""
|
||||||
sets data in model
|
sets data in model
|
||||||
"""
|
"""
|
||||||
self.data = submissions_to_df(ctx=self.ctx)
|
self.data = submissions_to_df(ctx=self.ctx, limit=100)
|
||||||
try:
|
try:
|
||||||
self.data['id'] = self.data['id'].apply(str)
|
self.data['id'] = self.data['id'].apply(str)
|
||||||
self.data['id'] = self.data['id'].str.zfill(3)
|
self.data['id'] = self.data['id'].str.zfill(3)
|
||||||
@@ -269,7 +269,7 @@ class SubmissionDetails(QDialog):
|
|||||||
# get submision from db
|
# get submision from db
|
||||||
data = lookup_submission_by_id(ctx=ctx, id=id)
|
data = lookup_submission_by_id(ctx=ctx, id=id)
|
||||||
logger.debug(f"Submission details data:\n{pprint.pformat(data.to_dict())}")
|
logger.debug(f"Submission details data:\n{pprint.pformat(data.to_dict())}")
|
||||||
self.base_dict = data.to_dict()
|
self.base_dict = data.to_dict(full_data=True)
|
||||||
# don't want id
|
# don't want id
|
||||||
del self.base_dict['id']
|
del self.base_dict['id']
|
||||||
# retrieve jinja template
|
# retrieve jinja template
|
||||||
|
|||||||
@@ -87,25 +87,6 @@ def convert_nans_to_nones(input_str) -> str|None:
|
|||||||
return input_str
|
return input_str
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def check_is_power_user(ctx:dict) -> bool:
|
|
||||||
"""
|
|
||||||
Check to ensure current user is in power users list.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
ctx (dict): settings passed down from gui.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
bool: True if user is in power users, else false.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
check = getpass.getuser() in ctx.power_users
|
|
||||||
except KeyError as e:
|
|
||||||
check = False
|
|
||||||
except Exception as e:
|
|
||||||
logger.debug(f"Check encountered unknown error: {type(e).__name__} - {e}")
|
|
||||||
check = False
|
|
||||||
return check
|
|
||||||
|
|
||||||
def create_reagent_list(in_dict:dict) -> list[str]:
|
def create_reagent_list(in_dict:dict) -> list[str]:
|
||||||
"""
|
"""
|
||||||
Makes list of reagent types without "lot\_" prefix for each key in a dictionary
|
Makes list of reagent types without "lot\_" prefix for each key in a dictionary
|
||||||
@@ -118,21 +99,6 @@ def create_reagent_list(in_dict:dict) -> list[str]:
|
|||||||
"""
|
"""
|
||||||
return [item.strip("lot_") for item in in_dict.keys()]
|
return [item.strip("lot_") for item in in_dict.keys()]
|
||||||
|
|
||||||
def check_if_app(ctx:dict=None) -> bool:
|
|
||||||
"""
|
|
||||||
Checks if the program is running from pyinstaller compiled
|
|
||||||
|
|
||||||
Args:
|
|
||||||
ctx (dict, optional): Settings passed down from gui. Defaults to None.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
bool: True if running from pyinstaller. Else False.
|
|
||||||
"""
|
|
||||||
if getattr(sys, 'frozen', False):
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
def retrieve_rsl_number(in_str:str) -> Tuple[str, str]:
|
def retrieve_rsl_number(in_str:str) -> Tuple[str, str]:
|
||||||
"""
|
"""
|
||||||
Uses regex to retrieve the plate number and submission type from an input string
|
Uses regex to retrieve the plate number and submission type from an input string
|
||||||
@@ -356,8 +322,8 @@ class Settings(BaseSettings):
|
|||||||
directory_path: Path
|
directory_path: Path
|
||||||
database_path: Path|None = None
|
database_path: Path|None = None
|
||||||
backup_path: Path
|
backup_path: Path
|
||||||
super_users: list
|
super_users: list|None = None
|
||||||
power_users: list
|
power_users: list|None = None
|
||||||
rerun_regex: str
|
rerun_regex: str
|
||||||
submission_types: dict|None = None
|
submission_types: dict|None = None
|
||||||
database_session: Session|None = None
|
database_session: Session|None = None
|
||||||
@@ -431,6 +397,7 @@ def get_config(settings_path: Path|str|None=None) -> dict:
|
|||||||
Returns:
|
Returns:
|
||||||
Settings: Pydantic settings object
|
Settings: Pydantic settings object
|
||||||
"""
|
"""
|
||||||
|
logger.debug(f"Creating settings...")
|
||||||
if isinstance(settings_path, str):
|
if isinstance(settings_path, str):
|
||||||
settings_path = Path(settings_path)
|
settings_path = Path(settings_path)
|
||||||
# custom pyyaml constructor to join fields
|
# custom pyyaml constructor to join fields
|
||||||
@@ -450,8 +417,8 @@ def get_config(settings_path: Path|str|None=None) -> dict:
|
|||||||
LOGDIR.mkdir(parents=True)
|
LOGDIR.mkdir(parents=True)
|
||||||
except FileExistsError:
|
except FileExistsError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# if user hasn't defined config path in cli args
|
# if user hasn't defined config path in cli args
|
||||||
copy_settings_trigger = False
|
|
||||||
if settings_path == None:
|
if settings_path == None:
|
||||||
# Check user .config/submissions directory
|
# Check user .config/submissions directory
|
||||||
if CONFIGDIR.joinpath("config.yml").exists():
|
if CONFIGDIR.joinpath("config.yml").exists():
|
||||||
@@ -466,10 +433,12 @@ def get_config(settings_path: Path|str|None=None) -> dict:
|
|||||||
settings_path = Path(sys._MEIPASS).joinpath("files", "config.yml")
|
settings_path = Path(sys._MEIPASS).joinpath("files", "config.yml")
|
||||||
else:
|
else:
|
||||||
settings_path = package_dir.joinpath('config.yml')
|
settings_path = package_dir.joinpath('config.yml')
|
||||||
|
with open(settings_path, "r") as dset:
|
||||||
|
default_settings = yaml.load(dset, Loader=yaml.Loader)
|
||||||
# Tell program we need to copy the config.yml to the user directory
|
# Tell program we need to copy the config.yml to the user directory
|
||||||
# copy_settings_trigger = True
|
# copy_settings_trigger = True
|
||||||
# copy settings to config directory
|
# copy settings to config directory
|
||||||
return Settings(**copy_settings(settings_path=CONFIGDIR.joinpath("config.yml"), settings=settings))
|
return Settings(**copy_settings(settings_path=CONFIGDIR.joinpath("config.yml"), settings=default_settings))
|
||||||
else:
|
else:
|
||||||
# check if user defined path is directory
|
# check if user defined path is directory
|
||||||
if settings_path.is_dir():
|
if settings_path.is_dir():
|
||||||
@@ -478,9 +447,11 @@ def get_config(settings_path: Path|str|None=None) -> dict:
|
|||||||
elif settings_path.is_file():
|
elif settings_path.is_file():
|
||||||
settings_path = settings_path
|
settings_path = settings_path
|
||||||
else:
|
else:
|
||||||
logger.error("No config.yml file found. Cannot continue.")
|
logger.error("No config.yml file found. Writing to directory.")
|
||||||
raise FileNotFoundError("No config.yml file found. Cannot continue.")
|
# raise FileNotFoundError("No config.yml file found. Cannot continue.")
|
||||||
return {}
|
with open(settings_path, "r") as dset:
|
||||||
|
default_settings = yaml.load(dset, Loader=yaml.Loader)
|
||||||
|
return Settings(**copy_settings(settings_path=settings_path, settings=default_settings))
|
||||||
logger.debug(f"Using {settings_path} for config file.")
|
logger.debug(f"Using {settings_path} for config file.")
|
||||||
with open(settings_path, "r") as stream:
|
with open(settings_path, "r") as stream:
|
||||||
# try:
|
# try:
|
||||||
@@ -595,8 +566,9 @@ def copy_settings(settings_path:Path, settings:dict) -> dict:
|
|||||||
del settings['super_users']
|
del settings['super_users']
|
||||||
if not getpass.getuser() in settings['power_users']:
|
if not getpass.getuser() in settings['power_users']:
|
||||||
del settings['power_users']
|
del settings['power_users']
|
||||||
with open(settings_path, 'w') as f:
|
if not settings_path.exists():
|
||||||
yaml.dump(settings, f)
|
with open(settings_path, 'w') as f:
|
||||||
|
yaml.dump(settings, f)
|
||||||
return settings
|
return settings
|
||||||
|
|
||||||
def jinja_template_loading():
|
def jinja_template_loading():
|
||||||
@@ -615,3 +587,38 @@ def jinja_template_loading():
|
|||||||
loader = FileSystemLoader(loader_path)
|
loader = FileSystemLoader(loader_path)
|
||||||
env = Environment(loader=loader)
|
env = Environment(loader=loader)
|
||||||
return env
|
return env
|
||||||
|
|
||||||
|
def check_is_power_user(ctx:Settings) -> bool:
|
||||||
|
"""
|
||||||
|
Check to ensure current user is in power users list.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
ctx (dict): settings passed down from gui.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True if user is in power users, else false.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
check = getpass.getuser() in ctx.power_users
|
||||||
|
except KeyError as e:
|
||||||
|
check = False
|
||||||
|
except Exception as e:
|
||||||
|
logger.debug(f"Check encountered unknown error: {type(e).__name__} - {e}")
|
||||||
|
check = False
|
||||||
|
return check
|
||||||
|
|
||||||
|
def check_if_app(ctx:Settings=None) -> bool:
|
||||||
|
"""
|
||||||
|
Checks if the program is running from pyinstaller compiled
|
||||||
|
|
||||||
|
Args:
|
||||||
|
ctx (dict, optional): Settings passed down from gui. Defaults to None.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True if running from pyinstaller. Else False.
|
||||||
|
"""
|
||||||
|
if getattr(sys, 'frozen', False):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
Reference in New Issue
Block a user