Skip to content

Commit

Permalink
Merge pull request #83 from Sahayana/search
Browse files Browse the repository at this point in the history
[Search, chat] 마이그레이션
  • Loading branch information
Sahayana authored Nov 3, 2023
2 parents a8582b3 + 7716e32 commit 1824251
Show file tree
Hide file tree
Showing 41 changed files with 1,454 additions and 3 deletions.
8 changes: 5 additions & 3 deletions alaltalk/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@
# Application definition

INSTALLED_APPS = [
# "apps.chat",
# "channels",
# chat
"apps.chat",
"channels",
# django
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
Expand All @@ -41,7 +43,7 @@
# app
"apps.account",
"apps.friend",
# "apps.search",
"apps.search",
# 3rd party
"storages",
"six",
Expand Down
Empty file added apps/chat/__init__.py
Empty file.
3 changes: 3 additions & 0 deletions apps/chat/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.contrib import admin

# Register your models here.
Empty file added apps/chat/apis/__init__.py
Empty file.
Empty file added apps/chat/apis/v1/__init__.py
Empty file.
Empty file.
67 changes: 67 additions & 0 deletions apps/chat/apis/v1/chat_room_router.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
from django.http import JsonResponse
from ninja import Router
from search.models import Book, News, Shopping, Youtube

router = Router(tags=["chat_room"])


@router.post("/youtube")
def create_chat_room(request) -> JsonResponse:
youtube_id = request.POST["id"]
friend_youtube = Youtube.objects.get(pk=youtube_id)
friend_youtube.pk = None
friend_youtube.user_id = request.user.id
if Youtube.objects.filter(user=request.user.id, url=friend_youtube.url).exists():
result = "AlreadyExist"
else:
result = "success"
friend_youtube.save()
data = {"result": result}
return JsonResponse(data)


@router.post("/news")
def create_chat_room(request) -> JsonResponse:
news_id = request.POST["id"]
friend_news = News.objects.get(pk=news_id)
friend_news.pk = None
friend_news.user_id = request.user.id
if News.objects.filter(user=request.user.id, link=friend_news.link).exists():
result = "AlreadyExist"
else:
result = "success"
friend_news.save()
data = {"result": result}
return JsonResponse(data)


@router.post("/book")
def create_chat_room(request) -> JsonResponse:
book_id = request.POST["id"]
friend_book = Book.objects.get(pk=book_id)
friend_book.pk = None
friend_book.user_id = request.user.id
if Book.objects.filter(user=request.user.id, link=friend_book.link).exists():
result = "AlreadyExist"
else:
result = "success"
friend_book.save()
data = {"result": result}
return JsonResponse(data)


@router.post("/shopping")
def create_chat_room(request) -> JsonResponse:
shopping_id = request.POST["id"]
friend_shopping = Shopping.objects.get(pk=shopping_id)
friend_shopping.pk = None
friend_shopping.user_id = request.user.id
if Shopping.objects.filter(
user=request.user.id, link=friend_shopping.link
).exists():
result = "AlreadyExist"
else:
result = "success"
friend_shopping.save()
data = {"result": result}
return JsonResponse(data)
Empty file.
7 changes: 7 additions & 0 deletions apps/chat/apis/v1/schemas/chat_message_create_request.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from ninja import Schema


class ChatMessageCreateRequest(Schema):
room_id: int
user_id: int
message: str
8 changes: 8 additions & 0 deletions apps/chat/apis/v1/schemas/chat_message_response.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from ninja import Schema


class ChatMessageCreateRequest(Schema):
id: int
room_id: int
user_id: int
message: str
6 changes: 6 additions & 0 deletions apps/chat/apis/v1/schemas/chat_room_create_request.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from ninja import Schema


class ChatRoomCreateRequest(Schema):
user1_id: int
user2_id: int
7 changes: 7 additions & 0 deletions apps/chat/apis/v1/schemas/chat_room_response.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from ninja import Schema


class ChatRoomResponse(Schema):
room_id: int
user1_id: int
user2_id: int
6 changes: 6 additions & 0 deletions apps/chat/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class ChatConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "apps.chat"
92 changes: 92 additions & 0 deletions apps/chat/consumers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import json

from asgiref.sync import async_to_sync
from channels.generic.websocket import WebsocketConsumer

from apps.account.models import CustomUser

from .models import ChatMessage


class ChatConsumer(WebsocketConsumer):
# 이전 메세지 불러오기(소켓시 진입자 구별 불가로 미사용)
def fetch_messages(self, data):
messages = ChatMessage.last_10_messages()
content = {"command": "messages", "messages": self.messages_to_json(messages)}
self.send_chat_message(content)

# 새로운 메세지 DB에 저장하기
def new_message(self, data):
user_id = data["from"]
chatroom_id = data["room_id"]
chat_count = ChatMessage.objects.filter(chatroom_id=chatroom_id)
author = CustomUser.objects.filter(id=user_id)[0]
author_id = author.id
message = ChatMessage.objects.create(
author_id=author_id, message=data["message"], chatroom_id=chatroom_id
)
content = {
"command": "new_message",
"message": self.message_to_json(message),
"chat_count": len(chat_count),
}
return self.send_chat_message(content)

# DB에서 불러온 이전 메세지를 리스트 형태로 변환
def messages_to_json(self, messages):
result = []
for message in messages:
result.append(self.message_to_json(message))
return result

# 리스트 형태로 변환된 메세지를 key:value 형태로 반환
def message_to_json(self, message):
return {
"author": message.author.id,
"message": message.message,
"created_at": str(message.created_at),
"chatroom_id": message.chatroom.id,
}

# commands에 따라 실행되는 함수를 제어
commands = {"fetch_messages": fetch_messages, "new_messages": new_message}

# 웹소켓에 연결 되었을 때의 동작
def connect(self):
self.room_id = self.scope["url_route"]["kwargs"]["room_id"]
self.room_group_id = "chat_%s" % self.room_id

# room_id를 통해 그룹에 들어가기
async_to_sync(self.channel_layer.group_add)(
self.room_group_id, self.channel_name
)

self.accept()

# 웹소켓 연결이 끊어 졌을 때의 동작
def disconnect(self, close_code):
# 그룹에서 나오기
async_to_sync(self.channel_layer.group_discard)(
self.room_group_id, self.channel_name
)

# commands 를 통해 데이터 받아오기
def receive(self, text_data):
data = json.loads(text_data)
self.commands[data["command"]](self, data)

# room_id로 묶인 그룹에 메세지 보내주기
def send_chat_message(self, message):
async_to_sync(self.channel_layer.group_send)(
self.room_group_id, {"type": "chat_message", "message": message}
)

# 메세지는 json이나 바이너리 형태로 전송
def send_message(self, message):
self.send(text_data=json.dumps(message))

# room_id로 묶인 그룹에서 메세지 받기
# 웹소켓으로 메세지 전달
def chat_message(self, event):
message = event["message"]
self.send(text_data=json.dumps(message))
32 changes: 32 additions & 0 deletions apps/chat/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from django.db import models

from apps.account.models import CustomUser


class ChatRoom(models.Model):
class Meta:
db_table = "chat"

created_at = models.DateTimeField(auto_now_add=True)
participant1 = models.ForeignKey(
CustomUser, related_name="participant1_chatroom", on_delete=models.CASCADE
)
participant2 = models.ForeignKey(
CustomUser, related_name="participant2_chatroom", on_delete=models.CASCADE
)


class ChatMessage(models.Model):
class Meta:
db_table = "message"

chatroom = models.ForeignKey(ChatRoom, on_delete=models.CASCADE)
author = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
message = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)

