From: Michael Tremer Date: Wed, 31 Dec 2025 14:11:43 +0000 (+0000) Subject: dnsbl: Show the history of a list X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=262382acf8f3923ab36737a50d6d45bc11d1ab7d;p=ipfire.org.git dnsbl: Show the history of a list Signed-off-by: Michael Tremer --- diff --git a/Makefile.am b/Makefile.am index cde06b00..6839bfb5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -190,6 +190,7 @@ templates_dnsbl_DATA = \ templates_dnsbldir = $(templatesdir)/dnsbl templates_dnsbl_lists_DATA = \ + src/templates/dnsbl/lists/history.html \ src/templates/dnsbl/lists/index.html \ src/templates/dnsbl/lists/reports.html \ src/templates/dnsbl/lists/sources.html \ diff --git a/src/backend/dnsbl.py b/src/backend/dnsbl.py index 18329d0a..62bb5213 100644 --- a/src/backend/dnsbl.py +++ b/src/backend/dnsbl.py @@ -6,6 +6,7 @@ import json import logging import pydantic import tornado.httpclient +import typing import urllib.parse import uuid @@ -239,6 +240,18 @@ class List(Model): # Return the report return Report(self._backend, **response) + # History + + async def get_history(self, limit=None): + """ + Fetches the history of this list + """ + response = await self._backend.dnsbl._fetch( + "/lists/%s/history" % self.slug, args={ "limit" : limit }, + ) + + return [History(self._backend, **data) for data in response] + class Source(Model): """ @@ -331,3 +344,17 @@ class Report(Model): self._list = await self._backend.dnsbl.get_list(self.list_slug) return self._list + + +class History(Model): + """ + Represents a history event + """ + # Timestamp + ts: datetime.datetime + + # Domains Added + domains_added: typing.List[str] = [] + + # Domains Removed + domains_removed: typing.List[str] = [] diff --git a/src/templates/dnsbl/lists/history.html b/src/templates/dnsbl/lists/history.html new file mode 100644 index 00000000..e77ce5b1 --- /dev/null +++ b/src/templates/dnsbl/lists/history.html @@ -0,0 +1,90 @@ +{% extends "../../base.html" %} + +{% block head %} + {% module OpenGraph( + title=_("IPFire DNSBL - %s - History") % list, + description=list.description, + ) %} +{% end block %} + +{% block title %}{{ _("IPFire DNSBL") }} - {{ list }} - {{ _("History") }}{% end block %} + +{% block container %} +
+
+
+ + +

+ {{ _("History: %s") % list }} +

+
+
+
+ + {# Events #} + {% for event in reversed(history) %} +
+
+
+ {{ locale.format_date(event.ts) }} +
+ + {# Tags #} + + {% if event.domains_added %} + + + {{ len(event.domains_added) }} + + {% end %} + + {% if event.domains_removed %} + + − {{ len(event.domains_removed) }} + + {% end %} + + +
    + {# Domains Added #} + {% for domain in event.domains_added %} +
  • + + {{ domain }} +
  • + {% end %} + + {# Domains Removed #} + {% for domain in event.domains_removed %} +
  • + − {{ domain }} +
  • + {% end %} +
+
+
+ {% end %} +{% end block %} diff --git a/src/templates/dnsbl/lists/show.html b/src/templates/dnsbl/lists/show.html index 2d3a144e..85d7b299 100644 --- a/src/templates/dnsbl/lists/show.html +++ b/src/templates/dnsbl/lists/show.html @@ -96,11 +96,19 @@ - + {{ _("Sources") }} + + + + + + + {{ _("History") }} + diff --git a/src/web/__init__.py b/src/web/__init__.py index 1e1e440f..92fe0fb5 100644 --- a/src/web/__init__.py +++ b/src/web/__init__.py @@ -217,6 +217,7 @@ class Application(tornado.web.Application): (r"/dnsbl/?", StaticHandler, { "template" : "dnsbl/index.html" }), (r"/dnsbl/lists", dnsbl.ListsHandler), (r"/dnsbl/lists/(\w+)", dnsbl.ListHandler), + (r"/dnsbl/lists/(\w+)/history", dnsbl.ListHistoryHandler), (r"/dnsbl/lists/(\w+)/reports", dnsbl.ListReportsHandler), (r"/dnsbl/lists/(\w+)/sources", dnsbl.ListSourcesHandler), (r"/dnsbl/report", dnsbl.SubmitReportHandler), diff --git a/src/web/dnsbl.py b/src/web/dnsbl.py index 22a22490..58360111 100644 --- a/src/web/dnsbl.py +++ b/src/web/dnsbl.py @@ -32,6 +32,20 @@ class ListHandler(base.AnalyticsMixin, BaseHandler): self.render("dnsbl/lists/show.html", list=list) +class ListHistoryHandler(base.AnalyticsMixin, BaseHandler): + async def get(self, slug): + # Fetch the list + list = await self.backend.dnsbl.get_list(slug) + if not list: + raise tornado.web.HTTPError(404, "Could not find list '%s'" % slug) + + # Fetch the history + history = await list.get_history(limit=10) + + # Render the page + self.render("dnsbl/lists/history.html", list=list, history=history) + + class ListReportsHandler(base.AnalyticsMixin, BaseHandler): async def get(self, slug): # Fetch the list