Skip to content

Commit

Permalink
Merge branch 'develop' of https://github.com/A-to-P/atop into feat/#40-…
Browse files Browse the repository at this point in the history
…detailedRequest
  • Loading branch information
Chaewon14 committed Jul 3, 2023
2 parents 43de57b + 3d6be9f commit 4732c6c
Show file tree
Hide file tree
Showing 26 changed files with 737 additions and 37 deletions.
10 changes: 9 additions & 1 deletion atop/asgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,16 @@

import os

from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application

import chat.routing

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'atop.settings')

application = get_asgi_application()
application = ProtocolTypeRouter({
'http': get_asgi_application(),
# websocket 프로토콜 타입으로 요청받으면 'config.asgi.application' 실행 (settings에 추가)
"websocket": AuthMiddlewareStack(URLRouter(chat.routing.websocket_urlpatterns)),
})
11 changes: 11 additions & 0 deletions atop/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
# Application definition

INSTALLED_APPS = [
'channels',
'chat',

'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
Expand Down Expand Up @@ -77,6 +80,14 @@

WSGI_APPLICATION = 'atop.wsgi.application'

ASGI_APPLICATION = 'atop.asgi.application'

CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels.layers.InMemoryChannelLayer"
}
}


# Database
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases
Expand Down
1 change: 1 addition & 0 deletions atop/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from django.conf.urls.static import static

urlpatterns = [
path('', include("chat.urls")),
path('', include("base.urls")),
path('', include("consulting.urls")),
path('', include("matching.urls")),
Expand Down
Empty file added chat/__init__.py
Empty file.
6 changes: 6 additions & 0 deletions chat/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.contrib import admin
from .models import Room, Message
# Register your models here.

admin.site.register(Room)
admin.site.register(Message)
6 changes: 6 additions & 0 deletions 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 = 'chat'
103 changes: 103 additions & 0 deletions chat/consumers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import json

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

from account.models import User
from chat.models import Message, Room

class ChatConsumer(WebsocketConsumer):
def fetch_messages(self, data):
room_id = int(self.room_name)
messages = Message.ordered_messages(self, room_id=room_id)
content = {
'command': 'messages',
'messages': self.messages_to_json(messages)
}
self.send_message(content)

def new_message(self, data):
user_id = data['user_id']
room_id = int(self.room_name)
user_contact = User.objects.filter(id=user_id)[0]
room_contact = Room.objects.filter(id=room_id)[0]
message_creat = Message.objects.create(
user=user_contact,
room=room_contact,
message=data['message'],
filename = data['file']['filename'],
base64URL = data['file']['base64URL'],
)
content = {
'command': 'new_message',
'message': self.message_to_json(message_creat)
}
return self.send_chat_message(content)

def messages_to_json(self, messages):
result = []
for message in messages:
result.append(self.message_to_json(message))
return result

def message_to_json(self, message):
result= {}
result['message_id']= message.id
result['author']= message.user.username,
result['content']= message.message,
result['file']= {'filename' : message.filename, 'base64URL':message.base64URL},
result['timestamp']= str(message.created_at)
return result

commands = {
'fetch_messages': fetch_messages,
'new_message': new_message
}

# websocket 연결
def connect(self):
# room_name 파라미터를 chat/routing.py URl 에서 얻고, 열러있는 websocket에 접속
self.room_name = self.scope["url_route"]["kwargs"]["room_name"]
# 인용이나 이스케이프 없이 사용자 지정 방 이름에서 직접 채널 그룹 이름을 구성
# 그룹 이름에는 문자, 숫자, 하이픈 및 마침표만 사용할 수 있어서 튜토리얼 예제 코드는 다른 문자가 있는 방이름 에서는 실패
self.room_group_name = "chat_%s" % self.room_name

# Join room group / 그룹에 참여
async_to_sync(self.channel_layer.group_add)(
self.room_group_name,
self.channel_name
)
# websocket 연결을 수락 / connect() 메서드 내에서 accept()를 호출하지 않으면 연결이 거부되고 닫힌다.
self.accept()

# websocket 연결 해제
def disconnect(self, close_code):
# Leave room group / 그룹에서 탈퇴
async_to_sync(self.channel_layer.group_discard)(
self.room_group_name,
self.channel_name
)

# Receive message from WebSocket
def receive(self, text_data):
data = json.loads(text_data)
self.commands[data['command']](self, data)

def send_chat_message(self, message):
async_to_sync(self.channel_layer.group_send)(
self.room_group_name,
{
"type": "chat_message",
"message": message
}
)

def send_message(self, message):
self.send(text_data=json.dumps(message))

# Receive message from room group
def chat_message(self, event):
message = event["message"]

# Send message to WebSocket
self.send(text_data=json.dumps(message))
38 changes: 38 additions & 0 deletions chat/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Generated by Django 4.2.2 on 2023-06-29 17:34

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

initial = True

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

operations = [
migrations.CreateModel(
name='Room',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('consultant', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='room_consultant', to=settings.AUTH_USER_MODEL)),
('restaurant', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='room_restaurant', to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='Message',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('message', models.TextField()),
('room', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='message', to='chat.room')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='message', to=settings.AUTH_USER_MODEL)),
],
),
]
18 changes: 18 additions & 0 deletions chat/migrations/0002_message_file.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 4.2.2 on 2023-07-02 15:54

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('chat', '0001_initial'),
]