def __str__(self):
return self.author

def last_10_messages():
return ChatMessage.objects.order_by("-created_at").all()[:10]
8 changes: 8 additions & 0 deletions apps/chat/routing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# 유저를 대신하여 consumers와 연결해주는 router 생성
from django.urls import re_path

from apps.chat import consumers

websocket_urlpatterns = [
re_path(r"ws/chat/room/(?P<room_id>\w+)/$", consumers.ChatConsumer.as_asgi()),
]
Empty file added apps/chat/services/__init__.py
Empty file.
13 changes: 13 additions & 0 deletions apps/chat/services/chat_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from chat.models import ChatRoom


def create_an_chat_room(user1_id: int, user2_id: int) -> ChatRoom:
return ChatRoom.objects.create(user1_id=user1_id, user2_id=user2_id)


def get_an_chat_room(room_id: int, user_id: int) -> ChatRoom:
return ChatRoom.objects.filter(user_id=user_id).get(id=room_id)


def delete_an_chat_room(room_id: int) -> None:
ChatRoom.objects.filter(id=room_id).delete()
24 changes: 24 additions & 0 deletions apps/chat/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from chat import views
from django.urls import path

app_name = "chat"

urlpatterns = [
path("", views.show_chat_list, name="show_chat_list"),
path("<int:id>/", views.create_chat_room, name="create_chat_room"),
path(
"room/<int:room_id>/",
views.post_data_to_chat_room,
name="post_data_to_chat_room",
),
path("chatlog/", views.chat_log_send, name="chat_log_send"),
path("morelist/", views.more_list, name="more_list"),
path("messageloader/", views.message_loader, name="massage_loader"),
path(
"latestmessagenotconnected/",
views.latest_message_not_connected,
name="latest_message_not_connected",
),
path("getroomid/", views.get_room_id, name="get_room_id"),
path("delete/<int:room_id>/", views.delete_chat_room, name="delete_chat_room"),
]
Loading

0 comments on commit 1824251

Please sign in to comment.