]> git.ipfire.org Git - dbl.git/commitdiff
search: Refactor the search process
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 14 Jan 2026 18:30:20 +0000 (18:30 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 14 Jan 2026 18:30:20 +0000 (18:30 +0000)
In order to search for a domain and what their status is, we will need
to fetch the latest entry of the domain events table.

In order to do that, we will need to find the correct domain name
(because someone could be searching for a sub-domain).

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/dbl/__init__.py
src/dbl/api/__init__.py

index 919d499a03f57aeaaab3edf233ff66accea33e2a..446a29ab25a472f0da0ee58671de23f71382eab6 100644 (file)
@@ -130,22 +130,22 @@ class Backend(object):
                        .select(
                                domains.Domain,
                        )
-                       .join(
-                               sources.Source,
-                               domains.Domain.source_id == sources.Source.id,
-                       )
                        .join(
                                lists.List,
-                               sources.Source.list_id == lists.List.id,
+                               lists.List.id == domains.Domain.list_id,
                        )
                        .where(
+                               # List cannot be deleted
+                               lists.List.deleted_at == None,
+
+                               # Domains cannot be deleted
+                               domains.Domain.removed_at == None,
+
+                               # Look for an exact match of the name or subdomains
                                sqlmodel.or_(
                                        domains.Domain.name == name,
                                        sqlmodel.literal(name).like("%." + domains.Domain.name),
                                ),
-                               domains.Domain.removed_at == None,
-                               sources.Source.deleted_at == None,
-                               lists.List.deleted_at == None,
                        )
                )
 
@@ -154,9 +154,22 @@ class Backend(object):
                # Group all matches by list
                for domain in self.db.fetch(stmt):
                        try:
-                               res[domain.source.list].append(domain)
+                               res[domain.list].append(domain.name)
                        except KeyError:
-                               res[domain.source.list] = [domain]
+                               res[domain.list] = [domain.name]
+
+               # Search the history for the longest match
+               for list, matches in res.items():
+                       # Sort the domains by length
+                       matches = sorted(matches, key=lambda x: len(x))
+
+                       # Fetch the longest match
+                       domain = matches.pop()
+
+                       # Fetch the history of the longest match
+                       for history in list.get_domain_history(domain, limit=1):
+                               res[list] = history
+                               break
 
                return res
 
index c3224c1e080a39e37aaee7a43db3d8f76aea7446..c9daa7d3b7e8f9ccabec03a4fe15d89b07c61f50 100644 (file)
@@ -63,10 +63,27 @@ def search(q: str):
        """
                Performs a simple search
        """
+       res = {}
+
        # Perform the search
        results = backend.search(q)
 
-       # Return the result as a mapping of the list slug and a list of matching domain names
-       return {
-               list.slug : set(domain.name for domain in results[list]) for list in results
-       }
+       # Format the result
+       for list, event in results.items():
+               if event.allows:
+                       status = "ALLOWED"
+               elif event.blocks:
+                       status = "BLOCKED"
+
+               # Skip if the domain is not listed
+               else:
+                       continue
+
+               # Append result
+               res[list.slug] = {
+                       "domain"     : event.domain.name,
+                       "changed_at" : event.timestamp,
+                       "status"     : status,
+               }
+
+       return res