dev #21

Merged
WorldTeacher merged 46 commits from dev into main 2025-11-24 12:59:41 +00:00
Showing only changes of commit a64fa9770f - Show all commits

View File

@@ -1,6 +1,7 @@
import datetime import datetime
import json import json
import os import os
import re
import sqlite3 as sql import sqlite3 as sql
import sys import sys
import tempfile import tempfile
@@ -382,49 +383,67 @@ class Database:
""" """
return self.query_db("SELECT id FROM media ORDER BY id DESC", one=True)[0] 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: Args:
data (dict[str, str]): A dictionary containing the data to be searched for. The dictionary can contain the following: data: may contain:
- signature: The signature of the book - "signature": regex to match against BookData.signature
- title: The title of the book - "title": regex to match against BookData.title
Returns: 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 mode = 0
if len(data) == 1: if len(data) == 1 and "signature" in data:
if "signature" in data.keys(): mode = 1
mode = 1 elif len(data) == 1 and "title" in data:
elif "title" in data.keys(): mode = 2
mode = 2 elif len(data) == 2 and "signature" in data and "title" in data:
elif len(data) == 2:
mode = 3 mode = 3
else: else:
return None return None
ret = []
for book in rdata: def _compile(expr: str) -> re.Pattern:
bookdata = BookData().from_string(book[1]) try:
app_id = book[2] return re.compile(expr, re.IGNORECASE | re.UNICODE)
prof_id = book[3] 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 mode == 1:
if data["signature"] in bookdata.signature: if sig_re.search(sig_val):
ret.append((bookdata, app_id, prof_id)) results.append((bookdata, app_id, prof_id))
elif mode == 2: elif mode == 2:
if data["title"] in bookdata.title: if title_re.search(title_val):
ret.append((bookdata, app_id, prof_id)) results.append((bookdata, app_id, prof_id))
elif mode == 3: else: # mode == 3
if ( if sig_re.search(sig_val) and title_re.search(title_val):
data["signature"] in bookdata.signature results.append((bookdata, app_id, prof_id))
and data["title"] in bookdata.title
): return results
ret.append((bookdata, app_id, prof_id))
# log.debug(ret)
return ret
def setAvailability(self, book_id: str, available: str): def setAvailability(self, book_id: str, available: str):
""" """