From: Michael Tremer Date: Fri, 5 Dec 2025 15:59:02 +0000 (+0000) Subject: dnsbl: Add a command to add a source to a list X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bd40ecf76d723c8146f61dd08a0975dc9372deff;p=dbl.git dnsbl: Add a command to add a source to a list Signed-off-by: Michael Tremer --- diff --git a/Makefile.am b/Makefile.am index ddbfcb2..14a72ad 100644 --- a/Makefile.am +++ b/Makefile.am @@ -54,6 +54,7 @@ dist_pkgpython_PYTHON = \ src/dnsbl/i18n.py \ src/dnsbl/lists.py \ src/dnsbl/logger.py \ + src/dnsbl/sources.py \ src/dnsbl/util.py # ------------------------------------------------------------------------------ diff --git a/src/dnsbl/__init__.py b/src/dnsbl/__init__.py index 4b108be..e4240b0 100644 --- a/src/dnsbl/__init__.py +++ b/src/dnsbl/__init__.py @@ -31,6 +31,7 @@ log = logging.getLogger(__name__) # Import sub-modules from . import lists +from . import sources class Backend(object): def __init__(self, config=None, debug=False): @@ -84,6 +85,10 @@ class Backend(object): def lists(self): return lists.Lists(self) + @functools.cached_property + def sources(self): + return sources.Sources(self) + def update_sources(self): """ Updates all sources diff --git a/src/dnsbl/lists.py b/src/dnsbl/lists.py index 3f683d4..4bd8820 100644 --- a/src/dnsbl/lists.py +++ b/src/dnsbl/lists.py @@ -20,7 +20,9 @@ import datetime import sqlmodel +import typing +from . import sources from . import util class Lists(object): @@ -105,3 +107,6 @@ class List(sqlmodel.SQLModel, table=True): # License license : str + + # Sources + sources : typing.List["Source"] = sqlmodel.Relationship(back_populates="list") diff --git a/src/dnsbl/sources.py b/src/dnsbl/sources.py new file mode 100644 index 0000000..ed30291 --- /dev/null +++ b/src/dnsbl/sources.py @@ -0,0 +1,96 @@ +############################################################################### +# # +# dnsbl - A DNS Blacklist Compositor For IPFire # +# Copyright (C) 2025 IPFire Development Team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +############################################################################### + +import datetime +import sqlmodel + +class Sources(object): + def __init__(self, backend): + self.backend = backend + + def get_by_id(self, id): + stmt = ( + sqlmodel + .select( + Source, + ) + .where( + Source.id == id, + ) + ) + + with self.backend.session() as session: + result = session.execute(stmt) + + return result.scalar_one_or_none() + + def create(self, list, name, url, created_by, license): + """ + Creates a new source + """ + # Create a new source + with self.backend.session() as session: + source = Source( + list = list, + name = name, + url = url, + created_by = created_by, + license = license, + ) + session.add(source) + session.commit() + + return source + + +class Source(sqlmodel.SQLModel, table=True): + __tablename__ = "sources" + + # ID + id : int = sqlmodel.Field(primary_key=True) + + # Name + name : str + + # URL + url : str + + # Created At + created_at : datetime.datetime = sqlmodel.Field( + sa_column_kwargs = {"server_default" : sqlmodel.text("CURRENT_TIMESTAMP")} + ) + + # Created By + created_by : str + + # Deleted At + deleted_at : datetime.datetime | None + + # Deleted By + deleted_by : str | None + + # License + license : str + + # List ID + list_id : int = sqlmodel.Field(foreign_key="lists.id") + + # List + list : "List" = sqlmodel.Relationship(back_populates="sources") diff --git a/src/scripts/dnsbl.in b/src/scripts/dnsbl.in index ef4556d..7b6a214 100644 --- a/src/scripts/dnsbl.in +++ b/src/scripts/dnsbl.in @@ -56,6 +56,21 @@ class CLI(object): help=_("The license of the list")) create_list.set_defaults(func=self.__create_list) + # list-add-source + list_add_source = subparsers.add_parser("list-add-source", + help=_("Creates a new source to a list")) + list_add_source.add_argument("list", + help=_("The name of the list")) + list_add_source.add_argument("--name", required=True, + help=_("The name of the source")) + list_add_source.add_argument("--url", required=True, + help=_("The URL of the source")) + list_add_source.add_argument("--license", required=True, + help=_("The license of the source")) + list_add_source.add_argument("--created-by", required=True, + default=os.environ.get("USER"), help=_("The creator of the source")) + list_add_source.set_defaults(func=self.__list_add_source) + # update update = subparsers.add_parser("update", help=_("Update sources")) update.set_defaults(func=self.__update) @@ -104,6 +119,22 @@ class CLI(object): license = args.license, ) + def __list_add_source(self, backend, args): + """ + Adds a new source to a list + """ + # Fetch the list + list = backend.lists.get_by_slug(args.list) + + # Create the source + backend.sources.create( + list = list, + name = args.name, + url = args.url, + created_by = args.created_by, + license = args.license, + ) + def __update(self, backend, args): """ Updates all sources