Exemplo n.º 1
0
def _message_to_pb(message: Message):
    """
    Turns the given message to a protocol buffer
    """
    if message.is_normal_message:
        return conversations_pb2.Message(
            message_id=message.id,
            author_user_id=message.author_id,
            time=Timestamp_from_datetime(message.time),
            text=conversations_pb2.MessageContentText(text=message.text),
        )
    else:
        return conversations_pb2.Message(
            message_id=message.id,
            author_user_id=message.author_id,
            time=Timestamp_from_datetime(message.time),
            chat_created=conversations_pb2.MessageContentChatCreated()
            if message.message_type == MessageType.chat_created else None,
            chat_edited=conversations_pb2.MessageContentChatEdited()
            if message.message_type == MessageType.chat_edited else None,
            user_invited=conversations_pb2.MessageContentUserInvited(
                target_user_id=message.target_id)
            if message.message_type == MessageType.user_invited else None,
            user_left=conversations_pb2.MessageContentUserLeft()
            if message.message_type == MessageType.user_left else None,
            user_made_admin=conversations_pb2.MessageContentUserMadeAdmin(
                target_user_id=message.target_id)
            if message.message_type == MessageType.user_made_admin else None,
            user_removed_admin=conversations_pb2.
            MessageContentUserRemovedAdmin(target_user_id=message.target_id) if
            message.message_type == MessageType.user_removed_admin else None,
        )
Exemplo n.º 2
0
    def GetUser(self, request, context):
        with session_scope(self._Session) as session:
            user = get_user_by_field(session, request.user)
            if not user:
                context.abort(grpc.StatusCode.NOT_FOUND, "No such user.")

            return api_pb2.User(
                username=user.username,
                name=user.name,
                city=user.city,
                verification=user.verification,
                community_standing=user.community_standing,
                num_references=0,
                gender=user.gender,
                age=user.age,
                color=user.color,
                joined=Timestamp_from_datetime(user.display_joined),
                last_active=Timestamp_from_datetime(user.display_last_active),
                occupation=user.occupation,
                about_me=user.about_me,
                about_place=user.about_place,
                languages=user.languages.split("|") if user.languages else [],
                countries_visited=user.countries_visited.split("|")
                if user.countries_visited else [],
                countries_lived=user.countries_lived.split("|")
                if user.countries_lived else [],
                friends=get_friends_status(session, context.user_id, user.id),
            )
Exemplo n.º 3
0
    def InitiateMediaUpload(self, request, context):
        key = random_hex()

        created = now()
        expiry = created + timedelta(minutes=20)

        with session_scope() as session:
            upload = InitiatedUpload(key=key, created=created, expiry=expiry, initiator_user_id=context.user_id)
            session.add(upload)
            session.commit()

            req = media_pb2.UploadRequest(
                key=upload.key,
                type=media_pb2.UploadRequest.UploadType.IMAGE,
                created=Timestamp_from_datetime(upload.created),
                expiry=Timestamp_from_datetime(upload.expiry),
                max_width=2000,
                max_height=1600,
            ).SerializeToString()

        data = urlsafe_b64encode(req).decode("utf8")
        sig = urlsafe_b64encode(generate_hash_signature(req, config["MEDIA_SERVER_SECRET_KEY"])).decode("utf8")

        path = "upload?" + urlencode({"data": data, "sig": sig})

        return api_pb2.InitiateMediaUploadRes(
            upload_url=urls.media_upload_url(path),
            expiry=Timestamp_from_datetime(expiry),
        )
Exemplo n.º 4
0
def message_to_pb(message: Message):
    """
    Turns the given message to a protocol buffer
    """
    if message.is_normal_message:
        return conversations_pb2.Message(
            message_id=message.id,
            author_user_id=message.author_id,
            time=Timestamp_from_datetime(message.time),
            text=conversations_pb2.MessageContentText(text=message.text),
        )
    else:
        return conversations_pb2.Message(
            message_id=message.id,
            author_user_id=message.author_id,
            time=Timestamp_from_datetime(message.time),
            chat_created=conversations_pb2.MessageContentChatCreated()
            if message.message_type == MessageType.chat_created else None,
            host_request_status_changed=conversations_pb2.
            MessageContentHostRequestStatusChanged(
                status=hostrequeststatus2api[
                    message.host_request_status_target])
            if message.message_type == MessageType.host_request_status_changed
            else None,
        )
Exemplo n.º 5
0
 def Search(self, request, context):
     with session_scope(self._Session) as session:
         return api_pb2.SearchRes(
             users=[
                 api_pb2.User(
                     username=user.username,
                     name=user.name,
                     city=user.city,
                     verification=user.verification,
                     community_standing=user.community_standing,
                     num_references=0,
                     gender=user.gender,
                     age=user.age,
                     color=user.color,
                     joined=Timestamp_from_datetime(user.display_joined),
                     last_active=Timestamp_from_datetime(user.display_last_active),
                     occupation=user.occupation,
                     about_me=user.about_me,
                     about_place=user.about_place,
                     languages=user.languages.split("|") if user.languages else [],
                     countries_visited=user.countries_visited.split("|") if user.countries_visited else [],
                     countries_lived=user.countries_lived.split("|") if user.countries_lived else []
                 ) for user in session.query(User) \
                     .filter(
                         or_(
                             User.name.ilike(f"%{request.query}%"),
                             User.username.ilike(f"%{request.query}%"),
                         )
                     ) \
                     .all()
             ]
         )
