refactor searchBook to allow for regex matches

This commit is contained in:
2025-09-03 12:32:05 +02:00
parent 0061708785
commit a64fa9770f

View File

@@ -1,6 +1,7 @@
import datetime
import json
import os
import re
import sqlite3 as sql
import sys
import tempfile
@@ -382,49 +383,67 @@ class Database:
"""
return self.query_db("SELECT id FROM media ORDER BY id DESC", one=True)[0]
def searchBook(self, data: dict[str, str]) -> list[tuple[BookData, int]]:
def searchBook(
self, data: dict[str, str]
) -> Optional[list[tuple["BookData", int, int]]]:
"""
Search a book in the database based on the sent data.
Search a book in the database using regex against signature/title.
Args:
data (dict[str, str]): A dictionary containing the data to be searched for. The dictionary can contain the following:
- signature: The signature of the book
- title: The title of the book
data: may contain:
- "signature": regex to match against BookData.signature
- "title": regex to match against BookData.title
Returns:
list[tuple[BookData, int]]: A list of tuples containing the wrapped Metadata and the id of the book
list of (BookData, app_id, prof_id) tuples, or None if invalid args
"""
rdata = self.query_db("SELECT * FROM media WHERE deleted=0")
# log.debug(rdata, len(rdata))
# Determine mode (kept compatible with your original logic)
mode = 0
if len(data) == 1:
if "signature" in data.keys():
mode = 1
elif "title" in data.keys():
mode = 2
elif len(data) == 2:
if len(data) == 1 and "signature" in data:
mode = 1
elif len(data) == 1 and "title" in data:
mode = 2
elif len(data) == 2 and "signature" in data and "title" in data:
mode = 3
else:
return None
ret = []
for book in rdata:
bookdata = BookData().from_string(book[1])
app_id = book[2]
prof_id = book[3]
def _compile(expr: str) -> re.Pattern:
try:
return re.compile(expr, re.IGNORECASE | re.UNICODE)
except re.error:
# If user provided a broken regex, treat it as a literal
return re.compile(re.escape(expr), re.IGNORECASE | re.UNICODE)
sig_re = _compile(data["signature"]) if mode in (1, 3) else None
title_re = _compile(data["title"]) if mode in (2, 3) else None
# Fetch candidates once
rows = self.query_db("SELECT * FROM media WHERE deleted=0")
results: list[tuple["BookData", int, int]] = []
for row in rows:
bookdata = BookData().from_string(
row[1]
) # assumes row[1] is the serialized bookdata
app_id = row[2]
prof_id = row[3]
sig_val = getattr(bookdata, "signature", None) or ""
title_val = getattr(bookdata, "title", None) or ""
if mode == 1:
if data["signature"] in bookdata.signature:
ret.append((bookdata, app_id, prof_id))
if sig_re.search(sig_val):
results.append((bookdata, app_id, prof_id))
elif mode == 2:
if data["title"] in bookdata.title:
ret.append((bookdata, app_id, prof_id))
elif mode == 3:
if (
data["signature"] in bookdata.signature
and data["title"] in bookdata.title
):
ret.append((bookdata, app_id, prof_id))
# log.debug(ret)
return ret
if title_re.search(title_val):
results.append((bookdata, app_id, prof_id))
else: # mode == 3
if sig_re.search(sig_val) and title_re.search(title_val):
results.append((bookdata, app_id, prof_id))
return results
def setAvailability(self, book_id: str, available: str):
"""