Page MenuHomePhabricator

No OneTemporary

diff --git a/sylk/applications/webrtcgateway/models/jsonobjects.py b/sylk/applications/webrtcgateway/models/jsonobjects.py
index d19e381..9685d61 100644
--- a/sylk/applications/webrtcgateway/models/jsonobjects.py
+++ b/sylk/applications/webrtcgateway/models/jsonobjects.py
@@ -1,498 +1,525 @@
class Validator(object):
def validate(self, value):
"""Check value and raise ValueError if invalid, else return the (possibly modified) value"""
return value
class CompositeValidator(Validator):
def __init__(self, *validators):
if len(validators) < 2:
raise TypeError('need at least two validators to create a CompositeValidator')
if not all(isinstance(validator, Validator) for validator in validators):
raise ValueError('validators need to be Validator instances')
self.validators = validators
def validate(self, value):
for validator in self.validators:
value = validator.validate(value)
return value
class MultiType(tuple):
"""
A collection of types for which isinstance(obj, multi_type) returns True if 'obj'
is an instance of any of the types in the multi_type.
Instantiating the multi_type will instantiate the first type in the multi_type.
"""
# noinspection PyArgumentList
def __new__(cls, *args):
if not args:
raise ValueError('{.__name__} must have at least one type'.format(cls))
instance = super(MultiType, cls).__new__(cls, args)
instance.__name__ = ', '.join(cls.__name__ for cls in args)
instance.main_type = args[0]
return instance
def __call__(self, value):
return self.main_type(value)
class AbstractProperty(object):
data_type = object
container = False
def __init__(self, optional=False, default=None, validator=None):
if validator is not None and not isinstance(validator, Validator):
raise TypeError('validator should be a Validator instance or None')
self.default = default
self.optional = optional
self.validator = validator
self.name = None # will be set by the JSONObjectType metaclass when associating properties with objects
def __get__(self, instance, owner):
if instance is None:
return self
return instance.__dict__.get(self.name, self.default) # mandatory properties are guaranteed to be present, only optional ones can be missing
def __set__(self, instance, value):
if value is None and self.optional:
instance.__dict__[self.name] = None
else:
instance.__dict__[self.name] = self._parse(value)
def __delete__(self, instance):
if not self.optional:
raise AttributeError('Cannot delete mandatory property {property.name!r} of object {instance.__class__.__name__!r}'.format(instance=instance, property=self))
try:
del instance.__dict__[self.name]
except KeyError:
raise AttributeError(self.name)
def _parse(self, value):
if not isinstance(value, self.data_type):
raise ValueError('Invalid value for {property.name!r} property: {value!r}'.format(property=self, value=value))
if self.validator is not None:
value = self.validator.validate(value)
return value
class BooleanProperty(AbstractProperty):
data_type = bool
class IntegerProperty(AbstractProperty):
data_type = int, long
class NumberProperty(AbstractProperty):
data_type = int, long, float
class StringProperty(AbstractProperty):
data_type = str, unicode
+class FixedValueProperty(AbstractProperty):
+ def __init__(self, value):
+ super(FixedValueProperty, self).__init__(optional=True, default=value)
+ self.value = value
+
+ def _parse(self, value):
+ if value != self.value:
+ raise ValueError('Invalid value for {property.name!r} property: {value!r} (should be {property.value!r})'.format(property=self, value=value))
+ return value
+
+
+class LimitedChoiceProperty(AbstractProperty):
+ def __init__(self, values, optional=False, default=None):
+ if not values:
+ raise ValueError('values needs to be an non-empty sequence of elements')
+ if optional and default is not None and default not in values:
+ raise ValueError('default value needs to be one of the allowed values or None')
+ super(LimitedChoiceProperty, self).__init__(optional=optional, default=default)
+ self.values = frozenset(values)
+ self.values_string = ' or '.join(', '.join(sorted(values)).rsplit(', ', 1))
+
+ def _parse(self, value):
+ if value not in self.values:
+ raise ValueError('Invalid value for {property.name!r} property: {value!r} (expected: {property.values_string})'.format(property=self, value=value))
+ return value
+
+
class ArrayProperty(AbstractProperty):
data_type = list, tuple
container = True
def __init__(self, array_type, optional=False):
if not issubclass(array_type, JSONArray):
raise TypeError('array_type should be a subclass of JSONArray')
super(ArrayProperty, self).__init__(optional=optional, default=None, validator=None)
self.array_type = array_type
def _parse(self, value):
if type(value) is self.array_type:
return value
elif isinstance(value, self.data_type):
return self.array_type(value)
else:
raise ValueError('Invalid value for {property.name!r} property: {value!r}'.format(property=self, value=value))
class ObjectProperty(AbstractProperty):
data_type = dict
container = True
def __init__(self, object_type, optional=False):
if not issubclass(object_type, JSONObject):
raise TypeError('object_type should be a subclass of JSONObject')
super(ObjectProperty, self).__init__(optional=optional, default=None, validator=None)
self.object_type = object_type
def _parse(self, value):
if type(value) is self.object_type:
return value
elif isinstance(value, self.data_type):
return self.object_type(**value)
else:
raise ValueError('Invalid value for {property.name!r} property: {value!r}'.format(property=self, value=value))
class PropertyContainer(object):
def __init__(self, cls):
self.__dict__.update({item.name: item for cls in reversed(cls.__mro__) for item in cls.__dict__.itervalues() if isinstance(item, AbstractProperty)})
def __getitem__(self, name):
return self.__dict__[name]
def __contains__(self, name):
return name in self.__dict__
def __iter__(self):
return self.__dict__.itervalues()
@property
def names(self):
return set(self.__dict__)
class JSONObjectType(type):
# noinspection PyShadowingBuiltins
def __init__(cls, name, bases, dictionary):
super(JSONObjectType, cls).__init__(name, bases, dictionary)
for name, property in ((name, item) for name, item in dictionary.iteritems() if isinstance(item, AbstractProperty)):
property.name = name
cls.__properties__ = PropertyContainer(cls)
class JSONObject(object):
__metaclass__ = JSONObjectType
# noinspection PyShadowingBuiltins
def __init__(self, **data):
for property in self.__properties__:
if property.name in data:
property.__set__(self, data[property.name])
elif not property.optional:
raise ValueError('Mandatory property {property.name!r} of {object.__class__.__name__!r} object is missing'.format(property=property, object=self))
# noinspection PyShadowingBuiltins
@property
def __data__(self):
data = {}
for property in self.__properties__:
value = self.__dict__.get(property.name, property.default)
if value is not None:
data[property.name] = value.__data__ if property.container else value
elif property.name in self.__dict__:
data[property.name] = None
return data
def __contains__(self, name):
return name in self.__properties__
class ArrayParser(object):
def __init__(self, cls):
self.item_type = MultiType(*cls.item_type) if isinstance(cls.item_type, (list, tuple)) else cls.item_type
self.item_validator = cls.item_validator # this is only used for primitive item types
if isinstance(self.item_type, JSONObjectType):
self.parse_item = self.__parse_object_item
self.parse_list = self.__parse_object_list
elif isinstance(self.item_type, JSONArrayType):
self.parse_item = self.__parse_array_item
self.parse_list = self.__parse_array_list
else:
self.parse_item = self.__parse_primitive_item
self.parse_list = self.__parse_primitive_list
def __parse_primitive_item(self, item):
if not isinstance(item, self.item_type):
raise ValueError('Invalid value for {type.__name__}: {item!r}'.format(type=self.item_type, item=item))
if self.item_validator is not None:
item = self.item_validator.validate(item)
return item
def __parse_primitive_list(self, iterable):
item_type = self.item_type
for item in iterable:
if not isinstance(item, item_type):
raise ValueError('Invalid value for {type.__name__}: {item!r}'.format(type=item_type, item=item))
if self.item_validator is not None: # note: can be optimized by moving this test outside the loop (not sure if the decreased readability is worth it)
item = self.item_validator.validate(item)
yield item
def __parse_array_item(self, item):
try:
return item if type(item) is self.item_type else self.item_type(item)
except TypeError:
raise ValueError('Invalid value for {type.__name__}: {item!r}'.format(type=self.item_type, item=item))
def __parse_array_list(self, iterable):
item_type = self.item_type
for item in iterable:
try:
yield item if type(item) is item_type else item_type(item)
except TypeError:
raise ValueError('Invalid value for {type.__name__}: {item!r}'.format(type=item_type, item=item))
def __parse_object_item(self, item):
try:
return item if type(item) is self.item_type else self.item_type(**item)
except TypeError:
raise ValueError('Invalid value for {type.__name__}: {item!r}'.format(type=self.item_type, item=item))
def __parse_object_list(self, iterable):
item_type = self.item_type
for item in iterable:
try:
yield item if type(item) is item_type else item_type(**item)
except TypeError:
raise ValueError('Invalid value for {type.__name__}: {item!r}'.format(type=item_type, item=item))
class JSONArrayType(type):
item_type = object
item_validator = None
list_validator = None
def __init__(cls, name, bases, dictionary):
super(JSONArrayType, cls).__init__(name, bases, dictionary)
if cls.item_validator is not None and isinstance(cls.item_type, (JSONArrayType, JSONObjectType)):
raise TypeError('item_validator is not used for JSONArray and JSONObject item types as they have their own validators')
if cls.item_validator is not None and not isinstance(cls.item_validator, Validator):
raise TypeError('item_validator should be a Validator instance or None')
if cls.list_validator is not None and not isinstance(cls.list_validator, Validator):
raise TypeError('list_validator should be a Validator instance or None')
cls.parser = ArrayParser(cls)
class JSONArray(object):
__metaclass__ = JSONArrayType
item_type = object
item_validator = None # this should only be defined for primitive item types
list_validator = None
def __init__(self, iterable):
if isinstance(iterable, basestring): # prevent iterable primitive types from being interpreted as arrays
raise ValueError('Invalid value for {.__class__.__name__}: {!r}'.format(self, iterable))
items = list(self.parser.parse_list(iterable))
if self.list_validator is not None:
items = self.list_validator.validate(items)
self.__items__ = items
@property
def __data__(self):
return [item.__data__ for item in self.__items__] if isinstance(self.item_type, (JSONArrayType, JSONObjectType)) else self.__items__[:]
def __repr__(self):
return '{0.__class__.__name__}({0.__items__!r})'.format(self)
def __contains__(self, item):
return item in self.__items__
def __iter__(self):
return iter(self.__items__)
def __len__(self):
return len(self.__items__)
def __reversed__(self):
return reversed(self.__items__)
__hash__ = None
def __getitem__(self, index):
return self.__items__[index]
def __setitem__(self, index, value):
value = self.parser.parse_item(value)
if self.list_validator is not None:
clone = self.__items__[:]
clone[index] = value
self.__items__ = self.list_validator.validate(clone)
else:
self.__items__[index] = value
def __delitem__(self, index):
if self.list_validator is not None:
clone = self.__items__[:]
del clone[index]
self.__items__ = self.list_validator.validate(clone)
else:
del self.__items__[index]
def __getslice__(self, i, j):
return self.__items__[i:j]
def __setslice__(self, i, j, sequence):
sequence = list(self.parser.parse_list(sequence))
if self.list_validator is not None:
clone = self.__items__[:]
clone[i:j] = sequence
self.__items__ = self.list_validator.validate(clone)
else:
self.__items__[i:j] = sequence
def __delslice__(self, i, j):
if self.list_validator is not None:
clone = self.__items__[:]
del clone[i:j]
self.__items__ = self.list_validator.validate(clone)
else:
del self.__items__[i:j]
def __add__(self, other):
if isinstance(other, JSONArray):
return self.__class__(self.__items__ + other.__items__)
else:
return self.__class__(self.__items__ + other)
def __radd__(self, other):
if isinstance(other, JSONArray):
return self.__class__(other.__items__ + self.__items__)
else:
return self.__class__(other + self.__items__)
def __iadd__(self, other):
if isinstance(other, JSONArray) and self.item_type == other.item_type:
items = other.__items__
else:
items = list(self.parser.parse_list(other))
if self.list_validator is not None:
clone = self.__items__[:]
clone += items
self.__items__ = self.list_validator.validate(clone)
else:
self.__items__ += items
return self
def __mul__(self, n):
return self.__class__(self.__items__ * n)
def __rmul__(self, n):
return self.__class__(self.__items__ * n)
def __imul__(self, n):
if self.list_validator is not None:
self.__items__ = self.list_validator.validate(n * self.__items__)
else:
self.__items__ *= n
return self
def __eq__(self, other):
return self.__items__ == other.__items__ if isinstance(other, JSONArray) else self.__items__ == other
def __ne__(self, other):
return self.__items__ != other.__items__ if isinstance(other, JSONArray) else self.__items__ != other
def __lt__(self, other):
return self.__items__ < other.__items__ if isinstance(other, JSONArray) else self.__items__ < other
def __le__(self, other):
return self.__items__ <= other.__items__ if isinstance(other, JSONArray) else self.__items__ <= other
def __gt__(self, other):
return self.__items__ > other.__items__ if isinstance(other, JSONArray) else self.__items__ > other
def __ge__(self, other):
return self.__items__ >= other.__items__ if isinstance(other, JSONArray) else self.__items__ >= other
def __format__(self, format_spec):
return self.__items__.__format__(format_spec)
def index(self, value, *args):
return self.__items__.index(value, *args)
def count(self, value):
return self.__items__.count(value)
def append(self, value):
value = self.parser.parse_item(value)
if self.list_validator is not None:
clone = self.__items__[:]
clone.append(value)
self.__items__ = self.list_validator.validate(clone)
else:
self.__items__.append(value)
def insert(self, index, value):
value = self.parser.parse_item(value)
if self.list_validator is not None:
clone = self.__items__[:]
clone.insert(index, value)
self.__items__ = self.list_validator.validate(clone)
else:
self.__items__.insert(index, value)
def extend(self, other):
if isinstance(other, JSONArray) and self.item_type == other.item_type:
items = other.__items__
else:
items = list(self.parser.parse_list(other))
if self.list_validator is not None:
clone = self.__items__[:]
clone.extend(items)
self.__items__ = self.list_validator.validate(clone)
else:
self.__items__.extend(items)
def pop(self, index=-1):
if self.list_validator is not None:
clone = self.__items__[:]
clone.pop(index)
self.__items__ = self.list_validator.validate(clone)
else:
self.__items__.pop(index)
def remove(self, value):
if self.list_validator is not None:
clone = self.__items__[:]
clone.remove(value)
self.__items__ = self.list_validator.validate(clone)
else:
self.__items__.remove(value)
def reverse(self):
if self.list_validator is not None:
clone = self.__items__[:]
clone.reverse()
self.__items__ = self.list_validator.validate(clone)
else:
self.__items__.reverse()
def sort(self, key=None, reverse=False):
if self.list_validator is not None:
clone = self.__items__[:]
clone.sort(key=key, reverse=reverse)
self.__items__ = self.list_validator.validate(clone)
else:
self.__items__.sort(key=key, reverse=reverse)
class BooleanArray(JSONArray):
item_type = bool
class IntegerArray(JSONArray):
item_type = int, long
class NumberArray(JSONArray):
item_type = int, long, float
class StringArray(JSONArray):
item_type = str, unicode
class ArrayOf(object):
def __new__(cls, item_type, name='GenericArray', item_validator=None, list_validator=None):
return JSONArrayType(name, (JSONArray,), dict(item_type=item_type, item_validator=item_validator, list_validator=list_validator))
JSONList = JSONArray
BooleanList = BooleanArray
IntegerList = IntegerArray
NumberList = NumberArray
StringList = StringArray
ListOf = ArrayOf
diff --git a/sylk/applications/webrtcgateway/models/sylkrtc.py b/sylk/applications/webrtcgateway/models/sylkrtc.py
index 625fe1d..bb998fb 100644
--- a/sylk/applications/webrtcgateway/models/sylkrtc.py
+++ b/sylk/applications/webrtcgateway/models/sylkrtc.py
@@ -1,424 +1,395 @@
from application.python import subclasses
from sipsimple.core import SIPURI, SIPCoreError
from .jsonobjects import Validator, CompositeValidator
-from .jsonobjects import JSONObject, AbstractProperty, BooleanProperty, IntegerProperty, StringProperty, ArrayProperty, ObjectProperty
+from .jsonobjects import JSONObject, BooleanProperty, IntegerProperty, StringProperty, ArrayProperty, ObjectProperty, FixedValueProperty
from .jsonobjects import JSONArray, StringArray
# Validators
class AORValidator(Validator):
def validate(self, value):
prefix, sep, suffix = value.partition(':')
if sep and prefix in ('sip', 'sips'):
aor = suffix
else:
aor = value
try:
SIPURI.parse('sip:' + aor)
except SIPCoreError:
raise ValueError('invalid SIP URI: {}'.format(value))
return aor
class URIValidator(Validator):
def validate(self, value):
prefix, sep, suffix = value.partition(':')
if sep and prefix in ('sip', 'sips'):
uri = 'sip:' + suffix
else:
uri = 'sip:' + value
try:
SIPURI.parse(uri)
except SIPCoreError:
raise ValueError('invalid SIP URI: {}'.format(value))
return uri
class UniqueItemsValidator(Validator):
def validate(self, sequence):
seen = set()
unique = []
for item in sequence:
if item not in seen:
seen.add(item)
unique.append(item)
return unique
class LengthValidator(Validator):
def __init__(self, minimum=0, maximum=float('inf')):
self.minimum = minimum
self.maximum = maximum
def validate(self, value):
if self.minimum <= len(value) <= self.maximum:
return value
else:
raise ValueError("the value's length must be between {0.minimum} and {0.maximum} inclusive".format(self))
-# Custom JSONObject properties
-
-class FixedValueProperty(AbstractProperty):
- def __init__(self, value):
- super(FixedValueProperty, self).__init__(optional=True, default=value)
- self.value = value
-
- def _parse(self, value):
- if value != self.value:
- raise ValueError('Invalid value for {property.name!r} property: {value!r} (should be {property.value!r})'.format(property=self, value=value))
- return value
-
-
-class LimitedChoiceProperty(AbstractProperty):
- def __init__(self, values, optional=False, default=None):
- if not values:
- raise ValueError('values needs to be an non-empty sequence of elements')
- if optional and default is not None and default not in values:
- raise ValueError('default value needs to be one of the allowed values or None')
- super(LimitedChoiceProperty, self).__init__(optional=optional, default=default)
- self.values = frozenset(values)
- self.values_string = ' or '.join(', '.join(sorted(values)).rsplit(', ', 1))
-
- def _parse(self, value):
- if value not in self.values:
- raise ValueError('Invalid value for {property.name!r} property: {value!r} (expected: {property.values_string})'.format(property=self, value=value))
- return value
-
-
# Base models (these are abstract and should not be used directly)
class SylkRTCRequestBase(JSONObject):
transaction = StringProperty()
class SylkRTCResponseBase(JSONObject):
transaction = StringProperty()
class AccountRequestBase(SylkRTCRequestBase):
account = StringProperty(validator=AORValidator())
class SessionRequestBase(SylkRTCRequestBase):
session = StringProperty()
class VideoroomRequestBase(SylkRTCRequestBase):
session = StringProperty()
class AccountEventBase(JSONObject):
sylkrtc = FixedValueProperty('account-event')
account = StringProperty(validator=AORValidator())
class SessionEventBase(JSONObject):
sylkrtc = FixedValueProperty('session-event')
session = StringProperty()
class VideoroomEventBase(JSONObject):
sylkrtc = FixedValueProperty('videoroom-event')
session = StringProperty()
class AccountRegistrationStateEvent(AccountEventBase):
event = FixedValueProperty('registration-state')
class SessionStateEvent(SessionEventBase):
event = FixedValueProperty('state')
class VideoroomSessionStateEvent(VideoroomEventBase):
event = FixedValueProperty('session-state')
# Miscellaneous models
class SIPIdentity(JSONObject):
uri = StringProperty(validator=AORValidator())
display_name = StringProperty(optional=True)
class ICECandidate(JSONObject):
candidate = StringProperty()
sdpMLineIndex = IntegerProperty()
sdpMid = StringProperty()
class ICECandidates(JSONArray):
item_type = ICECandidate
class AORList(StringArray):
list_validator = UniqueItemsValidator()
item_validator = AORValidator()
class VideoroomPublisher(JSONObject):
id = StringProperty()
uri = StringProperty(validator=AORValidator())
display_name = StringProperty(optional=True)
class VideoroomPublishers(JSONArray):
item_type = VideoroomPublisher
class VideoroomActiveParticipants(StringArray):
list_validator = CompositeValidator(UniqueItemsValidator(), LengthValidator(maximum=2))
class VideoroomSessionOptions(JSONObject):
audio = BooleanProperty(optional=True)
video = BooleanProperty(optional=True)
bitrate = IntegerProperty(optional=True)
# Response models
class AckResponse(SylkRTCResponseBase):
sylkrtc = FixedValueProperty('ack')
class ErrorResponse(SylkRTCResponseBase):
sylkrtc = FixedValueProperty('error')
error = StringProperty()
# Connection events
class ReadyEvent(JSONObject):
sylkrtc = FixedValueProperty('ready-event')
# Account events
class AccountIncomingSessionEvent(AccountEventBase):
event = FixedValueProperty('incoming-session')
session = StringProperty()
originator = ObjectProperty(SIPIdentity)
sdp = StringProperty()
class AccountMissedSessionEvent(AccountEventBase):
event = FixedValueProperty('missed-session')
originator = ObjectProperty(SIPIdentity)
class AccountConferenceInviteEvent(AccountEventBase):
event = FixedValueProperty('conference-invite')
room = StringProperty(validator=AORValidator())
originator = ObjectProperty(SIPIdentity)
class AccountRegisteringEvent(AccountRegistrationStateEvent):
state = FixedValueProperty('registering')
class AccountRegisteredEvent(AccountRegistrationStateEvent):
state = FixedValueProperty('registered')
class AccountRegistrationFailedEvent(AccountRegistrationStateEvent):
state = FixedValueProperty('failed')
reason = StringProperty(optional=True)
# Session events
class SessionProgressEvent(SessionStateEvent):
state = FixedValueProperty('progress')
class SessionAcceptedEvent(SessionStateEvent):
state = FixedValueProperty('accepted')
sdp = StringProperty(optional=True) # missing for incoming sessions
class SessionEstablishedEvent(SessionStateEvent):
state = FixedValueProperty('established')
class SessionTerminatedEvent(SessionStateEvent):
state = FixedValueProperty('terminated')
reason = StringProperty(optional=True)
# Video room events
class VideoroomConfigureEvent(VideoroomEventBase):
event = FixedValueProperty('configure')
originator = StringProperty()
active_participants = ArrayProperty(VideoroomActiveParticipants)
class VideoroomSessionProgressEvent(VideoroomSessionStateEvent):
state = FixedValueProperty('progress')
class VideoroomSessionAcceptedEvent(VideoroomSessionStateEvent):
state = FixedValueProperty('accepted')
sdp = StringProperty()
class VideoroomSessionEstablishedEvent(VideoroomSessionStateEvent):
state = FixedValueProperty('established')
class VideoroomSessionTerminatedEvent(VideoroomSessionStateEvent):
state = FixedValueProperty('terminated')
reason = StringProperty(optional=True)
class VideoroomFeedAttachedEvent(VideoroomEventBase):
event = FixedValueProperty('feed-attached')
feed = StringProperty()
sdp = StringProperty()
class VideoroomFeedEstablishedEvent(VideoroomEventBase):
event = FixedValueProperty('feed-established')
feed = StringProperty()
class VideoroomInitialPublishersEvent(VideoroomEventBase):
event = FixedValueProperty('initial-publishers')
publishers = ArrayProperty(VideoroomPublishers)
class VideoroomPublishersJoinedEvent(VideoroomEventBase):
event = FixedValueProperty('publishers-joined')
publishers = ArrayProperty(VideoroomPublishers)
class VideoroomPublishersLeftEvent(VideoroomEventBase):
event = FixedValueProperty('publishers-left')
publishers = ArrayProperty(StringArray)
# Account request models
class AccountAddRequest(AccountRequestBase):
sylkrtc = FixedValueProperty('account-add')
password = StringProperty(validator=LengthValidator(minimum=1, maximum=9999))
display_name = StringProperty(optional=True)
user_agent = StringProperty(optional=True)
class AccountRemoveRequest(AccountRequestBase):
sylkrtc = FixedValueProperty('account-remove')
class AccountRegisterRequest(AccountRequestBase):
sylkrtc = FixedValueProperty('account-register')
class AccountUnregisterRequest(AccountRequestBase):
sylkrtc = FixedValueProperty('account-unregister')
class AccountDeviceTokenRequest(AccountRequestBase):
sylkrtc = FixedValueProperty('account-devicetoken')
old_token = StringProperty(optional=True)
new_token = StringProperty(optional=True)
# Session request models
class SessionCreateRequest(SessionRequestBase):
sylkrtc = FixedValueProperty('session-create')
account = StringProperty(validator=AORValidator())
uri = StringProperty(validator=AORValidator())
sdp = StringProperty()
class SessionAnswerRequest(SessionRequestBase):
sylkrtc = FixedValueProperty('session-answer')
sdp = StringProperty()
class SessionTrickleRequest(SessionRequestBase):
sylkrtc = FixedValueProperty('session-trickle')
candidates = ArrayProperty(ICECandidates)
class SessionTerminateRequest(SessionRequestBase):
sylkrtc = FixedValueProperty('session-terminate')
# Videoroom request models
class VideoroomJoinRequest(VideoroomRequestBase):
sylkrtc = FixedValueProperty('videoroom-join')
account = StringProperty(validator=AORValidator())
uri = StringProperty(validator=AORValidator())
sdp = StringProperty()
class VideoroomLeaveRequest(VideoroomRequestBase):
sylkrtc = FixedValueProperty('videoroom-leave')
class VideoroomConfigureRequest(VideoroomRequestBase):
sylkrtc = FixedValueProperty('videoroom-configure')
active_participants = ArrayProperty(VideoroomActiveParticipants)
class VideoroomFeedAttachRequest(VideoroomRequestBase):
sylkrtc = FixedValueProperty('videoroom-feed-attach')
publisher = StringProperty()
feed = StringProperty()
class VideoroomFeedAnswerRequest(VideoroomRequestBase):
sylkrtc = FixedValueProperty('videoroom-feed-answer')
feed = StringProperty()
sdp = StringProperty()
class VideoroomFeedDetachRequest(VideoroomRequestBase):
sylkrtc = FixedValueProperty('videoroom-feed-detach')
feed = StringProperty()
class VideoroomInviteRequest(VideoroomRequestBase):
sylkrtc = FixedValueProperty('videoroom-invite')
participants = ArrayProperty(AORList)
class VideoroomSessionTrickleRequest(VideoroomRequestBase):
sylkrtc = FixedValueProperty('videoroom-session-trickle')
candidates = ArrayProperty(ICECandidates)
class VideoroomSessionUpdateRequest(VideoroomRequestBase):
sylkrtc = FixedValueProperty('videoroom-session-update')
options = ObjectProperty(VideoroomSessionOptions)
# SylkRTC request to model mapping
class ProtocolError(Exception):
pass
class SylkRTCRequest(object):
__classmap__ = {cls.sylkrtc.value: cls for cls in subclasses(SylkRTCRequestBase) if hasattr(cls, 'sylkrtc')}
@classmethod
def from_message(cls, message):
try:
request_type = message['sylkrtc']
except KeyError:
raise ProtocolError('could not get WebSocket message type')
try:
request_class = cls.__classmap__[request_type]
except KeyError:
raise ProtocolError('unknown WebSocket request: %s' % request_type)
return request_class(**message)

File Metadata

Mime Type
text/x-diff
Expires
Tue, Nov 26, 7:44 AM (1 d, 22 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3414536
Default Alt Text
(32 KB)

Event Timeline