Exemplo n.º 6
0
    def ListGroupChats(self, request, context):
        with session_scope(self._Session) as session:
            # select group chats where you have a subscription, and for each of
            # these, the latest message from them

            t = (session.query(
                GroupChatSubscription.group_chat_id.label("group_chat_id"),
                func.max(GroupChatSubscription.id).label(
                    "group_chat_subscriptions_id"),
                func.max(Message.id).label("message_id"),
            ).join(
                Message,
                Message.conversation_id == GroupChatSubscription.group_chat_id
            ).filter(GroupChatSubscription.user_id == context.user_id).filter(
                Message.time >= GroupChatSubscription.joined).filter(
                    or_(Message.time <= GroupChatSubscription.left,
                        GroupChatSubscription.left == None)).group_by(
                            GroupChatSubscription.group_chat_id).order_by(
                                func.max(Message.id).desc()).subquery())

            results = (session.query(
                t, GroupChat, GroupChatSubscription,
                Message).join(Message, Message.id == t.c.message_id).join(
                    GroupChatSubscription, GroupChatSubscription.id ==
                    t.c.group_chat_subscriptions_id).join(
                        GroupChat,
                        GroupChat.conversation_id == t.c.group_chat_id).filter(
                            or_(t.c.message_id <= request.last_message_id,
                                request.last_message_id == 0)).order_by(
                                    t.c.message_id.desc()).limit(
                                        PAGINATION_LENGTH + 1).all())

            return conversations_pb2.ListGroupChatsRes(
                group_chats=[
                    conversations_pb2.GroupChat(
                        group_chat_id=result.GroupChat.conversation_id,
                        title=result.GroupChat.
                        title,  # TODO: proper title for DMs, etc
                        member_user_ids=_get_visible_members_for_subscription(
                            result.GroupChatSubscription),
                        admin_user_ids=_get_visible_admins_for_subscription(
                            result.GroupChatSubscription),
                        only_admins_invite=result.GroupChat.only_admins_invite,
                        is_dm=result.GroupChat.is_dm,
                        created=Timestamp_from_datetime(
                            result.GroupChat.conversation.created),
                        unseen_message_count=result.GroupChatSubscription.
                        unseen_message_count,
                        last_seen_message_id=result.GroupChatSubscription.
                        last_seen_message_id,
                        latest_message=_message_to_pb(result.Message)
                        if result.Message else None,
                    ) for result in results[:PAGINATION_LENGTH]
                ],
                next_message_id=min(
                    map(lambda g: g.Message.id
                        if g.Message else 1, results[:PAGINATION_LENGTH])) -
                1 if len(results) > 0 else 0,  # TODO
                no_more=len(results) <= PAGINATION_LENGTH,
            )
Exemplo n.º 7
0
    def GetGroupChat(self, request, context):
        with session_scope() as session:
            result = session.execute(
                select(GroupChat, GroupChatSubscription, Message)
                .join(Message, Message.conversation_id == GroupChatSubscription.group_chat_id)
                .join(GroupChat, GroupChat.conversation_id == GroupChatSubscription.group_chat_id)
                .where(GroupChatSubscription.user_id == context.user_id)
                .where(GroupChatSubscription.group_chat_id == request.group_chat_id)
                .where(Message.time >= GroupChatSubscription.joined)
                .where(or_(Message.time <= GroupChatSubscription.left, GroupChatSubscription.left == None))
                .order_by(Message.id.desc())
            ).first()

            if not result:
                context.abort(grpc.StatusCode.NOT_FOUND, errors.CHAT_NOT_FOUND)

            return conversations_pb2.GroupChat(
                group_chat_id=result.GroupChat.conversation_id,
                title=result.GroupChat.title,
                member_user_ids=_get_visible_members_for_subscription(result.GroupChatSubscription),
                admin_user_ids=_get_visible_admins_for_subscription(result.GroupChatSubscription),
                only_admins_invite=result.GroupChat.only_admins_invite,
                is_dm=result.GroupChat.is_dm,
                created=Timestamp_from_datetime(result.GroupChat.conversation.created),
                unseen_message_count=_unseen_message_count(session, result.GroupChatSubscription.id),
                last_seen_message_id=result.GroupChatSubscription.last_seen_message_id,
                latest_message=_message_to_pb(result.Message) if result.Message else None,
                mute_info=_mute_info(result.GroupChatSubscription),
            )
Exemplo n.º 8
0
    def ListPendingReferencesToWrite(self, request, context):
        with session_scope() as session:
            q1 = (session.query(literal(True), HostRequest).outerjoin(
                Reference, Reference.host_request_id == HostRequest.
                conversation_id).filter(Reference.id == None).filter(
                    HostRequest.can_write_reference).filter(
                        HostRequest.from_user_id == context.user_id))

            q2 = (session.query(literal(False), HostRequest).outerjoin(
                Reference, Reference.host_request_id == HostRequest.
                conversation_id).filter(Reference.id == None).filter(
                    HostRequest.can_write_reference).filter(
                        HostRequest.to_user_id == context.user_id))

            host_request_references = q1.union_all(q2).order_by(
                HostRequest.end_time_to_write_reference.asc()).all()

            return references_pb2.ListPendingReferencesToWriteRes(
                pending_references=[
                    references_pb2.AvailableWriteReferenceType(
                        host_request_id=host_request.conversation_id,
                        reference_type=reftype2api[
                            ReferenceType.surfed if surfed else ReferenceType.
                            hosted],
                        time_expires=Timestamp_from_datetime(
                            host_request.end_time_to_write_reference),
                    ) for surfed, host_request in host_request_references
                ], )
Exemplo n.º 9
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.º 10
0
    def AvailableWriteReferences(self, request, context):
        # can't write anything for ourselves, but let's return empty so this can be used generically on profile page
        if request.to_user_id == context.user_id:
            return references_pb2.AvailableWriteReferencesRes()

        with session_scope() as session:
            if not session.execute(
                    select(User).where_users_visible(context).where(
                        User.id == request.to_user_id)).scalar_one_or_none():
                context.abort(grpc.StatusCode.NOT_FOUND, errors.USER_NOT_FOUND)

            can_write_friend_reference = (session.execute(
                select(Reference).where(
                    Reference.from_user_id == context.user_id).where(
                        Reference.to_user_id == request.to_user_id).where(
                            Reference.reference_type == ReferenceType.friend)).
                                          scalar_one_or_none()) is None

            q1 = (select(literal(True), HostRequest).outerjoin(
                Reference,
                and_(
                    Reference.host_request_id == HostRequest.conversation_id,
                    Reference.from_user_id == context.user_id,
                ),
            ).where(Reference.id == None).where(
                HostRequest.can_write_reference).where(
                    HostRequest.surfer_user_id == context.user_id).where(
                        HostRequest.host_user_id == request.to_user_id))

            q2 = (select(literal(False), HostRequest).outerjoin(
                Reference,
                and_(
                    Reference.host_request_id == HostRequest.conversation_id,
                    Reference.from_user_id == context.user_id,
                ),
            ).where(Reference.id == None).where(
                HostRequest.can_write_reference).where(
                    HostRequest.surfer_user_id == request.to_user_id).where(
                        HostRequest.host_user_id == context.user_id))

            union = union_all(q1, q2).order_by(
                HostRequest.end_time_to_write_reference.asc()).subquery()
            union = select(union.c[0].label("surfed"),
                           aliased(HostRequest, union))
            host_request_references = session.execute(union).all()

            return references_pb2.AvailableWriteReferencesRes(
                can_write_friend_reference=can_write_friend_reference,
                available_write_references=[
                    references_pb2.AvailableWriteReferenceType(
                        host_request_id=host_request.conversation_id,
                        reference_type=reftype2api[
                            ReferenceType.surfed if surfed else ReferenceType.
                            hosted],
                        time_expires=Timestamp_from_datetime(
                            host_request.end_time_to_write_reference),
                    ) for surfed, host_request in host_request_references
                ],
            )
