Commit 8b3a82ff authored by steve-e's avatar steve-e

Merge changes from default branch into refactoring branch

parents 10428555 1c28dbfa
AC_INIT([Gajim - A Jabber Instant Messager],
[0.12.5.8-dev],[http://trac.gajim.org/],[gajim])
[0.13.0.1-dev],[http://trac.gajim.org/],[gajim])
AC_PREREQ([2.59])
AC_CONFIG_HEADER(config.h)
......
......@@ -98,6 +98,22 @@ class StandardChatCommands(CommandContainer):
raise CommandError(_('Command is not supported for zeroconf accounts'))
gajim.connections[self.account].sendPing(self.contact)
@command('dtmf')
@documentation(_("Sends DTMF events through an open audio session"))
def dtmf(self, events):
if not self.audio_sid:
raise CommandError(_("There is no open audio session with this contact"))
# Valid values for DTMF tones are *, # or a number
events = [event for event in events
if event in ('*', '#') or event.isdigit()]
if events:
session = gajim.connections[self.account].get_jingle_session(
self.contact.get_full_jid(), self.audio_sid)
content = session.get_content('audio')
content.batch_dtmf(events)
else:
raise CommandError(_("No valid DTMF event specified"))
@command('audio')
@documentation(_("Toggle audio session"))
def audio(self):
......
......@@ -37,8 +37,11 @@ import base64
import hashlib
from common.xmpp import NS_XHTML_IM, NS_RECEIPTS, NS_ESESSION, NS_CHATSTATES
from common.xmpp import NS_JINGLE_ICE_UDP, NS_JINGLE_RTP_AUDIO
from common.xmpp import NS_JINGLE_RTP_VIDEO
# Features where we cannot safely assume that the other side supports them
FEATURE_BLACKLIST = [NS_CHATSTATES, NS_XHTML_IM, NS_RECEIPTS, NS_ESESSION]
FEATURE_BLACKLIST = [NS_CHATSTATES, NS_XHTML_IM, NS_RECEIPTS, NS_ESESSION,
NS_JINGLE_ICE_UDP, NS_JINGLE_RTP_AUDIO, NS_JINGLE_RTP_VIDEO]
# Query entry status codes
NEW = 0
......
......@@ -207,6 +207,7 @@ class Contacts:
def change_account_name(self, old_name, new_name):
self._accounts[new_name] = self._accounts[old_name]
self._accounts[new_name].name = new_name
del self._accounts[old_name]
self._metacontact_manager.change_account_name(old_name, new_name)
......
This diff is collapsed.
##
## Copyright (C) 2006 Gajim Team
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published
## by the Free Software Foundation; version 2 only.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
''' Handles Jingle contents (XEP 0166). '''
contents = {}
def get_jingle_content(node):
namespace = node.getNamespace()
if namespace in contents:
return contents[namespace](node)
else:
return None
class JingleContent(object):
''' An abstraction of content in Jingle sessions. '''
def __init__(self, session, transport):
self.session = session
self.transport = transport
# will be filled by JingleSession.add_content()
# don't uncomment these lines, we will catch more buggy code then
# (a JingleContent not added to session shouldn't send anything)
#self.creator = None
#self.name = None
self.accepted = False
self.sent = False
self.media = None
self.senders = 'both' #FIXME
self.allow_sending = True # Used for stream direction, attribute 'senders'
self.callbacks = {
# these are called when *we* get stanzas
'content-accept': [self.__transportInfoCB],
'content-add': [self.__transportInfoCB],
'content-modify': [],
'content-reject': [],
'content-remove': [],
'description-info': [],
'security-info': [],
'session-accept': [self.__transportInfoCB],
'session-info': [],
'session-initiate': [self.__transportInfoCB],
'session-terminate': [],
'transport-info': [self.__transportInfoCB],
'transport-replace': [],
'transport-accept': [],
'transport-reject': [],
'iq-result': [],
'iq-error': [],
# these are called when *we* sent these stanzas
'content-accept-sent': [self.__fillJingleStanza],
'content-add-sent': [self.__fillJingleStanza],
'session-initiate-sent': [self.__fillJingleStanza],
'session-accept-sent': [self.__fillJingleStanza],
'session-terminate-sent': [],
}
def is_ready(self):
return (self.accepted and not self.sent)
def add_remote_candidates(self, candidates):
''' Add a list of candidates to the list of remote candidates. '''
pass
def stanzaCB(self, stanza, content, error, action):
''' Called when something related to our content was sent by peer. '''
if action in self.callbacks:
for callback in self.callbacks[action]:
callback(stanza, content, error, action)
def __transportInfoCB(self, stanza, content, error, action):
''' Got a new transport candidate. '''
candidates = self.transport.parse_transport_stanza(
content.getTag('transport'))
if candidates:
self.add_remote_candidates(candidates)
def __content(self, payload=[]):
''' Build a XML content-wrapper for our data. '''
return xmpp.Node('content',
attrs={'name': self.name, 'creator': self.creator},
payload=payload)
def send_candidate(self, candidate):
content = self.__content()
content.addChild(self.transport.make_transport([candidate]))
self.session.send_transport_info(content)
def __fillJingleStanza(self, stanza, content, error, action):
''' Add our things to session-initiate stanza. '''
self._fillContent(content)
self.sent = True
content.addChild(node=self.transport.make_transport())
def destroy(self):
self.callbacks = None
del self.session.contents[(self.creator, self.name)]
This diff is collapsed.
This diff is collapsed.
##
## Copyright (C) 2006 Gajim Team
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published
## by the Free Software Foundation; version 2 only.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
''' Handles Jingle Transports (currently only ICE-UDP). '''
import xmpp
transports = {}
def get_jingle_transport(node):
namespace = node.getNamespace()
if namespace in transports:
return transports[namespace]()
else:
return None
class TransportType(object):
''' Possible types of a JingleTransport '''
datagram = 1
streaming = 2
class JingleTransport(object):
''' An abstraction of a transport in Jingle sessions. '''
def __init__(self, type_):
self.type = type_
self.candidates = []
self.remote_candidates = []
def _iter_candidates(self):
for candidate in self.candidates:
yield self.make_candidate(candidate)
def make_candidate(self, candidate):
''' Build a candidate stanza for the given candidate. '''
pass
def make_transport(self, candidates=None):
''' Build a transport stanza with the given candidates (or
self.candidates if candidates is None). '''
if not candidates:
candidates = self._iter_candidates()
transport = xmpp.Node('transport', payload=candidates)
return transport
def parse_transport_stanza(self, transport):
''' Returns the list of transport candidates from a transport stanza. '''
return []
import farsight
class JingleTransportICEUDP(JingleTransport):
def __init__(self):
JingleTransport.__init__(self, TransportType.datagram)
def make_candidate(self, candidate):
types = {farsight.CANDIDATE_TYPE_HOST: 'host',
farsight.CANDIDATE_TYPE_SRFLX: 'srflx',
farsight.CANDIDATE_TYPE_PRFLX: 'prflx',
farsight.CANDIDATE_TYPE_RELAY: 'relay',
farsight.CANDIDATE_TYPE_MULTICAST: 'multicast'}
attrs = {
'component': candidate.component_id,
'foundation': '1', # hack
'generation': '0',
'ip': candidate.ip,
'network': '0',
'port': candidate.port,
'priority': int(candidate.priority), # hack
}
if candidate.type in types:
attrs['type'] = types[candidate.type]
if candidate.proto == farsight.NETWORK_PROTOCOL_UDP:
attrs['protocol'] = 'udp'
else:
# we actually don't handle properly different tcp options in jingle
attrs['protocol'] = 'tcp'
return xmpp.Node('candidate', attrs=attrs)
def make_transport(self, candidates=None):
transport = JingleTransport.make_transport(self, candidates)
transport.setNamespace(xmpp.NS_JINGLE_ICE_UDP)
if self.candidates and self.candidates[0].username and \
self.candidates[0].password:
transport.setAttr('ufrag', self.candidates[0].username)
transport.setAttr('pwd', self.candidates[0].password)
return transport
def parse_transport_stanza(self, transport):
candidates = []
for candidate in transport.iterTags('candidate'):
cand = farsight.Candidate()
cand.component_id = int(candidate['component'])
cand.ip = str(candidate['ip'])
cand.port = int(candidate['port'])
cand.foundation = str(candidate['foundation'])
#cand.type = farsight.CANDIDATE_TYPE_LOCAL
cand.priority = int(candidate['priority'])
if candidate['protocol'] == 'udp':
cand.proto = farsight.NETWORK_PROTOCOL_UDP
else:
# we actually don't handle properly different tcp options in jingle
cand.proto = farsight.NETWORK_PROTOCOL_TCP
cand.username = str(transport['ufrag'])
cand.password = str(transport['pwd'])
#FIXME: huh?
types = {'host': farsight.CANDIDATE_TYPE_HOST,
'srflx': farsight.CANDIDATE_TYPE_SRFLX,
'prflx': farsight.CANDIDATE_TYPE_PRFLX,
'relay': farsight.CANDIDATE_TYPE_RELAY,
'multicast': farsight.CANDIDATE_TYPE_MULTICAST}
if 'type' in candidate and candidate['type'] in types:
cand.type = types[candidate['type']]
else:
print 'Unknown type %s', candidate['type']
candidates.append(cand)
self.remote_candidates.extend(candidates)
return candidates
transports[xmpp.NS_JINGLE_ICE_UDP] = JingleTransportICEUDP
......@@ -610,8 +610,8 @@ class HistoryManager:
liststore, list_of_paths))
def on_search_db_button_clicked(self, widget):
text = self.search_entry.get_text()
if text == '':
text = self.search_entry.get_text().decode('utf-8')
if not text:
return
self.welcome_vbox.hide()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment