PK ! django_ping_me/__init__.pyPK ! django_ping_me/admin.pyfrom django.contrib import admin from .models import Domain, Ping, PingSummary admin.site.register(Domain) admin.site.register(Ping) admin.site.register(PingSummary)PK ! xX X django_ping_me/apps.pyfrom django.apps import AppConfig class PingMeConfig(AppConfig): name = 'ping_me' PK ! `9 9 django_ping_me/cron.pyfrom .models import Domain, Ping, PingSummary from django_cron import CronJobBase, Schedule # https://django-cron.readthedocs.io import aloha.network import datetime import logging import pytz logger = logging.getLogger(__name__) class PingMeCronJob(CronJobBase): RUN_EVERY_MINS = 1 schedule = Schedule(run_every_mins=RUN_EVERY_MINS) code = 'ping_me.cron' def do(self): """Fonction principale d'exécution du cron""" all_domains = Domain.objects.order_by('url') logger.debug("Mise à jour des domaines PingMe! {} domaine(s) trouvé(s) !" .format(len(all_domains))) for domain in all_domains: self.update_domain(domain) def update_domain(self, domain): """Met à jour un domaine""" try: last_ping = Ping.objects.filter(domain=domain).latest('date') except Ping.DoesNotExist: last_ping = None ping = self.create_ping(domain) if last_ping: # Si le domaine ne répond plus au ping if last_ping.success and not ping.success: logger.error("Le domaine {} vient de tomber! :-o".format(domain.url)) # Si le dernier ping date du mois dernier if last_ping.date.month != ping.date.month: self.clean_pings(domain, last_ping) def create_ping(self, domain): """Exécute un nouveau ping et l'enregistre en base de données""" ip_address = aloha.network.resolve_hostname(domain.url) ping = Ping(address=ip_address, domain=domain) if aloha.network.is_http_alive(domain.url, timeout=5): ping.success = True logger.debug("Site {} fonctionnel !".format(domain.url)) else: ping.success = False logger.warning("Site {} cassé ! :-(".format(domain.url)) ping.save() return ping def clean_pings(self, domain, last_ping): """Nettoie les pings du mois précédent et crée un résumé en base de données""" start_date = datetime.datetime( year=last_ping.date.year, month=last_ping.date.month, day=1, tzinfo=pytz.UTC ) end_date = start_date + datetime.timedelta(days=32) end_date = end_date.replace(day=1) all_pings = Ping.objects.filter(domain=domain, date__range=(start_date, end_date)) logger.info("clean_pings: {} pings trouvés pour le mois {}" .format(len(all_pings), start_date.strftime('%m/%Y'))) summary = PingSummary(domain=domain, date=start_date.date()) for ping in all_pings: if ping.success: summary.nb_success += 1 else: summary.nb_errors += 1 summary.save() all_pings.delete()PK ! f f ) django_ping_me/migrations/0001_initial.py# Generated by Django 2.0.6 on 2018-08-19 19:46 from django.conf import settings from django.db import migrations, models import django.db.models.deletion class Migration(migrations.Migration): initial = True dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( name='Domain', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('url', models.CharField(max_length=255, verbose_name='Adresse')), ('description', models.CharField(max_length=255, verbose_name='Description')), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ], ), migrations.CreateModel( name='Ping', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('date', models.DateTimeField(auto_now_add=True)), ('success', models.BooleanField()), ('address', models.GenericIPAddressField()), ('domain', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='django_ping_me.Domain')), ], ), migrations.CreateModel( name='PingSummary', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('date', models.DateField()), ('nb_success', models.IntegerField(default=0)), ('nb_errors', models.IntegerField(default=0)), ('domain', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='django_ping_me.Domain')), ], ), ] PK ! % django_ping_me/migrations/__init__.pyPK ! 'i$ django_ping_me/models.pyfrom django.conf import settings from django.db import models import datetime class Domain(models.Model): url = models.CharField(verbose_name='Adresse', max_length=255) description = models.CharField(verbose_name='Description', max_length=255) user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) @property def last_ping(self): return Ping.objects.filter(domain=self).latest('date') @property def last_month_summary(self): date = datetime.date.today().replace(day=1) date = date - datetime.timedelta(days=1) date = date.replace(day=1) return PingSummary.objects.get(domain=self, date=date) @property def current_month_summary(self): summary = PingSummary(domain=self) summary.date = datetime.date.today().replace(day=1) all_pings = Ping.objects.filter(domain=self, date__gte=summary.date) for ping in all_pings: if ping.success: summary.nb_success += 1 else: summary.nb_errors += 1 return summary def __str__(self): desc = self.description if self.user.email: desc += " - " + self.user.email return "{} ({})".format(self.url, desc) class Ping(models.Model): date = models.DateTimeField(auto_now_add=True) success = models.BooleanField() address = models.GenericIPAddressField() domain = models.ForeignKey('Domain', on_delete=models.CASCADE) def __str__(self): success = 'success' if self.success else 'fail' return "{:%Y-%m-%d %H:%M:%S} - {} - {} - {}"\ .format(self.date, self.domain.url, self.address, success) class PingSummary(models.Model): date = models.DateField() domain = models.ForeignKey('Domain', on_delete=models.CASCADE) nb_success = models.IntegerField(default=0) nb_errors = models.IntegerField(default=0) @property def nb_attempt(self): return self.nb_success + self.nb_errors @property def percentage(self): if self.nb_attempt <= 0: return 0 return self.nb_success * 100 / self.nb_attempt def to_str(self): return "{:,} succès et {:,} échecs"\ .format(self.nb_success, self.nb_errors)\ .replace(',', ' ') def __str__(self): return "{:%Y:%m} - {} - {}"\ .format(self.date, self.domain.url, self.to_str())PK ! es 1 django_ping_me/templates/ping_me/domain_list.html{% load static %} {% include 'ping_me/partials/edit_popup.html' %} {% if domain_list %} {% include 'ping_me/partials/delete_popup.html' %}
Domain | IP | Description | {{ current_month|date:"F Y"|capfirst }} | {{ last_month|date:"F Y"|capfirst }} | {% if user.is_authenticated and user.is_staff %}Bound to | Action | {% endif %}
---|---|---|---|---|---|---|
{% if domain.last_ping and domain.last_ping.success %} {% else %} {% endif %} {{ domain.url }} (see website) | {% if domain.last_ping %} {{ domain.last_ping.address }} {% else %} No IP {% endif %} | {{ domain.description }} | {% include 'ping_me/partials/summary_percentage.html' with summary=domain.current_month_summary %} | {% include 'ping_me/partials/summary_percentage.html' with summary=domain.last_month_summary %} | {% if user.is_authenticated and user.is_staff %}{% if domain.user.email %} {{ domain.user.email }} {% else %} {{ domain.user.username }} (no email) {% endif %} | {% endif %} |
You have no domain to show.
{% endif %} {% if user.is_authenticated and user.is_staff %} {% endif %} PK ! 9V : django_ping_me/templates/ping_me/partials/delete_form.htmlPK ! ~< < ; django_ping_me/templates/ping_me/partials/delete_popup.html