Beispiel #1
0
    def get_task_list_filtered_and_sorted(self, order=None, start=0, length=None, search_value=None, id_list=None,
                                          status=None, task_type=None):
        try:
            query = (Tasks.select())

            if id_list:
                query = query.where(Tasks.id.in_(id_list))

            if search_value:
                query = query.where(Tasks.abspath.contains(search_value))

            if status:
                query = query.where(Tasks.status.in_([status]))

            if task_type:
                query = query.where(Tasks.type.in_([task_type]))

            # Get order by
            order_by = None
            if order:
                if order.get("dir") == "asc":
                    order_by = attrgetter(order.get("column"))(Tasks).asc()
                else:
                    order_by = attrgetter(order.get("column"))(Tasks).desc()

            if order_by and length:
                query = query.order_by(order_by).limit(length).offset(start)

        except Tasks.DoesNotExist:
            # No task entries exist yet
            self._log("No tasks exist yet.", level="warning")
            query = []

        return query.dicts()
Beispiel #2
0
    def reorder_tasks(self, id_list, direction):
        # Get the task with the highest ID
        order = {
            "column": 'priority',
            "dir": 'desc',
        }
        pending_task_results = self.get_task_list_filtered_and_sorted(
            order=order,
            start=0,
            length=1,
            search_value=None,
            id_list=None,
            status=None)
        for pending_task_result in pending_task_results:
            task_top_priority = pending_task_result.get('priority')
            break

        # Add 500 to that number to offset it above all others.
        new_priority_offset = (int(task_top_priority) + 500)

        # Update the list of tasks by ID from the database adding the priority offset to their current priority
        # If the direction is to send it to the bottom, then set the priority as 0
        query = Tasks.update(
            priority=Tasks.priority +
            new_priority_offset if (direction == "top") else 0).where(
                Tasks.id.in_(id_list))
        return query.execute()
Beispiel #3
0
    def delete_tasks_recursively(self, id_list):
        """
        Deletes a given list of tasks based on their IDs

        :param id_list:
        :return:
        """
        # Prevent running if no list of IDs was given
        if not id_list:
            return False

        try:
            query = (Tasks.select())

            if id_list:
                query = query.where(Tasks.id.in_(id_list))

            for task_id in query:
                result = common.delete_model_recursively(task_id)
                if not result:
                    # break there and return
                    self._log("Failed to delete task ID: {}.".format(task_id),
                              level="warning")
                    return False

            return True

        except Tasks.DoesNotExist:
            # No task entries exist yet
            self._log("No tasks currently exist.", level="warning")
Beispiel #4
0
    def delete_tasks_recursively(self, id_list):
        """
        Deletes a given list of tasks based on their IDs

        :param id_list:
        :return:
        """
        # Prevent running if no list of IDs was given
        if not id_list:
            return False

        try:
            query = (Tasks.select())

            if id_list:
                query = query.where(Tasks.id.in_(id_list))

            for task_id in query:
                try:
                    task_id.delete_instance(recursive=True)
                except Exception as e:
                    # Catch delete exceptions
                    self._log("An error occurred while deleting task ID: {}.".format(task_id), str(e), level="exception")
                    return False

            return True

        except Tasks.DoesNotExist:
            # No task entries exist yet
            self._log("No tasks currently exist.", level="warning")
Beispiel #5
0
def build_tasks_query_full_task_list(status,
                                     sort_by='id',
                                     sort_order='asc',
                                     limit=None):
    """
    Return all task items in the task list filtered by status.
    The query is sorted by the self.sort_by and self.sort_order variables
    and may be limited by the limit variable.

    :param sort_order:
    :param sort_by:
    :param status:
    :param limit:
    :return:
    """
    query = Tasks.select(Tasks, TaskProbe).where(
        (Tasks.status == status)).join(TaskProbe)

    # Set the sort order
    if sort_order == 'asc':
        query = query.order_by(sort_by.asc())
    else:
        query = query.order_by(sort_by.desc())

    # Set query limit if one was given
    if limit:
        query = query.limit(limit)

    # Return results as dictionary
    return query.dicts()
Beispiel #6
0
def build_tasks_query(status, sort_by='id', sort_order='asc'):
    """
    Return the first task item in the task list filtered by status
    and sorted by the self.sort_by and self.sort_order variables.

    :param sort_order:
    :param sort_by:
    :param status:
    :return:
    """
    # pick query based on sort params
    if sort_order == 'asc':
        query = Tasks.select().where(
            (Tasks.status == status)).limit(1).order_by(sort_by.asc())
    else:
        query = Tasks.select().where(
            (Tasks.status == status)).limit(1).order_by(sort_by.desc())
    return query.first()
