2020-06-14 12:08:11 +02:00
|
|
|
import urllib.request
|
|
|
|
from enum import Enum
|
2020-06-14 19:59:44 +02:00
|
|
|
from socket import timeout
|
2020-06-14 12:08:11 +02:00
|
|
|
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)
|
|
|
|
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'})
|
2020-06-14 19:59:44 +02:00
|
|
|
return urllib.request.urlopen(request, timeout=1)
|
|
|
|
except (URLError, timeout):
|
2020-06-14 12:08:11 +02:00
|
|
|
return None
|
|
|
|
|
|
|
|
def get_status(self):
|
|
|
|
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']
|
2020-06-14 12:28:05 +02:00
|
|
|
if self.url not in result:
|
2020-06-14 12:29:17 +02:00
|
|
|
return self.url + (result if result.startswith("/") else f"/{result}")
|
2020-06-14 12:28:05 +02:00
|
|
|
else:
|
|
|
|
return result
|