Exemplo n.º 11
0
def reference_to_pb(reference: Reference, context):
    return references_pb2.Reference(
        reference_id=reference.id,
        from_user_id=reference.from_user_id,
        to_user_id=reference.to_user_id,
        reference_type=reftype2api[reference.reference_type],
        text=reference.text,
        written_time=Timestamp_from_datetime(
            reference.time.replace(hour=0, minute=0, second=0, microsecond=0)),
        host_request_id=reference.host_request_id if context.user_id
        in [reference.from_user_id, reference.to_user_id] else None,
    )
Exemplo n.º 12
0
def create_event(token, community_id, group_id, title, content, start_td):
    with events_session(token) as api:
        res = api.CreateEvent(
            events_pb2.CreateEventReq(
                title=title,
                content=content,
                offline_information=events_pb2.OfflineEventInformation(
                    address="Near Null Island",
                    lat=0.1,
                    lng=0.2,
                ),
                start_time=Timestamp_from_datetime(now() + start_td),
                end_time=Timestamp_from_datetime(now() + start_td +
                                                 timedelta(hours=2)),
                timezone="UTC",
            ))
        api.TransferEvent(
            events_pb2.TransferEventReq(
                event_id=res.event_id,
                new_owner_community_id=community_id,
                new_owner_group_id=group_id,
            ))
Exemplo n.º 13
0
    def GetDirectMessage(self, request, context):
        with session_scope(self._Session) as session:
            count = func.count(GroupChatSubscription.id).label("count")
            subquery = (session.query(
                GroupChatSubscription.group_chat_id).filter(
                    or_(
                        GroupChatSubscription.user_id == context.user_id,
                        GroupChatSubscription.user_id == request.user_id,
                    )).filter(GroupChatSubscription.left == None).join(
                        GroupChat, GroupChat.conversation_id ==
                        GroupChatSubscription.group_chat_id).filter(
                            GroupChat.is_dm == True).group_by(
                                GroupChatSubscription.group_chat_id).having(
                                    count == 2).subquery())

            result = (session.query(
                subquery, GroupChat, GroupChatSubscription, Message
            ).join(
                subquery, subquery.c.group_chat_id == GroupChat.conversation_id
            ).join(
                Message, Message.conversation_id == GroupChat.conversation_id
            ).filter(GroupChatSubscription.user_id == context.user_id).filter(
                GroupChatSubscription.group_chat_id == GroupChat.
                conversation_id).filter(
                    Message.time >= GroupChatSubscription.joined).filter(
                        or_(Message.time <= GroupChatSubscription.left,
                            GroupChatSubscription.left == None)).order_by(
                                Message.id.desc()).first())

            if not result:
                context.abort(grpc.StatusCode.NOT_FOUND,
                              "Couldn't find that chat.")

            return conversations_pb2.GroupChat(
                group_chat_id=result.GroupChat.conversation_id,
                title=result.GroupChat.title,
                member_user_ids=_get_visible_members_for_subscription(
                    result.GroupChatSubscription),
                admin_user_ids=_get_visible_admins_for_subscription(
                    result.GroupChatSubscription),
                only_admins_invite=result.GroupChat.only_admins_invite,
                is_dm=result.GroupChat.is_dm,
                created=Timestamp_from_datetime(
                    result.GroupChat.conversation.created),
                unseen_message_count=result.GroupChatSubscription.
                unseen_message_count,
                last_seen_message_id=result.GroupChatSubscription.
                last_seen_message_id,
                latest_message=_message_to_pb(result.Message)
                if result.Message else None,
            )
Exemplo n.º 14
0
def page_to_pb(page: Page, context):
    first_version = page.versions[0]
    current_version = page.versions[-1]

    owner_community_id = None
    owner_group_id = None
    if page.owner_cluster:
        if page.owner_cluster.is_official_cluster:
            owner_community_id = page.owner_cluster.parent_node_id
        else:
            owner_group_id = page.owner_cluster.id

    return pages_pb2.Page(
        page_id=page.id,
        type=pagetype2api[page.type],
        slug=current_version.slug,
        created=Timestamp_from_datetime(first_version.created),
        last_edited=Timestamp_from_datetime(current_version.created),
        last_editor_user_id=current_version.editor_user_id,
        creator_user_id=page.creator_user_id,
        owner_user_id=page.owner_user_id,
        owner_community_id=owner_community_id,
        owner_group_id=owner_group_id,
        thread=thread_to_pb(page.thread_id),
        title=current_version.title,
        content=current_version.content,
        photo_url=current_version.photo.full_url if current_version.photo_key else None,
        address=current_version.address,
        location=pages_pb2.Coordinate(
            lat=current_version.coordinates[0],
            lng=current_version.coordinates[1],
        )
        if current_version.coordinates
        else None,
        editor_user_ids=remove_duplicates_retain_order([version.editor_user_id for version in page.versions]),
        can_edit=_is_page_owner(page, context.user_id),
        can_moderate=_can_moderate_page(page, context.user_id),
    )
