mirror of https://gitlab.com/litecord/litecord.git
153 lines
4.5 KiB
Python
153 lines
4.5 KiB
Python
from quart import Blueprint, jsonify, request, current_app as app
|
|
from asyncpg import UniqueViolationError
|
|
|
|
from ..auth import token_check
|
|
from ..schemas import validate, RELATIONSHIP
|
|
from ..enums import RelationshipType
|
|
|
|
|
|
bp = Blueprint('relationship', __name__)
|
|
|
|
|
|
@bp.route('/@me/relationships', methods=['GET'])
|
|
async def get_me_relationships():
|
|
user_id = await token_check()
|
|
return jsonify(await app.storage.get_relationships(user_id))
|
|
|
|
|
|
@bp.route('/@me/relationships/<int:peer_id>', methods=['PUT'])
|
|
async def add_relationship(peer_id: int):
|
|
"""Add a relationship to the peer."""
|
|
user_id = await token_check()
|
|
payload = validate(await request.get_json(), RELATIONSHIP)
|
|
rel_type = payload['type']
|
|
_friend = RelationshipType.FRIEND.value
|
|
|
|
await app.db.execute("""
|
|
INSERT INTO relationships (user_id, peer_id, rel_type)
|
|
VALUES ($1, $2, $3)
|
|
""", user_id, peer_id, rel_type)
|
|
|
|
# check if this is an acceptance
|
|
# of a friend request
|
|
existing = await app.db.fetchrow("""
|
|
SELECT user_id, peer_id
|
|
FROM relationships
|
|
WHERE user_id = $1 AND peer_id = $2 AND rel_type = $3
|
|
""", peer_id, user_id, _friend)
|
|
|
|
_dispatch = app.dispatcher.dispatch_user
|
|
|
|
if existing:
|
|
# accepted a friend request, dispatch respective
|
|
# relationship events
|
|
await _dispatch(user_id, 'RELATIONSHIP_REMOVE', {
|
|
'type': RelationshipType.INCOMING.value,
|
|
'id': str(peer_id)
|
|
})
|
|
|
|
await _dispatch(user_id, 'RELATIONSHIP_ADD', {
|
|
'type': _friend,
|
|
'id': str(peer_id),
|
|
'user': await app.storage.get_user(peer_id)
|
|
})
|
|
|
|
await _dispatch(peer_id, 'RELATIONSHIP_ADD', {
|
|
'type': _friend,
|
|
'id': str(user_id),
|
|
'user': await app.storage.get_user(user_id)
|
|
})
|
|
|
|
return '', 204
|
|
|
|
# check if friend AND not acceptance of fr
|
|
if rel_type == _friend:
|
|
await _dispatch(user_id, 'RELATIONSHIP_ADD', {
|
|
'id': str(peer_id),
|
|
'type': RelationshipType.OUTGOING.value,
|
|
'user': await app.storage.get_user(peer_id),
|
|
})
|
|
|
|
await _dispatch(peer_id, 'RELATIONSHIP_ADD', {
|
|
'id': str(user_id),
|
|
'type': RelationshipType.INCOMING.value,
|
|
'user': await app.storage.get_user(user_id)
|
|
})
|
|
|
|
return '', 204
|
|
|
|
# its a block.
|
|
await app.dispatcher.dispatch_user(user_id, 'RELATIONSHIP_ADD', {
|
|
'id': str(peer_id),
|
|
'type': RelationshipType.BLOCK.value,
|
|
'user': await app.storage.get_user(peer_id)
|
|
})
|
|
|
|
return '', 204
|
|
|
|
|
|
@bp.route('/@me/relationships/<int:peer_id>', methods=['DELETE'])
|
|
async def remove_relationship(peer_id: int):
|
|
"""Remove an existing relationship"""
|
|
user_id = await token_check()
|
|
_friend = RelationshipType.FRIEND.value
|
|
_block = RelationshipType.BLOCK.value
|
|
_dispatch = app.dispatcher.dispatch_user
|
|
|
|
rel_type = await app.db.fetchval("""
|
|
SELECT rel_type
|
|
FROM relationships
|
|
WHERE user_id = $1 AND peer_id = $2
|
|
""", user_id, peer_id)
|
|
|
|
incoming_rel_type = await app.db.fetchval("""
|
|
SELECT rel_type
|
|
FROM relationships
|
|
WHERE user_id = $1 AND peer_id = $2
|
|
""", peer_id, user_id)
|
|
|
|
# if any of those are friend
|
|
if _friend in (rel_type, incoming_rel_type):
|
|
# closing the friendship, have to delete both rows
|
|
await app.db.execute("""
|
|
DELETE FROM relationships
|
|
WHERE (
|
|
(user_id = $1 AND peer_id = $2) OR
|
|
(user_id = $2 AND peer_id = $1)
|
|
) AND rel_type = $3
|
|
""", user_id, peer_id, _friend)
|
|
|
|
# if there wasnt any mutual friendship before,
|
|
# assume they were requests of INCOMING
|
|
# and OUTGOING.
|
|
user_del_type = RelationshipType.OUTGOING.value if \
|
|
incoming_rel_type != _friend else _friend
|
|
|
|
await _dispatch(user_id, 'RELATIONSHIP_REMOVE', {
|
|
'id': str(peer_id),
|
|
'type': user_del_type,
|
|
})
|
|
|
|
peer_del_type = RelationshipType.INCOMING.value if \
|
|
incoming_rel_type != _friend else _friend
|
|
|
|
await _dispatch(peer_id, 'RELATIONSHIP_REMOVE', {
|
|
'id': str(user_id),
|
|
'type': peer_del_type,
|
|
})
|
|
|
|
return '', 204
|
|
|
|
# was a block!
|
|
await app.db.execute("""
|
|
DELETE FROM relationships
|
|
WHERE user_id = $1 AND peer_id = $2 AND rel_type = $3
|
|
""", user_id, peer_id, _block)
|
|
|
|
await _dispatch(user_id, 'RELATIONSHIP_REMOVE', {
|
|
'id': str(peer_id),
|
|
'type': _block,
|
|
})
|
|
|
|
return '', 204
|