Skip to content

Commit c107942

Browse files
authored
Merge pull request #254 from slipeer/thumbnails
Media API
2 parents 8efb34c + 58383c6 commit c107942

File tree

3 files changed

+163
-5
lines changed

3 files changed

+163
-5
lines changed

matrix_client/api.py

Lines changed: 85 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,7 @@ def create_filter(self, user_id, filter_params):
682682
filter_params)
683683

684684
def _send(self, method, path, content=None, query_params=None, headers=None,
685-
api_path=MATRIX_V2_API_PATH):
685+
api_path=MATRIX_V2_API_PATH, return_json=True):
686686
if query_params is None:
687687
query_params = {}
688688
if headers is None:
@@ -741,8 +741,10 @@ def _send(self, method, path, content=None, query_params=None, headers=None,
741741
raise MatrixRequestError(
742742
code=response.status_code, content=response.text
743743
)
744-
745-
return response.json()
744+
if return_json:
745+
return response.json()
746+
else:
747+
return response
746748

747749
def media_upload(self, content, content_type, filename=None):
748750
query_params = {}
@@ -779,8 +781,87 @@ def get_download_url(self, mxcurl):
779781
else:
780782
raise ValueError("MXC URL did not begin with 'mxc://'")
781783

784+
def media_download(self, mxcurl, allow_remote=True):
785+
"""Download raw media from provided mxc URL.
786+
787+
Args:
788+
mxcurl (str): mxc media URL.
789+
allow_remote (bool): indicates to the server that it should not
790+
attempt to fetch the media if it is deemed remote. Defaults
791+
to true if not provided.
792+
"""
793+
query_params = {}
794+
if not allow_remote:
795+
query_params["allow_remote"] = False
796+
if mxcurl.startswith('mxc://'):
797+
return self._send(
798+
"GET", mxcurl[6:],
799+
api_path="/_matrix/media/r0/download/",
800+
query_params=query_params,
801+
return_json=False
802+
)
803+
else:
804+
raise ValueError(
805+
"MXC URL '%s' did not begin with 'mxc://'" % mxcurl
806+
)
807+
808+
def get_thumbnail(self, mxcurl, width, height, method='scale', allow_remote=True):
809+
"""Download raw media thumbnail from provided mxc URL.
810+
811+
Args:
812+
mxcurl (str): mxc media URL
813+
width (int): desired thumbnail width
814+
height (int): desired thumbnail height
815+
method (str): thumb creation method. Must be
816+
in ['scale', 'crop']. Default 'scale'.
817+
allow_remote (bool): indicates to the server that it should not
818+
attempt to fetch the media if it is deemed remote. Defaults
819+
to true if not provided.
820+
"""
821+
if method not in ['scale', 'crop']:
822+
raise ValueError(
823+
"Unsupported thumb method '%s'" % method
824+
)
825+
query_params = {
826+
"width": width,
827+
"height": height,
828+
"method": method
829+
}
830+
if not allow_remote:
831+
query_params["allow_remote"] = False
832+
if mxcurl.startswith('mxc://'):
833+
return self._send(
834+
"GET", mxcurl[6:],
835+
query_params=query_params,
836+
api_path="/_matrix/media/r0/thumbnail/",
837+
return_json=False
838+
)
839+
else:
840+
raise ValueError(
841+
"MXC URL '%s' did not begin with 'mxc://'" % mxcurl
842+
)
843+
844+
def get_url_preview(self, url, ts=None):
845+
"""Get preview for URL.
846+
847+
Args:
848+
url (str): URL to get a preview
849+
ts (double): The preferred point in time to return
850+
a preview for. The server may return a newer
851+
version if it does not have the requested
852+
version available.
853+
"""
854+
params = {'url': url}
855+
if ts:
856+
params['ts'] = ts
857+
return self._send(
858+
"GET", "",
859+
query_params=params,
860+
api_path="/_matrix/media/r0/preview_url"
861+
)
862+
782863
def get_room_id(self, room_alias):
783-
"""Get room id from its alias
864+
"""Get room id from its alias.
784865
785866
Args:
786867
room_alias (str): The room alias name.

test/api_test.py

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import responses
22
import pytest
33
import json
4+
from copy import deepcopy
45
from matrix_client import client, api
56
from matrix_client.errors import MatrixRequestError, MatrixError, MatrixHttpLibError
67
from matrix_client import __version__ as lib_version
7-
8+
from . import response_examples
89
MATRIX_V2_API_PATH = "/_matrix/client/r0"
910

1011

@@ -317,6 +318,72 @@ def test_send_request_error(self):
317318
mapi._send("GET", self.test_path)
318319

319320

321+
class TestMediaApi:
322+
cli = client.MatrixClient("http://example.com")
323+
user_id = "@alice:example.com"
324+
mxcurl = "mxc://example.com/OonjUOmcuVpUnmOWKtzPmAFe"
325+
326+
@responses.activate
327+
def test_media_download(self):
328+
media_url = \
329+
"http://example.com/_matrix/media/r0/download/" + self.mxcurl[6:]
330+
with open('test/response_examples.py', 'rb') as fil:
331+
responses.add(
332+
responses.GET, media_url,
333+
content_type='application/python',
334+
body=fil.read(), status=200, stream=True
335+
)
336+
resp = self.cli.api.media_download(self.mxcurl, allow_remote=False)
337+
resp.raw.decode_content = True
338+
req = responses.calls[0].request
339+
assert req.url.split('?')[0] == media_url
340+
assert req.method == 'GET'
341+
342+
def test_media_download_wrong_url(self):
343+
with pytest.raises(ValueError):
344+
self.cli.api.media_download(self.mxcurl[6:])
345+
346+
@responses.activate
347+
def test_get_thumbnail(self):
348+
media_url = \
349+
"http://example.com/_matrix/media/r0/thumbnail/" + self.mxcurl[6:]
350+
with open('test/response_examples.py', 'rb') as fil:
351+
responses.add(
352+
responses.GET, media_url,
353+
content_type='application/python',
354+
body=fil.read(), status=200, stream=True
355+
)
356+
resp = self.cli.api.get_thumbnail(
357+
self.mxcurl, 28, 28, allow_remote=False
358+
)
359+
resp.raw.decode_content = True
360+
req = responses.calls[0].request
361+
assert req.url.split('?')[0] == media_url
362+
assert req.method == 'GET'
363+
364+
def test_get_thumbnail_wrong_url(self):
365+
with pytest.raises(ValueError):
366+
self.cli.api.get_thumbnail(self.mxcurl[6:], 28, 28)
367+
368+
def test_get_thumbnail_wrong_method(self):
369+
with pytest.raises(ValueError):
370+
self.cli.api.get_thumbnail(self.mxcurl, 28, 28, 'cut')
371+
372+
@responses.activate
373+
def test_get_url_preview(self):
374+
media_url = \
375+
"http://example.com/_matrix/media/r0/preview_url"
376+
preview_url = deepcopy(response_examples.example_preview_url)
377+
responses.add(
378+
responses.GET, media_url,
379+
body=json.dumps(preview_url)
380+
)
381+
self.cli.api.get_url_preview("https://google.com/", 1510610716656)
382+
req = responses.calls[0].request
383+
assert req.url.split('?')[0] == media_url
384+
assert req.method == 'GET'
385+
386+
320387
class TestRoomApi:
321388
cli = client.MatrixClient("http://example.com")
322389
user_id = "@user:matrix.org"

test/response_examples.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,3 +174,13 @@
174174
"home_server": "matrix.org",
175175
"device_id": "GHTYAJCE"
176176
}
177+
178+
example_preview_url = {
179+
"matrix:image:size": 102400,
180+
"og:description": "This is a really cool blog post from matrix.org",
181+
"og:image": "mxc://example.com/ascERGshawAWawugaAcauga",
182+
"og:image:height": 48,
183+
"og:image:type": "image/png",
184+
"og:image:width": 48,
185+
"og:title": "Matrix Blog Post"
186+
}

0 commit comments

Comments
 (0)