Exemplo n.º 15
0
def group_to_pb(cluster: Cluster, context):
    with session_scope() as session:
        can_moderate = can_moderate_node(session, context.user_id, cluster.parent_node_id)

        member_count = session.execute(
            select(func.count())
            .select_from(ClusterSubscription)
            .where_users_column_visible(context, ClusterSubscription.user_id)
            .where(ClusterSubscription.cluster_id == cluster.id)
        ).scalar_one()
        is_member = (
            session.execute(
                select(ClusterSubscription)
                .where(ClusterSubscription.user_id == context.user_id)
                .where(ClusterSubscription.cluster_id == cluster.id)
            ).scalar_one_or_none()
            is not None
        )

        admin_count = session.execute(
            select(func.count())
            .select_from(ClusterSubscription)
            .where_users_column_visible(context, ClusterSubscription.user_id)
            .where(ClusterSubscription.cluster_id == cluster.id)
            .where(ClusterSubscription.role == ClusterRole.admin)
        ).scalar_one()
        is_admin = (
            session.execute(
                select(ClusterSubscription)
                .where(ClusterSubscription.user_id == context.user_id)
                .where(ClusterSubscription.cluster_id == cluster.id)
                .where(ClusterSubscription.role == ClusterRole.admin)
            ).scalar_one_or_none()
            is not None
        )

    return groups_pb2.Group(
        group_id=cluster.id,
        name=cluster.name,
        slug=cluster.slug,
        description=cluster.description,
        created=Timestamp_from_datetime(cluster.created),
        parents=_parents_to_pb(cluster),
        main_page=page_to_pb(cluster.main_page, context),
        member=is_member,
        admin=is_admin,
        member_count=member_count,
        admin_count=admin_count,
        can_moderate=can_moderate,
    )
Exemplo n.º 16
0
def community_to_pb(node: Node, context):
    with session_scope() as session:
        can_moderate = can_moderate_node(session, context.user_id, node.id)

        member_count = session.execute(
            select(func.count())
            .select_from(ClusterSubscription)
            .where_users_column_visible(context, ClusterSubscription.user_id)
            .where(ClusterSubscription.cluster_id == node.official_cluster.id)
        ).scalar_one()
        is_member = (
            session.execute(
                select(ClusterSubscription)
                .where(ClusterSubscription.user_id == context.user_id)
                .where(ClusterSubscription.cluster_id == node.official_cluster.id)
            ).scalar_one_or_none()
            is not None
        )

        admin_count = session.execute(
            select(func.count())
            .select_from(ClusterSubscription)
            .where_users_column_visible(context, ClusterSubscription.user_id)
            .where(ClusterSubscription.cluster_id == node.official_cluster.id)
            .where(ClusterSubscription.role == ClusterRole.admin)
        ).scalar_one()
        is_admin = (
            session.execute(
                select(ClusterSubscription)
                .where(ClusterSubscription.user_id == context.user_id)
                .where(ClusterSubscription.cluster_id == node.official_cluster.id)
                .where(ClusterSubscription.role == ClusterRole.admin)
            ).scalar_one_or_none()
            is not None
        )

    return communities_pb2.Community(
        community_id=node.id,
        name=node.official_cluster.name,
        slug=node.official_cluster.slug,
        description=node.official_cluster.description,
        created=Timestamp_from_datetime(node.created),
        parents=_parents_to_pb(node.id),
        member=is_member,
        admin=is_admin,
        member_count=member_count,
        admin_count=admin_count,
        main_page=page_to_pb(node.official_cluster.main_page, context),
        can_moderate=can_moderate,
    )
Exemplo n.º 17
0
def paginate_references_result(request, query):
    total_matches = query.count()
    references = query.order_by(Reference.time.desc()).offset(request.start_at).limit(request.number).all()
    # order by time, pagination
    return api_pb2.GetReferencesRes(
        total_matches=total_matches,
        references=[
            api_pb2.Reference(
                reference_id=reference.id,
                from_user_id=reference.from_user_id,
                to_user_id=reference.to_user_id,
                reference_type=reftype2api[reference.reference_type],
                text=reference.text,
                # Fuzz reference written time
                written_time=Timestamp_from_datetime(reference.time.replace(hour=0, minute=0, second=0, microsecond=0)),
            )
            for reference in references
        ],
    )
Exemplo n.º 18
0
    def ListPendingReferencesToWrite(self, request, context):
        with session_scope() as session:
            q1 = (select(literal(True), HostRequest).outerjoin(
                Reference,
                and_(
                    Reference.host_request_id == HostRequest.conversation_id,
                    Reference.from_user_id == context.user_id,
                ),
            ).where_users_column_visible(
                context,
                HostRequest.host_user_id).where(Reference.id == None).where(
                    HostRequest.can_write_reference).where(
                        HostRequest.surfer_user_id == context.user_id))

            q2 = (select(literal(False), HostRequest).outerjoin(
                Reference,
                and_(
                    Reference.host_request_id == HostRequest.conversation_id,
                    Reference.from_user_id == context.user_id,
                ),
            ).where_users_column_visible(
                context,
                HostRequest.surfer_user_id).where(Reference.id == None).where(
                    HostRequest.can_write_reference).where(
                        HostRequest.host_user_id == context.user_id))

            union = union_all(q1, q2).order_by(
                HostRequest.end_time_to_write_reference.asc()).subquery()
            union = select(union.c[0].label("surfed"),
                           aliased(HostRequest, union))
            host_request_references = session.execute(union).all()

            return references_pb2.ListPendingReferencesToWriteRes(
                pending_references=[
                    references_pb2.AvailableWriteReferenceType(
                        host_request_id=host_request.conversation_id,
                        reference_type=reftype2api[
                            ReferenceType.surfed if surfed else ReferenceType.
                            hosted],
                        time_expires=Timestamp_from_datetime(
                            host_request.end_time_to_write_reference),
                    ) for surfed, host_request in host_request_references
                ], )
Exemplo n.º 19
0
    def GetHostRequest(self, request, context):
        with session_scope() as session:
            host_request = session.execute(
                select(HostRequest).where_users_column_visible(
                    context,
                    HostRequest.surfer_user_id).where_users_column_visible(
                        context, HostRequest.host_user_id).
                where(HostRequest.conversation_id ==
                      request.host_request_id).where(
                          or_(HostRequest.surfer_user_id == context.user_id,
                              HostRequest.host_user_id ==
                              context.user_id))).scalar_one_or_none()

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

            initial_message = session.execute(
                select(Message).where(
                    Message.conversation_id ==
                    host_request.conversation_id).order_by(
                        Message.id.asc()).limit(1)).scalar_one()

            latest_message = session.execute(
                select(Message).where(
                    Message.conversation_id ==
                    host_request.conversation_id).order_by(
                        Message.id.desc()).limit(1)).scalar_one()

            return requests_pb2.HostRequest(
                host_request_id=host_request.conversation_id,
                surfer_user_id=host_request.surfer_user_id,
                host_user_id=host_request.host_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.surfer_last_seen_message_id
                if context.user_id == host_request.surfer_user_id else
                host_request.host_last_seen_message_id,
                latest_message=message_to_pb(latest_message),
            )
