Cache local media on upload, fix media local echo

This commit is contained in:
miruka 2019-11-06 09:43:05 -04:00
parent 1de82492dd
commit 18e184d1f0
3 changed files with 52 additions and 17 deletions

View File

@ -237,8 +237,13 @@ class MatrixClient(nio.AsyncClient):
path, upload_item, encrypt=encrypt, path, upload_item, encrypt=encrypt,
) )
await self.media_cache.create_media(url, path.read_bytes())
kind = (mime or "").split("/")[0] kind = (mime or "").split("/")[0]
thumb_url: str = ""
thumb_info: Dict[str, Any] = {}
content: dict = { content: dict = {
"body": path.name, "body": path.name,
"info": { "info": {
@ -266,13 +271,20 @@ class MatrixClient(nio.AsyncClient):
) )
try: try:
thumb_url, thumb_info, thumb_crypt_dict = \ thumb_data, thumb_url, thumb_info, thumb_crypt_dict = \
await self.upload_thumbnail( await self.upload_thumbnail(
path, upload_item, is_svg=is_svg, encrypt=encrypt, path, upload_item, is_svg=is_svg, encrypt=encrypt,
) )
except (UneededThumbnail, UnthumbnailableError): except (UneededThumbnail, UnthumbnailableError):
pass pass
else: else:
await self.media_cache.create_thumbnail(
thumb_url,
thumb_data,
content["info"]["w"],
content["info"]["h"],
)
if encrypt: if encrypt:
content["info"]["thumbnail_file"] = { content["info"]["thumbnail_file"] = {
"url": thumb_url, "url": thumb_url,
@ -331,6 +343,9 @@ class MatrixClient(nio.AsyncClient):
media_duration = content["info"].get("duration", 0), media_duration = content["info"].get("duration", 0),
media_size = content["info"]["size"], media_size = content["info"]["size"],
media_mime = content["info"]["mimetype"], media_mime = content["info"]["mimetype"],
thumbnail_url = thumb_url,
thumbnail_width = thumb_info.get("w", 0),
thumbnail_height = thumb_info.get("h", 0),
) )
await self._send_message(room_id, uuid, content) await self._send_message(room_id, uuid, content)
@ -352,7 +367,7 @@ class MatrixClient(nio.AsyncClient):
sender_name = our_info.display_name, sender_name = our_info.display_name,
sender_avatar = our_info.avatar_url, sender_avatar = our_info.avatar_url,
is_local_echo = True, is_local_echo = True,
local_event_type = event_type.__name__, local_event_type = event_type,
**event_fields, **event_fields,
) )
@ -457,7 +472,7 @@ class MatrixClient(nio.AsyncClient):
item: Optional[Upload] = None, item: Optional[Upload] = None,
is_svg: bool = False, is_svg: bool = False,
encrypt: bool = False, encrypt: bool = False,
) -> Tuple[str, Dict[str, Any], CryptDict]: ) -> Tuple[bytes, str, Dict[str, Any], CryptDict]:
png_modes = ("1", "L", "P", "RGBA") png_modes = ("1", "L", "P", "RGBA")
@ -511,6 +526,7 @@ class MatrixClient(nio.AsyncClient):
item.status = UploadStatus.UploadingThumbnail item.status = UploadStatus.UploadingThumbnail
return ( return (
data,
await self.upload(data, upload_mime, Path(path).name), await self.upload(data, upload_mime, Path(path).name),
{ {
"w": thumb.width, "w": thumb.width,

View File

@ -219,10 +219,21 @@ class MediaCache:
self.downloads_dir.mkdir(parents=True, exist_ok=True) self.downloads_dir.mkdir(parents=True, exist_ok=True)
async def create_media(self, mxc: str, data: bytes) -> None:
await Media(self, mxc, data, {}).create()
async def get_media(self, mxc: str, crypt_dict: CryptDict = None) -> str: async def get_media(self, mxc: str, crypt_dict: CryptDict = None) -> str:
return str(await Media(self, mxc, None, crypt_dict).get()) return str(await Media(self, mxc, None, crypt_dict).get())
async def create_thumbnail(
self, mxc: str, data: bytes, width: int, height: int,
) -> None:
thumb = Thumbnail(self, mxc, data, {}, (round(width), round(height)))
await thumb.create()
async def get_thumbnail( async def get_thumbnail(
self, mxc: str, width: int, height: int, crypt_dict: CryptDict = None, self, mxc: str, width: int, height: int, crypt_dict: CryptDict = None,
) -> str: ) -> str:

View File

@ -2,7 +2,7 @@ import re
from dataclasses import dataclass, field from dataclasses import dataclass, field
from datetime import datetime from datetime import datetime
from pathlib import Path from pathlib import Path
from typing import Any, Dict, List, Optional, Tuple from typing import Any, Dict, List, Optional, Tuple, Type
from uuid import uuid4 from uuid import uuid4
import lxml # nosec import lxml # nosec
@ -160,7 +160,7 @@ class Event(ModelItem):
target_avatar: str = "" target_avatar: str = ""
is_local_echo: bool = False is_local_echo: bool = False
local_event_type: str = "" local_event_type: Optional[Type[nio.Event]] = None
media_url: str = "" media_url: str = ""
media_title: str = "" media_title: str = ""
@ -187,12 +187,20 @@ class Event(ModelItem):
@property @property
def event_type(self) -> str: def event_type(self) -> str:
return self.local_event_type or type(self.source).__name__ if self.local_event_type:
return self.local_event_type.__name__
return type(self.source).__name__
@property @property
def links(self) -> List[str]: def links(self) -> List[str]:
if isinstance(self.source, local_type = self.local_event_type
(nio.RoomMessageMedia, nio.RoomEncryptedMedia)): media_classes = (nio.RoomMessageMedia, nio.RoomEncryptedMedia)
if local_type and issubclass(local_type, media_classes):
return [self.media_url]
if isinstance(self.source, media_classes):
return [self.media_url] return [self.media_url]
if not self.content.strip(): if not self.content.strip():