Skip to content

Commit

Permalink
Merge branch 'main' into frontend/translations
Browse files Browse the repository at this point in the history
  • Loading branch information
okbrandon committed Nov 14, 2024
2 parents cc1b9a2 + 1d88240 commit 87a1b89
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 16 deletions.
11 changes: 9 additions & 2 deletions backend/api/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,13 @@ def update_users_statuses(sender, **kwargs):
User.objects.bulk_update(users, ['status'])

def create_test_accounts(sender, **kwargs):
from .models import User
from .models import User, Relationship

if os.environ.get('SKIP_EMAIL_VERIFICATION', '').lower() == 'true':
for i in range(1, 5):
username = f'test{i}'
if not User.objects.filter(username=username).exists():
User.objects.create(
user = User.objects.create(
userID=generate_id('user'),
username=username,
email=f'{username}@example.com',
Expand All @@ -105,3 +105,10 @@ def create_test_accounts(sender, **kwargs):
flags=1, # Set EMAIL_VERIFIED flag
money=100000
)

Relationship.objects.create(
relationshipID=generate_id("rel"),
userA=user.userID,
userB="user_ai",
status=1 # Accepted/friends status
)
55 changes: 52 additions & 3 deletions backend/api/consumers/tournaments.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
from django.conf import settings
from django.core.cache import cache
from django.utils import timezone
from django.db.models import Q
from django.db.models import Q, Count

from ..models import User, Tournament, Match
from ..models import User, Tournament, Match, Conversation
from ..util import get_safe_profile, generate_id
from ..serializers import UserSerializer, MatchSerializer
from ..serializers import UserSerializer, MatchSerializer, MessageSerializer

from asgiref.sync import sync_to_async

Expand Down Expand Up @@ -212,10 +212,59 @@ async def start_next_match(self):
}
)

# Warn players of the next match
for player in next_match['players']:
await self.send_prune_message(player['userID'], f"Your next match in tournament '{self.tournament.name}' is starting soon!")

# Get the next next match
next_next_match = await self.get_next_unstarted_match()
if next_next_match:
for player in next_next_match['players']:
await self.send_prune_message(player['userID'], f"Your match in tournament '{self.tournament.name}' is coming up next. Please be ready!")

return next_match
finally:
await self.delete_lock(lock_key)

async def send_prune_message(self, user_id, content):
prune_user = await sync_to_async(User.objects.get)(userID="user_ai")
conversation = await self.get_or_create_prune_conversation(user_id)

message = await sync_to_async(conversation.messages.create)(
messageID=generate_id("msg"),
sender=prune_user,
content=content
)

await self.channel_layer.group_send(
f"chat_{user_id}",
{
"type": "conversation_update",
"conversationID": conversation.conversationID,
"sender": get_safe_profile(UserSerializer(prune_user).data, me=False),
"message": MessageSerializer(message).data
}
)
@sync_to_async
def get_or_create_prune_conversation(self, user_id):
user = User.objects.get(userID=user_id)
prune_user = User.objects.get(userID="user_ai")

conversation = Conversation.objects.filter(
participants__userID__in=[user_id, "user_ai"],
conversationType='private_message'
).annotate(participant_count=Count('participants')).filter(participant_count=2).first()

if not conversation:
conversation = Conversation.objects.create(
conversationID=generate_id("conv"),
conversationType='private_message'
)
conversation.participants.add(user, prune_user)
conversation.save()

return conversation

@sync_to_async
def set_match_start_time(self, match_id):
Match.objects.filter(matchID=match_id, startedAt__isnull=True).update(startedAt=timezone.now())
Expand Down
10 changes: 9 additions & 1 deletion backend/api/views/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from django.utils import timezone
from django.contrib.auth.hashers import check_password

from ..models import User, VerificationCode
from ..models import User, VerificationCode, Relationship
from ..serializers import UserSerializer
from ..util import generate_id, send_verification_email, send_otp_via_email, send_otp_via_sms
from ..backends import AuthBackend
Expand Down Expand Up @@ -52,6 +52,14 @@ def post(self, request, *args, **kwargs):
flags=1 if skip_email_verification else 0 # Set EMAIL_VERIFIED flag if skipping verification
)

# Create a relationship with the AI user
Relationship.objects.create(
relationshipID=generate_id("rel"),
userA=user.userID,
userB="user_ai",
status=1 # Accepted/friends status
)

if not skip_email_verification:
verification_code = generate_id('code')
VerificationCode.objects.create(
Expand Down
9 changes: 8 additions & 1 deletion backend/api/views/oauth.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from rest_framework_simplejwt.tokens import RefreshToken

from ..util import generate_id, send_welcome_email
from ..models import User
from ..models import User, Relationship

@permission_classes([AllowAny])
class OAuth42Login(APIView):
Expand Down Expand Up @@ -82,6 +82,13 @@ def get(self, request):

if created:
send_welcome_email(user.email)
# Create a relationship with the AI user
Relationship.objects.create(
relationshipID=generate_id("rel"),
userA=user.userID,
userB="user_ai",
status=1 # Accepted/friends status
)

login(request, user)

Expand Down
17 changes: 8 additions & 9 deletions backend/api/views/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,15 +290,7 @@ def put(self, request, *args, **kwargs):
return Response({"error": "Invalid data"}, status=status.HTTP_400_BAD_REQUEST)

if target_user_id == "user_ai":
if relationship_type == 2: # tries to block prune
return Response({"error": "There's no escaping prune, nice try."}, status=status.HTTP_400_BAD_REQUEST)
relationship = Relationship.objects.create(
relationshipID=generate_id("rel"),
userA=me.userID,
userB=target_user_id,
status=1 # Accepted/friends status
)
return Response({"status": "AI friend added, you must feel very lonely. don't worry Prune is a good friend."}, status=status.HTTP_200_OK)
return Response({"error": "There's no escaping prune, nice try."}, status=status.HTTP_400_BAD_REQUEST)

try:
target_user = User.objects.get(userID=target_user_id)
Expand Down Expand Up @@ -357,6 +349,13 @@ def delete(self, request, relationshipID, *args, **kwargs):
relationshipID=relationshipID
)

# Check if the user is part of the relationship
if me.userID != relationship.userA and me.userID != relationship.userB:
return Response({"error": "You are not part of this relationship"}, status=status.HTTP_403_FORBIDDEN)

if relationship.userA == "user_ai" or relationship.userB == "user_ai":
return Response({"error": "There's no escaping prune, nice try."}, status=status.HTTP_400_BAD_REQUEST)

if relationship.status == 0:
if me.userID != relationship.userA:
self.notify_chat_websocket(relationship, status="rejected")
Expand Down

0 comments on commit 87a1b89

Please sign in to comment.