coding standards

This commit is contained in:
Yann Leboulanger 2009-09-16 20:41:12 +02:00
parent af44ee0840
commit 11c7de6c34

View file

@ -85,26 +85,27 @@ class JingleSession(object):
''' This represents one jingle session. ''' ''' This represents one jingle session. '''
def __init__(self, con, weinitiate, jid, sid=None): def __init__(self, con, weinitiate, jid, sid=None):
''' con -- connection object, ''' con -- connection object,
weinitiate -- boolean, are we the initiator? weinitiate -- boolean, are we the initiator?
jid - jid of the other entity''' jid - jid of the other entity'''
self.contents={} # negotiated contents self.contents = {} # negotiated contents
self.connection=con # connection to use self.connection = con # connection to use
# our full jid # our full jid
self.ourjid=gajim.get_jid_from_account(self.connection.name)+'/'+con.server_resource self.ourjid = gajim.get_jid_from_account(self.connection.name) + '/' + \
self.peerjid=jid # jid we connect to con.server_resource
self.peerjid = jid # jid we connect to
# jid we use as the initiator # jid we use as the initiator
self.initiator=weinitiate and self.ourjid or self.peerjid self.initiator = weinitiate and self.ourjid or self.peerjid
# jid we use as the responder # jid we use as the responder
self.responder=weinitiate and self.peerjid or self.ourjid self.responder = weinitiate and self.peerjid or self.ourjid
# are we an initiator? # are we an initiator?
self.weinitiate=weinitiate self.weinitiate = weinitiate
# what state is session in? (one from JingleStates) # what state is session in? (one from JingleStates)
self.state=JingleStates.ended self.state = JingleStates.ended
if not sid: if not sid:
sid=con.connection.getAnID() sid = con.connection.getAnID()
self.sid=sid # sessionid self.sid = sid # sessionid
self.accepted=True # is this session accepted by user self.accepted = True # is this session accepted by user
self.candidates_ready = False # True when local candidates are prepared self.candidates_ready = False # True when local candidates are prepared
# callbacks to call on proper contents # callbacks to call on proper contents
@ -118,10 +119,13 @@ class JingleSession(object):
'content-remove': [self.__defaultCB, self.__contentRemoveCB], 'content-remove': [self.__defaultCB, self.__contentRemoveCB],
'description-info': [self.__defaultCB], #TODO 'description-info': [self.__defaultCB], #TODO
'security-info': [self.__defaultCB], #TODO 'security-info': [self.__defaultCB], #TODO
'session-accept': [self.__sessionAcceptCB, self.__contentAcceptCB, self.__broadcastCB, self.__defaultCB], 'session-accept': [self.__sessionAcceptCB, self.__contentAcceptCB,
self.__broadcastCB, self.__defaultCB],
'session-info': [self.__sessionInfoCB, self.__broadcastCB], 'session-info': [self.__sessionInfoCB, self.__broadcastCB],
'session-initiate': [self.__sessionInitiateCB, self.__broadcastCB, self.__defaultCB], 'session-initiate': [self.__sessionInitiateCB, self.__broadcastCB,
'session-terminate': [self.__sessionTerminateCB, self.__broadcastAllCB, self.__defaultCB], self.__defaultCB],
'session-terminate': [self.__sessionTerminateCB, self.__broadcastAllCB,
self.__defaultCB],
'transport-info': [self.__broadcastCB, self.__defaultCB], 'transport-info': [self.__broadcastCB, self.__defaultCB],
'transport-replace': [self.__broadcastCB, self.__transportReplaceCB], #TODO 'transport-replace': [self.__broadcastCB, self.__transportReplaceCB], #TODO
'transport-accept': [self.__defaultCB], #TODO 'transport-accept': [self.__defaultCB], #TODO
@ -132,12 +136,14 @@ class JingleSession(object):
''' Interaction with user ''' ''' Interaction with user '''
def approveSession(self): def approveSession(self):
''' Called when user accepts session in UI (when we aren't the initiator).''' ''' Called when user accepts session in UI (when we aren't the initiator).
self.accepted=True '''
self.accepted = True
self.acceptSession() self.acceptSession()
def declineSession(self): def declineSession(self):
''' Called when user declines session in UI (when we aren't the initiator)''' ''' Called when user declines session in UI (when we aren't the initiator)
'''
reason = xmpp.Node('reason') reason = xmpp.Node('reason')
reason.addChild('decline') reason.addChild('decline')
self.__sessionTerminate(reason) self.__sessionTerminate(reason)
@ -151,18 +157,20 @@ class JingleSession(object):
Creator must be one of ('we', 'peer', 'initiator', 'responder')''' Creator must be one of ('we', 'peer', 'initiator', 'responder')'''
assert creator in ('we', 'peer', 'initiator', 'responder') assert creator in ('we', 'peer', 'initiator', 'responder')
if self.state==JingleStates.pending: if self.state == JingleStates.pending:
raise WrongState raise WrongState
if (creator=='we' and self.weinitiate) or (creator=='peer' and not self.weinitiate): if (creator == 'we' and self.weinitiate) or (creator == 'peer' and \
creator='initiator' not self.weinitiate):
elif (creator=='peer' and self.weinitiate) or (creator=='we' and not self.weinitiate): creator = 'initiator'
creator='responder' elif (creator == 'peer' and self.weinitiate) or (creator == 'we' and \
not self.weinitiate):
creator = 'responder'
content.creator = creator content.creator = creator
content.name = name content.name = name
self.contents[(creator,name)]=content self.contents[(creator,name)] = content
if self.state==JingleStates.active: if self.state == JingleStates.active:
pass # TODO: send proper stanza, shouldn't be needed now pass # TODO: send proper stanza, shouldn't be needed now
def removeContent(self, creator, name): def removeContent(self, creator, name):
@ -187,7 +195,7 @@ class JingleSession(object):
def sendSessionInfo(self): pass def sendSessionInfo(self): pass
def sendContentAccept(self, content): def sendContentAccept(self, content):
assert self.state!=JingleStates.ended assert self.state != JingleStates.ended
stanza, jingle = self.__makeJingle('content-accept') stanza, jingle = self.__makeJingle('content-accept')
jingle.addChild(node=content) jingle.addChild(node=content)
self.connection.connection.send(stanza) self.connection.connection.send(stanza)
@ -258,7 +266,7 @@ class JingleSession(object):
else: else:
stanza, jingle = self.__makeJingle('transport-reject') stanza, jingle = self.__makeJingle('transport-reject')
c = jingle.setTag('content', attrs={'creator': creator, c = jingle.setTag('content', attrs={'creator': creator,
'name': name}) 'name': name})
c.setTag('transport', namespace=transport_ns) c.setTag('transport', namespace=transport_ns)
self.connection.connection.send(stanza) self.connection.connection.send(stanza)
raise xmpp.NodeProcessed raise xmpp.NodeProcessed
@ -267,7 +275,7 @@ class JingleSession(object):
#For now, reject the transport #For now, reject the transport
stanza, jingle = self.__makeJingle('transport-reject') stanza, jingle = self.__makeJingle('transport-reject')
c = jingle.setTag('content', attrs={'creator': creator, c = jingle.setTag('content', attrs={'creator': creator,
'name': name}) 'name': name})
c.setTag('transport', namespace=transport_ns) c.setTag('transport', namespace=transport_ns)
self.connection.connection.send(stanza) self.connection.connection.send(stanza)
raise xmpp.NodeProcessed raise xmpp.NodeProcessed
@ -357,7 +365,8 @@ class JingleSession(object):
self.state = JingleStates.pending self.state = JingleStates.pending
# Send event about starting a session # Send event about starting a session
self.connection.dispatch('JINGLE_INCOMING', (self.initiator, self.sid, contents)) self.connection.dispatch('JINGLE_INCOMING', (self.initiator, self.sid,
contents))
def __broadcastCB(self, stanza, jingle, error, action): def __broadcastCB(self, stanza, jingle, error, action):
''' Broadcast the stanza contents to proper content handlers. ''' ''' Broadcast the stanza contents to proper content handlers. '''
@ -419,14 +428,14 @@ class JingleSession(object):
self.state=JingleStates.active self.state=JingleStates.active
def __sessionInfo(self, payload=None): def __sessionInfo(self, payload=None):
assert self.state!=JingleStates.ended assert self.state != JingleStates.ended
stanza, jingle = self.__makeJingle('session-info') stanza, jingle = self.__makeJingle('session-info')
if payload: if payload:
jingle.addChild(node=payload) jingle.addChild(node=payload)
self.connection.connection.send(stanza) self.connection.connection.send(stanza)
def __sessionTerminate(self, reason=None): def __sessionTerminate(self, reason=None):
assert self.state!=JingleStates.ended assert self.state != JingleStates.ended
stanza, jingle = self.__makeJingle('session-terminate') stanza, jingle = self.__makeJingle('session-terminate')
if reason is not None: if reason is not None:
jingle.addChild(node=reason) jingle.addChild(node=reason)
@ -435,16 +444,16 @@ class JingleSession(object):
self.connection.deleteJingle(self) self.connection.deleteJingle(self)
def __contentAdd(self): def __contentAdd(self):
assert self.state==JingleStates.active assert self.state == JingleStates.active
def __contentAccept(self): def __contentAccept(self):
assert self.state!=JingleStates.ended assert self.state != JingleStates.ended
def __contentModify(self): def __contentModify(self):
assert self.state!=JingleStates.ended assert self.state != JingleStates.ended
def __contentRemove(self): def __contentRemove(self):
assert self.state!=JingleStates.ended assert self.state != JingleStates.ended
class JingleTransport(object): class JingleTransport(object):
@ -469,7 +478,7 @@ class JingleContent(object):
self.senders = 'both' #FIXME self.senders = 'both' #FIXME
self.allow_sending = True # Used for stream direction, attribute 'senders' self.allow_sending = True # Used for stream direction, attribute 'senders'
self.callbacks = { self.callbacks = {
# these are called when *we* get stanzas # these are called when *we* get stanzas
'content-accept': [], 'content-accept': [],
'content-add': [], 'content-add': [],
@ -507,21 +516,21 @@ class JingleContent(object):
#cand.type = farsight.CANDIDATE_TYPE_LOCAL #cand.type = farsight.CANDIDATE_TYPE_LOCAL
cand.priority = int(candidate['priority']) cand.priority = int(candidate['priority'])
if candidate['protocol']=='udp': if candidate['protocol'] == 'udp':
cand.proto=farsight.NETWORK_PROTOCOL_UDP cand.proto=farsight.NETWORK_PROTOCOL_UDP
else: else:
# we actually don't handle properly different tcp options in jingle # we actually don't handle properly different tcp options in jingle
cand.proto=farsight.NETWORK_PROTOCOL_TCP cand.proto = farsight.NETWORK_PROTOCOL_TCP
cand.username = str(transport['ufrag']) cand.username = str(transport['ufrag'])
cand.password = str(transport['pwd']) cand.password = str(transport['pwd'])
#FIXME: huh? #FIXME: huh?
types = {'host': farsight.CANDIDATE_TYPE_HOST, types = {'host': farsight.CANDIDATE_TYPE_HOST,
'srflx': farsight.CANDIDATE_TYPE_SRFLX, 'srflx': farsight.CANDIDATE_TYPE_SRFLX,
'prflx': farsight.CANDIDATE_TYPE_PRFLX, 'prflx': farsight.CANDIDATE_TYPE_PRFLX,
'relay': farsight.CANDIDATE_TYPE_RELAY, 'relay': farsight.CANDIDATE_TYPE_RELAY,
'multicast': farsight.CANDIDATE_TYPE_MULTICAST} 'multicast': farsight.CANDIDATE_TYPE_MULTICAST}
if 'type' in candidate and candidate['type'] in types: if 'type' in candidate and candidate['type'] in types:
cand.type = types[candidate['type']] cand.type = types[candidate['type']]
candidates.append(cand) candidates.append(cand)
@ -538,10 +547,10 @@ class JingleContent(object):
def __candidate(self, candidate): def __candidate(self, candidate):
types = {farsight.CANDIDATE_TYPE_HOST: 'host', types = {farsight.CANDIDATE_TYPE_HOST: 'host',
farsight.CANDIDATE_TYPE_SRFLX: 'srlfx', farsight.CANDIDATE_TYPE_SRFLX: 'srlfx',
farsight.CANDIDATE_TYPE_PRFLX: 'prlfx', farsight.CANDIDATE_TYPE_PRFLX: 'prlfx',
farsight.CANDIDATE_TYPE_RELAY: 'relay', farsight.CANDIDATE_TYPE_RELAY: 'relay',
farsight.CANDIDATE_TYPE_MULTICAST: 'multicast'} farsight.CANDIDATE_TYPE_MULTICAST: 'multicast'}
attrs={ attrs={
'component': candidate.component_id, 'component': candidate.component_id,
'foundation': '1', # hack 'foundation': '1', # hack
@ -554,10 +563,10 @@ class JingleContent(object):
if candidate.type in types: if candidate.type in types:
attrs['type'] = types[candidate.type] attrs['type'] = types[candidate.type]
if candidate.proto==farsight.NETWORK_PROTOCOL_UDP: if candidate.proto==farsight.NETWORK_PROTOCOL_UDP:
attrs['protocol']='udp' attrs['protocol'] = 'udp'
else: else:
# we actually don't handle properly different tcp options in jingle # we actually don't handle properly different tcp options in jingle
attrs['protocol']='tcp' attrs['protocol'] = 'tcp'
return xmpp.Node('candidate', attrs=attrs) return xmpp.Node('candidate', attrs=attrs)
def iterCandidates(self): def iterCandidates(self):
@ -565,11 +574,11 @@ class JingleContent(object):
yield self.__candidate(candidate) yield self.__candidate(candidate)
def send_candidate(self, candidate): def send_candidate(self, candidate):
c=self.__content() c = self.__content()
t=c.addChild(xmpp.NS_JINGLE_ICE_UDP+' transport') t = c.addChild(xmpp.NS_JINGLE_ICE_UDP + ' transport')
if candidate.username: t['ufrag']=candidate.username if candidate.username: t['ufrag'] = candidate.username
if candidate.password: t['pwd']=candidate.password if candidate.password: t['pwd'] = candidate.password
t.addChild(node=self.__candidate(candidate)) t.addChild(node=self.__candidate(candidate))
self.session.sendTransportInfo(c) self.session.sendTransportInfo(c)
@ -578,14 +587,14 @@ class JingleContent(object):
''' Add our things to session-initiate stanza. ''' ''' Add our things to session-initiate stanza. '''
self._fillContent(content) self._fillContent(content)
if self.candidates and self.candidates[0].username and self.candidates[0].password: if self.candidates and self.candidates[0].username and \
self.candidates[0].password:
attrs = {'ufrag': self.candidates[0].username, attrs = {'ufrag': self.candidates[0].username,
'pwd': self.candidates[0].password} 'pwd': self.candidates[0].password}
else: else:
attrs = {} attrs = {}
content.addChild(xmpp.NS_JINGLE_ICE_UDP+' transport', attrs=attrs, content.addChild(xmpp.NS_JINGLE_ICE_UDP + ' transport', attrs=attrs,
payload=self.iterCandidates()) payload=self.iterCandidates())
class JingleRTPContent(JingleContent): class JingleRTPContent(JingleContent):
def __init__(self, session, media, node=None): def __init__(self, session, media, node=None):
@ -613,8 +622,8 @@ class JingleRTPContent(JingleContent):
self.funnel = None self.funnel = None
def _fillContent(self, content): def _fillContent(self, content):
content.addChild(xmpp.NS_JINGLE_RTP+' description', attrs={'media': self.media}, content.addChild(xmpp.NS_JINGLE_RTP + ' description',
payload=self.iterCodecs()) attrs={'media': self.media}, payload=self.iterCodecs())
def _on_gst_message(self, bus, message): def _on_gst_message(self, bus, message):
if message.type == gst.MESSAGE_ELEMENT: if message.type == gst.MESSAGE_ELEMENT:
@ -631,7 +640,8 @@ class JingleRTPContent(JingleContent):
elif name == 'farsight-new-local-candidate': elif name == 'farsight-new-local-candidate':
candidate = message.structure['candidate'] candidate = message.structure['candidate']
self.candidates.append(candidate) self.candidates.append(candidate)
if self.session.candidates_ready: #FIXME: Is this case even possible? if self.session.candidates_ready:
#FIXME: Is this case even possible?
self.send_candidate(candidate) self.send_candidate(candidate)
elif name == 'farsight-component-state-changed': elif name == 'farsight-component-state-changed':
state = message.structure['state'] state = message.structure['state']
@ -641,7 +651,8 @@ class JingleRTPContent(JingleContent):
#TODO: farsight.DIRECTION_BOTH only if senders='both' #TODO: farsight.DIRECTION_BOTH only if senders='both'
self.p2pstream.set_property('direction', farsight.DIRECTION_BOTH) self.p2pstream.set_property('direction', farsight.DIRECTION_BOTH)
#if not self.session.weinitiate: #FIXME: one more FIXME... #if not self.session.weinitiate: #FIXME: one more FIXME...
# self.session.sendContentAccept(self.__content((xmpp.Node('description', payload=self.iterCodecs()),))) # self.session.sendContentAccept(self.__content((xmpp.Node(
# 'description', payload=self.iterCodecs()),)))
elif name == 'farsight-error': elif name == 'farsight-error':
print 'Farsight error #%d!' % message.structure['error-no'] print 'Farsight error #%d!' % message.structure['error-no']
print 'Message: %s' % message.structure['error-msg'] print 'Message: %s' % message.structure['error-msg']
@ -656,30 +667,32 @@ class JingleRTPContent(JingleContent):
codecs = [] codecs = []
for codec in content.getTag('description').iterTags('payload-type'): for codec in content.getTag('description').iterTags('payload-type'):
c = farsight.Codec(int(codec['id']), codec['name'], c = farsight.Codec(int(codec['id']), codec['name'],
farsight.MEDIA_TYPE_AUDIO, int(codec['clockrate'])) farsight.MEDIA_TYPE_AUDIO, int(codec['clockrate']))
if 'channels' in codec: if 'channels' in codec:
c.channels = int(codec['channels']) c.channels = int(codec['channels'])
else: else:
c.channels = 1 c.channels = 1
c.optional_params = [(str(p['name']), str(p['value'])) for p in codec.iterTags('parameter')] c.optional_params = [(str(p['name']), str(p['value'])) for p in \
codec.iterTags('parameter')]
codecs.append(c) codecs.append(c)
if len(codecs)==0: return if len(codecs) == 0: return
#FIXME: Handle this case: #FIXME: Handle this case:
# glib.GError: There was no intersection between the remote codecs and the local ones # glib.GError: There was no intersection between the remote codecs and
# the local ones
self.p2pstream.set_remote_codecs(codecs) self.p2pstream.set_remote_codecs(codecs)
self.got_codecs=True self.got_codecs = True
def iterCodecs(self): def iterCodecs(self):
codecs=self.p2psession.get_property('codecs') codecs=self.p2psession.get_property('codecs')
for codec in codecs: for codec in codecs:
a = {'name': codec.encoding_name, a = {'name': codec.encoding_name,
'id': codec.id, 'id': codec.id,
'channels': codec.channels} 'channels': codec.channels}
if codec.clock_rate: a['clockrate']=codec.clock_rate if codec.clock_rate: a['clockrate']=codec.clock_rate
if codec.optional_params: if codec.optional_params:
p = (xmpp.Node('parameter', {'name': name, 'value': value}) p = (xmpp.Node('parameter', {'name': name, 'value': value})
for name, value in codec.optional_params) for name, value in codec.optional_params)
else: p = () else: p = ()
yield xmpp.Node('payload-type', a, p) yield xmpp.Node('payload-type', a, p)
@ -708,7 +721,7 @@ class JingleVoIP(JingleRTPContent):
# the network part # the network part
participant = self.conference.new_participant(self.session.peerjid) participant = self.conference.new_participant(self.session.peerjid)
params = {'controlling-mode': self.session.weinitiate,# 'debug': False} params = {'controlling-mode': self.session.weinitiate,# 'debug': False}
'stun-ip': '69.0.208.27', 'debug': False} 'stun-ip': '69.0.208.27', 'debug': False}
self.p2psession = self.conference.new_session(farsight.MEDIA_TYPE_AUDIO) self.p2psession = self.conference.new_session(farsight.MEDIA_TYPE_AUDIO)
@ -716,13 +729,13 @@ class JingleVoIP(JingleRTPContent):
#FIXME: codec ID is an important thing for psi (and pidgin?) #FIXME: codec ID is an important thing for psi (and pidgin?)
# So, if it doesn't work with pidgin or psi, LOOK AT THIS # So, if it doesn't work with pidgin or psi, LOOK AT THIS
codecs = [farsight.Codec(farsight.CODEC_ID_ANY, 'SPEEX', codecs = [farsight.Codec(farsight.CODEC_ID_ANY, 'SPEEX',
farsight.MEDIA_TYPE_AUDIO, 8000), farsight.MEDIA_TYPE_AUDIO, 8000),
farsight.Codec(farsight.CODEC_ID_ANY, 'SPEEX', farsight.Codec(farsight.CODEC_ID_ANY, 'SPEEX',
farsight.MEDIA_TYPE_AUDIO, 16000)] farsight.MEDIA_TYPE_AUDIO, 16000)]
self.p2psession.set_codec_preferences(codecs) self.p2psession.set_codec_preferences(codecs)
self.p2pstream = self.p2psession.new_stream(participant, farsight.DIRECTION_NONE, self.p2pstream = self.p2psession.new_stream(participant,
'nice', params) farsight.DIRECTION_NONE, 'nice', params)
# the local parts # the local parts
# TODO: use gconfaudiosink? # TODO: use gconfaudiosink?
@ -754,7 +767,8 @@ class JingleVoIP(JingleRTPContent):
self.funnel.link(sink) self.funnel.link(sink)
pad.link(self.funnel.get_pad('sink%d')) pad.link(self.funnel.get_pad('sink%d'))
self.mic_volume.get_pad('src').link(self.p2psession.get_property('sink-pad')) self.mic_volume.get_pad('src').link(self.p2psession.get_property(
'sink-pad'))
self.p2pstream.connect('src-pad-added', src_pad_added) self.p2pstream.connect('src-pad-added', src_pad_added)
# The following is needed for farsight to process ICE requests: # The following is needed for farsight to process ICE requests:
@ -775,7 +789,7 @@ class ConnectionJingle(object):
''' Add a jingle session to a jingle stanza dispatcher ''' Add a jingle session to a jingle stanza dispatcher
jingle - a JingleSession object. jingle - a JingleSession object.
''' '''
self.__sessions[(jingle.peerjid, jingle.sid)]=jingle self.__sessions[(jingle.peerjid, jingle.sid)] = jingle
def deleteJingle(self, jingle): def deleteJingle(self, jingle):
''' Remove a jingle session from a jingle stanza dispatcher ''' ''' Remove a jingle session from a jingle stanza dispatcher '''
@ -812,13 +826,14 @@ class ConnectionJingle(object):
raise xmpp.NodeProcessed raise xmpp.NodeProcessed
def addJingleIqCallback(self, jid, id, jingle): def addJingleIqCallback(self, jid, id, jingle):
self.__iq_responses[(jid, id)]=jingle self.__iq_responses[(jid, id)] = jingle
def startVoIP(self, jid): def startVoIP(self, jid):
jingle = JingleSession(self, weinitiate=True, jid=jid) jingle = JingleSession(self, weinitiate=True, jid=jid)
self.addJingle(jingle) self.addJingle(jingle)
jingle.addContent('voice', JingleVoIP(jingle)) jingle.addContent('voice', JingleVoIP(jingle))
jingle.startSession() jingle.startSession()
def getJingleSession(self, jid, sid): def getJingleSession(self, jid, sid):
try: try:
return self.__sessions[(jid, sid)] return self.__sessions[(jid, sid)]