Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F7172195
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
32 KB
Referenced Files
None
Subscribers
None
View Options
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
Details
Attached
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)
Attached To
Mode
rSYLK SylkServer
Attached
Detach File
Event Timeline
Log In to Comment