Skip to content

Commit 97f8229

Browse files
normanarguetaManik Sachdeva
authored andcommitted
Adding set_archive_layout() method (#139)
* Adding set_archive_layout() method
1 parent df143ce commit 97f8229

File tree

5 files changed

+143
-3
lines changed

5 files changed

+143
-3
lines changed

README.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,25 @@ Note that you can also create an automatically archived session, by passing in
207207
``ArchiveModes.always`` as the ``archive_mode`` parameter when you call the
208208
``opentok.create_session()`` method (see "Creating Sessions," above).
209209

210+
For composed archives, you can change the layout dynamically, using the `opentok.set_archive_layout(archive_id, type, stylesheet)` method:
211+
212+
.. code:: python
213+
214+
opentok.set_archive_layout('ARCHIVEID', 'horizontalPresentation')
215+
216+
Setting the layout of composed archives is optional. By default, composed archives use the `best fit` layout. Other valid values are: `custom`, `horizontalPresentation`, `pip` and `verticalPresentation`. If you specify a `custom` layout type, set the stylesheet parameter:
217+
218+
.. code:: python
219+
220+
opentok.set_archive_layout(
221+
'ARCHIVEID',
222+
'custom',
223+
'stream.instructor {position: absolute; width: 100%; height:50%;}'
224+
)
225+
226+
For other layout types, do not set the stylesheet property. For more information see
227+
`Customizing the video layout for composed archives <https://tokbox.com/developer/guides/archiving/layout-control.html>`_.
228+
210229
For more information on archiving, see the
211230
`OpenTok archiving <https://tokbox.com/opentok/tutorials/archiving/>`_ programming guide.
212231

opentok/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from .opentok import OpenTok, Roles, MediaModes, ArchiveModes
22
from .session import Session
33
from .archives import Archive, ArchiveList, OutputModes
4-
from .exceptions import OpenTokException, AuthError, ForceDisconnectError
4+
from .exceptions import OpenTokException, AuthError, ForceDisconnectError, ArchiveError
55
from .version import __version__
66
from .stream import Stream
7-
from .streamlist import StreamList
7+
from .streamlist import StreamList

opentok/endpoints.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,8 @@ def force_disconnect_url(self, session_id, connection_id):
4040
session_id + '/connection/' + connection_id
4141
)
4242
return url
43+
44+
def set_archive_layout_url(self, archive_id):
45+
""" this method returns the url to set the archive layout """
46+
url = self.api_url + '/v2/project/' + self.api_key + '/archive/' + archive_id + '/layout'
47+
return url

opentok/opentok.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,44 @@ def force_disconnect(self, session_id, connection_id):
598598
else:
599599
raise RequestError('An unexpected error occurred', response.status_code)
600600

601+
def set_archive_layout(self, archive_id, layout_type, stylesheet=None):
602+
"""
603+
Use this method to change the layout of videos in an OpenTok archive
604+
605+
:param String archive_id: The ID of the archive that will be updated
606+
607+
:param String layout_type: The layout type for the archive. Valid values are:
608+
'bestFit', 'custom', 'horizontalPresentation', 'pip' and 'verticalPresentation'
609+
610+
:param String stylesheet optional: CSS used to style the custom layout.
611+
Specify this only if you set the type property to 'custom'
612+
"""
613+
payload = {
614+
'type': layout_type,
615+
}
616+
617+
if layout_type == 'custom':
618+
if stylesheet is not None:
619+
payload['stylesheet'] = stylesheet
620+
621+
endpoint = self.endpoints.set_archive_layout_url(archive_id)
622+
response = requests.put(
623+
endpoint,
624+
data=json.dumps(payload),
625+
headers=self.json_headers(),
626+
proxies=self.proxies,
627+
timeout=self.timeout
628+
)
629+
630+
if response.status_code == 200:
631+
pass
632+
elif response.status_code == 400:
633+
raise ArchiveError('Invalid request. This response may indicate that data in your request data is invalid JSON. It may also indicate that you passed in invalid layout options.')
634+
elif response.status_code == 403:
635+
raise AuthError('Authentication error.')
636+
else:
637+
raise RequestError('OpenTok server error.', response.status_code)
638+
601639
def _sign_string(self, string, secret):
602640
return hmac.new(secret.encode('utf-8'), string.encode('utf-8'), hashlib.sha1).hexdigest()
603641