Exemplo n.º 20
0
def community_to_pb(node: Node, user_id):
    with session_scope() as session:
        can_moderate = can_moderate_node(session, user_id, node.id)

    return communities_pb2.Community(
        community_id=node.id,
        name=node.official_cluster.name,
        slug=node.official_cluster.slug,
        description=node.official_cluster.description,
        created=Timestamp_from_datetime(node.created),
        parents=_parents_to_pb(node.id, user_id),
        main_page=page_to_pb(node.official_cluster.main_page, user_id),
        member=node.official_cluster.members.filter(
            User.id == user_id).one_or_none() is not None,
        admin=node.official_cluster.admins.filter(
            User.id == user_id).one_or_none() is not None,
        member_count=node.official_cluster.members.count(),
        admin_count=node.official_cluster.admins.count(),
        can_moderate=can_moderate,
    )
Exemplo n.º 21
0
def group_to_pb(cluster: Cluster, user_id):
    with session_scope() as session:
        can_moderate = can_moderate_node(session, user_id,
                                         cluster.parent_node_id)

    return groups_pb2.Group(
        group_id=cluster.id,
        name=cluster.name,
        slug=cluster.slug,
        description=cluster.description,
        created=Timestamp_from_datetime(cluster.created),
        parents=_parents_to_pb(cluster, user_id),
        main_page=page_to_pb(cluster.main_page, user_id),
        member=cluster.members.filter(User.id == user_id).one_or_none()
        is not None,
        admin=cluster.admins.filter(User.id == user_id).one_or_none()
        is not None,
        member_count=cluster.members.count(),
        admin_count=cluster.admins.count(),
        can_moderate=can_moderate,
    )
Exemplo n.º 22
0
def discussion_to_pb(discussion: Discussion, user_id):
    owner_community_id = None
    owner_group_id = None
    if discussion.owner_cluster.is_official_cluster:
        owner_community_id = discussion.owner_cluster.parent_node_id
    else:
        owner_group_id = discussion.owner_cluster.id

    with session_scope() as session:
        can_moderate = can_moderate_node(session, user_id, discussion.owner_cluster.parent_node_id)

    return discussions_pb2.Discussion(
        discussion_id=discussion.id,
        slug=discussion.slug,
        created=Timestamp_from_datetime(discussion.created),
        creator_user_id=discussion.creator_user_id,
        owner_community_id=owner_community_id,
        owner_group_id=owner_group_id,
        title=discussion.title,
        content=discussion.content,
        thread_id=pack_thread_id(discussion.thread_id, 0),
        can_moderate=can_moderate,
    )
Exemplo n.º 23
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)
Exemplo n.º 24
0
def event_to_pb(session, occurrence: EventOccurrence, context):
    event = occurrence.event

    next_occurrence = (event.occurrences.where(
        EventOccurrence.end_time >= now()).order_by(
            EventOccurrence.end_time.asc()).first())

    owner_community_id = None
    owner_group_id = None
    if event.owner_cluster:
        if event.owner_cluster.is_official_cluster:
            owner_community_id = event.owner_cluster.parent_node_id
        else:
            owner_group_id = event.owner_cluster.id

    attendance = occurrence.attendees.where(
        EventOccurrenceAttendee.user_id == context.user_id).one_or_none()
    attendance_state = attendance.attendee_status if attendance else None

    can_moderate = _can_moderate_event(session, event, context.user_id)

    going_count = session.execute(
        select(func.count()).
        select_from(EventOccurrenceAttendee).where_users_column_visible(
            context, EventOccurrenceAttendee.user_id).where(
                EventOccurrenceAttendee.occurrence_id == occurrence.id).where(
                    EventOccurrenceAttendee.attendee_status ==
                    AttendeeStatus.going)).scalar_one()
    maybe_count = session.execute(
        select(func.count()).
        select_from(EventOccurrenceAttendee).where_users_column_visible(
            context, EventOccurrenceAttendee.user_id).where(
                EventOccurrenceAttendee.occurrence_id == occurrence.id).where(
                    EventOccurrenceAttendee.attendee_status ==
                    AttendeeStatus.maybe)).scalar_one()

    organizer_count = session.execute(
        select(func.count()).select_from(
            EventOrganizer).where_users_column_visible(
                context, EventOrganizer.user_id).where(
                    EventOrganizer.event_id == event.id)).scalar_one()
    subscriber_count = session.execute(
        select(func.count()).select_from(
            EventSubscription).where_users_column_visible(
                context, EventSubscription.user_id).where(
                    EventSubscription.event_id == event.id)).scalar_one()

    return events_pb2.Event(
        event_id=occurrence.id,
        is_next=False
        if not next_occurrence else occurrence.id == next_occurrence.id,
        title=event.title,
        slug=event.slug,
        content=occurrence.content,
        photo_url=occurrence.photo.full_url if occurrence.photo else None,
        online_information=events_pb2.OnlineEventInformation(
            link=occurrence.link, ) if occurrence.link else None,
        offline_information=events_pb2.OfflineEventInformation(
            lat=occurrence.coordinates[0],
            lng=occurrence.coordinates[1],
            address=occurrence.address,
        ) if occurrence.geom else None,
        created=Timestamp_from_datetime(occurrence.created),
        last_edited=Timestamp_from_datetime(occurrence.last_edited),
        creator_user_id=occurrence.creator_user_id,
        start_time=Timestamp_from_datetime(occurrence.start_time),
        end_time=Timestamp_from_datetime(occurrence.end_time),
        timezone=occurrence.timezone,
        start_time_display=str(occurrence.start_time),
        end_time_display=str(occurrence.end_time),
        attendance_state=attendancestate2api[attendance_state],
        organizer=event.organizers.where(
            EventOrganizer.user_id == context.user_id).one_or_none()
        is not None,
        subscriber=event.subscribers.where(
            EventSubscription.user_id == context.user_id).one_or_none()
        is not None,
        going_count=going_count,
        maybe_count=maybe_count,
        organizer_count=organizer_count,
        subscriber_count=subscriber_count,
        owner_user_id=event.owner_user_id,
        owner_community_id=owner_community_id,
        owner_group_id=owner_group_id,
        thread=thread_to_pb(event.thread_id),
        can_edit=_is_event_owner(event, context.user_id),
        can_moderate=can_moderate,
    )
