yepcord / server

Unofficial discord backend implementation in python.
GNU Affero General Public License v3.0
2 stars 1 forks source link

check for to_user settings #207

Closed github-actions[bot] closed 1 year ago

github-actions[bot] commented 1 year ago

https://api.github.com/yepcord/server/blob/7ef992105618d9e66d7f1bba156273b78f56623f/src/yepcord/models/users.py#L507


        return proto

class RelationshipQS(SnowflakeAIQuerySet):
    async def rexists(self, user1: User, user2: User) -> bool:
        return await self.filter(or_(
            and_(from_user=user1, to_user=user2),
            and_(from_user=user2, to_user=user1)
        )).exists()

    async def rget(self, user1: User, user2: User) -> bool:
        return await self.get(or_(
            and_(from_user=user1, to_user=user2),
            and_(from_user=user2, to_user=user1)
        ))

    async def available(self, from_user: User, to_user: User, *, raise_: bool=False) -> bool:
        available = not await self.rexists(from_user, to_user)  # TODO: check for to_user settings
        if not available and raise_:
            raise InvalidDataErr(400, Errors.make(80007))
        return available

    async def request(self, from_user: User, to_user: User) -> Relationship:
        if not await self.available(from_user, to_user):
            raise InvalidDataErr(400, Errors.make(80007))
        return await self.create(from_user=from_user, to_user=to_user, type=RelationshipType.PENDING)

    async def accept(self, from_user: User, to_user: User) -> Optional[Relationship]:
        if (rel := await self.get_or_none(from_user=from_user, to_user=to_user, type=RelationshipType.PENDING)) is None:
            return
        await rel.update(type=RelationshipType.FRIEND)
        return rel

    async def block(self, user: User, block_user: User) -> dict:
        rels = await self.all(or_(and_(from_user=user, to_user=block_user), and_(from_user=block_user, to_user=user)))
        block = True
        ret = {"block": False, "delete": []}
        if not rels:
            pass
        elif len(rels) == 1 and rels[0].type != RelationshipType.BLOCK:
            rel = rels[0]
            ret["delete"] = [
                {"id": rel.from_user.id, "rel": rel.to_user.id, "type": rel.discord_rel_type(rel.from_user)},
                {"id": rel.to_user.id, "rel": rel.from_user.id, "type": rel.discord_rel_type(rel.to_user)}
            ]
            await rels[0].delete()
        elif len(rels) == 1 and rels[0].type == RelationshipType.BLOCK:
            if rels[0].from_user == user and rels[0].to_user == block_user:
                block = False
        elif len(rels) == 2:
            block = False
        if block:
            await self.create(from_user=user, to_user=block_user, type=RelationshipType.BLOCK)
            ret["block"] = True
        return ret

    async def rdelete(self, current: User, target: User) -> dict:
        rels = await self.all(or_(and_(from_user=current, to_user=target),
                                  and_(from_user=target, to_user=current)))
        ret = {"delete": []}
        if not rels:
            pass
        elif len(rels) == 1 and rels[0].type != RelationshipType.BLOCK:
            rel = rels[0]
            ret["delete"] = [
                {"id": rel.from_user.id, "rel": rel.to_user.id, "type": rel.discord_rel_type(rel.from_user)},
                {"id": rel.to_user.id, "rel": rel.from_user.id, "type": rel.discord_rel_type(rel.to_user)}
            ]
            await rel.delete()
        elif len(rels) == 1 and rels[0].type == RelationshipType.BLOCK:
            rel = rels[0]
            if rel.from_user == current and rel.to_user == target:
                ret["delete"] = [
                    {"id": rel.from_user.id, "rel": rel.to_user.id, "type": rel.discord_rel_type(rel.from_user)}
                ]
                await rel.delete()
        elif len(rels) == 2:
            rel = [r for r in rels if r.from_user == current and r.to_user == target][0]
            ret["delete"] = [
                {"id": rel.from_user.id, "rel": rel.to_user.id, "type": rel.discord_rel_type(rel.from_user)}
            ]
            await rel.delete()
        return ret

    async def is_blocked(self, user: User, check_blocked: User) -> bool:
        return await self.filter(from_user=user, to_user=check_blocked, type=RelationshipType.BLOCK).exists()

class Relationship(ormar.Model):
    class Meta(DefaultMeta):
        queryset_class = RelationshipQS

    id: int = ormar.BigInteger(primary_key=True, autoincrement=True)
    from_user: User = ormar.ForeignKey(User, ondelete=ReferentialAction.CASCADE, related_name="from_user")
    to_user: User = ormar.ForeignKey(User, ondelete=ReferentialAction.CASCADE, related_name="to_user")
    type: int = ormar.Integer(choices=[0, 1, 2])

    def other_user(self, current_user: User) -> User:
        return self.from_user if self.to_user == current_user else self.to_user

    def discord_rel_type(self, current_user: User) -> Optional[int]:
        if self.type == RelationshipType.BLOCK and self.from_user.id != current_user.id:
            return None
        elif self.type == RelationshipType.BLOCK:
            return RelTypeDiscord.BLOCK
        elif self.type == RelationshipType.FRIEND:
            return RelTypeDiscord.FRIEND
        elif self.from_user == current_user:
            return RelTypeDiscord.REQUEST_SENT
        elif self.to_user == current_user:
            return RelTypeDiscord.REQUEST_RECV

    async def ds_json(self, current_user: User, with_data=False) -> Optional[dict]:
github-actions[bot] commented 1 year ago

Closed in d2da2d5fc2531f2122dfd44001dccb1f4bcbeeef