tests/test_archive_api.py

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,15 @@
99
import pytz
1010
from .validate_jwt import validate_jwt_header
1111

12-
from opentok import OpenTok, Archive, ArchiveList, OutputModes, OpenTokException, __version__
12+
from opentok import (
13+
OpenTok,
14+
Archive,
15+
ArchiveList,
16+
OutputModes,
17+
OpenTokException,
18+
__version__,
19+
ArchiveError
20+
)
1321

1422
class OpenTokArchiveApiTest(unittest.TestCase):
1523
def setUp(self):
@@ -1049,3 +1057,73 @@ def test_find_archive_with_unknown_properties(self):
10491057
archive = self.opentok.get_archive(archive_id)
10501058

10511059
expect(archive).to(be_an(Archive))
1060+
1061+
@httpretty.activate
1062+
def test_set_archive_layout(self):
1063+
""" Test set archive layout functionality """
1064+
archive_id = u('f6e7ee58-d6cf-4a59-896b-6d56b158ec71')
1065+
1066+
httpretty.register_uri(
1067+
httpretty.PUT,
1068+
u('https://api.opentok.com/v2/project/{0}/archive/{1}/layout').format(
1069+
self.api_key,
1070+
archive_id
1071+
),
1072+
status=200,
1073+
content_type=u('application/json')
1074+
)
1075+
1076+
self.opentok.set_archive_layout(archive_id, 'horizontalPresentation')
1077+
1078+
validate_jwt_header(self, httpretty.last_request().headers[u('x-opentok-auth')])
1079+
expect(httpretty.last_request().headers[u('user-agent')]).to(contain(
1080+
u('OpenTok-Python-SDK/')+__version__))
1081+
expect(httpretty.last_request().headers[u('content-type')]).to(equal(u('application/json')))
1082+
1083+
@httpretty.activate
1084+
def test_set_custom_archive_layout(self):
1085+
""" Test set a custom archive layout specifying the 'stylesheet' parameter """
1086+
archive_id = u('f6e7ee58-d6cf-4a59-896b-6d56b158ec71')
1087+
1088+
httpretty.register_uri(
1089+
httpretty.PUT,
1090+
u('https://api.opentok.com/v2/project/{0}/archive/{1}/layout').format(
1091+
self.api_key,
1092+
archive_id
1093+
),
1094+
status=200,
1095+
content_type=u('application/json')
1096+
)
1097+
1098+
self.opentok.set_archive_layout(
1099+
archive_id,
1100+
'custom',
1101+
'stream.instructor {position: absolute; width: 100%; height:50%;}'
1102+
)
1103+
1104+
validate_jwt_header(self, httpretty.last_request().headers[u('x-opentok-auth')])
1105+
expect(httpretty.last_request().headers[u('user-agent')]).to(contain(
1106+
u('OpenTok-Python-SDK/')+__version__))
1107+
expect(httpretty.last_request().headers[u('content-type')]).to(equal(u('application/json')))
1108+
1109+
@httpretty.activate
1110+
def test_set_archive_layout_throws_exception(self):
1111+
""" Test invalid request in set archive layout """
1112+
archive_id = u('f6e7ee58-d6cf-4a59-896b-6d56b158ec71')
1113+
1114+
httpretty.register_uri(
1115+
httpretty.PUT,
1116+
u('https://api.opentok.com/v2/project/{0}/archive/{1}/layout').format(
1117+
self.api_key,
1118+
archive_id
1119+
),
1120+
status=400,
1121+
content_type=u('application/json')
1122+
)
1123+
1124+
self.assertRaises(
1125+
ArchiveError,
1126+
self.opentok.set_archive_layout,
1127+
archive_id,
1128+
'horizontalPresentation'
1129+
)

0 commit comments

Comments
 (0)