Convert markdown to HTML for sendbox

Also pass to clientManager the Backend, and to Client the clientManager,
and set Qt parents for them.
This commit is contained in:
miruka 2019-04-17 23:28:25 -04:00
parent a7649d1a7a
commit 98b494fcc2
6 changed files with 30 additions and 12 deletions

View File

@ -34,3 +34,5 @@
- Spinner when loading past room events or images - Spinner when loading past room events or images
- nio: org.matrix.room.preview\_urls, m.room.aliases - nio: org.matrix.room.preview\_urls, m.room.aliases
- Markdown: don't turn #things into title (space), disable __ syntax

View File

@ -6,7 +6,6 @@ from typing import Dict, Set
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSlot from PyQt5.QtCore import QObject, pyqtProperty, pyqtSlot
from .client_manager import ClientManager
from .html_filter import HtmlFilter from .html_filter import HtmlFilter
from .model.items import User from .model.items import User
from .model.qml_models import QMLModels from .model.qml_models import QMLModels
@ -18,7 +17,8 @@ class Backend(QObject):
self.past_tokens: Dict[str, str] = {} self.past_tokens: Dict[str, str] = {}
self.fully_loaded_rooms: Set[str] = set() self.fully_loaded_rooms: Set[str] = set()
self._client_manager: ClientManager = ClientManager() from .client_manager import ClientManager
self._client_manager: ClientManager = ClientManager(self)
self._models: QMLModels = QMLModels() self._models: QMLModels = QMLModels()
self._html_filter: HtmlFilter = HtmlFilter() self._html_filter: HtmlFilter = HtmlFilter()
# a = self._client_manager; m = self._models # a = self._client_manager; m = self._models

View File

@ -48,9 +48,13 @@ class Client(QObject):
roomTypingUsersUpdated = pyqtSignal(str, list) roomTypingUsersUpdated = pyqtSignal(str, list)
def __init__(self, hostname: str, username: str, device_id: str = "" def __init__(self,
) -> None: manager,
super().__init__() hostname: str,
username: str,
device_id: str = "") -> None:
super().__init__(manager)
self.manager = manager
host, *port = hostname.split(":") host, *port = hostname.split(":")
self.host: str = host self.host: str = host
@ -189,10 +193,11 @@ class Client(QObject):
@pyqtSlot(str, str) @pyqtSlot(str, str)
@futurize @futurize
def sendMessage(self, room_id: str, text: str) -> None: def sendMarkdown(self, room_id: str, text: str) -> None:
html = self.manager.backend.htmlFilter.fromMarkdown(text)
content = { content = {
"body": text, "body": text,
"formatted_body": text, "formatted_body": html,
"format": "org.matrix.custom.html", "format": "org.matrix.custom.html",
"msgtype": "m.text", "msgtype": "m.text",
} }

View File

@ -15,6 +15,7 @@ from PyQt5.QtCore import (
from harmonyqml import __about__ from harmonyqml import __about__
from .backend import Backend
from .client import Client from .client import Client
AccountConfig = Dict[str, Dict[str, str]] AccountConfig = Dict[str, Dict[str, str]]
@ -28,8 +29,9 @@ class ClientManager(QObject):
clientDeleted = pyqtSignal(str) clientDeleted = pyqtSignal(str)
def __init__(self) -> None: def __init__(self, backend: Backend) -> None:
super().__init__() super().__init__(backend)
self.backend = backend
self._clients: Dict[str, Client] = {} self._clients: Dict[str, Client] = {}
@ -45,7 +47,7 @@ class ClientManager(QObject):
@pyqtSlot() @pyqtSlot()
def configLoad(self) -> None: def configLoad(self) -> None:
for user_id, info in self.configAccounts().items(): for user_id, info in self.configAccounts().items():
client = Client(info["hostname"], user_id) client = Client(self, info["hostname"], user_id)
client.resumeSession(user_id, info["token"], info["device_id"])\ client.resumeSession(user_id, info["token"], info["device_id"])\
.add_done_callback(lambda _, c=client: self._on_connected(c)) .add_done_callback(lambda _, c=client: self._on_connected(c))
@ -55,7 +57,7 @@ class ClientManager(QObject):
def new(self, hostname: str, username: str, password: str, def new(self, hostname: str, username: str, password: str,
device_id: str = "") -> None: device_id: str = "") -> None:
client = Client(hostname, username, device_id) client = Client(self, hostname, username, device_id)
client.login(password, self.defaultDeviceName)\ client.login(password, self.defaultDeviceName)\
.add_done_callback(lambda _: self._on_connected(client)) .add_done_callback(lambda _: self._on_connected(client))

View File

@ -4,6 +4,7 @@
import re import re
import html_sanitizer.sanitizer as sanitizer import html_sanitizer.sanitizer as sanitizer
import mistune
from lxml.html import HtmlElement, etree from lxml.html import HtmlElement, etree
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSlot from PyQt5.QtCore import QObject, pyqtProperty, pyqtSlot
@ -37,6 +38,14 @@ class HtmlFilter(QObject):
sanitizer.lxml.html.clean.Cleaner.safe_attrs |= \ sanitizer.lxml.html.clean.Cleaner.safe_attrs |= \
self.sanitizer_settings["attributes"]["font"] self.sanitizer_settings["attributes"]["font"]
# hard_wrap: convert all \n to <br> without required two spaces
self._markdown_to_html = mistune.Markdown(hard_wrap=True)
@pyqtSlot(str, result=str)
def fromMarkdown(self, text: str) -> str:
return self.filter(self._markdown_to_html(text))
@pyqtSlot(str, result=str) @pyqtSlot(str, result=str)
def filter(self, html: str) -> str: def filter(self, html: str) -> str:

View File

@ -54,7 +54,7 @@ Rectangle {
if (textArea.text === "") { return } if (textArea.text === "") { return }
Backend.clientManager.clients[chatPage.user_id] Backend.clientManager.clients[chatPage.user_id]
.sendMessage(chatPage.room.room_id, textArea.text) .sendMarkdown(chatPage.room.room_id, textArea.text)
textArea.clear() textArea.clear()
} }
Keys.onEnterPressed: Keys.onReturnPressed(event) // numpad enter Keys.onEnterPressed: Keys.onReturnPressed(event) // numpad enter