add doxc compatibilty

This commit is contained in:
2026-01-10 11:41:14 +01:00
parent d5e1a537b7
commit f8986da1aa
2 changed files with 29 additions and 14 deletions

View File

@@ -6,3 +6,4 @@ sentence-transformers==2.2.2
transformers==4.28.1 transformers==4.28.1
torch==1.13.1 torch==1.13.1
numpy==1.24.2 numpy==1.24.2
python-docx

View File

@@ -7,6 +7,12 @@ import zipfile
import io import io
import traceback import traceback
# NEU: Word Support
try:
import docx
except ImportError:
docx = None # Fallback, falls nicht installiert
from sentence_transformers import SentenceTransformer, util from sentence_transformers import SentenceTransformer, util
from rapidfuzz import process, fuzz from rapidfuzz import process, fuzz
@@ -48,6 +54,10 @@ sys.stderr = sys.stdout
print(f"--- START LOGGING ---") print(f"--- START LOGGING ---")
print(f"Logfile: {log_file_path}") print(f"Logfile: {log_file_path}")
# Check ob docx installiert ist und warnen im Log
if docx is None:
print("WARNUNG: 'python-docx' ist nicht installiert. .docx Dateien werden ignoriert.")
def qt_message_handler(mode, context, message): def qt_message_handler(mode, context, message):
msg_lower = message.lower() msg_lower = message.lower()
ignore_keywords = [ ignore_keywords = [
@@ -73,7 +83,6 @@ class SearchResultItem(QFrame):
super().__init__(parent) super().__init__(parent)
self.filepath = filepath self.filepath = filepath
# Optik der Karte
self.setFrameShape(QFrame.Shape.StyledPanel) self.setFrameShape(QFrame.Shape.StyledPanel)
self.setStyleSheet(""" self.setStyleSheet("""
SearchResultItem { SearchResultItem {
@@ -91,7 +100,7 @@ class SearchResultItem(QFrame):
layout = QVBoxLayout(self) layout = QVBoxLayout(self)
layout.setContentsMargins(10, 10, 10, 10) layout.setContentsMargins(10, 10, 10, 10)
# 1. Dateiname (Sieht aus wie ein Link, ist aber ein Button) # 1. Dateiname
self.btn_title = QPushButton(filename) self.btn_title = QPushButton(filename)
self.btn_title.setCursor(Qt.CursorShape.PointingHandCursor) self.btn_title.setCursor(Qt.CursorShape.PointingHandCursor)
self.btn_title.setStyleSheet(""" self.btn_title.setStyleSheet("""
@@ -109,13 +118,12 @@ class SearchResultItem(QFrame):
""") """)
self.btn_title.clicked.connect(self.open_file) self.btn_title.clicked.connect(self.open_file)
# 2. Snippet (Textvorschau) # 2. Snippet
# Wir nutzen QLabel mit WordWrap. HTML für Fettung ist okay.
self.lbl_snippet = QLabel(snippet) self.lbl_snippet = QLabel(snippet)
self.lbl_snippet.setWordWrap(True) self.lbl_snippet.setWordWrap(True)
self.lbl_snippet.setStyleSheet("color: #444; font-size: 10pt; margin-top: 5px;") self.lbl_snippet.setStyleSheet("color: #444; font-size: 10pt; margin-top: 5px;")
# 3. Pfad (Grau und klein) # 3. Pfad
self.lbl_path = QLabel(filepath) self.lbl_path = QLabel(filepath)
self.lbl_path.setStyleSheet("color: #888; font-size: 8pt; margin-top: 5px;") self.lbl_path.setStyleSheet("color: #888; font-size: 8pt; margin-top: 5px;")
@@ -124,19 +132,13 @@ class SearchResultItem(QFrame):
layout.addWidget(self.lbl_path) layout.addWidget(self.lbl_path)
def open_file(self): def open_file(self):
"""
Öffnet die Datei direkt über QDesktopServices.
"""
print(f"Öffne Datei: {self.filepath}") print(f"Öffne Datei: {self.filepath}")
target_path = self.filepath target_path = self.filepath
# Falls es ein ZIP-Pfad ist (erkennbar am Trenner " :: ")
if " :: " in target_path: if " :: " in target_path:
target_path = target_path.split(" :: ")[0] target_path = target_path.split(" :: ")[0]
url = QUrl.fromLocalFile(target_path) url = QUrl.fromLocalFile(target_path)
success = QDesktopServices.openUrl(url) success = QDesktopServices.openUrl(url)
if not success: if not success:
print("Fehler: Konnte Datei nicht öffnen.") print("Fehler: Konnte Datei nicht öffnen.")
@@ -267,12 +269,25 @@ class IndexerThread(QThread):
ext = os.path.splitext(filename)[1].lower() ext = os.path.splitext(filename)[1].lower()
text = "" text = ""
try: try:
# --- PDF ---
if ext == ".pdf": if ext == ".pdf":
try: try:
with pdfplumber.open(stream) as pdf: with pdfplumber.open(stream) as pdf:
for p in pdf.pages: for p in pdf.pages:
if t := p.extract_text(): text += t + "\n" if t := p.extract_text(): text += t + "\n"
except: pass except: pass
# --- WORD / DOCX ---
elif ext == ".docx" and docx is not None:
try:
# python-docx kann file-like objects (BytesIO oder file) lesen
doc = docx.Document(stream)
for para in doc.paragraphs:
text += para.text + "\n"
except Exception as e:
print(f"Docx Error {filename}: {e}")
# --- PLAIN TEXT ---
elif ext in [".txt", ".md", ".py", ".json", ".csv", ".html", ".log", ".ini", ".xml"]: elif ext in [".txt", ".md", ".py", ".json", ".csv", ".html", ".log", ".ini", ".xml"]:
try: try:
content = stream.read() content = stream.read()
@@ -347,7 +362,7 @@ class UffWindow(QMainWindow):
self.load_saved_folders() self.load_saved_folders()
def initUI(self): def initUI(self):
self.setWindowTitle("UFF Search v6.0 (Widget List)") self.setWindowTitle("UFF Search")
self.resize(1000, 700) self.resize(1000, 700)
central = QWidget() central = QWidget()
self.setCentralWidget(central) self.setCentralWidget(central)
@@ -458,7 +473,7 @@ class UffWindow(QMainWindow):
if not query: return if not query: return
self.lbl_status.setText("Suche läuft...") self.lbl_status.setText("Suche läuft...")
QApplication.processEvents() # UI Update erzwingen QApplication.processEvents()
# 1. Alte Ergebnisse löschen # 1. Alte Ergebnisse löschen
while self.results_layout.count(): while self.results_layout.count():
@@ -481,7 +496,6 @@ class UffWindow(QMainWindow):
item = SearchResultItem(fname, fpath, snippet) item = SearchResultItem(fname, fpath, snippet)
self.results_layout.addWidget(item) self.results_layout.addWidget(item)
# Stretch am Ende, damit alles oben bleibt
self.results_layout.addStretch() self.results_layout.addStretch()
# --- Folder Management --- # --- Folder Management ---