From 9421fd0186f2b4a395e7879fa83642ee4fe696c6 Mon Sep 17 00:00:00 2001 From: vadim-shalapugin Date: Thu, 8 Dec 2022 21:16:31 +0500 Subject: [PATCH 1/2] fixed Docker --- Dockerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 5752a1b..da6ee11 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,6 @@ COPY ./requirements.txt /code/requirements.txt RUN pip install -r /code/requirements.txt COPY . /code/ -COPY c WORKDIR /code/ EXPOSE 8000 From e775e5727206baa977e4206c156889f974f14335 Mon Sep 17 00:00:00 2001 From: vadim-shalapugin Date: Thu, 8 Dec 2022 22:07:58 +0500 Subject: [PATCH 2/2] corrected PEP8 --- .env | 2 - .env.example | 2 + .gitignore | 143 ++++++++++++++++++ Dockerfile | 1 + README.md | 37 +++-- config/chat/consumers.py | 20 ++- config/chat/forms.py | 2 +- config/chat/routing.py | 2 + config/chat/static/js/messages.js | 27 ++++ config/chat/templates/chat/chatroom.html | 42 +++++ .../templates/chat}/enter_room.html | 7 +- config/chat/templates/chat/register.html | 11 ++ config/chat/urls.py | 2 +- config/chat/views.py | 18 +-- config/config/asgi.py | 1 - config/config/routing.py | 2 +- config/config/settings.py | 9 +- config/config/urls.py | 10 +- config/db.sqlite3 | Bin 131072 -> 0 bytes config/templates/base.html | 11 +- config/templates/chatroom.html | 84 ---------- config/templates/register.html | 22 --- docker-compose.yml | 2 +- requirements.txt | Bin 1288 -> 1284 bytes 24 files changed, 302 insertions(+), 155 deletions(-) delete mode 100644 .env create mode 100644 .env.example create mode 100644 config/chat/static/js/messages.js create mode 100644 config/chat/templates/chat/chatroom.html rename config/{templates => chat/templates/chat}/enter_room.html (85%) create mode 100644 config/chat/templates/chat/register.html delete mode 100644 config/db.sqlite3 delete mode 100644 config/templates/chatroom.html delete mode 100644 config/templates/register.html diff --git a/.env b/.env deleted file mode 100644 index b20c16a..0000000 --- a/.env +++ /dev/null @@ -1,2 +0,0 @@ -SECRET_KEY=django-insecure-48x7)it7dhzahw_#+^4@%026gg)f0j$gq5j=2(slj-smu+litp -DOMAIN=127.0.0.1:8000 \ No newline at end of file diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..ba979d6 --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +SECRET_KEY=YourSecretKey +DOMAIN=YourDomain \ No newline at end of file diff --git a/.gitignore b/.gitignore index a174f14..e2319d9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,146 @@ /venv/ /.idea/ /config.chat.migrations/ +### Python template +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# extra +.idea/ +config/db.sqlite3 \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index da6ee11..9281ed9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,5 @@ FROM python:3.10 + ENV PYTHONUNBUFFERED 1 ENV DJANGO_ENV dev ENV DOCKER_CONTAINER 1 diff --git a/README.md b/README.md index d3bb91f..b51bd5e 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,50 @@ -## Simple web chat on Websockets and Django - - - -## If you want to change settings, you should edit the env file - +# Simple web chat on Websockets and Django Launch ------- +---------- -``` +```bash git clone https://github.com/BenitoSwaggolini/WebChat.git +cd WebChat python -m venv venv .\venv\Scripts\activate pip install -r requirements.txt cd config python manage.py migrate -python manage.py runserver ``` +#### Create file `.env` or delete ```.example``` from ```.env.example``` +#### Fill in the data in the file `.env` -Docker ------- +### Example: +```dotenv +SECRET_KEY=MySecretKey +DOMAIN=127.0.0.1:8000 ``` -https://github.com/BenitoSwaggolini/WebChat.git -docker-compose up -d + +#### Run +``` +python manage.py runserver ``` +Docker +------ +```bash +https://github.com/BenitoSwaggolini/WebChat.git +cd WebChat +``` +``` +docker-compose up -d +``` Opportunities: ------ - * `chat/` - Chat * `log` - Authorization * `item` - Registration diff --git a/config/chat/consumers.py b/config/chat/consumers.py index 0e7c5d5..58aaa87 100644 --- a/config/chat/consumers.py +++ b/config/chat/consumers.py @@ -1,8 +1,14 @@ -from channels.generic.websocket import AsyncWebsocketConsumer import json +from channels.generic.websocket import AsyncWebsocketConsumer + class ChatRoomConsumer(AsyncWebsocketConsumer): + def __init__(self, *args, **kwargs): + super().__init__(args, kwargs) + self.room_group_name = None + self.room_name = None + async def connect(self): self.room_name = self.scope['url_route']['kwargs']['room_name'] self.room_group_name = f'chat_{self.room_name}' @@ -22,19 +28,21 @@ async def disconnect(self, code): async def receive(self, text_data=None, bytes_data=None): text_data_in_json = json.loads(text_data) + message = text_data_in_json['message'] username = text_data_in_json['username'] await self.channel_layer.group_send( self.room_group_name, - {'message': message, - 'username': username, - 'type': 'chat_message'} + { + 'message': message, + 'username': username, + 'type': 'chat_message' + } ) async def chat_message(self, event): message = event['message'] username = event['username'] - await self.send(text_data=json.dumps({'message': message, 'username': username,})) - + await self.send(text_data=json.dumps({'message': message, 'username': username})) diff --git a/config/chat/forms.py b/config/chat/forms.py index b7c6730..80296af 100644 --- a/config/chat/forms.py +++ b/config/chat/forms.py @@ -23,4 +23,4 @@ class LoginForm(AuthenticationForm): class Meta: model = User - fields = ['username', 'password'] \ No newline at end of file + fields = ['username', 'password'] diff --git a/config/chat/routing.py b/config/chat/routing.py index 9f41242..08758e4 100644 --- a/config/chat/routing.py +++ b/config/chat/routing.py @@ -1,5 +1,7 @@ from django.urls import re_path + from .consumers import ChatRoomConsumer + websocket_urlpatterns = [ re_path(r'ws/chat/(?P\w+)/$', ChatRoomConsumer.as_asgi()) ] diff --git a/config/chat/static/js/messages.js b/config/chat/static/js/messages.js new file mode 100644 index 0000000..9b3cdb8 --- /dev/null +++ b/config/chat/static/js/messages.js @@ -0,0 +1,27 @@ +const roomName = JSON.parse(document.getElementById("room-name").textContent); +const username = JSON.parse(document.getElementById("username").textContent); + +document.querySelector('#submit').onclick = function (e) { + + const messageInputDom = document.querySelector('#input'); + const message = messageInputDom.value; + + ChatSocket.send(JSON.stringify({ + 'message': message, + 'username': username, + })); + + messageInputDom.value = ''; +}; + +const ChatSocket = new WebSocket( + 'ws://' + window.location.host + '/ws/chat/' + roomName + '/' +); + +ChatSocket.onmessage = function (e) { + const data = JSON.parse(e.data) + + console.log(data) + + document.querySelector('#chat-messages').value += (data.username + ': ' + data.message + '\n') +} \ No newline at end of file diff --git a/config/chat/templates/chat/chatroom.html b/config/chat/templates/chat/chatroom.html new file mode 100644 index 0000000..23b5b1a --- /dev/null +++ b/config/chat/templates/chat/chatroom.html @@ -0,0 +1,42 @@ +{% extends 'base.html' %} +{% load static %} + +{% block css %} + +{% endblock css %} + + +{% block title %} + Hello +{% endblock title %} + +{% block content %} +
+
+

