Files
PdfScrapper/pdfscrapper/bridge.py
T
2026-08-11 15:41:55 +02:00

57 lines
2.1 KiB
Python

"""Pont JS ↔ Python (QWebChannel) utilisé par le mode "capture au survol"
et par la détection continue des liens de "suite" (voir link_detector.py).
QtWebEngine exécute la page dans un processus Chromium séparé : le seul
canal officiellement supporté pour qu'un script de la page appelle du code
Python est QWebChannel. On expose ici un unique objet `pdfscrapperBridge`
côté JavaScript, avec :
- une méthode `captureBlock(text)` que le script d'overlay (voir
block_picker.py) appelle au clic sur un bloc ;
- une méthode `reportLinks(json)` que le MutationObserver de
link_detector.py appelle à chaque (re)scan de la page.
"""
from __future__ import annotations
from PySide6.QtCore import QFile, QIODevice, QObject, Signal, Slot
class Bridge(QObject):
"""Objet exposé côté JS sous `window.pdfscrapperBridge`."""
block_captured = Signal(str)
links_detected = Signal(str)
@Slot(str)
def captureBlock(self, text: str) -> None: # noqa: N802 (nom appelé depuis JS)
if text and text.strip():
self.block_captured.emit(text.strip())
@Slot(str)
def reportLinks(self, links_json: str) -> None: # noqa: N802 (nom appelé depuis JS)
self.links_detected.emit(links_json)
def load_qwebchannel_js() -> str:
"""Charge le script qwebchannel.js embarqué dans les ressources Qt."""
resource = QFile(":/qtwebchannel/qwebchannel.js")
if not resource.open(QIODevice.OpenModeFlag.ReadOnly):
raise RuntimeError("Impossible de charger la ressource Qt qtwebchannel/qwebchannel.js")
try:
return bytes(resource.readAll().data()).decode("utf-8")
finally:
resource.close()
def build_bridge_init_script() -> str:
"""Script injecté au tout début de chaque page pour établir le canal
QWebChannel et exposer `window.pdfscrapperBridge` une fois prêt."""
return (
load_qwebchannel_js()
+ """
new QWebChannel(qt.webChannelTransport, function (channel) {
window.pdfscrapperBridge = channel.objects.pdfscrapperBridge;
});
"""
)