Exemplo n.º 25
0
def user_model_to_pb(db_user, session, context):
    num_references = session.query(Reference.from_user_id).filter(Reference.to_user_id == db_user.id).count()

    # returns (lat, lng)
    # we put people without coords on null island
    # https://en.wikipedia.org/wiki/Null_Island
    lat, lng = db_user.coordinates or (0, 0)

    user = api_pb2.User(
        user_id=db_user.id,
        username=db_user.username,
        name=db_user.name,
        city=db_user.city,
        hometown=db_user.hometown,
        lat=lat,
        lng=lng,
        radius=db_user.geom_radius,
        verification=db_user.verification,
        community_standing=db_user.community_standing,
        num_references=num_references,
        gender=db_user.gender,
        pronouns=db_user.pronouns,
        age=db_user.age,
        joined=Timestamp_from_datetime(db_user.display_joined),
        last_active=Timestamp_from_datetime(db_user.display_last_active),
        hosting_status=hostingstatus2api[db_user.hosting_status],
        meetup_status=meetupstatus2api[db_user.meetup_status],
        occupation=db_user.occupation,
        education=db_user.education,
        about_me=db_user.about_me,
        my_travels=db_user.my_travels,
        things_i_like=db_user.things_i_like,
        about_place=db_user.about_place,
        languages=db_user.languages.split("|") if db_user.languages else [],
        countries_visited=db_user.countries_visited.split("|") if db_user.countries_visited else [],
        countries_lived=db_user.countries_lived.split("|") if db_user.countries_lived else [],
        additional_information=db_user.additional_information,
        friends=get_friends_status(session, context.user_id, db_user.id),
        mutual_friends=[
            api_pb2.MutualFriend(user_id=mutual_friend.id, username=mutual_friend.username, name=mutual_friend.name)
            for mutual_friend in db_user.mutual_friends(context.user_id)
        ],
        smoking_allowed=smokinglocation2api[db_user.smoking_allowed],
        sleeping_arrangement=sleepingarrangement2api[db_user.sleeping_arrangement],
        parking_details=parkingdetails2api[db_user.parking_details],
        avatar_url=db_user.avatar.thumbnail_url if db_user.avatar else None,
    )

    if db_user.max_guests is not None:
        user.max_guests.value = db_user.max_guests

    if db_user.last_minute is not None:
        user.last_minute.value = db_user.last_minute

    if db_user.has_pets is not None:
        user.has_pets.value = db_user.has_pets

    if db_user.accepts_pets is not None:
        user.accepts_pets.value = db_user.accepts_pets

    if db_user.pet_details is not None:
        user.pet_details.value = db_user.pet_details

    if db_user.has_kids is not None:
        user.has_kids.value = db_user.has_kids

    if db_user.accepts_kids is not None:
        user.accepts_kids.value = db_user.accepts_kids

    if db_user.kid_details is not None:
        user.kid_details.value = db_user.kid_details

    if db_user.has_housemates is not None:
        user.has_housemates.value = db_user.has_housemates

    if db_user.housemate_details is not None:
        user.housemate_details.value = db_user.housemate_details

    if db_user.wheelchair_accessible is not None:
        user.wheelchair_accessible.value = db_user.wheelchair_accessible

    if db_user.smokes_at_home is not None:
        user.smokes_at_home.value = db_user.smokes_at_home

    if db_user.drinking_allowed is not None:
        user.drinking_allowed.value = db_user.drinking_allowed

    if db_user.drinks_at_home is not None:
        user.drinks_at_home.value = db_user.drinks_at_home

    if db_user.other_host_info is not None:
        user.other_host_info.value = db_user.other_host_info

    if db_user.sleeping_details is not None:
        user.sleeping_details.value = db_user.sleeping_details

    if db_user.area is not None:
        user.area.value = db_user.area

    if db_user.house_rules is not None:
        user.house_rules.value = db_user.house_rules

    if db_user.parking is not None:
        user.parking.value = db_user.parking

    if db_user.camping_ok is not None:
        user.camping_ok.value = db_user.camping_ok

    return user
Exemplo n.º 26
0
    def CreateGroupChat(self, request, context):
        with session_scope() as session:
            recipient_user_ids = [
                user_id
                for user_id in (
                    session.execute(
                        select(User.id).where_users_visible(context).where(User.id.in_(request.recipient_user_ids))
                    )
                    .scalars()
                    .all()
                )
            ]

            # make sure all requested users are visible
            if len(recipient_user_ids) != len(request.recipient_user_ids):
                context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.USER_NOT_FOUND)

            if not recipient_user_ids:
                context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.NO_RECIPIENTS)

            if len(recipient_user_ids) != len(set(recipient_user_ids)):
                # make sure there's no duplicate users
                context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.INVALID_RECIPIENTS)

            if context.user_id in recipient_user_ids:
                context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.CANT_ADD_SELF)

            if len(recipient_user_ids) == 1:
                # can only have one DM at a time between any two users
                other_user_id = recipient_user_ids[0]

                # the following sql statement selects subscriptions that are DMs and have the same group_chat_id, and have
                # user_id either this user or the recipient user. If you find two subscriptions to the same DM group
                # chat, you know they already have a shared group chat
                count = func.count(GroupChatSubscription.id).label("count")
                if session.execute(
                    select(count)
                    .where(
                        or_(
                            GroupChatSubscription.user_id == context.user_id,
                            GroupChatSubscription.user_id == other_user_id,
                        )
                    )
                    .where(GroupChatSubscription.left == None)
                    .join(GroupChat, GroupChat.conversation_id == GroupChatSubscription.group_chat_id)
                    .where(GroupChat.is_dm == True)
                    .group_by(GroupChatSubscription.group_chat_id)
                    .having(count == 2)
                ).scalar_one_or_none():
                    context.abort(
                        grpc.StatusCode.FAILED_PRECONDITION, "You already have a direct message chat with this user."
                    )

            conversation = Conversation()
            session.add(conversation)

            group_chat = GroupChat(
                conversation=conversation,
                title=request.title.value,
                creator_id=context.user_id,
                is_dm=True if len(recipient_user_ids) == 1 else False,  # TODO
            )
            session.add(group_chat)

            your_subscription = GroupChatSubscription(
                user_id=context.user_id,
                group_chat=group_chat,
                role=GroupChatRole.admin,
            )
            session.add(your_subscription)

            for recipient_id in request.recipient_user_ids:
                subscription = GroupChatSubscription(
                    user_id=recipient_id,
                    group_chat=group_chat,
                    role=GroupChatRole.participant,
                )
                session.add(subscription)

            _add_message_to_subscription(session, your_subscription, message_type=MessageType.chat_created)

            session.flush()

            return conversations_pb2.GroupChat(
                group_chat_id=group_chat.conversation_id,
                title=group_chat.title,
                member_user_ids=_get_visible_members_for_subscription(your_subscription),
                admin_user_ids=_get_visible_admins_for_subscription(your_subscription),
                only_admins_invite=group_chat.only_admins_invite,
                is_dm=group_chat.is_dm,
                created=Timestamp_from_datetime(group_chat.conversation.created),
                mute_info=_mute_info(your_subscription),
            )