Chat "{{ room_name }}"

+ +
+ + + +
+ + {{ room_name|json_script:"room-name" }} + {{ request.user.username|json_script:"username" }} + + + + + + + + +{% endblock content %} diff --git a/config/templates/enter_room.html b/config/chat/templates/chat/enter_room.html similarity index 85% rename from config/templates/enter_room.html rename to config/chat/templates/chat/enter_room.html index 25e49cb..aa28b04 100644 --- a/config/templates/enter_room.html +++ b/config/chat/templates/chat/enter_room.html @@ -1,8 +1,7 @@ {% extends 'base.html' %} -{% block title %} - -{% endblock %} +{% block title %} +{% endblock title %} {% block content %} @@ -18,4 +17,4 @@

HOW TO JOIN THE CHAT:

{{DOMAIN}}/chat/ + your_chatroom_name -{% endblock %} \ No newline at end of file +{% endblock content %} diff --git a/config/chat/templates/chat/register.html b/config/chat/templates/chat/register.html new file mode 100644 index 0000000..42d05fd --- /dev/null +++ b/config/chat/templates/chat/register.html @@ -0,0 +1,11 @@ +{% extends 'base.html' %} + +{% block content %} +
+ {% csrf_token %} + + {{ form.as_p }} + + +
+{% endblock content %} diff --git a/config/chat/urls.py b/config/chat/urls.py index eadd7a1..f40f9bf 100644 --- a/config/chat/urls.py +++ b/config/chat/urls.py @@ -1,4 +1,5 @@ from django.urls import path + from .views import room, enter_room, register, authorization, logout_user urlpatterns = [ @@ -7,5 +8,4 @@ path('reg', register, name='reg'), path('log', authorization, name='log'), path('logout', logout_user, name='logout'), - ] diff --git a/config/chat/views.py b/config/chat/views.py index bc11a4c..da7a391 100644 --- a/config/chat/views.py +++ b/config/chat/views.py @@ -2,18 +2,20 @@ from django.contrib.auth.decorators import login_required from django.shortcuts import render, redirect from django.urls import reverse_lazy + from chat.forms import RegisterForm, LoginForm from config.settings import DOMAIN -def enter_room(request): - return render(request, 'enter_room.html', {'DOMAIN': DOMAIN}) +def enter_room(request): + return render(request, 'chat/enter_room.html', {'DOMAIN': DOMAIN}) def room(request, room_name): if not request.user.is_authenticated: return redirect('reg') - return render(request, 'chatroom.html', {'room_name': room_name}) + + return render(request, 'chat/chatroom.html', {'room_name': room_name}) def register(request): @@ -27,27 +29,25 @@ def register(request): return redirect('enter_room') except: pass - return render(request, 'register.html', {'form': form}) - + return render(request, 'chat/register.html', {'form': form}) def authorization(request): form = LoginForm() if request.method == "POST": - form = LoginForm(data=request.POST) + if form.is_valid(): user = form.get_user() login(request=request, user=user) return redirect('enter_room') - return render(request, 'register.html', {'form': form}) - + return render(request, 'chat/register.html', {'form': form}) @login_required(login_url=reverse_lazy('log')) def logout_user(request): logout(request) - return redirect('log') \ No newline at end of file + return redirect('log') diff --git a/config/config/asgi.py b/config/config/asgi.py index 4e4d210..a00b3b5 100644 --- a/config/config/asgi.py +++ b/config/config/asgi.py @@ -1,4 +1,3 @@ - import os from django.core.asgi import get_asgi_application diff --git a/config/config/routing.py b/config/config/routing.py index 971f3b0..4fa58d8 100644 --- a/config/config/routing.py +++ b/config/config/routing.py @@ -2,7 +2,7 @@ from channels.routing import ProtocolTypeRouter, URLRouter import chat.routing -"""URLS FOR ASGI UPDATE(ASYNC)""" +# URLS FOR ASGI UPDATE(ASYNC) application = ProtocolTypeRouter({ 'websocket': AuthMiddlewareStack( diff --git a/config/config/settings.py b/config/config/settings.py index ff8da33..f8c2029 100644 --- a/config/config/settings.py +++ b/config/config/settings.py @@ -9,9 +9,9 @@ For the full list of settings and their values, see https://docs.djangoproject.com/en/4.1/ref/settings/ """ +import os from dotenv import load_dotenv from pathlib import Path -import os load_dotenv() @@ -24,16 +24,18 @@ ALLOWED_HOSTS = [] INSTALLED_APPS = [ - 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', + + # applications 'chat', - 'channels', + # libraries + 'channels', ] MIDDLEWARE = [ @@ -97,6 +99,7 @@ USE_TZ = True STATIC_URL = 'static/' +STATIC_ROOT = os.path.join(BASE_DIR, 'static') DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' diff --git a/config/config/urls.py b/config/config/urls.py index fac1373..7437b1f 100644 --- a/config/config/urls.py +++ b/config/config/urls.py @@ -1,9 +1,15 @@ +from django.conf import settings +from django.conf.urls.static import static from django.contrib import admin from django.urls import path, include + from chat import urls -from chat.views import enter_room +from chat.views import enter_room + urlpatterns = [ + path('', enter_room, name='enter_room'), path('admin/', admin.site.urls), path('chat/', include(urls)), - path('', enter_room, name='enter_room') ] + +urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_URL) diff --git a/config/db.sqlite3 b/config/db.sqlite3 deleted file mode 100644 index ba3b1b3f0ce0454cca0a395b9ae30be6828c371e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 131072 zcmeI5Yi#4#b;m_Zmi&_FvB#@PW@ks%%@ZP6wzvIUwZMcOZEgC;3jB>9jA z=)DvrQZL)<%oNkvqruQ5@41Kn`@5HyH?wBXWF`}ZZ&3HsDgT!jI7c42D(7H5}mvt%jH}Fwa8~|171sSFhdZC<&>64%6MTF63MbF(XK6 z?MOb4b|jP^3oQzXM7v0oBE*W)F;dy8AD5U<<)o~L5VaNGMGu(mq1%K(=?>+iG`d~m zQAHtpbbo`_)EgYSu{wAb>9g25j(F_T>bKUGw6m*rVzlk;?@;q?MptSEH7`%RF(c|) zq3{jV)97QW!)A+pe4MBrwg6R_D~Ket)bh}YVMvfhX8 zqVa#j+1*}?ePV)m;}^8@XcUz~X`AK_CDT%$K=C}f;-Ttny(KumLgOhRo6I#`yj4jT zUz{4(XRT+VbXr{1MU%yzV~Oeqm6NT*p?D#m=hH$|O!FCZCz9rU-e{bSvr*+Xq(g>Y z6=w4jMF+$4J=g9+I%LCTZ)m~~7K$u%Ta`3g>?}*1m6RIqkh8-sQ*+ICuy_KsPwSB* z!J7KcwbCe4=VaGki{-zVI~n7p}TR&$lTirw78v4}G!=Y<~UmkoD8Nmk#00AHX1b_e#00KY& z2mpa50_;ey;nux?EY`+pD2k$aDJvBvAGf6X(6yu<&8INa%_D^~Iw4e4aUh6fC z?FR63H?n7VAzefxR!T@#3tI6R;e=0%*<|scqbDzlsxhw*BTox;Pc&c3E77HVA$L;I zjqu1FJ-EG$pPnU=ht;|VO4U*eCE%xwi)64Ya!l zR^5?b@2DR3yGRhl`rY*M5c2bZx*wnF=U7Nfh)=G7f^+dWFBS^90-r%uCnUv=h}?d^ zpYaCdV1+-tbE5K!Yk3Pwy3@y+Cp8+dCYRJa9o#7iMfY`C}AU`Lwb87Yfg zusFDk2Db_orJivhHkaiSX(7qS4ssHT3v_bD`mw8k3AsX)RacDWN|lAq+8lP<(FLw- zmNFt2_ZlwF?GRWmg>p>yAf_mX(jlDRgRr=H`+WpLcdr%Q`A4E@H|@2Oziu#-#|HA> z$*+>1Bag|Cke?<`nz}UD00KY&2mk>f00e*l5C8%|00;m9AOHleL}1ipoFH1J+1#-9 z8^`;Uol3L~IUea(HgPluZH-z7jJIpK@E)VxXk>{Fb27}MJ;upCH9?76;F!f2VVtg8 zYcmx_29RSj`4I#8UGlHVuaRFMe+zBE2M7QGAOHk_01yBIKmZ5;0U!VbfB+D9S_H0} zZrvp66Nl8l<`+%(?hyJJ5xVtWt7&XZ2?*eLfXQYWvnyLl_`o=78XH$OwW%0A*G%?X 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 Sx^p$zH^XvMH09-3`hNlC2fI1| diff --git a/config/templates/base.html b/config/templates/base.html index 49db471..4f2444c 100644 --- a/config/templates/base.html +++ b/config/templates/base.html @@ -2,14 +2,17 @@ - {% block title %}{% endblock %} - {% block css_js %} - {% endblock %} + {% block title %}{% endblock title %} + + {% block css %} + {% endblock css %} + + {% block content %} -{% endblock %} +{% endblock content %} \ No newline at end of file diff --git a/config/templates/chatroom.html b/config/templates/chatroom.html deleted file mode 100644 index cb29964..0000000 --- a/config/templates/chatroom.html +++ /dev/null @@ -1,84 +0,0 @@ -{% extends 'base.html' %} - -{% block css_js %} - - - - - -{% endblock %} - - -{% block title %} - -Hello -{% endblock %} - -{% block content %} - -
- - -
-

Chat "{{room_name}}"

- -
- - - -
- - - - -
- -{{ room_name|json_script:"room-name"}} -{{ request.user.username|json_script:"username" }} - - - - - - - -{% endblock %} - - - - - diff --git a/config/templates/register.html b/config/templates/register.html deleted file mode 100644 index c2758ec..0000000 --- a/config/templates/register.html +++ /dev/null @@ -1,22 +0,0 @@ -{% extends 'base.html' %} - -{% block content %} - - - - -
- - {% csrf_token %} - - {{form.as_p}} - - - - -
- - - - -{% endblock %} \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index c078988..9f0a44c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,7 +5,7 @@ services: build: . command: bash -c "python config/manage.py migrate && python config/manage.py runserver 0.0.0.0:8000" ports: - - 8000:8000 + - "8000:8000" volumes: - .:/code expose: diff --git a/requirements.txt b/requirements.txt index cac0ae58b910396896117c0fe26dbb2a77bf1d7a..4d0e099bf9aadd7424aac7b28e43db6922b60ce2 100644 GIT binary patch delta 11 ScmeC+YT?@8z%to|fqYoz%to}