diff --git a/semantica/explorer/routes/export_import.py b/semantica/explorer/routes/export_import.py
index 587afa56..8c7c2e56 100644
--- a/semantica/explorer/routes/export_import.py
+++ b/semantica/explorer/routes/export_import.py
@@ -5,7 +5,7 @@ Export & import routes.
import asyncio
import io
import json
-import json
+import logging
import os
import tempfile
from typing import Optional
@@ -13,6 +13,8 @@ from typing import Optional
from fastapi import APIRouter, Depends, File, UploadFile
from fastapi.responses import Response
+logger = logging.getLogger(__name__)
+
from ..dependencies import get_session, get_ws_manager
from ..schemas import ExportRequest
from ..session import GraphSession
@@ -229,7 +231,8 @@ async def import_file(
"detail": f"File type not supported yet: {filename}",
}
except Exception as exc:
- result = {"status": "error", "detail": str(exc)}
+ logger.exception("Import failed")
+ result = {"status": "error", "detail": "An internal error occurred during import"}
await ws.broadcast("import_completed", result)
return result
diff --git a/semantica/ingest/email_ingestor.py b/semantica/ingest/email_ingestor.py
index b626abfd..0f16d9df 100644
--- a/semantica/ingest/email_ingestor.py
+++ b/semantica/ingest/email_ingestor.py
@@ -392,7 +392,7 @@ class EmailParser:
# Extract URLs from text using regex
import re
- url_pattern = r"http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+"
+ url_pattern = r"https?://(?:[a-zA-Z0-9]|[$\-_.&+!*(),]|(?:%[0-9a-fA-F]{2}))+"
text_links = re.findall(url_pattern, email_content)
links.extend(text_links)
diff --git a/semantica/normalize/text_cleaner.py b/semantica/normalize/text_cleaner.py
index f97ceb45..a6b5f93c 100644
--- a/semantica/normalize/text_cleaner.py
+++ b/semantica/normalize/text_cleaner.py
@@ -302,10 +302,10 @@ class TextCleaner:
# Remove potential script tags
text = re.sub(
- r"", "", text, flags=re.IGNORECASE | re.DOTALL
+ r"]*)?>", "", text, flags=re.IGNORECASE | re.DOTALL
)
text = re.sub(
- r"", "", text, flags=re.IGNORECASE | re.DOTALL
+ r"]*)?>", "", text, flags=re.IGNORECASE | re.DOTALL
)
# Remove javascript: URLs
diff --git a/semantica/ontology/naming_conventions.py b/semantica/ontology/naming_conventions.py
index f3ebd01a..2d4e0e39 100644
--- a/semantica/ontology/naming_conventions.py
+++ b/semantica/ontology/naming_conventions.py
@@ -350,7 +350,7 @@ class NamingConventions:
def _is_noun_phrase(self, name: str) -> bool:
"""Check if name is a noun phrase (basic heuristic)."""
# Basic heuristic: PascalCase words are typically nouns
- return bool(re.match(r"^[A-Z][a-zA-Z0-9]*([A-Z][a-zA-Z0-9]*)*$", name))
+ return bool(re.match(r"^[A-Z][a-zA-Z0-9]*(?:[A-Z][a-zA-Z0-9]*)*$", name))
def _is_verb_phrase(self, name: str) -> bool:
"""Check if name is a verb phrase (basic heuristic)."""