Skip to content

Commit e60dd3d

Browse files
committed
move archiving implementation, test start archive
1 parent 3638346 commit e60dd3d

File tree

5 files changed

+127
-62
lines changed

5 files changed

+127
-62
lines changed

opentok/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from .opentok import OpenTok, Roles
22
from .session import Session
3+
from .archives import Archive, ArchiveList
34
from .exceptions import OpenTokException
45
from .version import __version__
56

opentok/archives.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
from datetime import datetime, date
2+
from six import iteritems
3+
import json
4+
5+
dthandler = lambda obj: obj.isoformat() if isinstance(obj, datetime) or isinstance(obj, date) else None
6+
7+
class Archive(object):
8+
9+
def __init__(self, sdk, values):
10+
self.sdk = sdk
11+
self.id = values.get('id')
12+
self.name = values.get('name')
13+
self.status = values.get('status')
14+
self.session_id = values.get('sessionId')
15+
self.partner_id = values.get('partnerId')
16+
self.created_at = datetime.fromtimestamp(values.get('createdAt') / 1000)
17+
self.size = values.get('size')
18+
self.duration = values.get('duration')
19+
self.url = values.get('url')
20+
21+
def stop(self):
22+
self.sdk.stop_archive(self.id)
23+
24+
def delete(self):
25+
self.sdk.delete_archive(self.id)
26+
27+
def attrs(self):
28+
return dict((k, v) for k, v in iteritems(self.__dict__) if k is not "sdk")
29+
30+
def json(self):
31+
return json.dumps(self.attrs(), default=dthandler, indent=4)
32+
33+
class ArchiveList(object):
34+
35+
def __init__(self, values):
36+
self.count = values.get('count')
37+
self.items = map(lambda x: OpenTokArchive(self, x), values.get('items', []))
38+
39+
def __iter__(self):
40+
for x in self.items:
41+
yield x
42+
43+
def attrs(self):
44+
return {
45+
'count': self.count,
46+
'items': map(OpenTokArchive.attrs, self.items)
47+
}
48+
49+
def json(self):
50+
return json.dumps(self.attrs(), default=dthandler, indent=4)
51+
52+

opentok/opentok.py

Lines changed: 12 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,32 @@
11
from datetime import datetime # generate_token
22
import calendar # generate_token
3+
import base64 # generate_token
4+
import random # generate_token
35
import time # generate_token
46
import hmac # _sign_string
57
import hashlib # _sign_string
6-
import base64 # generate_token
7-
import random # generate_token
88
import requests # create_session, archiving
99
import json # archiving
1010
from socket import inet_aton # create_session
1111
import xml.dom.minidom as xmldom # create_session
1212

13-
from .exceptions import OpenTokException, RequestError, AuthError, NotFoundError, ArchiveError
14-
from .session import Session
15-
from .version import __version__
16-
1713
# compat
1814
from six.moves import map
1915
from six.moves.urllib.parse import urlencode
2016
from six import text_type, u, b, PY3
2117
from enum import Enum
2218

23-
dthandler = lambda obj: obj.isoformat() if isinstance(obj, datetime.datetime) or isinstance(obj, datetime.date) else None
19+
from .version import __version__
20+
from .session import Session
21+
from .archives import Archive, ArchiveList
22+
from .exceptions import OpenTokException, RequestError, AuthError, NotFoundError, ArchiveError
2423

2524
class Roles(Enum):
2625
"""List of valid roles for a token."""
2726
subscriber = u('subscriber') # Can only subscribe
2827
publisher = u('publisher') # Can publish, subscribe, and signal
2928
moderator = u('moderator') # Can do the above along with forceDisconnect and forceUnpublish
3029

