Initial upload implementation

This commit is contained in:
miruka 2019-10-28 15:27:36 -04:00
parent 820cc68373
commit 001d6eff71
3 changed files with 82 additions and 7 deletions

View File

@ -1,5 +1,6 @@
hsluv == 0.0.2 hsluv == 0.0.2
Pillow >= 5.4.1, < 6 Pillow >= 5.4.1, < 6
pymediainfo >= 4.1, < 5
aiofiles >= 0.4.0, < 0.5 aiofiles >= 0.4.0, < 0.5
appdirs >= 1.4.3, < 2 appdirs >= 1.4.3, < 2
filetype >= 1.0.5, < 2 filetype >= 1.0.5, < 2

View File

@ -14,6 +14,8 @@ from typing import DefaultDict, Dict, Optional, Set, Tuple, Type, Union
from uuid import uuid4 from uuid import uuid4
import nio import nio
from PIL import Image as PILImage
from pymediainfo import MediaInfo
from . import __about__, utils from . import __about__, utils
from .html_filter import HTML_FILTER from .html_filter import HTML_FILTER
@ -197,12 +199,77 @@ class MatrixClient(nio.AsyncClient):
uuid = str(uuid4()) uuid = str(uuid4())
await self._local_echo(room_id, uuid, echo_body, event_type) await self._local_echo(room_id, uuid, event_type, content=echo_body)
await self._send_message(room_id, uuid, content)
async def send_file(self, room_id: str, path: Union[Path, str]) -> None:
path = Path(path)
url, mime = await self.upload_file(path)
kind = (mime or "").split("/")[0]
content: dict = {
"body": path.name,
"url": url,
"info": {
"mimetype": mime,
"size": path.resolve().stat().st_size,
},
}
if kind == "image":
event_type = nio.RoomMessageImage
content["msgtype"] = "m.image"
content["info"]["w"], content["info"]["h"] = \
PILImage.open(path).size
elif kind == "audio":
event_type = nio.RoomMessageAudio
content["msgtype"] = "m.audio"
content["info"]["duration"] = getattr(
MediaInfo.parse(path).tracks[0], "duration", 0,
) or 0
elif kind == "video":
event_type = nio.RoomMessageVideo
content["msgtype"] = "m.video"
tracks = MediaInfo.parse(path).tracks
content["info"]["duration"] = \
getattr(tracks[0], "duration", 0) or 0
content["info"]["w"] = max(
getattr(t, "width", 0) or 0 for t in tracks
)
content["info"]["h"] = max(
getattr(t, "height", 0) or 0 for t in tracks
)
else:
event_type = nio.RoomMessageFile
content["msgtype"] = "m.file"
content["filename"] = path.name
uuid = str(uuid4())
await self._local_echo(
room_id, uuid, event_type,
inline_content = path.name,
media_url = url,
media_title = path.name,
media_width = content["info"].get("w", 0),
media_height = content["info"].get("h", 0),
media_duration = content["info"].get("duration", 0),
media_size = content["info"]["size"],
media_mime = content["info"]["mimetype"],
)
await self._send_message(room_id, uuid, content) await self._send_message(room_id, uuid, content)
async def _local_echo( async def _local_echo(
self, room_id: str, uuid: str, content: str, self, room_id: str, uuid: str,
event_type: Type[nio.Event], **event_fields, event_type: Type[nio.Event], **event_fields,
) -> None: ) -> None:
@ -216,9 +283,9 @@ class MatrixClient(nio.AsyncClient):
sender_id = self.user_id, sender_id = self.user_id,
sender_name = our_info.display_name, sender_name = our_info.display_name,
sender_avatar = our_info.avatar_url, sender_avatar = our_info.avatar_url,
content = content,
is_local_echo = True, is_local_echo = True,
local_event_type = event_type.__name__, local_event_type = event_type.__name__,
**event_fields,
) )
self.local_echoes_uuid.add(uuid) self.local_echoes_uuid.add(uuid)
@ -306,7 +373,8 @@ class MatrixClient(nio.AsyncClient):
self.models.pop((Member, room_id), None) self.models.pop((Member, room_id), None)
async def upload_file(self, path: Union[Path, str]) -> str: async def upload_file(self, path: Union[Path, str],
) -> Tuple[str, Optional[str]]:
path = Path(path) path = Path(path)
with open(path, "rb") as file: with open(path, "rb") as file:
@ -316,7 +384,7 @@ class MatrixClient(nio.AsyncClient):
resp = await self.upload(file, mime, path.name) resp = await self.upload(file, mime, path.name)
if not isinstance(resp, nio.ErrorResponse): if not isinstance(resp, nio.ErrorResponse):
return resp.content_uri return (resp.content_uri, mime)
if resp.status_code == 403: if resp.status_code == 403:
raise UploadForbidden() raise UploadForbidden()
@ -328,7 +396,8 @@ class MatrixClient(nio.AsyncClient):
async def set_avatar_from_file(self, path: Union[Path, str]) -> None: async def set_avatar_from_file(self, path: Union[Path, str]) -> None:
await self.set_avatar(await self.upload_file(path)) # TODO: check if mime is image
await self.set_avatar((await self.upload_file(path))[0])
async def import_keys(self, infile: str, passphrase: str) -> None: async def import_keys(self, infile: str, passphrase: str) -> None:

View File

@ -208,12 +208,17 @@ Rectangle {
HButton { HButton {
icon.name: "upload-file" icon.name: "upload-file"
backgroundColor: theme.chat.composer.uploadButton.background backgroundColor: theme.chat.composer.uploadButton.background
toolTip.text: qsTr("Upload files") toolTip.text: qsTr("Send files")
Layout.fillHeight: true Layout.fillHeight: true
HFileDialogOpener { HFileDialogOpener {
dialog.title: qsTr("Select files to upload") dialog.title: qsTr("Select files to upload")
onFileChanged: {
let path = Qt.resolvedUrl(file).replace(/^file:/, "")
let args = [chatPage.roomId, path]
py.callClientCoro(chatPage.userId, "send_file", args)
}
} }
} }
} }