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()
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()
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")
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")
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()
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()
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')
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()
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()
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)
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
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
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
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()
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()
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
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()
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")
def get_total_task_list_count(self): task_query = Tasks.select().order_by(Tasks.id.desc()) return task_query.count()
def delete_all_tasks(self): rows_deleted_count = Tasks.delete().execute() self._log( "Deleted {} items from tasks list".format(rows_deleted_count), level='debug')