Exemplo n.º 1
0
    def GetHostRequest(self, request, context):
        with session_scope() as session:
            host_request = (session.query(HostRequest).filter(
                HostRequest.conversation_id == request.host_request_id).filter(
                    or_(HostRequest.from_user_id == context.user_id,
                        HostRequest.to_user_id ==
                        context.user_id)).one_or_none())

            if not host_request:
                context.abort(grpc.StatusCode.NOT_FOUND,
                              errors.HOST_REQUEST_NOT_FOUND)

            initial_message = (session.query(
                Message.time).filter(Message.conversation_id ==
                                     host_request.conversation_id).order_by(
                                         Message.id.asc()).limit(1).one())

            latest_message = (session.query(Message).filter(
                Message.conversation_id ==
                host_request.conversation_id).order_by(
                    Message.id.desc()).limit(1).one())

            return requests_pb2.HostRequest(
                host_request_id=host_request.conversation_id,
                from_user_id=host_request.from_user_id,
                to_user_id=host_request.to_user_id,
                status=hostrequeststatus2api[host_request.status],
                created=Timestamp_from_datetime(initial_message.time),
                from_date=date_to_api(host_request.from_date),
                to_date=date_to_api(host_request.to_date),
                last_seen_message_id=host_request.from_last_seen_message_id
                if context.user_id == host_request.from_user_id else
                host_request.to_last_seen_message_id,
                latest_message=message_to_pb(latest_message),
            )
Exemplo n.º 2
0
    def ListHostRequests(self, request, context):
        if request.only_sent and request.only_received:
            context.abort(grpc.StatusCode.INVALID_ARGUMENT,
                          errors.HOST_REQUEST_SENT_OR_RECEIVED)

        with session_scope() as session:
            pagination = request.number if request.number > 0 else DEFAULT_PAGINATION_LENGTH
            pagination = min(pagination, MAX_PAGE_SIZE)

            # By outer joining messages on itself where the second id is bigger, only the highest IDs will have
            # none as message_2.id. So just filter for these ones to get highest messages only.
            # See https://stackoverflow.com/a/27802817/6115336
            message_2 = aliased(Message)
            query = (session.query(
                Message, HostRequest, Conversation).outerjoin(
                    message_2,
                    and_(Message.conversation_id == message_2.conversation_id,
                         Message.id < message_2.id)).join(
                             HostRequest, HostRequest.conversation_id ==
                             Message.conversation_id).join(
                                 Conversation, Conversation.id ==
                                 HostRequest.conversation_id).filter(
                                     message_2.id == None).filter(
                                         or_(
                                             HostRequest.conversation_id <
                                             request.last_request_id,
                                             request.last_request_id == 0)))

            if request.only_sent:
                query = query.filter(
                    HostRequest.from_user_id == context.user_id)
            elif request.only_received:
                query = query.filter(HostRequest.to_user_id == context.user_id)
            else:
                query = query.filter(
                    or_(HostRequest.to_user_id == context.user_id,
                        HostRequest.from_user_id == context.user_id))

            # TODO: I considered having the latest control message be the single source of truth for
            # the HostRequest.status, but decided agains it because of this filter.
            # Another possibility is to filter in the python instead of SQL, but that's slower
            if request.only_active:
                query = query.filter(
                    or_(
                        HostRequest.status == HostRequestStatus.pending,
                        HostRequest.status == HostRequestStatus.accepted,
                        HostRequest.status == HostRequestStatus.confirmed,
                    ))
                query = query.filter(HostRequest.end_time <= func.now())

            query = query.order_by(Message.id.desc()).limit(pagination + 1)

            results = query.all()

            host_requests = [
                requests_pb2.HostRequest(
                    host_request_id=result.HostRequest.conversation_id,
                    from_user_id=result.HostRequest.from_user_id,
                    to_user_id=result.HostRequest.to_user_id,
                    status=hostrequeststatus2api[result.HostRequest.status],
                    created=Timestamp_from_datetime(
                        result.Conversation.created),
                    from_date=date_to_api(result.HostRequest.from_date),
                    to_date=date_to_api(result.HostRequest.to_date),
                    last_seen_message_id=result.HostRequest.
                    from_last_seen_message_id
                    if context.user_id == result.HostRequest.from_user_id else
                    result.HostRequest.to_last_seen_message_id,
                    latest_message=message_to_pb(result.Message),
                ) for result in results[:pagination]
            ]
            last_request_id = (min(
                map(
                    lambda g: g.HostRequest.conversation_id
                    if g.HostRequest else 1, results[:pagination]))
                               if len(results) > 0 else 0)  # TODO
            no_more = len(results) <= pagination

            return requests_pb2.ListHostRequestsRes(
                last_request_id=last_request_id,
                no_more=no_more,
                host_requests=host_requests)