operations = [
migrations.AddField(
model_name='message',
name='file',
field=models.FileField(blank=True, default=None, null=True, upload_to='chat/%y/%m/%d/'),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Generated by Django 4.2.2 on 2023-07-03 08:30

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('chat', '0002_message_file'),
]

operations = [
migrations.RemoveField(
model_name='message',
name='file',
),
migrations.AddField(
model_name='message',
name='base64URL',
field=models.TextField(blank=True, default=''),
),
migrations.AddField(
model_name='message',
name='filename',
field=models.CharField(blank=True, default='', max_length=50),
),
]
Empty file added chat/migrations/__init__.py
Empty file.
30 changes: 30 additions & 0 deletions chat/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from django.db import models

# Create your models here.


class Room(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)

consultant = models.ForeignKey(
"account.User", related_name='room_consultant', on_delete=models.CASCADE)
restaurant = models.ForeignKey(
"account.User", related_name='room_restaurant', on_delete=models.CASCADE)


class Message(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)

message = models.TextField() # 카카오톡은 글자수제한이 없다고함
user = models.ForeignKey("account.User", on_delete=models.CASCADE, related_name='message')
room = models.ForeignKey("chat.Room", on_delete=models.CASCADE, related_name='message')
filename = models.CharField(max_length=50, default="", blank=True)
base64URL = models.TextField(default="", blank=True)

def __str__(self) -> str:
return f"{self.user.username} \"{self.message[:5]}{'...' if len(self.message)>5 else ''}\""

def ordered_messages(self, room_id):
return Message.objects.filter(room=room_id).order_by('created_at')
7 changes: 7 additions & 0 deletions chat/routing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from django.urls import re_path

from chat import consumers

websocket_urlpatterns = [
re_path(r"ws/chat/(?P<room_name>\w+)/$", consumers.ChatConsumer.as_asgi()),
]
29 changes: 29 additions & 0 deletions chat/services/chat_room_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from typing import Tuple

from django.db.models import QuerySet

from chat.models import Room


def creat_an_chat_room(consult_id, rest_id) -> Room:
return Room.objects.create(consultant=consult_id, restaurant=rest_id)


def get_an_chat_room(room_id) -> Room:
return Room.objects.get(id=room_id)


def get_an_chat_room_list(user_id: int, job) -> QuerySet[Room]:
if job == "consultant":
return Room.objects.filter(consultant=user_id)
return Room.objects.filter(restaurant=user_id)


def get_chat_room_user(room_id: int) -> QuerySet[Room]:
return Room.objects.filter(room_id=room_id)


def confirm_user_chat_room_join(user_id: int, room_id: int, job) -> Room:
if job == "consultant":
return Room.objects.get(consultant=user_id, id=room_id)
return Room.objects.get(restaurant=user_id, id=room_id)
11 changes: 11 additions & 0 deletions chat/services/message_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from django.db.models import QuerySet

from chat.models import Message


def creat_an_message(user_id: int, room_id: int, message: str) -> Message:
return Message.objects.create(user=user_id, room=room_id, message=message)


def get_an_message_list(room_id: int) -> QuerySet[Message]:
return Message.objects.filter(room=room_id)
27 changes: 27 additions & 0 deletions chat/static/css/room.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#chat-log::-webkit-scrollbar {
width: 0.2rem; /*스크롤바의 너비*/
}
#chat-log::-webkit-scrollbar-thumb {
background-color: #2d2727; /*스크롤바의 색상*/
}
#chat-log::-webkit-scrollbar-track {
background-color: transparent; /*스크롤바 트랙 색상*/
}

.chat-message {
max-width: 20rem;
}

.file-download {
background-color: transparent;
border: none;
background-image: url("../../static/download.svg");
background-repeat: no-repeat;
width: 1rem;
height: 1rem;
margin-left: 0.5rem;
}

.hidden {
display: none;
}
4 changes: 4 additions & 0 deletions chat/static/download.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 4732c6c

Please sign in to comment.