Files
oxapp25/windows/site_window.py
2025-04-13 19:06:01 +02:00

158 lines
6.8 KiB
Python

import os
from pathlib import Path
import sqlite3
from PySide6.QtWebEngineCore import QWebEngineSettings, QWebEngineProfile, QWebEnginePage, QWebEngineCookieStore
from PySide6.QtWidgets import QWidget
from PySide6.QtWebEngineWidgets import QWebEngineView
from PySide6.QtWebChannel import QWebChannel
from PySide6.QtCore import Slot, QFile, QIODevice, Signal, Qt, QStandardPaths, QTimer, QDateTime
from PySide6.QtNetwork import QNetworkCookie
import sys
from src.conf import ConfManager
from src.handler import WebHandler
# https://gitea.devpanel.fr/oxpanel/app/src/branch/master/window/site.py
class SiteWindow(QWebEngineView):
on_cookie_added = Signal(QNetworkCookie)
def __init__(self, parent=None):
super().__init__(parent)
self.conf = parent.conf
self.web_handler = parent.web_handler
self.page().profile().cookieStore().deleteAllCookies()
storage_path = Path(QStandardPaths.writableLocation(QStandardPaths.StandardLocation.AppDataLocation))
if not storage_path.exists():
storage_path.mkdir(parents=True)
self.persistent_profile = QWebEngineProfile("OxAppProfile", parent=self)
self.cookie_store = self.persistent_profile.cookieStore()
self.cookie_store.cookieAdded.connect(self.on_cookie_added.emit)
self.cookie_store.cookieAdded.connect(self.test_cookie)
self.persistent_profile.setHttpCacheType(QWebEngineProfile.HttpCacheType.MemoryHttpCache)
self.persistent_profile.setPersistentStoragePath(str(self.conf.app_config_path / "web_cache"))
self.persistent_profile.setPersistentCookiesPolicy(QWebEngineProfile.PersistentCookiesPolicy.AllowPersistentCookies)
self.persistent_profile.setHttpUserAgent("oxapp25")
custom_page = QWebEnginePage(self.persistent_profile, parent=self)
self.setPage(custom_page)
self.settings().setAttribute(QWebEngineSettings.WebAttribute.Accelerated2dCanvasEnabled, True)
self.settings().setAttribute(QWebEngineSettings.WebAttribute.ScrollAnimatorEnabled, True)
self.settings().setAttribute(QWebEngineSettings.WebAttribute.WebGLEnabled, True)
# self.settings().setAttribute(QWebEngineSettin gs.WebAttribute.LocalStorageEnabled, False)
# self.settings().setAttribute(QWebEngineSettings.WebAttribute.AutoLoadImages, True)
# self.settings().setAttribute(QWebEngineSettings.WebAttribute.PluginsEnabled, False)
self.settings().setAttribute(QWebEngineSettings.WebAttribute.ShowScrollBars, True)
self.page().setBackgroundColor(Qt.GlobalColor.white)
self.web_channel = QWebChannel(self)
self.web_channel.registerObject("handler", self.web_handler)
self.page().setWebChannel(self.web_channel)
self.loadFinished.connect(self.on_load_finished)
self.load(parent.url)
def test_cookie(self, *args, **kwargs):
print("cook", *args, **kwargs)
# self.cookie_store.loadAllCookies()
@Slot(bool)
def on_load_finished(self, is_success):
print("load finished")
if is_success:
api_file = QFile(":/qtwebchannel/qwebchannel.js")
api_file.open(QIODevice.OpenModeFlag.ReadOnly)
api_content = api_file.readAll().data().decode("utf-8")
api_file.close()
self.page().runJavaScript(api_content)
# fix main scrollbar
css = """
html::-webkit-scrollbar,
body::-webkit-scrollbar {
display: none;
}
html, body {
scrollbar-width: none; /* Pour Firefox */
-ms-overflow-style: none; /* Pour Internet Explorer et Edge */
overflow: auto; /* Conserver la capacité de défilement */
}
"""
js_code = f"var style = document.createElement('style'); style.textContent = `{css}`; document.head.appendChild(style);"
self.page().runJavaScript(js_code)
self.recreate_sessionid_cookie()
def sessionid_from_cookie_store(self) -> None|sqlite3.Row:
# Cette approche est expérimentale et dépend de l'implémentation interne
profile_path = self.persistent_profile.persistentStoragePath()
cookies_db_path = os.path.join(profile_path, "Cookies")
if os.path.exists(cookies_db_path):
try:
conn = sqlite3.connect(cookies_db_path)
conn.row_factory = sqlite3.Row
cursor = conn.cursor()
cursor.execute("SELECT * FROM cookies WHERE name='sessionid'")
result = cursor.fetchone()
conn.close()
if result:
return result # La valeur du cookie
except Exception as e:
print(f"Erreur lors de l'accès au fichier de cookies: {e}")
return None
def recreate_sessionid_cookie(self):
cookie_info = self.sessionid_from_cookie_store()
if cookie_info is None:
return
# Créer un nouveau cookie avec le nom et la valeur
cookie = QNetworkCookie(b"sessionid", cookie_info['value'].encode())
# Configurer toutes les propriétés disponibles
cookie.setDomain(cookie_info['host_key'])
cookie.setPath(cookie_info['path'])
# Gérer les dates d'expiration (conversion du format si nécessaire)
if cookie_info['has_expires']:
# Convertir depuis le format UNIX en QDateTime
# Attention: Chromium stocke les dates en microseconds depuis 1601-01-01 UTC
# Vous devrez peut-être ajuster cette conversion selon le format exact
expires = QDateTime.fromSecsSinceEpoch(int(cookie_info['expires_utc'] / 1000000) - 11644473600)
cookie.setExpirationDate(expires)
# Configurer les attributs de sécurité
cookie.setSecure(bool(cookie_info['is_secure']))
cookie.setHttpOnly(bool(cookie_info['is_httponly']))
# Configurer SameSite si disponible dans votre version de PySide6
# Vérifier si l'attribut est disponible (PySide6 ≥ 6.2.0)
if hasattr(cookie, 'setSameSitePolicy'):
# Conversion des valeurs numériques en constantes SameSite
samesite_value = cookie_info['samesite']
samesite_map = {
0: QNetworkCookie.SameSite.None_, # None
1: QNetworkCookie.SameSite.Lax, # Lax
2: QNetworkCookie.SameSite.Strict # Strict
}
if samesite_value in samesite_map:
cookie.setSameSitePolicy(samesite_map[samesite_value])
# Ajouter le cookie au store - cela va déclencher le signal cookieAdded
self.cookie_store.setCookie(cookie)
def contextMenuEvent(self, event):
# Ignorer l'événement pour empêcher l'affichage du menu contextuel
event.ignore()