]> git.ipfire.org Git - dnsbl.git/commitdiff
exporters: Split logic for text and binary exporters
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 10 Dec 2025 11:36:24 +0000 (11:36 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 10 Dec 2025 11:36:24 +0000 (11:36 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/dnsbl/exporters.py
src/dnsbl/lists.py
src/scripts/dnsbl.in

index a52d7493d6443d5dbf7695b3988c6bcf25827d6a..a11443086ea47f52a27078020881eb4fe39f8cfd 100644 (file)
@@ -22,6 +22,7 @@ import abc
 import dns.name
 import dns.rdataclass
 import dns.zone
+import io
 
 class Exporter(abc.ABC):
        """
@@ -31,6 +32,13 @@ class Exporter(abc.ABC):
                self.backend = backend
                self.list = list
 
+       def __call__(self, f, **kwargs):
+               """
+                       The main entry point to export something with this exporter...
+               """
+               # Export!
+               self.export(f, **kwargs)
+
        @abc.abstractmethod
        def export(self, f, **kwargs):
                """
@@ -38,6 +46,24 @@ class Exporter(abc.ABC):
                """
                raise NotImplementedError
 
+
+class TextExporter(Exporter):
+       def __call__(self, f, **kwargs):
+               detach = False
+
+               # Convert any file handles to handle plain text
+               if not isinstance(f, io.TextIOBase):
+                       f = io.TextIOWrapper(f, encoding="utf-8")
+                       detach = True
+
+               # Export!
+               super().__call__(f, **kwargs)
+
+               # Detach the underlying stream. That way, the wrapper won't close
+               # the underlying file handle.
+               if detach:
+                       f.detach()
+
        def write_header(self, f, delim="#"):
                """
                        Writes a header
@@ -81,7 +107,7 @@ class Exporter(abc.ABC):
                        f.write("%s%s\n" % (delim, line))
 
 
-class DomainsExporter(Exporter):
+class DomainsExporter(TextExporter):
        """
                Exports the plain domains
        """
@@ -94,7 +120,7 @@ class DomainsExporter(Exporter):
                        f.write("%s\n" % domain)
 
 
-class HostsExporter(Exporter):
+class HostsExporter(TextExporter):
        """
                Exports a file like /etc/hosts
        """
@@ -107,7 +133,7 @@ class HostsExporter(Exporter):
                        f.write("0.0.0.0 %s\n" % domain)
 
 
-class ZoneExporter(Exporter):
+class ZoneExporter(TextExporter):
        def export(self, f, ttl=60, rpz_action="."):
                # Write the header
                self.write_header(f, ";")
index e3ee23e6c3253e71de478cdaa36fd1a3fc3b6d3b..042b81d37c90d943ff954a1841926b0c9b421232 100644 (file)
@@ -246,13 +246,6 @@ class List(sqlmodel.SQLModel, database.BackendMixin, table=True):
                """
                        Exports the list
                """
-               detach = False
-
-               # Convert any file handles to handle plain text
-               if not isinstance(f, io.TextIOBase):
-                       f = io.TextIOWrapper(f, encoding="utf-8")
-                       detach = True
-
                formats = {
                        "domains" : exporters.DomainsExporter,
                        "dnsbl"   : exporters.BlocklistExporter,
@@ -269,9 +262,4 @@ class List(sqlmodel.SQLModel, database.BackendMixin, table=True):
                        raise ValueError("Unknown output format: %s" % format) from e
 
                # Run the export
-               exporter.export(f, **kwargs)
-
-               # Detach the underlying stream. That way, the wrapper won't close
-               # the underlying file handle.
-               if detach:
-                       f.detach()
+               exporter(f, **kwargs)
index e810d762a97239012d00418f11ed0d3dfa0f905e..ecc512459faff83eb5466e1c6b2af1434fb87663 100644 (file)
@@ -98,7 +98,7 @@ class CLI(object):
                # export
                export = subparsers.add_parser("export", help=_("Exports a list"))
                export.add_argument("list", help=_("The name of the list"))
-               export.add_argument("output", type=argparse.FileType("w"),
+               export.add_argument("output", type=argparse.FileType("wb"),
                                help=_("The output file"))
                export.add_argument("--format", default="domains",
                                choices=("domains", "dnsbl", "hosts", "rpz",), help=_("Output Format"))