Add openMessagesLinksOrFilesExternally keybind

This required us to set the media downloaded local path on events
entirely from python instead of simply lazy-fetching them when needed
from QML, due to pyotherside's async nature and files that must be open
in a certain order.
This commit is contained in:
miruka
2020-07-20 22:58:02 -04:00
parent 89e6931d9d
commit 55e22ea948
8 changed files with 96 additions and 79 deletions

View File

@@ -18,7 +18,7 @@ from .matrix_client import MatrixClient
from .media_cache import MediaCache
from .models import SyncId
from .models.filters import FieldSubstringFilter
from .models.items import Account
from .models.items import Account, Event
from .models.model import Model
from .models.model_store import ModelStore
from .presence import Presence
@@ -86,6 +86,9 @@ class Backend:
presences: A `{user_id: Presence}` dict for storing presence info about
matrix users registered on Mirage.
mxc_events: A dict storing media `Event` model items for any account
that have the same mxc URI
"""
def __init__(self) -> None:
@@ -117,6 +120,8 @@ class Backend:
self.concurrent_get_presence_limit = asyncio.BoundedSemaphore(8)
self.mxc_events: DefaultDict[str, List[Event]] = DefaultDict(list)
def __repr__(self) -> str:
return f"{type(self).__name__}(clients={self.clients!r})"

View File

@@ -693,7 +693,9 @@ class MatrixClient(nio.AsyncClient):
await asyncio.sleep(0.1)
upload_item.status = UploadStatus.Caching
await Media.from_existing_file(self.backend.media_cache, url, path)
local_media = await Media.from_existing_file(
self.backend.media_cache, url, path,
)
kind = (mime or "").split("/")[0]
@@ -843,6 +845,7 @@ class MatrixClient(nio.AsyncClient):
media_size = content["info"]["size"],
media_mime = content["info"]["mimetype"],
media_crypt_dict = crypt_dict,
media_local_path = await local_media.get_local(),
thumbnail_url = thumb_url,
thumbnail_crypt_dict = thumb_crypt_dict,
@@ -1926,7 +1929,7 @@ class MatrixClient(nio.AsyncClient):
event_id: str = "",
override_fetch_profile: Optional[bool] = None,
**fields,
) -> None:
) -> Event:
"""Register/update a `nio.Event` as a `models.items.Event` object."""
await self.register_nio_room(room)
@@ -1988,7 +1991,7 @@ class MatrixClient(nio.AsyncClient):
# Alerts
if from_us or await self.event_is_past(ev):
return
return item
mentions_us = HTML.user_id_link_in_html(item.content, self.user_id)
AlertRequested(high_importance=mentions_us)
@@ -2000,3 +2003,4 @@ class MatrixClient(nio.AsyncClient):
room_item.local_highlights = True
await self.update_account_unread_counts()
return item

View File

@@ -47,30 +47,6 @@ class MediaCache:
self.downloads_dir.mkdir(parents=True, exist_ok=True)
async def get_local_media(self, mxc: str, title: str) -> Optional[Path]:
"""Return `Media.get_local()`'s result for QML."""
media = Media(self, mxc, title, None)
try:
return await media.get_local()
except FileNotFoundError:
return None
async def get_local_thumbnail(
self, mxc: str, title: str, width: int, height: int,
) -> Optional[Path]:
"""Return `Thumbnail.get_local()`'s result for QML."""
th = Thumbnail(self, mxc, title, None, (round(width), round(height)))
try:
return await th.get_local()
except FileNotFoundError:
return None
async def get_media(
self,
mxc: str,
@@ -166,6 +142,10 @@ class Media:
await file.write(data)
done()
if type(self) is Media:
for event in self.cache.backend.mxc_events[self.mxc]:
event.media_local_path = self.local_path
return self.local_path

View File

@@ -279,14 +279,15 @@ class Event(ModelItem):
is_local_echo: bool = False
source: Optional[nio.Event] = None
media_url: str = ""
media_title: str = ""
media_width: int = 0
media_height: int = 0
media_duration: int = 0
media_size: int = 0
media_mime: str = ""
media_crypt_dict: Dict[str, Any] = field(default_factory=dict)
media_url: str = ""
media_title: str = ""
media_width: int = 0
media_height: int = 0
media_duration: int = 0
media_size: int = 0
media_mime: str = ""
media_crypt_dict: Dict[str, Any] = field(default_factory=dict)
media_local_path: Union[str, Path] = ""
thumbnail_url: str = ""
thumbnail_mime: str = ""

View File

@@ -6,12 +6,14 @@ import logging as log
from dataclasses import dataclass, field
from datetime import datetime, timedelta
from html import escape
from pathlib import Path
from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, Union
from urllib.parse import quote
import nio
from .html_markdown import HTML_PROCESSOR
from .media_cache import Media
from .models.items import TypeSpecifier
from .presence import Presence
from .pyotherside_events import DevicesUpdated
@@ -190,7 +192,17 @@ class NioCallbacks:
thumb_info = info.get("thumbnail_info", {})
thumb_crypt_dict = info.get("thumbnail_file", {})
await self.client.register_nio_event(
try:
media_local_path: Union[Path, str] = await Media(
cache = self.client.backend.media_cache,
mxc = ev.url,
title = ev.body,
crypt_dict = media_crypt_dict,
).get_local()
except FileNotFoundError:
media_local_path = ""
item = await self.client.register_nio_event(
room,
ev,
content = "",
@@ -204,6 +216,7 @@ class NioCallbacks:
media_size = info.get("size") or 0,
media_mime = info.get("mimetype") or "",
media_crypt_dict = media_crypt_dict,
media_local_path = media_local_path,
thumbnail_url =
info.get("thumbnail_url") or thumb_crypt_dict.get("url") or "",
@@ -214,6 +227,8 @@ class NioCallbacks:
thumbnail_crypt_dict = thumb_crypt_dict,
)
self.client.backend.mxc_events[ev.url].append(item)
async def onRoomEncryptedMedia(
self, room: nio.MatrixRoom, ev: nio.RoomEncryptedMedia,

View File

@@ -357,16 +357,17 @@ class UISettings(JSONDataFile):
"10": f"{alt_or_cmd()}+0",
},
"unfocusOrDeselectAllMessages": ["Ctrl+D"],
"focusPreviousMessage": ["Ctrl+Up", "Ctrl+K"],
"focusNextMessage": ["Ctrl+Down", "Ctrl+J"],
"toggleSelectMessage": ["Ctrl+Space"],
"selectMessagesUntilHere": ["Ctrl+Shift+Space"],
"removeFocusedOrSelectedMessages": ["Ctrl+R", "Alt+Del"],
"replyToFocusedOrLastMessage": ["Ctrl+Q"], # Q for Quote
"debugFocusedMessage": ["Ctrl+Shift+D"],
"openMessagesLinksOrFiles": ["Ctrl+O"],
"clearRoomMessages": ["Ctrl+L"],
"unfocusOrDeselectAllMessages": ["Ctrl+D"],
"focusPreviousMessage": ["Ctrl+Up", "Ctrl+K"],
"focusNextMessage": ["Ctrl+Down", "Ctrl+J"],
"toggleSelectMessage": ["Ctrl+Space"],
"selectMessagesUntilHere": ["Ctrl+Shift+Space"],
"removeFocusedOrSelectedMessages": ["Ctrl+R", "Alt+Del"],
"replyToFocusedOrLastMessage": ["Ctrl+Q"], # Q Quote
"debugFocusedMessage": ["Ctrl+Shift+D"],
"openMessagesLinksOrFiles": ["Ctrl+O"],
"openMessagesLinksOrFilesExternally": ["Ctrl+Shift+O"],
"clearRoomMessages": ["Ctrl+L"],
"sendFile": ["Alt+S"],
"sendFileFromPathInClipboard": ["Alt+Shift+S"],