Exemplo n.º 27
0
def user_model_to_pb(db_user, session, context):
    num_references = session.query(Reference.from_user_id).filter(
        Reference.to_user_id == db_user.id).count()

    user = api_pb2.User(
        user_id=db_user.id,
        username=db_user.username,
        name=db_user.name,
        city=db_user.city,
        verification=db_user.verification,
        community_standing=db_user.community_standing,
        num_references=num_references,
        gender=db_user.gender,
        age=db_user.age,
        color=db_user.color,
        joined=Timestamp_from_datetime(db_user.display_joined),
        last_active=Timestamp_from_datetime(db_user.display_last_active),
        hosting_status=hostingstatus2api[db_user.hosting_status],
        occupation=db_user.occupation,
        about_me=db_user.about_me,
        about_place=db_user.about_place,
        languages=db_user.languages.split("|") if db_user.languages else [],
        countries_visited=db_user.countries_visited.split("|")
        if db_user.countries_visited else [],
        countries_lived=db_user.countries_lived.split("|")
        if db_user.countries_lived else [],
        friends=get_friends_status(session, context.user_id, db_user.id),
        mutual_friends=[
            api_pb2.MutualFriend(user_id=mutual_friend.id,
                                 username=mutual_friend.username,
                                 name=mutual_friend.name)
            for mutual_friend in db_user.mutual_friends(context.user_id)
        ],
        smoking_allowed=smokinglocation2api[db_user.smoking_allowed],
        avatar_url=db_user.avatar_url,
    )

    if db_user.max_guests is not None:
        user.max_guests.value = db_user.max_guests

    if db_user.multiple_groups is not None:
        user.multiple_groups.value = db_user.multiple_groups

    if db_user.last_minute is not None:
        user.last_minute.value = db_user.last_minute

    if db_user.accepts_pets is not None:
        user.accepts_pets.value = db_user.accepts_pets

    if db_user.accepts_kids is not None:
        user.accepts_kids.value = db_user.accepts_kids

    if db_user.wheelchair_accessible is not None:
        user.wheelchair_accessible.value = db_user.wheelchair_accessible

    if db_user.sleeping_arrangement is not None:
        user.sleeping_arrangement.value = db_user.sleeping_arrangement

    if db_user.area is not None:
        user.area.value = db_user.area

    if db_user.house_rules is not None:
        user.house_rules.value = db_user.house_rules

    return user
Exemplo n.º 28
0
def _mute_info(subscription):
    (muted, muted_until) = subscription.muted_display()
    return conversations_pb2.MuteInfo(
        muted=muted,
        muted_until=Timestamp_from_datetime(muted_until) if muted_until else None,
    )
Exemplo n.º 29
0
    def CreateGroupChat(self, request, context):
        if len(request.recipient_user_ids) < 1:
            context.abort(grpc.StatusCode.INVALID_ARGUMENT,
                          errors.NO_RECIPIENTS)

        if len(request.recipient_user_ids) != len(
                set(request.recipient_user_ids)):
            # make sure there's no duplicate users
            context.abort(grpc.StatusCode.INVALID_ARGUMENT,
                          errors.INVALID_RECIPIENTS)

        if context.user_id in request.recipient_user_ids:
            context.abort(grpc.StatusCode.INVALID_ARGUMENT,
                          errors.CANT_ADD_SELF)

        with session_scope(self._Session) as session:
            if len(request.recipient_user_ids) == 1:
                # can only have one DM at a time between any two users
                other_user_id = request.recipient_user_ids[0]

                # the following query selects subscriptions that are DMs and have the same group_chat_id, and have
                # user_id either this user or the recipient user. If you find two subscriptions to the same DM group
                # chat, you know they already have a shared group chat
                count = func.count(GroupChatSubscription.id).label("count")
                if (session.query(count).filter(
                        or_(
                            GroupChatSubscription.user_id == context.user_id,
                            GroupChatSubscription.user_id == other_user_id,
                        )).filter(GroupChatSubscription.left == None).join(
                            GroupChat, GroupChat.conversation_id ==
                            GroupChatSubscription.group_chat_id).
                        filter(GroupChat.is_dm == True).group_by(
                            GroupChatSubscription.group_chat_id).having(
                                count == 2).one_or_none()):
                    context.abort(
                        grpc.StatusCode.FAILED_PRECONDITION,
                        "You already have a direct message chat with this user."
                    )

            conversation = Conversation()
            session.add(conversation)

            group_chat = GroupChat(
                conversation=conversation,
                title=request.title.value,
                creator_id=context.user_id,
                is_dm=True
                if len(request.recipient_user_ids) == 1 else False,  # TODO
            )
            session.add(group_chat)

            your_subscription = GroupChatSubscription(
                user_id=context.user_id,
                group_chat=group_chat,
                role=GroupChatRole.admin,
            )
            session.add(your_subscription)

            for recipient in request.recipient_user_ids:
                if get_friends_status(
                        session, context.user_id,
                        recipient) != api_pb2.User.FriendshipStatus.FRIENDS:
                    if len(request.recipient_user_ids) > 1:
                        context.abort(grpc.StatusCode.FAILED_PRECONDITION,
                                      errors.GROUP_CHAT_ONLY_ADD_FRIENDS)
                    else:
                        context.abort(grpc.StatusCode.FAILED_PRECONDITION,
                                      errors.DIRECT_MESSAGE_ONLY_FRIENDS)

                subscription = GroupChatSubscription(
                    user_id=recipient,
                    group_chat=group_chat,
                    role=GroupChatRole.participant,
                )
                session.add(subscription)

            _add_message_to_subscription(session,
                                         your_subscription,
                                         message_type=MessageType.chat_created)

            session.flush()

            return conversations_pb2.GroupChat(
                group_chat_id=group_chat.conversation_id,
                title=group_chat.title,
                member_user_ids=_get_visible_members_for_subscription(
                    your_subscription),
                admin_user_ids=_get_visible_admins_for_subscription(
                    your_subscription),
                only_admins_invite=group_chat.only_admins_invite,
                is_dm=group_chat.is_dm,
                created=Timestamp_from_datetime(
                    group_chat.conversation.created),
            )
