""" LinkSyncServer - Query Executor """ import logging from typing import Any, Dict, List logger = logging.getLogger(__name__) def execute_query(parsed: Dict[str, Any], bookmarks: List[Dict[str, Any]]) -> List[Dict[str, Any]]: if not parsed or not bookmarks: return [] result_ids = _evaluate_node(parsed, bookmarks) return [b for b in bookmarks if b["id"] in result_ids] def _evaluate_node(node: Dict[str, Any], bookmarks: List[Dict[str, Any]]) -> set: operation = node.get("operation", "") if operation == "OR": operands = node.get("operands", []) if not operands: return set() result = _evaluate_node(operands[0], bookmarks) for operand in operands[1:]: result |= _evaluate_node(operand, bookmarks) return result if operation == "AND": operands = node.get("operands", []) if not operands: return set() result = _evaluate_node(operands[0], bookmarks) for operand in operands[1:]: result &= _evaluate_node(operand, bookmarks) return result if operation == "XOR": operands = node.get("operands", []) if not operands: return set() result = _evaluate_node(operands[0], bookmarks) for operand in operands[1:]: result ^= _evaluate_node(operand, bookmarks) return result if operation == "TERM": value = node.get("value", "").lower() return { b["id"] for b in bookmarks if value in b.get("title", "").lower() or value in b.get("description", "").lower() or value in b.get("url", "").lower() or value in b.get("notes", "").lower() } if operation == "TERM_SET": terms = node.get("value", []) terms_lower = [t.lower() for t in terms] result = set() for b in bookmarks: text = ( f"{b.get('title', '')} {b.get('description', '')} {b.get('url', '')} {b.get('notes', '')}" ).lower() if any(term in text for term in terms_lower): result.add(b["id"]) return result if operation.startswith("FIELD:"): field = operation.split(":", 1)[1].upper() value = node.get("value", "").lower() return _evaluate_field(field, value, bookmarks) logger.warning(f"Unknown operation: {operation}") return set() def _evaluate_field(field: str, value: str, bookmarks: List[Dict[str, Any]]) -> set: if field == "URL": return {b["id"] for b in bookmarks if value in b.get("url", "").lower()} if field == "TAG": return { b["id"] for b in bookmarks if any(value in t.lower() for t in (b.get("tags") or [])) } if field == "TITLE": return {b["id"] for b in bookmarks if value in b.get("title", "").lower()} if field == "DESCRIPTION": return {b["id"] for b in bookmarks if value in b.get("description", "").lower()} if field == "PATH": return {b["id"] for b in bookmarks if value in (b.get("path") or "").lower()} if field == "ID": return {b["id"] for b in bookmarks if b.get("id") == value} logger.warning(f"Unknown field: {field}") return set()