Beispiel #7
0
 def clear_tasks_on_startup(self):
     query = Tasks.delete()
     if not self.settings.get_clear_pending_tasks_on_restart():
         # Exclude all pending tasks except for those that are remote tasks... They need to be removed
         query = query.where((Tasks.status != 'pending')
                             | (Tasks.type == 'remote'))
     rows_deleted_count = query.execute()
     self._log(
         "Deleted {} items from tasks list".format(rows_deleted_count),
         level='debug')
Beispiel #8
0
    def set_tasks_library_id(id_list, library_id):
        """
        Updates the task library_id for a given list of tasks by ID

        :param id_list:
        :param library_id:
        :return:
        """
        query = Tasks.update(library_id=library_id).where(Tasks.id.in_(id_list))
        return query.execute()
Beispiel #9
0
    def set_tasks_status(id_list, status):
        """
        Updates the task status for a given list of tasks by ID

        :param id_list:
        :param status:
        :return:
        """
        query = Tasks.update(status=status).where(Tasks.id.in_(id_list))
        return query.execute()
Beispiel #10
0
    def read_and_set_task_by_absolute_path(self, abspath):
        """
        Sets the task by it's absolute path.
        If the task already exists in the list, then return that task.
        If the task does not yet exist in the list, create it first.

        :param abspath:
        :return:
        """
        # Get task matching the abspath
        self.task = Tasks.get(abspath=abspath)
Beispiel #11
0
    def check_if_task_exists_matching_path(abspath):
        """
        Check if a task already exists matching the given path

        :param abspath:
        :return:
        """
        existing_task_query = Tasks.select().where(
            (Tasks.abspath == abspath)).limit(1)
        if existing_task_query.count() > 0:
            return True
        return False
Beispiel #12
0
 def add_path_to_task_queue(self, pathname):
     # Check if file exists in task queue based on it's absolute path
     abspath = os.path.abspath(pathname)
     existing_task_query = Tasks.select().where(
         (Tasks.abspath == abspath)).limit(1)
     if existing_task_query.count() > 0:
         return False
     # Create the new task from the provide path
     new_task = self.create_task_from_path(pathname)
     if not new_task:
         return False
     return True
Beispiel #13
0
    def create_task_by_absolute_path(self, abspath, settings, source_data):
        """
        Creates the task by it's absolute path.
        If the task already exists in the list, then this will throw an exception and return false

        Calls to read_and_set_task_by_absolute_path() to read back all data out of the database.

        :param source_data:
        :param settings:
        :param abspath:
        :return:
        """
        try:
            self.task = Tasks.create(abspath=abspath, status='pending')
            self.save_task()
            self._log("Created new task with ID: {} for {}".format(
                self.task, abspath),
                      level="debug")

            # Save the current settings against this task
            self.create_task_settings_entry(settings, self.task)

            # Fetch the current file data and apply it to the task
            self.create_task_probe_entry(source_data, self.task)
            self._log("Set the source data", level="debug")

            # Read application settings and apply it to the task
            # Destination data is generated based on the settings saved against this task
            #   (not necessarily the current settings)
            destination_data = self.get_destination_data()
            self.set_destination_data(destination_data)
            self._log("Set the destination data", level="debug")

            # Set the cache path to use during the transcoding
            self.set_cache_path()

            # Set the default priority to the ID of the task
            self.task.priority = self.task.id

            # Save the task in order to save that cache path
            self.save_task()

            # Read back the task from the database (ensures that our data has been recorded correctly)
            self.read_and_set_task_by_absolute_path(abspath)
            self._log("Task read from database", level="debug")
            return True
        except IntegrityError as e:
            self._log("Cancel creating new task for {} - {}".format(
                abspath, e),
                      level="info")
            return False
Beispiel #14
0
def build_tasks_count_query(status):
    """
    Return a 0 if no tasks exist for the given status.
    Return a count >= 1 if any tasks exist for the given status.

    # TODO: look into peewee dynamic query building (surly this exists)

    :param status:
    :return:
    """
    # Fetch only on result in order to know that there are any at all
    # Filter by status
    query = Tasks.select().where((Tasks.status == status)).limit(1)
    return query.count()