Exemplo n.º 30
0
def user_model_to_pb(db_user, session, context):
    num_references = session.query(Reference.from_user_id).filter(
        Reference.to_user_id == db_user.id).count()

    # returns (lat, lng)
    # we put people without coords on null island
    # https://en.wikipedia.org/wiki/Null_Island
    lat, lng = db_user.coordinates or (0, 0)

    pending_friend_request = None
    if db_user.id == context.user_id:
        friends_status = api_pb2.User.FriendshipStatus.NA
    else:
        friend_relationship = (session.query(FriendRelationship).filter(
            or_(
                and_(FriendRelationship.from_user_id == context.user_id,
                     FriendRelationship.to_user_id == db_user.id),
                and_(FriendRelationship.from_user_id == db_user.id,
                     FriendRelationship.to_user_id == context.user_id),
            )).filter(
                or_(
                    FriendRelationship.status == FriendStatus.accepted,
                    FriendRelationship.status == FriendStatus.pending,
                )).one_or_none())

        if friend_relationship:
            if friend_relationship.status == FriendStatus.accepted:
                friends_status = api_pb2.User.FriendshipStatus.FRIENDS
            else:
                friends_status = api_pb2.User.FriendshipStatus.PENDING
                if friend_relationship.from_user_id == context.user_id:
                    # we sent it
                    pending_friend_request = api_pb2.FriendRequest(
                        friend_request_id=friend_relationship.id,
                        state=api_pb2.FriendRequest.FriendRequestStatus.
                        PENDING,
                        user_id=friend_relationship.to_user.id,
                        sent=True,
                    )
                else:
                    # we received it
                    pending_friend_request = api_pb2.FriendRequest(
                        friend_request_id=friend_relationship.id,
                        state=api_pb2.FriendRequest.FriendRequestStatus.
                        PENDING,
                        user_id=friend_relationship.from_user.id,
                        sent=False,
                    )
        else:
            friends_status = api_pb2.User.FriendshipStatus.NOT_FRIENDS

    user = api_pb2.User(
        user_id=db_user.id,
        username=db_user.username,
        name=db_user.name,
        city=db_user.city,
        hometown=db_user.hometown,
        lat=lat,
        lng=lng,
        radius=db_user.geom_radius,
        verification=db_user.verification,
        community_standing=db_user.community_standing,
        num_references=num_references,
        gender=db_user.gender,
        pronouns=db_user.pronouns,
        age=db_user.age,
        joined=Timestamp_from_datetime(db_user.display_joined),
        last_active=Timestamp_from_datetime(db_user.display_last_active),
        hosting_status=hostingstatus2api[db_user.hosting_status],
        meetup_status=meetupstatus2api[db_user.meetup_status],
        occupation=db_user.occupation,
        education=db_user.education,
        about_me=db_user.about_me,
        my_travels=db_user.my_travels,
        things_i_like=db_user.things_i_like,
        about_place=db_user.about_place,
        languages=db_user.languages.split("|") if db_user.languages else [],
        countries_visited=db_user.countries_visited.split("|")
        if db_user.countries_visited else [],
        countries_lived=db_user.countries_lived.split("|")
        if db_user.countries_lived else [],
        additional_information=db_user.additional_information,
        friends=friends_status,
        pending_friend_request=pending_friend_request,
        smoking_allowed=smokinglocation2api[db_user.smoking_allowed],
        sleeping_arrangement=sleepingarrangement2api[
            db_user.sleeping_arrangement],
        parking_details=parkingdetails2api[db_user.parking_details],
        avatar_url=db_user.avatar.full_url if db_user.avatar else None,
    )

    if db_user.max_guests is not None:
        user.max_guests.value = db_user.max_guests

    if db_user.last_minute is not None:
        user.last_minute.value = db_user.last_minute

    if db_user.has_pets is not None:
        user.has_pets.value = db_user.has_pets

    if db_user.accepts_pets is not None:
        user.accepts_pets.value = db_user.accepts_pets

    if db_user.pet_details is not None:
        user.pet_details.value = db_user.pet_details

    if db_user.has_kids is not None:
        user.has_kids.value = db_user.has_kids

    if db_user.accepts_kids is not None:
        user.accepts_kids.value = db_user.accepts_kids

    if db_user.kid_details is not None:
        user.kid_details.value = db_user.kid_details

    if db_user.has_housemates is not None:
        user.has_housemates.value = db_user.has_housemates

    if db_user.housemate_details is not None:
        user.housemate_details.value = db_user.housemate_details

    if db_user.wheelchair_accessible is not None:
        user.wheelchair_accessible.value = db_user.wheelchair_accessible

    if db_user.smokes_at_home is not None:
        user.smokes_at_home.value = db_user.smokes_at_home

    if db_user.drinking_allowed is not None:
        user.drinking_allowed.value = db_user.drinking_allowed

    if db_user.drinks_at_home is not None:
        user.drinks_at_home.value = db_user.drinks_at_home

    if db_user.other_host_info is not None:
        user.other_host_info.value = db_user.other_host_info

    if db_user.sleeping_details is not None:
        user.sleeping_details.value = db_user.sleeping_details

    if db_user.area is not None:
        user.area.value = db_user.area

    if db_user.house_rules is not None:
        user.house_rules.value = db_user.house_rules

    if db_user.parking is not None:
        user.parking.value = db_user.parking

    if db_user.camping_ok is not None:
        user.camping_ok.value = db_user.camping_ok

    return user