mirror of
https://github.com/seriousm4x/UpSnap.git
synced 2026-04-05 08:54:03 -04:00
add visitor counter. only run tasks when > 0 visitors
This commit is contained in:
@@ -4,7 +4,7 @@ A simple wake on lan app written with Django, Django-Channels (websockets), Cele
|
||||
|
||||
| Dark | Light |
|
||||
| -------------------- | --------------------- |
|
||||
|  |  |
|
||||
|  |  |
|
||||
|
||||
## Run your own instance
|
||||
|
||||
|
||||
@@ -9,14 +9,18 @@ https://docs.djangoproject.com/en/3.1/howto/deployment/asgi/
|
||||
|
||||
import os
|
||||
|
||||
from django.core.asgi import get_asgi_application
|
||||
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_wol.settings")
|
||||
django_asgi_app = get_asgi_application()
|
||||
|
||||
from channels.auth import AuthMiddlewareStack
|
||||
from channels.routing import ProtocolTypeRouter, URLRouter
|
||||
from django.core.asgi import get_asgi_application
|
||||
from wol.routing import ws_urlpatterns
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_wol.settings')
|
||||
|
||||
application = ProtocolTypeRouter({
|
||||
"http": get_asgi_application(),
|
||||
"http": django_asgi_app,
|
||||
"websocket": AuthMiddlewareStack(URLRouter(ws_urlpatterns))
|
||||
})
|
||||
|
||||
@@ -9,6 +9,10 @@ if [ -n "$DJANGO_SUPERUSER_USER" ] && [ -n "$DJANGO_SUPERUSER_PASSWORD" ]; then
|
||||
python -u manage.py shell -c "from django.contrib.auth.models import User; User.objects.create_superuser('$DJANGO_SUPERUSER_USER', password='$DJANGO_SUPERUSER_PASSWORD') if not User.objects.filter(username='$DJANGO_SUPERUSER_USER').exists() else print('Django user exists')"
|
||||
fi
|
||||
|
||||
# set visitors to 0
|
||||
python -u manage.py shell -c "from wol.models import Websocket; [i.delete() for i in Websocket.objects.all()]; Websocket.objects.create(visitors=0)"
|
||||
|
||||
celery -A django_wol worker &
|
||||
celery -A django_wol beat &
|
||||
gunicorn --bind 0.0.0.0:"$DJANGO_PORT" --workers 4 django_wol.asgi:application -k uvicorn.workers.UvicornWorker
|
||||
|
||||
|
||||
@@ -1,15 +1,55 @@
|
||||
import json
|
||||
|
||||
from channels.db import database_sync_to_async
|
||||
from channels.generic.websocket import AsyncWebsocketConsumer
|
||||
|
||||
from .models import Websocket
|
||||
|
||||
|
||||
class WSConsumer(AsyncWebsocketConsumer):
|
||||
async def connect(self):
|
||||
await self.channel_layer.group_add("status", self.channel_name)
|
||||
await self.channel_layer.group_add("wol", self.channel_name)
|
||||
await self.accept()
|
||||
await self.add_visitor()
|
||||
await self.channel_layer.group_send(
|
||||
"wol", {
|
||||
"type": "send_visitors",
|
||||
"message": {
|
||||
"visitors": await self.get_visitors()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
async def disconnect(self, code):
|
||||
await self.channel_layer.group_discard("status", self.channel_name)
|
||||
await self.channel_layer.group_discard("wol", self.channel_name)
|
||||
await self.remove_visitor()
|
||||
await self.channel_layer.group_send(
|
||||
"wol", {
|
||||
"type": "send_visitors",
|
||||
"message": {
|
||||
"visitors": await self.get_visitors()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
async def send_status(self, event):
|
||||
text_message = event["status"]
|
||||
await self.send(event["status"])
|
||||
|
||||
await self.send(text_message)
|
||||
async def send_visitors(self, event):
|
||||
await self.send(json.dumps(event["message"]))
|
||||
|
||||
@database_sync_to_async
|
||||
def add_visitor(self):
|
||||
visitor_count = Websocket.objects.first()
|
||||
visitor_count.visitors += 1
|
||||
visitor_count.save()
|
||||
|
||||
@database_sync_to_async
|
||||
def remove_visitor(self):
|
||||
visitor_count = Websocket.objects.first()
|
||||
visitor_count.visitors -= 1
|
||||
visitor_count.save()
|
||||
|
||||
@database_sync_to_async
|
||||
def get_visitors(self):
|
||||
return str(Websocket.objects.first().visitors)
|
||||
|
||||
@@ -7,3 +7,6 @@ class Device(models.Model):
|
||||
ip = models.GenericIPAddressField()
|
||||
mac = models.CharField(max_length=17)
|
||||
netmask = models.CharField(max_length=15, default="255.255.255.0", blank=False, null=False)
|
||||
|
||||
class Websocket(models.Model):
|
||||
visitors = models.PositiveSmallIntegerField(blank=False, null=False, default=0)
|
||||
|
||||
@@ -42,6 +42,12 @@
|
||||
background-color: var(--down-red);
|
||||
}
|
||||
|
||||
.button.is-static {
|
||||
background-color: #dbdbdb;
|
||||
border-color: transparent;
|
||||
color: #363636;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.box {
|
||||
background-color: var(--box-bg);
|
||||
|
||||
@@ -7,10 +7,16 @@ $('.wake-form').submit(function (e) {
|
||||
|
||||
var socket = new WebSocket("ws://" + location.host + "/wol/");
|
||||
socket.onmessage = function(event) {
|
||||
var device = JSON.parse(event.data);
|
||||
console.log(device);
|
||||
var message = JSON.parse(event.data);
|
||||
console.log(message);
|
||||
|
||||
if ("visitors" in message) {
|
||||
document.getElementById("visitors").innerHTML = message.visitors + ' Visitors';
|
||||
return;
|
||||
}
|
||||
|
||||
// get elements
|
||||
var device = message.device
|
||||
var deviceBox = document.getElementById(device.id + "-container");
|
||||
var statusDot = document.getElementById(device.id + "-dot");
|
||||
var statusPorts = document.getElementById(device.id + "-ports");
|
||||
|
||||
@@ -7,7 +7,7 @@ from asgiref.sync import async_to_sync
|
||||
from celery import shared_task
|
||||
from channels.layers import get_channel_layer
|
||||
|
||||
from .models import Device
|
||||
from .models import Device, Websocket
|
||||
|
||||
channel_layer = get_channel_layer()
|
||||
|
||||
@@ -29,6 +29,7 @@ class WolDevice:
|
||||
|
||||
def start(self, dev):
|
||||
data = {
|
||||
"device": {
|
||||
"id": dev.id,
|
||||
"name": dev.name,
|
||||
"ip": dev.ip,
|
||||
@@ -38,22 +39,26 @@ class WolDevice:
|
||||
"rdp": False,
|
||||
"ssh": False
|
||||
}
|
||||
}
|
||||
|
||||
if self.ping_device(dev.ip):
|
||||
data["up"] = True
|
||||
data["device"]["up"] = True
|
||||
if self.check_port(dev.ip, 5900):
|
||||
data["vnc"] = True
|
||||
data["device"]["vnc"] = True
|
||||
if self.check_port(dev.ip, 3389):
|
||||
data["rdp"] = True
|
||||
data["device"]["rdp"] = True
|
||||
if self.check_port(dev.ip, 22):
|
||||
data["ssh"] = True
|
||||
data["device"]["ssh"] = True
|
||||
|
||||
async_to_sync(channel_layer.group_send)(
|
||||
"status", {"type": "send_status", "status": json.dumps(data)})
|
||||
"wol", {"type": "send_status", "status": json.dumps(data)})
|
||||
|
||||
|
||||
@shared_task
|
||||
def status():
|
||||
if Websocket.objects.first().visitors == 0:
|
||||
return
|
||||
|
||||
devices = Device.objects.all()
|
||||
|
||||
for dev in devices:
|
||||
|
||||
@@ -27,12 +27,24 @@
|
||||
</p>
|
||||
</div>
|
||||
<div class="column is-one-third">
|
||||
<div class="field is-grouped">
|
||||
<p class="control">
|
||||
<a class="button is-light" href="/admin">
|
||||
<span>Admin</span>
|
||||
<span class="icon is-small">
|
||||
<i class="fas fa-user-cog"></i>
|
||||
</span>
|
||||
</a>
|
||||
</p>
|
||||
<p class="control">
|
||||
<div class="button is-static is-light">
|
||||
<span id="visitors">{{ visitors }} Visitors</span>
|
||||
<span class="icon is-small">
|
||||
<i class="fas fa-users"></i>
|
||||
</span>
|
||||
</div>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,22 +1,19 @@
|
||||
import ipaddress
|
||||
import json
|
||||
import subprocess
|
||||
from platform import system
|
||||
|
||||
import wakeonlan
|
||||
from django.core.serializers import serialize
|
||||
from django.http import JsonResponse
|
||||
from django.shortcuts import HttpResponse, get_object_or_404, render
|
||||
|
||||
from .forms import WakeDeviceForm
|
||||
from .models import Device
|
||||
from .models import Device, Websocket
|
||||
|
||||
|
||||
def index(request):
|
||||
devices = Device.objects.all().order_by("name")
|
||||
visitors = Websocket.objects.first().visitors
|
||||
|
||||
context = {
|
||||
"devices": devices
|
||||
"devices": devices,
|
||||
"visitors": visitors
|
||||
}
|
||||
|
||||
return render(request, "wol/index.html", context)
|
||||
|
||||
BIN
assets/dark.jpg
BIN
assets/dark.jpg
Binary file not shown.
|
Before Width: | Height: | Size: 241 KiB |
BIN
assets/light.jpg
BIN
assets/light.jpg
Binary file not shown.
|
Before Width: | Height: | Size: 243 KiB |
Reference in New Issue
Block a user