diff --git a/CHANGES.rst b/CHANGES.rst index 5a284c385..2c57a57a0 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,3 +1,39 @@ +Changes in synapse 0.5.4 (2014-12-03) +===================================== + + * Fix presence bug where some rooms did not display presence updates for + remote users. + * Do not log SQL timing log lines when started with "-v" + * Fix potential memory leak. + +Changes in synapse 0.5.3c (2014-12-02) +====================================== + + * Change the default value for the `content_addr` option to use the HTTP + listener, as by default the HTTPS listener will be using a self-signed + certificate. + +Changes in synapse 0.5.3 (2014-11-27) +===================================== + + * Fix bug that caused joining a remote room to fail if a single event was not + signed correctly. + * Fix bug which caused servers to continuously try and fetch events from other + servers. + +Changes in synapse 0.5.2 (2014-11-26) +===================================== + +Fix major bug that caused rooms to disappear from peoples initial sync. + +Changes in synapse 0.5.1 (2014-11-26) +===================================== +See UPGRADES.rst for specific instructions on how to upgrade. + + * Fix bug where we served up an Event that did not match its signatures. + * Fix regression where we no longer correctly handled the case where a + homeserver receives an event for a room it doesn't recognise (but is in.) + Changes in synapse 0.5.0 (2014-11-19) ===================================== This release includes changes to the federation protocol and client-server API diff --git a/README.rst b/README.rst index 6048c25a1..8459bcac2 100644 --- a/README.rst +++ b/README.rst @@ -94,7 +94,8 @@ header files for python C extensions. Installing prerequisites on Ubuntu or Debian:: $ sudo apt-get install build-essential python2.7-dev libffi-dev \ - python-pip python-setuptools + python-pip python-setuptools sqlite3 \ + libssl-dev Installing prerequisites on Mac OS X:: @@ -129,6 +130,9 @@ failing, e.g.:: $ pip install --user twisted +On OSX, if you encounter clang: error: unknown argument: '-mno-fused-madd' you +will need to export CFLAGS=-Qunused-arguments. + Running Your Homeserver ======================= diff --git a/VERSION b/VERSION index 8f0916f76..7d8568351 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.5.0 +0.5.4 diff --git a/contrib/jitsimeetbridge/jitsimeetbridge.py b/contrib/jitsimeetbridge/jitsimeetbridge.py new file mode 100644 index 000000000..dbc6f6ffa --- /dev/null +++ b/contrib/jitsimeetbridge/jitsimeetbridge.py @@ -0,0 +1,260 @@ +#!/usr/bin/env python + +""" +This is an attempt at bridging matrix clients into a Jitis meet room via Matrix +video call. It uses hard-coded xml strings overg XMPP BOSH. It can display one +of the streams from the Jitsi bridge until the second lot of SDP comes down and +we set the remote SDP at which point the stream ends. Our video never gets to +the bridge. + +Requires: +npm install jquery jsdom +""" + +import gevent +import grequests +from BeautifulSoup import BeautifulSoup +import json +import urllib +import subprocess +import time + +#ACCESS_TOKEN="" # + +MATRIXBASE = 'https://matrix.org/_matrix/client/api/v1/' +MYUSERNAME = '@davetest:matrix.org' + +HTTPBIND = 'https://meet.jit.si/http-bind' +#HTTPBIND = 'https://jitsi.vuc.me/http-bind' +#ROOMNAME = "matrix" +ROOMNAME = "pibble" + +HOST="guest.jit.si" +#HOST="jitsi.vuc.me" + +TURNSERVER="turn.guest.jit.si" +#TURNSERVER="turn.jitsi.vuc.me" + +ROOMDOMAIN="meet.jit.si" +#ROOMDOMAIN="conference.jitsi.vuc.me" + +class TrivialMatrixClient: + def __init__(self, access_token): + self.token = None + self.access_token = access_token + + def getEvent(self): + while True: + url = MATRIXBASE+'events?access_token='+self.access_token+"&timeout=60000" + if self.token: + url += "&from="+self.token + req = grequests.get(url) + resps = grequests.map([req]) + obj = json.loads(resps[0].content) + print "incoming from matrix",obj + if 'end' not in obj: + continue + self.token = obj['end'] + if len(obj['chunk']): + return obj['chunk'][0] + + def joinRoom(self, roomId): + url = MATRIXBASE+'rooms/'+roomId+'/join?access_token='+self.access_token + print url + headers={ 'Content-Type': 'application/json' } + req = grequests.post(url, headers=headers, data='{}') + resps = grequests.map([req]) + obj = json.loads(resps[0].content) + print "response: ",obj + + def sendEvent(self, roomId, evType, event): + url = MATRIXBASE+'rooms/'+roomId+'/send/'+evType+'?access_token='+self.access_token + print url + print json.dumps(event) + headers={ 'Content-Type': 'application/json' } + req = grequests.post(url, headers=headers, data=json.dumps(event)) + resps = grequests.map([req]) + obj = json.loads(resps[0].content) + print "response: ",obj + + + +xmppClients = {} + + +def matrixLoop(): + while True: + ev = matrixCli.getEvent() + print ev + if ev['type'] == 'm.room.member': + print 'membership event' + if ev['membership'] == 'invite' and ev['state_key'] == MYUSERNAME: + roomId = ev['room_id'] + print "joining room %s" % (roomId) + matrixCli.joinRoom(roomId) + elif ev['type'] == 'm.room.message': + if ev['room_id'] in xmppClients: + print "already have a bridge for that user, ignoring" + continue + print "got message, connecting" + xmppClients[ev['room_id']] = TrivialXmppClient(ev['room_id'], ev['user_id']) + gevent.spawn(xmppClients[ev['room_id']].xmppLoop) + elif ev['type'] == 'm.call.invite': + print "Incoming call" + #sdp = ev['content']['offer']['sdp'] + #print "sdp: %s" % (sdp) + #xmppClients[ev['room_id']] = TrivialXmppClient(ev['room_id'], ev['user_id']) + #gevent.spawn(xmppClients[ev['room_id']].xmppLoop) + elif ev['type'] == 'm.call.answer': + print "Call answered" + sdp = ev['content']['answer']['sdp'] + if ev['room_id'] not in xmppClients: + print "We didn't have a call for that room" + continue + # should probably check call ID too + xmppCli = xmppClients[ev['room_id']] + xmppCli.sendAnswer(sdp) + elif ev['type'] == 'm.call.hangup': + if ev['room_id'] in xmppClients: + xmppClients[ev['room_id']].stop() + del xmppClients[ev['room_id']] + +class TrivialXmppClient: + def __init__(self, matrixRoom, userId): + self.rid = 0 + self.matrixRoom = matrixRoom + self.userId = userId + self.running = True + + def stop(self): + self.running = False + + def nextRid(self): + self.rid += 1 + return '%d' % (self.rid) + + def sendIq(self, xml): + fullXml = "
%s" % (self.nextRid(), self.sid, xml) + #print "\t>>>%s" % (fullXml) + return self.xmppPoke(fullXml) + + def xmppPoke(self, xml): + headers = {'Content-Type': 'application/xml'} + req = grequests.post(HTTPBIND, verify=False, headers=headers, data=xml) + resps = grequests.map([req]) + obj = BeautifulSoup(resps[0].content) + return obj + + def sendAnswer(self, answer): + print "sdp from matrix client",answer + p = subprocess.Popen(['node', 'unjingle/unjingle.js', '--sdp'], stdin=subprocess.PIPE, stdout=subprocess.PIPE) + jingle, out_err = p.communicate(answer) + jingle = jingle % { + 'tojid': self.callfrom, + 'action': 'session-accept', + 'initiator': self.callfrom, + 'responder': self.jid, + 'sid': self.callsid + } + print "answer jingle from sdp",jingle + res = self.sendIq(jingle) + print "reply from answer: ",res + + self.ssrcs = {} + jingleSoup = BeautifulSoup(jingle) + for cont in jingleSoup.iq.jingle.findAll('content'): + if cont.description: + self.ssrcs[cont['name']] = cont.description['ssrc'] + print "my ssrcs:",self.ssrcs + + gevent.joinall([ + gevent.spawn(self.advertiseSsrcs) + ]) + + def advertiseSsrcs(self): + time.sleep(7) + print "SSRC spammer started" + while self.running: + ssrcMsg = "