Exemplo n.º 1
0
def zip_recent_dls_unit(unit: str, _zip=True) -> Path:
    """Func for gui to find (optional zip) most recent dls folder by parsing date in folder title"""
    from smseventlog.gui import _global as gbl
    from smseventlog.gui.dialogs import msg_simple, msgbox

    p_dls = get_recent_dls_unit(unit=unit)

    if not p_dls is None:
        msg = f'Found DLS folder: {p_dls.name}, calculating size...'
        gbl.update_statusbar(msg)
        gbl.get_mainwindow().app.processEvents()

        size = fl.calc_size(p_dls)
        msg = f'Found DLS folder:\n\n{p_dls.name}\n{size}\n\nZip now?'

        if not msgbox(msg=msg, yesno=True):
            return

    else:
        msg = 'Couldn\'t find recent DLS folder, check folder structure for issues.'
        msg_simple(msg=msg, icon='warning')
        return

    if _zip:
        p_zip = fl.zip_folder_threadsafe(p_src=p_dls, delete=False)
        return p_zip
    else:
        return p_dls
Exemplo n.º 2
0
        def wrapper(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except Exception as exc:
                log = get_logger_from_func(func)
                err_msg = f'Failed: {func.__name__}'
                if not msg is None:
                    err_msg = f'{err_msg} | {msg}'

                if status_msg:
                    from smseventlog.gui._global import update_statusbar
                    update_statusbar(msg)
                elif warn:
                    log.warning(err_msg)
                    if display:
                        display_error(exc=exc, msg=msg)
                elif err:
                    log_error(msg=msg,
                              display=display,
                              func=func,
                              exc_info=sys.exc_info())

                if discord:
                    from smseventlog import functions as f
                    f.discord(msg=format_traceback(exc_info=sys.exc_info()),
                              channel='err')

                return default  # default obj to return
Exemplo n.º 3
0
    def show(self, dls: bool = False) -> None:
        """Open main Event folder or downloads folder

        Parameters
        ----------
        dls : bool, optional
            open downloads folder, by default False
        """
        if not self.check():
            from smseventlog.gui import _global as gbl

            msg = f'Can\'t find unit folder: {self.p_unit}'
            gbl.update_statusbar(msg=msg, warn=True)
            return

        if not dls:
            p = self.p_unit
        else:
            p = self.p_dls_year if self.p_dls_year.exists() else self.p_dls

        fl.open_folder(p=p, check_drive=False)
Exemplo n.º 4
0
 def update_statusbar(self, msg=None, **kw):
     from smseventlog.gui._global import update_statusbar
     update_statusbar(msg=msg, **kw)
Exemplo n.º 5
0
    def setData(self,
                index: QModelIndex,
                val: Any,
                role: int = Qt.ItemDataRole.EditRole,
                triggers: bool = True,
                queue: bool = False,
                update_db: bool = True) -> Union[None, bool]:
        """Set data in TableView's underlying TableDataModel, usually save to database

        Parameters
        ----------
        index : QModelIndex
            index of item to update (passed in by default)
        val : Any
            value to set
        role : int, optional
            type of role, by default Qt.ItemDataRole.EditRole
        triggers : bool, optional
            allow other column update funcs to be triggered when value updated, by default True
        queue : bool, optional
            queue the data to be set to db later, by default False
        update_db : bool, optional
            update database, or only change value in TableView, by default True

        Returns
        -------
        Union[None, bool]
        """
        gbl.check_read_only()

        if not index.isValid():
            return False

        val_prev = index.data(
            role=Qt.ItemDataRole.EditRole
        )  # self.RawDataRole doesnt work great with pd.NA
        row, col = index.data(role=self.NameIndexRole)
        irow, icol = self.getRowCol(index)
        df = self.df

        # if val type doesn't match column dtype, try to enforce and convert
        m_type = {
            'object': str,
            'float64': float,
            'int64': int,
            'bool': bool,
            'datetime64[ns]': dt
        }
        m_conv = m_type.copy()  # bool/date need different func to convert
        m_conv |= {'bool': f.str_to_bool, 'datetime64[ns]': f.convert_date}

        dtype = self.get_dtype(icol=icol)

        # enforce dtypes
        if not type(val) == m_type[dtype]:
            try:
                # remove commas from floats
                if dtype in ('float64',
                             'int64') and type(val) == str and ',' in val:
                    val = val.replace(',', '')

                val = m_conv[dtype](val)
            except:
                # set numeric cols to None if given blank string
                if isinstance(val, str) and val.strip() == '':
                    val = None
                else:
                    msg = f'Error: incorrect data type "{type(val)}" for "{val}"'
                    gbl.update_statusbar(msg=msg)
                    return

        # set all blank strings to None
        if isinstance(val, str) and val.strip() == '':
            val = None

        # enforce other conditions (eg no_space for now)
        if icol in self.mcols['no_space'] and ' ' in val:
            msg = f'Error: Field "{self.get_col_name(icol)}" cannot have spaces. Value: "{val}"'
            gbl.update_statusbar(msg=msg)
            return

        # dont update db if value is same as previous
        if role == Qt.ItemDataRole.EditRole and val_prev != val:
            # keep original df copy in sync for future filtering
            self._df_orig.loc[row, col] = val
            df.loc[row, col] = val

            # set display vals, NOTE this could go into own func maybe
            if not pd.isnull(val):
                if col in self.formats.keys():
                    display_val = self.formats[col].format(val)
                else:
                    display_val = str(val)
            else:
                display_val = ''

            self.m_display[col][row] = display_val

            # set highlight color back to static dict
            func = self.highlight_funcs.get(col, None)
            if not func is None:
                self.m_color_bg[col][row] = func(
                    val=val, role=Qt.ItemDataRole.BackgroundRole)
                self.m_color_text[col][row] = func(
                    val=val, role=Qt.ItemDataRole.ForegroundRole)

            # reset stylemap for single col when val in dynamic_cols is changed
            if col in self.view.mcols['dynamic']:
                self.set_stylemap(col=col)

            # never try to update read-only column in db
            if not icol in self.mcols['disabled']:
                # either add items to the queue, or update single val
                if queue:
                    self.add_queue(vals={col: val}, irow=irow)
                elif update_db:
                    self.update_db(index=index, val=val)

                self.dataChanged.emit(index, index)

        # trigger column update funcs, stop other funcs from updating in a loop
        if triggers:
            func_list = self.view.col_func_triggers.get(
                col, None)  # dd of list of funcs to run
            if not func_list is None:
                for func in func_list:
                    func(index=index, val_new=val, val_prev=val_prev)

        return True
Exemplo n.º 6
0
 def clear_saved_tables(self):
     # reset dfs so they are forced to reload from the db
     from smseventlog.gui._global import update_statusbar
     self.dfs = {}
     update_statusbar('Saved database tables cleared.')