sdbs-infra/sdbs_infra/dashboard/models.py

68 lines
2.3 KiB
Python

import socket
import urllib.request
from enum import Enum
from socket import timeout
from urllib.error import URLError
from urllib.request import Request
from bs4 import BeautifulSoup
from django.db import models
from django.utils.functional import cached_property
from ordered_model.models import OrderedModel
class ServiceStatus(Enum):
OK = 'ok'
DOWN = 'down'
UNKNOWN = 'unknown'
class Service(OrderedModel):
short_name = models.CharField(null=False, max_length=64)
image = models.ImageField(null=True, blank=True, upload_to='services')
description = models.TextField(null=True, blank=True)
port = models.IntegerField(null=True, blank=True, help_text="Used for checking status")
url = models.URLField()
def __str__(self):
return f"{self.short_name} ({self.url})"
@cached_property
def index_request(self):
try:
request = Request(self.url, headers={'User-Agent': 'its just me humble status page'})
return urllib.request.urlopen(request, timeout=1)
except (URLError, timeout):
return None
def get_status(self):
if self.port:
a_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
location = ("localhost", self.port)
result_of_check = a_socket.connect_ex(location)
if result_of_check == 0:
return ServiceStatus.OK
else:
return ServiceStatus.DOWN
if self.index_request and self.index_request.getcode() == 200:
return ServiceStatus.OK
else:
return ServiceStatus.DOWN
@cached_property
def image_or_favicon(self):
if self.image:
return self.image.url
if self.index_request:
parsed_html = BeautifulSoup(self.index_request, features="html.parser")
link_tags = parsed_html.find_all('link')
for rel in ['apple-touch-icon', 'shortcut', 'icon']:
for link_tag in link_tags:
if rel in link_tag.attrs['rel']:
result = link_tag.attrs['href']
if self.url not in result:
return self.url + (result if result.startswith("/") else f"/{result}")
else:
return result