Example #1
0
    def get_tasks_as_geojson_feature_collection_no_geom(project_id):
        """
        Creates a geoJson.FeatureCollection object for all tasks related to the supplied project ID without geometry
        :param project_id: Owning project ID
        :return: geojson.FeatureCollection
        """
        project_tasks = (db.session.query(
            Task.id, Task.x, Task.y, Task.zoom, Task.is_square,
            Task.task_status).filter(Task.project_id == project_id).all())

        tasks_features = []
        for task in project_tasks:
            task_properties = dict(
                taskId=task.id,
                taskX=task.x,
                taskY=task.y,
                taskZoom=task.zoom,
                taskIsSquare=task.is_square,
                taskStatus=TaskStatus(task.task_status).name,
            )

            feature = geojson.Feature(properties=task_properties)
            tasks_features.append(feature)

        return geojson.FeatureCollection(tasks_features)
    def get_last_activity(project_id: int) -> ProjectLastActivityDTO:
        """ Gets the last activity for a project's tasks """

        results = (db.session.query(
            Task.id,
            Task.project_id,
            Task.task_status,
            Task.locked_by,
            Task.mapped_by,
            Task.validated_by,
        ).filter(Task.project_id == project_id).order_by(Task.id.asc()))
        last_activity_dto = ProjectLastActivityDTO()

        for item in results:
            latest = TaskStatusDTO()
            latest.task_id = item.id
            latest.task_status = TaskStatus(item.task_status).name
            latest_activity = (db.session.query(
                TaskHistory.action_date, TaskHistory.action,
                User.username).join(User).filter(
                    TaskHistory.task_id == item.id,
                    TaskHistory.project_id == project_id,
                    TaskHistory.action != "COMMENT",
                    User.id == TaskHistory.user_id,
                ).order_by(TaskHistory.id.desc()).first())
            if latest_activity:
                latest.action_date = latest_activity[0]
                latest.action_by = latest_activity[2]
            last_activity_dto.activity.append(latest)

        return last_activity_dto
Example #3
0
    def get_last_activity(project_id: int) -> ProjectLastActivityDTO:
        """ Gets the last activity for a project's tasks """
        sq = (TaskHistory.query.with_entities(
            TaskHistory.task_id,
            TaskHistory.action_date,
            TaskHistory.user_id,
        ).filter(TaskHistory.project_id == project_id).filter(
            TaskHistory.action != TaskAction.COMMENT.name).order_by(
                TaskHistory.task_id, TaskHistory.action_date.desc()).distinct(
                    TaskHistory.task_id).subquery())

        sq_statuses = (Task.query.with_entities(
            Task.id,
            Task.task_status).filter(Task.project_id == project_id).subquery())
        results = (db.session.query(
            sq_statuses.c.id,
            sq.c.action_date,
            sq_statuses.c.task_status,
            User.username,
        ).outerjoin(sq, sq.c.task_id == sq_statuses.c.id).outerjoin(
            User, User.id == sq.c.user_id).order_by(sq_statuses.c.id).all())

        dto = ProjectLastActivityDTO()
        dto.activity = [
            TaskStatusDTO(
                dict(
                    task_id=r.id,
                    task_status=TaskStatus(r.task_status).name,
                    action_date=r.action_date,
                    action_by=r.username,
                )) for r in results
        ]

        return dto
Example #4
0
    def unlock_task(self,
                    user_id,
                    new_state=None,
                    comment=None,
                    undo=False,
                    issues=None):
        """ Unlock task and ensure duration task locked is saved in History """
        if comment:
            self.set_task_history(
                action=TaskAction.COMMENT,
                comment=comment,
                user_id=user_id,
                mapping_issues=issues,
            )

        history = self.set_task_history(
            action=TaskAction.STATE_CHANGE,
            new_state=new_state,
            user_id=user_id,
            mapping_issues=issues,
        )

        if (new_state in [TaskStatus.MAPPED, TaskStatus.BADIMAGERY]
                and TaskStatus(
                    self.task_status) != TaskStatus.LOCKED_FOR_VALIDATION):
            # Don't set mapped if state being set back to mapped after validation
            self.mapped_by = user_id
        elif new_state == TaskStatus.VALIDATED:
            TaskInvalidationHistory.record_validation(self.project_id, self.id,
                                                      user_id, history)
            self.validated_by = user_id
        elif new_state == TaskStatus.INVALIDATED:
            TaskInvalidationHistory.record_invalidation(
                self.project_id, self.id, user_id, history)
            self.mapped_by = None
            self.validated_by = None

        if not undo:
            # Using a slightly evil side effect of Actions and Statuses having the same name here :)
            TaskHistory.update_task_locked_with_duration(
                self.id, self.project_id, TaskStatus(self.task_status),
                user_id)

        self.task_status = new_state.value
        self.locked_by = None
        self.update()
Example #5
0
    def is_mappable(self):
        """ Determines if task in scope is in suitable state for mapping """
        if TaskStatus(self.task_status) not in [
                TaskStatus.READY,
                TaskStatus.INVALIDATED,
        ]:
            return False

        return True
Example #6
0
    def get_locked_tasks_for_user(user_id: int):
        """ Gets tasks on project owned by specified user id"""
        tasks = Task.query.filter_by(locked_by=user_id)
        tasks_dto = LockedTasksForUser()
        for task in tasks:
            tasks_dto.locked_tasks.append(task.id)
            tasks_dto.project = task.project_id
            tasks_dto.task_status = TaskStatus(task.task_status).name

        return tasks_dto
