Fix image URL preview, add Thumbnail.create()

- Make HMxcImage's mxc property work with http too (temporary quick
solution)

- Thumbnail objects can now be initialized with existing bytes and not
  have to download anything.
This commit is contained in:
miruka 2019-11-04 07:00:28 -04:00
parent 337603595a
commit 484eefe86d
5 changed files with 44 additions and 39 deletions

View File

@ -443,7 +443,6 @@ class MatrixClient(nio.AsyncClient):
else:
crypt_dict, upload_mime = {}, mime
return (
await self.upload(data, upload_mime, Path(path).name),
{
@ -813,7 +812,7 @@ class MatrixClient(nio.AsyncClient):
ev,
content = "",
inline_content = ev.body,
media_url = nio.Api.mxc_to_http(ev.url),
media_url = ev.url,
media_title = ev.body,
media_width = info.get("w") or 0,
media_height = info.get("h") or 0,
@ -821,9 +820,7 @@ class MatrixClient(nio.AsyncClient):
media_size = info.get("size") or 0,
media_mime = info.get("mimetype") or 0,
thumbnail_url =
nio.Api.mxc_to_http(info.get("thumbnail_url") or ""),
thumbnail_url = info.get("thumbnail_url") or "",
thumbnail_width = thumb_info.get("w") or 0,
thumbnail_height = thumb_info.get("h") or 0,
)

View File

@ -26,8 +26,9 @@ class DownloadFailed(Exception):
@dataclass
class Media:
cache: "MediaCache" = field()
mxc: str = field()
cache: "MediaCache" = field()
mxc: str = field()
data: Optional[bytes] = field(repr=False)
def __post_init__(self) -> None:
@ -54,7 +55,7 @@ class Media:
try:
return await self._get_local_existing_file()
except FileNotFoundError:
return await self._download()
return await self.create()
async def _get_local_existing_file(self) -> Path:
@ -64,14 +65,15 @@ class Media:
return self.local_path
async def _download(self) -> Path:
async with CONCURRENT_DOWNLOADS_LIMIT:
body = await self._get_remote_data()
async def create(self) -> Path:
if self.data is None:
async with CONCURRENT_DOWNLOADS_LIMIT:
self.data = await self._get_remote_data()
self.local_path.parent.mkdir(parents=True, exist_ok=True)
async with aiofiles.open(self.local_path, "wb") as file:
await file.write(body)
await file.write(self.data)
return self.local_path
@ -82,9 +84,10 @@ class Media:
@dataclass
class Thumbnail(Media):
cache: "MediaCache" = field()
mxc: str = field()
wanted_size: Size = field()
cache: "MediaCache" = field()
mxc: str = field()
data: Optional[bytes] = field(repr=False)
wanted_size: Size = field()
server_size: Optional[Size] = field(init=False, repr=False, default=None)
@ -143,7 +146,6 @@ class Thumbnail(Media):
raise FileNotFoundError()
async def _get_remote_data(self) -> bytes:
parsed = urlparse(self.mxc)
@ -154,13 +156,13 @@ class Thumbnail(Media):
height = self.wanted_size[1],
)
if isinstance(resp, nio.ThumbnailError):
raise DownloadFailed(resp.message, resp.status_code)
with io.BytesIO(resp.body) as img:
# The server may return a thumbnail bigger than what we asked for
self.server_size = PILImage.open(img).size
if isinstance(resp, nio.ErrorResponse):
raise DownloadFailed(resp.message, resp.status_code)
return resp.body
@ -178,5 +180,5 @@ class MediaCache:
self.downloads_dir.mkdir(parents=True, exist_ok=True)
async def thumbnail(self, mxc: str, width: int, height: int) -> str:
return str(await Thumbnail(self, mxc, (width, height)).get())
async def get_thumbnail(self, mxc: str, width: int, height: int) -> str:
return str(await Thumbnail(self, mxc, None, (width, height)).get())

View File

@ -31,10 +31,18 @@ HImage {
if (! image) return // if it was destroyed
py.callClientCoro(clientUserId, "media_cache.thumbnail", arg, path => {
if (! image) return
image.cachedPath = path
show = image.visible
})
if (! image.mxc.startsWith("mxc://")) {
source = mxc
show = image.visible
return
}
py.callClientCoro(
clientUserId, "media_cache.get_thumbnail", [mxc, w, h], path => {
if (! image) return
image.cachedPath = path
show = image.visible
}
)
}
}

View File

@ -2,17 +2,19 @@ import QtQuick 2.12
import "../../Base"
import "../../utils.js" as Utils
HImage {
HMxcImage {
id: image
horizontalAlignment: Image.AlignLeft
sourceSize.width: theme.chat.message.thumbnailWidth // FIXME
source: animated ? openUrl : loader.previewUrl
sourceSize.width: 640 // FIXME
sourceSize.height: 480 // FIXME
animated: loader.singleMediaInfo.media_mime === "image/gif" ||
Utils.urlExtension(loader.mediaUrl) === "gif"
clientUserId: chatPage.userId
mxc: animated ? openUrl : (loader.thumbnailMxc || loader.mediaUrl)
property EventMediaLoader loader
readonly property url openUrl: loader.mediaUrl || loader.previewUrl
readonly property url openUrl: loader.mediaUrl || loader.thumbnailMxc
TapHandler {

View File

@ -8,7 +8,7 @@ HLoader {
property QtObject singleMediaInfo
property url mediaUrl
property string mediaUrl
property string showSender: ""
property string showDate: ""
@ -47,21 +47,17 @@ HLoader {
return EventDelegate.Media.Page
}
readonly property url previewUrl: (
type === EventDelegate.Media.File ||
type === EventDelegate.Media.Image ?
singleMediaInfo.thumbnail_url : ""
) || mediaUrl
readonly property string thumbnailMxc: singleMediaInfo.thumbnail_url
onPreviewUrlChanged: {
onTypeChanged: {
if (type === EventDelegate.Media.Image) {
var file = "EventImage.qml"
var file = "EventImage.qml"
// } else if (type === EventDelegate.Media.File) {
// var file = "EventFile.qml"
// var props = {
// thumbnailUrl: previewUrl,
// thumbnailMxc: thumbnailMxc,
// fileUrl: mediaUrl,
// fileTitle: info.media_title,
// fileSize: info.media_size,