31-
32-
class OpenTokArchive(object):
33-
34-
def __init__(self, sdk, values):
35-
self.sdk = sdk
36-
self.id = values.get('id')
37-
self.name = values.get('name')
38-
self.status = values.get('status')
39-
self.session_id = values.get('sessionId')
40-
self.partner_id = values.get('partnerId')
41-
self.created_at = datetime.datetime.fromtimestamp(values.get('createdAt') / 1000)
42-
self.size = values.get('size')
43-
self.duration = values.get('duration')
44-
self.url = values.get('url')
45-
46-
def stop(self):
47-
self.sdk.stop_archive(self.id)
48-
49-
def delete(self):
50-
self.sdk.delete_archive(self.id)
51-
52-
def attrs(self):
53-
return dict((k, v) for k, v in six.iteritems(self.__dict__) if k is not "sdk")
54-
55-
def json(self):
56-
return json.dumps(self.attrs(), default=dthandler, indent=4)
57-
58-
59-
class OpenTokArchiveList(object):
60-
61-
def __init__(self, values):
62-
self.count = values.get('count')
63-
self.items = map(lambda x: OpenTokArchive(self, x), values.get('items', []))
64-
65-
def __iter__(self):
66-
for x in self.items:
67-
yield x
68-
69-
def attrs(self):
70-
return {
71-
'count': self.count,
72-
'items': map(OpenTokArchive.attrs, self.items)
73-
}
74-
75-
def json(self):
76-
return json.dumps(self.attrs(), default=dthandler, indent=4)
77-
78-
7930
class OpenTok(object):
8031
"""Use this SDK to create tokens and interface with the server-side portion
8132
of the Opentok API.
@@ -221,7 +172,7 @@ def session_url(self):
221172
return url
222173

223174
def archive_url(self, archive_id=None):
224-
url = OpenTok.API_URL + '/v2/partner/' + self.api_key + '/archive'
175+
url = self.api_url + '/v2/partner/' + self.api_key + '/archive'
225176
if archive_id:
226177
url = url + '/' + archive_id
227178
return url
@@ -232,7 +183,7 @@ def start_archive(self, session_id, **kwargs):
232183
response = requests.post(self.archive_url(), data=json.dumps(payload), headers=self.archive_headers())
233184

234185
if response.status_code < 300:
235-
return OpenTokArchive(self, response.json())
186+
return Archive(self, response.json())
236187
elif response.status_code == 403:
237188
raise AuthError()
238189
elif response.status_code == 400:
@@ -248,7 +199,7 @@ def stop_archive(self, archive_id):
248199
response = requests.post(self.archive_url(archive_id) + '/stop', headers=self.archive_headers())
249200

250201
if response.status_code < 300:
251-
return OpenTokArchive(self, response.json())
202+
return Archive(self, response.json())
252203
elif response.status_code == 403:
253204
raise AuthError()
254205
elif response.status_code == 404:
@@ -274,7 +225,7 @@ def get_archive(self, archive_id):
274225
response = requests.get(self.archive_url(archive_id), headers=self.archive_headers())
275226

276227
if response.status_code < 300:
277-
return OpenTokArchive(self, response.json())
228+
return Archive(self, response.json())
278229
elif response.status_code == 403:
279230
raise AuthError()
280231
elif response.status_code == 404:
@@ -292,7 +243,7 @@ def get_archives(self, offset=None, count=None):
292243
response = requests.get(self.archive_url() + "?" + urlencode(params), headers=self.archive_headers())
293244

294245
if response.status_code < 300:
295-
return OpenTokArchiveList(response.json())
246+
return ArchiveList(response.json())
296247
elif response.status_code == 403:
297248
raise AuthError()
298249
elif response.status_code == 404:
@@ -302,3 +253,4 @@ def get_archives(self, offset=None, count=None):
302253

303254
def _sign_string(self, string, secret):
304255
return hmac.new(secret.encode('utf-8'), string.encode('utf-8'), hashlib.sha1).hexdigest()
256+

tests/test_archive_api.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import unittest
2+
from six import text_type, u, b, PY2, PY3
3+
from nose.tools import raises
4+
from sure import expect
5+
import httpretty
6+
import textwrap
7+
import json
8+
9+
from opentok import OpenTok, Archive, __version__
10+
11+
class OpenTokArchiveApiTest(unittest.TestCase):
12+
def setUp(self):
13+
self.api_key = u('123456')
14+
self.api_secret = u('1234567890abcdef1234567890abcdef1234567890')
15+
self.session_id = u('SESSIONID')
16+
# self.api_key = u('854511')
17+
# self.api_secret = u('***REMOVED***')
18+
# self.session_id = u('2_MX44NTQ1MTF-flR1ZSBOb3YgMTIgMDk6NDA6NTkgUFNUIDIwMTN-MC43NjU0Nzh-')
19+
self.opentok = OpenTok(self.api_key, self.api_secret)
20+
21+
@httpretty.activate
22+
def test_start_archive(self):
23+
httpretty.register_uri(httpretty.POST, u('https://api.opentok.com/v2/partner/{0}/archive').format(self.api_key),
24+
body=textwrap.dedent(u("""\
25+
{
26+
"createdAt" : 1395183243556,
27+
"duration" : 0,
28+
"id" : "30b3ebf1-ba36-4f5b-8def-6f70d9986fe9",
29+
"name" : "",
30+
"partnerId" : 123456,
31+
"reason" : "",
32+
"sessionId" : "SESSIONID",
33+
"size" : 0,
34+
"status" : "started",
35+
"url" : null
36+
}""")),
37+
status=200,
38+
content_type=u('application/json'))
39+
40+
archive = self.opentok.start_archive(self.session_id)
41+
#print(archive.json())
42+
43+
expect(httpretty.last_request().headers[u('x-tb-partner-auth')]).to.equal(self.api_key+u(':')+self.api_secret)
44+
expect(httpretty.last_request().headers[u('user-agent')]).to.contain(u('OpenTok-Python-SDK/')+__version__)
45+
expect(httpretty.last_request().headers[u('content-type')]).to.equal(u('application/json'))
46+
# non-deterministic json encoding. have to decode to test it properly
47+
if PY2:
48+
body = json.loads(httpretty.last_request().body)
49+
if PY3:
50+
body = json.loads(httpretty.last_request().body.decode('utf-8'))
51+
expect(body).to.have.key(u('name')).being.equal(None)
52+
expect(body).to.have.key(u('sessionId')).being.equal(u('SESSIONID'))
53+
expect(archive).to.be.an(Archive)
54+
expect(archive).to.have.property(u('id')).being.equal(u('30b3ebf1-ba36-4f5b-8def-6f70d9986fe9'))
55+
expect(archive).to.have.property(u('name')).being.equal(u(''))
56+
expect(archive).to.have.property(u('status')).being.equal(u('started'))
57+
expect(archive).to.have.property(u('session_id')).being.equal(u('SESSIONID'))
58+
expect(archive).to.have.property(u('partner_id')).being.equal(123456)
59+
#expect(archive).to.have.property(u('created_at')).being.equal(None)
60+
expect(archive).to.have.property(u('size')).being.equal(0)
61+
expect(archive).to.have.property(u('duration')).being.equal(0)
62+
expect(archive).to.have.property(u('url')).being.equal(None)

tests/test_session_creation.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ class OpenTokSessionCreationTest(unittest.TestCase):
1111
def setUp(self):
1212
self.api_key = u('123456')
1313
self.api_secret = u('1234567890abcdef1234567890abcdef1234567890')
14-
# self.api_key = u('854511')
15-
# self.api_secret = u('***REMOVED***')
1614
self.opentok = OpenTok(self.api_key, self.api_secret)
1715

1816
@httpretty.activate

0 commit comments

Comments
 (0)