def cleanup_missing_tasks(self):
        from tabulate import tabulate

        rows: [TaskRow] = self.get_lazy_db_connection().get_all_tasks()

        failed = []

        for row in rows:
            if not os.path.exists(row.outputdir):
                failed.append((row.submission_id, row.outputdir))
                continue
            try:
                _ = WorkflowManager.from_path_with_submission_id(
                    row.outputdir, row.submission_id, readonly=True
                )
            except Exception as e:
                failed.append((row.submission_id, row.outputdir))

        if failed:
            Logger.warn(f"Removing the following tasks:\n" + tabulate(failed))

            if "y" in str(input(f"Remove {len(failed)} tasks (Y / n)? ")).lower():
                self.get_lazy_db_connection().remove_by_ids([r[0] for r in failed])
                Logger.info("Cleaned up tasks")
            else:
                Logger.info("Skipping cleaning of tasks")
    def get_from_path_or_submission(
        self, submission_id, readonly: bool, perform_path_check=True
    ):
        if perform_path_check:
            expanded_path = fully_qualify_filename(submission_id)
            if os.path.exists(expanded_path):
                return WorkflowManager.from_path_get_latest_manager(
                    expanded_path, readonly=readonly
                )

        potential_submission = self.get_lazy_db_connection().get_by_id(submission_id)
        if potential_submission:
            return WorkflowManager.from_path_with_submission_id(
                potential_submission.execution_dir,
                submission_id=submission_id,
                readonly=readonly,
            )

        raise Exception(
            f"Couldn't find task with id='{submission_id}', and no directory was found "
        )
    def remove_task(self, task: Union[str, TaskRow], keep_output: bool):
        if isinstance(task, str):
            wid = task
            task = self.get_lazy_db_connection().get_by_wid(task)
            if task is None:
                raise Exception("Couldn't find workflow with ID = " + wid)

        tm = WorkflowManager.from_path_with_submission_id(
            task.outputdir, task.submission_id
        )
        tm.cleanup_execution()
        tm.database.close()

        if not keep_output and os.path.exists(task.outputdir):
            Logger.info("Removing " + task.outputdir)
            rmtree(task.outputdir)
        else:
            Logger.info("Skipping output dir deletion, can't find: " + task.outputdir)

        self.get_lazy_db_connection().remove_by_id(task.submission_id)
        Logger.info("Deleted task: " + task.submission_id)