add sse server
This commit is contained in:
parent
bf365b1204
commit
bd11ddbd60
22
deployment/migrations/0007_alter_deployment_id.py
Normal file
22
deployment/migrations/0007_alter_deployment_id.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# Generated by Django 4.2.5 on 2023-09-16 17:21
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("deployment", "0006_alter_deployment_id_alter_deployment_status_and_more"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="deployment",
|
||||||
|
name="id",
|
||||||
|
field=models.UUIDField(
|
||||||
|
default=uuid.UUID("0cc4ae03-f52e-4f3a-9fe1-fecda707b20e"),
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -4,6 +4,9 @@ from uuid import uuid4
|
|||||||
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.db.models.signals import pre_save, pre_delete
|
||||||
|
from django.dispatch import receiver
|
||||||
|
from django_eventstream import send_event
|
||||||
|
|
||||||
|
|
||||||
class Type(Enum):
|
class Type(Enum):
|
||||||
@ -41,3 +44,9 @@ class Deployment(models.Model):
|
|||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.name} | {self.type} | {self.status}"
|
return f"{self.name} | {self.type} | {self.status}"
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(pre_save, sender=Deployment)
|
||||||
|
@receiver(pre_delete, sender=Deployment)
|
||||||
|
def deployment_update_handler(sender, instance, **kwargs):
|
||||||
|
send_event("deployment", "update", {"id": instance.id, "status": instance.status})
|
||||||
|
|||||||
@ -9,7 +9,7 @@ from django.http import (
|
|||||||
from django.shortcuts import render, get_object_or_404
|
from django.shortcuts import render, get_object_or_404
|
||||||
|
|
||||||
from deployment.forms import DeploymentForm
|
from deployment.forms import DeploymentForm
|
||||||
from deployment.models import Deployment
|
from deployment.models import Deployment, Status
|
||||||
|
|
||||||
|
|
||||||
def index(request):
|
def index(request):
|
||||||
@ -19,14 +19,16 @@ def index(request):
|
|||||||
page_number = request.GET.get("page")
|
page_number = request.GET.get("page")
|
||||||
page_obj = paginator.get_page(page_number)
|
page_obj = paginator.get_page(page_number)
|
||||||
|
|
||||||
return render(request, "deployment/board.html", {"page_obj": page_obj})
|
return render(
|
||||||
|
request, "deployment/board.html", {"page_obj": page_obj, "url": "/events/"}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def details(request, deployment_id):
|
def details(request, deployment_id):
|
||||||
deployment = get_object_or_404(Deployment, id=deployment_id)
|
deployment = get_object_or_404(Deployment, id=deployment_id)
|
||||||
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
if deployment.status == deployment.RUNNING:
|
if deployment.status == Status.RUNNING:
|
||||||
return HttpResponseBadRequest("deployment is running")
|
return HttpResponseBadRequest("deployment is running")
|
||||||
try:
|
try:
|
||||||
deployment.delete()
|
deployment.delete()
|
||||||
|
|||||||
@ -8,9 +8,27 @@ https://docs.djangoproject.com/en/4.2/howto/deployment/asgi/
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from django.core.asgi import get_asgi_application
|
from django.core.asgi import get_asgi_application
|
||||||
|
from django.urls import path, re_path
|
||||||
|
from channels.routing import ProtocolTypeRouter, URLRouter
|
||||||
|
from channels.auth import AuthMiddlewareStack
|
||||||
|
import django_eventstream
|
||||||
|
|
||||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mumui.settings")
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "server.settings")
|
||||||
|
|
||||||
application = get_asgi_application()
|
application = ProtocolTypeRouter(
|
||||||
|
{
|
||||||
|
"http": URLRouter(
|
||||||
|
[
|
||||||
|
path(
|
||||||
|
"events/",
|
||||||
|
AuthMiddlewareStack(
|
||||||
|
URLRouter(django_eventstream.routing.urlpatterns)
|
||||||
|
),
|
||||||
|
{"channels": ["test"]},
|
||||||
|
),
|
||||||
|
re_path(r"", get_asgi_application()),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|||||||
@ -38,9 +38,12 @@ INSTALLED_APPS = [
|
|||||||
"django.contrib.messages",
|
"django.contrib.messages",
|
||||||
"django.contrib.staticfiles",
|
"django.contrib.staticfiles",
|
||||||
"deployment",
|
"deployment",
|
||||||
|
"channels",
|
||||||
|
"django_eventstream",
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
|
"django_grip.GripMiddleware",
|
||||||
"django.middleware.security.SecurityMiddleware",
|
"django.middleware.security.SecurityMiddleware",
|
||||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||||
"django.middleware.common.CommonMiddleware",
|
"django.middleware.common.CommonMiddleware",
|
||||||
@ -125,3 +128,5 @@ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
|
|||||||
|
|
||||||
LOGIN_REDIRECT_URL = "home"
|
LOGIN_REDIRECT_URL = "home"
|
||||||
LOGOUT_REDIRECT_URL = "home"
|
LOGOUT_REDIRECT_URL = "home"
|
||||||
|
|
||||||
|
ASGI_APPLICATION = "mumui.asgi.application"
|
||||||
|
|||||||
43
requirements.txt
Normal file
43
requirements.txt
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
asgiref==3.7.2
|
||||||
|
attrs==23.1.0
|
||||||
|
autobahn==23.6.2
|
||||||
|
Automat==22.10.0
|
||||||
|
black==23.9.1
|
||||||
|
certifi==2023.7.22
|
||||||
|
cffi==1.15.1
|
||||||
|
channels==3.0.5
|
||||||
|
charset-normalizer==3.2.0
|
||||||
|
click==8.1.7
|
||||||
|
constantly==15.1.0
|
||||||
|
cryptography==41.0.3
|
||||||
|
daphne==3.0.2
|
||||||
|
Django==4.2.5
|
||||||
|
django-eventstream==4.5.1
|
||||||
|
django-grip==3.4.0
|
||||||
|
gripcontrol==4.2.0
|
||||||
|
hyperlink==21.0.0
|
||||||
|
idna==3.4
|
||||||
|
incremental==22.10.0
|
||||||
|
MarkupSafe==2.1.3
|
||||||
|
mypy-extensions==1.0.0
|
||||||
|
packaging==23.1
|
||||||
|
pathspec==0.11.2
|
||||||
|
platformdirs==3.10.0
|
||||||
|
pubcontrol==3.5.0
|
||||||
|
pyasn1==0.5.0
|
||||||
|
pyasn1-modules==0.3.0
|
||||||
|
pycparser==2.21
|
||||||
|
PyJWT==2.8.0
|
||||||
|
pyOpenSSL==23.2.0
|
||||||
|
requests==2.31.0
|
||||||
|
ruff==0.0.290
|
||||||
|
service-identity==23.1.0
|
||||||
|
six==1.16.0
|
||||||
|
sqlparse==0.4.4
|
||||||
|
tomli==2.0.1
|
||||||
|
Twisted==23.8.0
|
||||||
|
txaio==23.1.1
|
||||||
|
typing_extensions==4.7.1
|
||||||
|
urllib3==2.0.4
|
||||||
|
Werkzeug==2.3.7
|
||||||
|
zope.interface==6.0
|
||||||
@ -3,8 +3,9 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>{% block title %}mumui{% endblock %}</title>
|
<title>{% block title %}mumui{% endblock %}</title>
|
||||||
|
{% block headscript %}{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body {% block bodyattr %}{% endblock %}>
|
||||||
<main>
|
<main>
|
||||||
{% if user.is_authenticated or "login" in request.path %}
|
{% if user.is_authenticated or "login" in request.path %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
@ -17,5 +18,6 @@
|
|||||||
<a href="{% url 'login' %}">log In</a>
|
<a href="{% url 'login' %}">log In</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</main>
|
</main>
|
||||||
|
{% block script %}{% endblock %}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@ -1,15 +1,42 @@
|
|||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
{% block title %}deployment's board{% endblock %}
|
{% block title %}deployment's board{% endblock %}
|
||||||
|
|
||||||
|
{% block headscript %}
|
||||||
|
<script src="{% static 'django_eventstream/json2.js' %}"></script>
|
||||||
|
<script src="{% static 'django_eventstream/eventsource.min.js' %}"></script>
|
||||||
|
<script src="{% static 'django_eventstream/reconnecting-eventsource.js' %}"></script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block bodyattr %}
|
||||||
|
onload="start();"
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{{ user.username }}'s board
|
{{ user.username }}'s board
|
||||||
{% if page_obj %}
|
{% if page_obj %}
|
||||||
<ul>
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>name</th>
|
||||||
|
<th>type</th>
|
||||||
|
<th>status</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
{% for deployment in page_obj %}
|
{% for deployment in page_obj %}
|
||||||
<li><a href="{% url 'deployment-details' deployment.id %}">{{ deployment.name }} | {{ deployment.type }} | {{ deployment.status }}</a></li>
|
<tr id="{{ deployment.id }}">
|
||||||
|
<th name="name">{{ deployment.name }}</th>
|
||||||
|
<th name="type">{{ deployment.type }}</th>
|
||||||
|
<th name="status">{{ deployment.status }}</th>
|
||||||
|
<th>
|
||||||
|
<a href="{% url 'deployment-details' deployment.id %}">
|
||||||
|
<button>details</button>
|
||||||
|
</a>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</table>
|
||||||
<div class="pagination">
|
<div class="pagination">
|
||||||
<span class="step-links">
|
<span class="step-links">
|
||||||
{% if page_obj.has_previous %}
|
{% if page_obj.has_previous %}
|
||||||
@ -33,4 +60,26 @@
|
|||||||
<a href="/deployment/create">
|
<a href="/deployment/create">
|
||||||
<button>create</button>
|
<button>create</button>
|
||||||
</a>
|
</a>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block script %}
|
||||||
|
<script>
|
||||||
|
var start = function () {
|
||||||
|
|
||||||
|
var es = new ReconnectingEventSource('{{ url|safe }}');
|
||||||
|
|
||||||
|
es.onopen = function () {
|
||||||
|
console.log('connected');
|
||||||
|
};
|
||||||
|
|
||||||
|
es.onerror = function () {
|
||||||
|
console.log('connection error');
|
||||||
|
};
|
||||||
|
|
||||||
|
es.addEventListener('deployment', function (e) {
|
||||||
|
e = JSON.parse(e.data);
|
||||||
|
console.log('stream reset: ' + JSON.stringify(e.channels));
|
||||||
|
}, false);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@ -10,11 +10,11 @@
|
|||||||
<th>type</th>
|
<th>type</th>
|
||||||
<th>status</th>
|
<th>status</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr id="{{ deployment.id }}">
|
||||||
<th>{{ deployment.id }}</th>
|
<th name="id">{{ deployment.id }}</th>
|
||||||
<th>{{ deployment.name }}</th>
|
<th name="name">{{ deployment.name }}</th>
|
||||||
<th>{{ deployment.type }}</th>
|
<th name="type">{{ deployment.type }}</th>
|
||||||
<th>{{ deployment.status }}</th>
|
<th name="status">{{ deployment.status }}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<form action="" method="post">
|
<form action="" method="post">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user