def get_todo_for_project_and_identifier( session: Session, identifier: t.Union[str, int], project: models.Project, ) -> models.ToDo: if identifier == 'l': todo = session.query(models.ToDo).filter( models.ToDo.project == project, ).order_by( models.ToDo.created_at.desc()).first() if todo is None: raise SimpleError('invalid todo') if todo.created_at < datetime.datetime.now() - datetime.timedelta( hours=1): raise SimpleError('todo too old for selecting as last') return todo todos = models.ToDo.get_list_for_identifier( session=session, identifier=identifier, base_query=models.ToDo.active_todos(session).filter( models.ToDo.project_id == project.id), ) if not todos: raise SimpleError('invalid todo') if len(todos) > 1: raise MultipleCandidateError( models.ToDo, sorted(todos, key=lambda _todo: (-_todo.priority.level, _todo.created_at), reverse=True), schemas.ToDoSchema(), ) return todos[0]
def modify_priority_level( todo: t.Union[str, int], priority: t.Union[str, int], project: models.Project, recursive: bool, ): todo = get_todo_for_project_and_identifier(SC.session, todo, project) priority_id = models.Priority.get_for_identifier_and_project( session = SC.session, project_id = todo.project_id, identifier = priority, target = models.Priority.id, ) if priority_id is None: return 'invalid priority', status.HTTP_400_BAD_REQUEST todo.priority_id = priority_id if recursive: for child in todo.traverse_children(): child.priority_id = priority_id SC.session.commit() return schemas.ToDoSchema().serialize(todo)
def comment_todo(target: t.Union[str, int], project: models.Project, comment: str): todo = get_todo_for_project_and_identifier(SC.session, target, project) comment = models.Comment(todo=todo, text=comment) SC.session.add(comment) SC.session.commit() return schemas.ToDoSchema().serialize(todo)
def dispatch_request( self, project: t.Union[str, int, None], tag: t.Optional[models.Tag], query: t.Optional[str], all_tasks: bool, flat: bool, limit: int, minimum_priority: t.Union[int, str, None], ignore_priority: bool, state: t.Optional[models.State], order_by: t.Optional[t.List[str]], ): project, level = get_project_and_minimum_priority( SC.session, project, minimum_priority, ignore_priority) todos = self.get_base_query().options( joinedload('tags'), joinedload('children'), joinedload('comments'), ).join(models.Priority) if order_by: todos = todos.order_by(*(self._order_by_map[s] for s in order_by)) else: todos = self.order_todos(todos) if project is not None: todos = todos.filter(models.ToDo.project_id == project.id) if level is not None: todos = todos.filter(models.Priority.level <= level) if state is not None: todos = todos.filter(models.ToDo.state == state) if not all_tasks: todos = todos.filter( ~exists().where( models.Dependency.child_id == models.ToDo.id), ) if query: todos = todos.filter(models.ToDo.text.contains(query)) if tag is not None: todos = todos.join( models.Tagged).filter(models.Tagged.tag_id == tag.id) todos = self.limit(todos, limit) schema = schemas.ToDoSchema(fields=self.get_schema_fields()) if flat: schema.fields = copy.copy(schema.fields) del schema.fields['children'] return {'todos': [schema.serialize(todo) for todo in todos]}
def add_dependency(parent: models.ToDo, child: models.ToDo): if parent in child.traverse_children(active_only=False): return 'Dependencies can not be circular', status.HTTP_400_BAD_REQUEST dependency = models.Dependency(parent_id=parent.id, child_id=child.id) SC.session.add(dependency) try: SC.session.commit() except (IntegrityError, OperationalError): SC.session.rollback() return 'Invalid args', status.HTTP_400_BAD_REQUEST return schemas.ToDoSchema().serialize(parent), status.HTTP_201_CREATED
def tag_todo(todo_target: t.Union[str, int], tag_target: models.Tag, project: models.Project, recursive: bool): todo = get_todo_for_project_and_identifier( SC.session, todo_target, project, ) todo.tags.append(tag_target) if recursive: for child in todo.traverse_children(): child.tags.append(tag_target) try: SC.session.commit() except (IntegrityError, OperationalError): SC.session.rollback() return 'Invalid args', status.HTTP_400_BAD_REQUEST return schemas.ToDoSchema().serialize(todo), status.HTTP_201_CREATED
def modify_todo_description(target: t.Union[int, str], project: models.Project, description: str): todo = get_todo_for_project_and_identifier(SC.session, target, project) todo.text = description SC.session.commit() return schemas.ToDoSchema().serialize(todo)