Beispiel #15
0
 def set_task_by_fetching_first_in_filtered_list(self,
                                                 status,
                                                 sort_by='id',
                                                 sort_order='asc'):
     task_query = Tasks.select().where((Tasks.status == status)).limit(1)
     # Add sort params
     if sort_order == 'asc':
         task_query.order_by(sort_by.asc())
     else:
         task_query.order_by(sort_by.desc())
     self.task = task_query.first()
     if not self.task:
         return False
     self.read_task_settings_from_db()
     self.read_task_source_from_db()
Beispiel #16
0
    def create_task_by_absolute_path(self, abspath, task_type='local', library_id=1, priority_score=0):
        """
        Creates the task by it's absolute path.
        If the task already exists in the list, then this will throw an exception and return false

        Calls to read_and_set_task_by_absolute_path() to read back all data out of the database.

        :param abspath:
        :param task_type:
        :param library_id:
        :param priority_score:
        :return:
        """
        try:
            self.task = Tasks.create(abspath=abspath, status='creating', library_id=library_id)
            self.save()
            self._log("Created new task with ID: {} for {}".format(self.task, abspath), level="debug")

            # Set the cache path to use during the transcoding
            self.set_cache_path()

            # Fetch the library priority score also for this task
            library_priority_score = self.get_task_library_priority_score()

            # Set the default priority to the ID of the task
            self.task.priority = int(self.task.id) + int(library_priority_score) + int(priority_score)

            # Set the task type
            self.task.type = task_type

            # Only local tasks should be progressed automatically
            # Remote tasks need to be progressed to pending by a remote trigger
            if task_type == 'local':
                # Now set the status to pending. Only then will it be picked up by a worker.
                # This will also save the task.
                self.set_status('pending')
            else:
                # Save the tasks updates without settings status to pending
                self.save()

            return True
        except IntegrityError as e:
            self._log("Cancel creating new task for {} - {}".format(abspath, e), level="info")
            return False
Beispiel #17
0
def build_tasks_query(status,
                      sort_by='id',
                      sort_order='asc',
                      local_only=False,
                      library_names=None,
                      library_tags=None):
    """
    Return the first task item in the task list filtered by status
    and sorted by the self.sort_by and self.sort_order variables.

    :param status:
    :param sort_order:
    :param sort_by:
    :param local_only:
    :param library_names:
    :param library_tags:
    :return:
    """
    # pick query based on sort params
    query = Tasks.select().where((Tasks.status == status))

    # Limit to one result
    if local_only:
        query = query.where((Tasks.type == 'local'))

    query = query.join(Libraries, on=(Libraries.id == Tasks.library_id))
    if library_names is not None:
        query = query.where(Libraries.name.in_(library_names))
    if library_tags is not None:
        query = query.join(LibraryTags, join_type='LEFT OUTER JOIN')
        query = query.join(Tags, join_type='LEFT OUTER JOIN')
        if library_tags:
            query = query.where(Tags.name.in_(library_tags))
        else:
            # Handle a query where the list is empty. In this case we want to match for only libraries that have no tags
            query = query.where(Tags.name.is_null())

    # Limit to one result
    query = query.limit(1)
    if sort_order == 'asc':
        query = query.order_by(sort_by.asc())
    else:
        query = query.order_by(sort_by.desc())
    return query.first()
Beispiel #18
0
    def delete_tasks_recursively(self, id_list):
        """
        Deletes a given list of tasks based on their IDs

        :param id_list:
        :return:
        """
        # Prevent running if no list of IDs was given
        if not id_list:
            return False

        try:
            query = (Tasks.select())

            if id_list:
                query = query.where(Tasks.id.in_(id_list))

            for task_id in query:
                try:
                    # Remote tasks need to be cleaned up from the cache partition also
                    if task_id.type == 'remote':
                        remote_task_dirname = task_id.abspath
                        if os.path.exists(task_id.abspath) and "unmanic_remote_pending_library" in remote_task_dirname:
                            self._log("Removing remote pending library task '{}'.".format(remote_task_dirname))
                            shutil.rmtree(os.path.dirname(remote_task_dirname))

                    task_id.delete_instance(recursive=True)
                except Exception as e:
                    # Catch delete exceptions
                    self._log("An error occurred while deleting task ID: {}.".format(task_id), str(e), level="exception")
                    return False

            return True

        except Tasks.DoesNotExist:
            # No task entries exist yet
            self._log("No tasks currently exist.", level="warning")
Beispiel #19
0
 def get_total_task_list_count(self):
     task_query = Tasks.select().order_by(Tasks.id.desc())
     return task_query.count()
Beispiel #20
0
 def delete_all_tasks(self):
     rows_deleted_count = Tasks.delete().execute()
     self._log(
         "Deleted {} items from tasks list".format(rows_deleted_count),
         level='debug')