Example #7
0
    def reset_lock(self, user_id, comment=None):
        """ Removes a current lock from a task, resets to last status and updates history with duration of lock """
        if comment:
            self.set_task_history(action=TaskAction.COMMENT,
                                  comment=comment,
                                  user_id=user_id)

        # Using a slightly evil side effect of Actions and Statuses having the same name here :)
        TaskHistory.update_task_locked_with_duration(
            self.id, self.project_id, TaskStatus(self.task_status), user_id)
        self.clear_lock()
Example #8
0
    def reset_task(self, user_id: int):
        if TaskStatus(self.task_status) in [
            TaskStatus.LOCKED_FOR_MAPPING,
            TaskStatus.LOCKED_FOR_VALIDATION,
        ]:
            self.record_auto_unlock()

        self.set_task_history(TaskAction.STATE_CHANGE, user_id, None, TaskStatus.READY)
        self.mapped_by = None
        self.validated_by = None
        self.locked_by = None
        self.task_status = TaskStatus.READY.value
        self.update()
Example #9
0
 def as_dto(
     self,
     task_history: List[TaskHistoryDTO] = [],
     last_updated: datetime.datetime = None,
 ):
     """Just converts to a TaskDTO"""
     task_dto = TaskDTO()
     task_dto.task_id = self.id
     task_dto.project_id = self.project_id
     task_dto.task_status = TaskStatus(self.task_status).name
     task_dto.lock_holder = self.lock_holder.username if self.lock_holder else None
     task_dto.task_history = task_history
     task_dto.last_updated = last_updated if last_updated else None
     task_dto.auto_unlock_seconds = Task.auto_unlock_delta().total_seconds()
     return task_dto
Example #10
0
    def reset_task(self, user_id: int):
        expiry_delta = Task.auto_unlock_delta()
        lock_duration = (datetime.datetime.min + expiry_delta).time().isoformat()
        if TaskStatus(self.task_status) in [
            TaskStatus.LOCKED_FOR_MAPPING,
            TaskStatus.LOCKED_FOR_VALIDATION,
        ]:
            self.record_auto_unlock(lock_duration)

        self.set_task_history(TaskAction.STATE_CHANGE, user_id, None, TaskStatus.READY)
        self.mapped_by = None
        self.validated_by = None
        self.locked_by = None
        self.task_status = TaskStatus.READY.value
        self.update()
Example #11
0
    def get_tasks_as_geojson_feature_collection(
        project_id,
        task_ids_str: str = None,
        order_by: str = None,
        order_by_type: str = "ASC",
        status: int = None,
    ):
        """
        Creates a geoJson.FeatureCollection object for tasks related to the supplied project ID
        :param project_id: Owning project ID
        :order_by: sorting option: available values update_date and building_area_diff
        :status: task status id to filter by
        :return: geojson.FeatureCollection
        """
        # subquery = (
        #     db.session.query(func.max(TaskHistory.action_date))
        #     .filter(
        #         Task.id == TaskHistory.task_id,
        #         Task.project_id == TaskHistory.project_id,
        #     )
        #     .correlate(Task)
        #     .group_by(Task.id)
        #     .label("update_date")
        # )
        query = db.session.query(
            Task.id,
            Task.x,
            Task.y,
            Task.zoom,
            Task.is_square,
            Task.task_status,
            Task.geometry.ST_AsGeoJSON().label("geojson"),
            Task.locked_by,
            # subquery,
        )

        filters = [Task.project_id == project_id]

        if task_ids_str:
            task_ids = map(int, task_ids_str.split(","))
            tasks = Task.get_tasks(project_id, task_ids)
            if not tasks or len(tasks) == 0:
                raise NotFound()
            else:
                tasks_filters = [task.id for task in tasks]
            filters = [
                Task.project_id == project_id,
                Task.id.in_(tasks_filters)
            ]
        else:
            tasks = Task.get_all_tasks(project_id)
            if not tasks or len(tasks) == 0:
                raise NotFound()

        if status:
            filters.append(Task.task_status == status)

        if order_by == "effort_prediction":
            query = query.outerjoin(TaskAnnotation).filter(*filters)
            if order_by_type == "DESC":
                query = query.order_by(
                    desc(
                        cast(
                            cast(
                                TaskAnnotation.
                                properties["building_area_diff"], Text),
                            Float,
                        )))
            else:
                query = query.order_by(
                    cast(
                        cast(TaskAnnotation.properties["building_area_diff"],
                             Text),
                        Float,
                    ))
        # elif order_by == "last_updated":
        #     if order_by_type == "DESC":
        #         query = query.filter(*filters).order_by(desc("update_date"))
        #     else:
        #         query = query.filter(*filters).order_by("update_date")
        else:
            query = query.filter(*filters)

        project_tasks = query.all()

        tasks_features = []
        for task in project_tasks:
            task_geometry = geojson.loads(task.geojson)
            task_properties = dict(
                taskId=task.id,
                taskX=task.x,
                taskY=task.y,
                taskZoom=task.zoom,
                taskIsSquare=task.is_square,
                taskStatus=TaskStatus(task.task_status).name,
                lockedBy=task.locked_by,
            )

            feature = geojson.Feature(geometry=task_geometry,
                                      properties=task_properties)
            tasks_features.append(feature)

        return geojson.FeatureCollection(tasks_features)