Fix seven contrib files with Python syntax errors (#5446)

* Fix seven contrib files with Python syntax errors

Signed-off-by: cclauss <cclauss@me.com>
This commit is contained in:
cclauss 2019-06-17 19:21:30 +02:00 committed by Amber Brown
parent d6328e03fd
commit 82d9d524bd
7 changed files with 131 additions and 119 deletions

1
changelog.d/5446.misc Normal file
View file

@ -0,0 +1 @@
Update Python syntax in contrib/ to Python 3.

View file

@ -15,6 +15,7 @@
# limitations under the License. # limitations under the License.
""" Starts a synapse client console. """ """ Starts a synapse client console. """
from __future__ import print_function
from twisted.internet import reactor, defer, threads from twisted.internet import reactor, defer, threads
from http import TwistedHttpClient from http import TwistedHttpClient
@ -109,7 +110,7 @@ class SynapseCmd(cmd.Cmd):
by using $. E.g. 'config roomid room1' then 'raw get /rooms/$roomid'. by using $. E.g. 'config roomid room1' then 'raw get /rooms/$roomid'.
""" """
if len(line) == 0: if len(line) == 0:
print json.dumps(self.config, indent=4) print(json.dumps(self.config, indent=4))
return return
try: try:
@ -123,8 +124,8 @@ class SynapseCmd(cmd.Cmd):
] ]
for key, valid_vals in config_rules: for key, valid_vals in config_rules:
if key == args["key"] and args["val"] not in valid_vals: if key == args["key"] and args["val"] not in valid_vals:
print "%s value must be one of %s" % (args["key"], print("%s value must be one of %s" % (args["key"],
valid_vals) valid_vals))
return return
# toggle the http client verbosity # toggle the http client verbosity
@ -133,11 +134,11 @@ class SynapseCmd(cmd.Cmd):
# assign the new config # assign the new config
self.config[args["key"]] = args["val"] self.config[args["key"]] = args["val"]
print json.dumps(self.config, indent=4) print(json.dumps(self.config, indent=4))
save_config(self.config) save_config(self.config)
except Exception as e: except Exception as e:
print e print(e)
def do_register(self, line): def do_register(self, line):
"""Registers for a new account: "register <userid> <noupdate>" """Registers for a new account: "register <userid> <noupdate>"
@ -153,7 +154,7 @@ class SynapseCmd(cmd.Cmd):
pwd = getpass.getpass("Type a password for this user: ") pwd = getpass.getpass("Type a password for this user: ")
pwd2 = getpass.getpass("Retype the password: ") pwd2 = getpass.getpass("Retype the password: ")
if pwd != pwd2 or len(pwd) == 0: if pwd != pwd2 or len(pwd) == 0:
print "Password mismatch." print("Password mismatch.")
pwd = None pwd = None
else: else:
password = pwd password = pwd
@ -174,12 +175,12 @@ class SynapseCmd(cmd.Cmd):
# check the registration flows # check the registration flows
url = self._url() + "/register" url = self._url() + "/register"
json_res = yield self.http_client.do_request("GET", url) json_res = yield self.http_client.do_request("GET", url)
print json.dumps(json_res, indent=4) print(json.dumps(json_res, indent=4))
passwordFlow = None passwordFlow = None
for flow in json_res["flows"]: for flow in json_res["flows"]:
if flow["type"] == "m.login.recaptcha" or ("stages" in flow and "m.login.recaptcha" in flow["stages"]): if flow["type"] == "m.login.recaptcha" or ("stages" in flow and "m.login.recaptcha" in flow["stages"]):
print "Unable to register: Home server requires captcha." print("Unable to register: Home server requires captcha.")
return return
if flow["type"] == "m.login.password" and "stages" not in flow: if flow["type"] == "m.login.password" and "stages" not in flow:
passwordFlow = flow passwordFlow = flow
@ -189,7 +190,7 @@ class SynapseCmd(cmd.Cmd):
return return
json_res = yield self.http_client.do_request("POST", url, data=data) json_res = yield self.http_client.do_request("POST", url, data=data)
print json.dumps(json_res, indent=4) print(json.dumps(json_res, indent=4))
if update_config and "user_id" in json_res: if update_config and "user_id" in json_res:
self.config["user"] = json_res["user_id"] self.config["user"] = json_res["user_id"]
self.config["token"] = json_res["access_token"] self.config["token"] = json_res["access_token"]
@ -215,7 +216,7 @@ class SynapseCmd(cmd.Cmd):
reactor.callFromThread(self._do_login, user, p) reactor.callFromThread(self._do_login, user, p)
#print " got %s " % p #print " got %s " % p
except Exception as e: except Exception as e:
print e print(e)
@defer.inlineCallbacks @defer.inlineCallbacks
def _do_login(self, user, password): def _do_login(self, user, password):
@ -227,13 +228,13 @@ class SynapseCmd(cmd.Cmd):
} }
url = self._url() + path url = self._url() + path
json_res = yield self.http_client.do_request("POST", url, data=data) json_res = yield self.http_client.do_request("POST", url, data=data)
print json_res print(json_res)
if "access_token" in json_res: if "access_token" in json_res:
self.config["user"] = user self.config["user"] = user
self.config["token"] = json_res["access_token"] self.config["token"] = json_res["access_token"]
save_config(self.config) save_config(self.config)
print "Login successful." print("Login successful.")
@defer.inlineCallbacks @defer.inlineCallbacks
def _check_can_login(self): def _check_can_login(self):
@ -242,10 +243,10 @@ class SynapseCmd(cmd.Cmd):
# submitting! # submitting!
url = self._url() + path url = self._url() + path
json_res = yield self.http_client.do_request("GET", url) json_res = yield self.http_client.do_request("GET", url)
print json_res print(json_res)
if "flows" not in json_res: if "flows" not in json_res:
print "Failed to find any login flows." print("Failed to find any login flows.")
defer.returnValue(False) defer.returnValue(False)
flow = json_res["flows"][0] # assume first is the one we want. flow = json_res["flows"][0] # assume first is the one we want.
@ -275,9 +276,9 @@ class SynapseCmd(cmd.Cmd):
json_res = yield self.http_client.do_request("POST", url, data=urllib.urlencode(args), jsonreq=False, json_res = yield self.http_client.do_request("POST", url, data=urllib.urlencode(args), jsonreq=False,
headers={'Content-Type': ['application/x-www-form-urlencoded']}) headers={'Content-Type': ['application/x-www-form-urlencoded']})
print json_res print(json_res)
if 'sid' in json_res: if 'sid' in json_res:
print "Token sent. Your session ID is %s" % (json_res['sid']) print("Token sent. Your session ID is %s" % (json_res['sid']))
def do_emailvalidate(self, line): def do_emailvalidate(self, line):
"""Validate and associate a third party ID """Validate and associate a third party ID
@ -297,7 +298,7 @@ class SynapseCmd(cmd.Cmd):
json_res = yield self.http_client.do_request("POST", url, data=urllib.urlencode(args), jsonreq=False, json_res = yield self.http_client.do_request("POST", url, data=urllib.urlencode(args), jsonreq=False,
headers={'Content-Type': ['application/x-www-form-urlencoded']}) headers={'Content-Type': ['application/x-www-form-urlencoded']})
print json_res print(json_res)
def do_3pidbind(self, line): def do_3pidbind(self, line):
"""Validate and associate a third party ID """Validate and associate a third party ID
@ -317,7 +318,7 @@ class SynapseCmd(cmd.Cmd):
json_res = yield self.http_client.do_request("POST", url, data=urllib.urlencode(args), jsonreq=False, json_res = yield self.http_client.do_request("POST", url, data=urllib.urlencode(args), jsonreq=False,
headers={'Content-Type': ['application/x-www-form-urlencoded']}) headers={'Content-Type': ['application/x-www-form-urlencoded']})
print json_res print(json_res)
def do_join(self, line): def do_join(self, line):
"""Joins a room: "join <roomid>" """ """Joins a room: "join <roomid>" """
@ -325,7 +326,7 @@ class SynapseCmd(cmd.Cmd):
args = self._parse(line, ["roomid"], force_keys=True) args = self._parse(line, ["roomid"], force_keys=True)
self._do_membership_change(args["roomid"], "join", self._usr()) self._do_membership_change(args["roomid"], "join", self._usr())
except Exception as e: except Exception as e:
print e print(e)
def do_joinalias(self, line): def do_joinalias(self, line):
try: try:
@ -333,7 +334,7 @@ class SynapseCmd(cmd.Cmd):
path = "/join/%s" % urllib.quote(args["roomname"]) path = "/join/%s" % urllib.quote(args["roomname"])
reactor.callFromThread(self._run_and_pprint, "POST", path, {}) reactor.callFromThread(self._run_and_pprint, "POST", path, {})
except Exception as e: except Exception as e:
print e print(e)
def do_topic(self, line): def do_topic(self, line):
""""topic [set|get] <roomid> [<newtopic>]" """"topic [set|get] <roomid> [<newtopic>]"
@ -343,17 +344,17 @@ class SynapseCmd(cmd.Cmd):
try: try:
args = self._parse(line, ["action", "roomid", "topic"]) args = self._parse(line, ["action", "roomid", "topic"])
if "action" not in args or "roomid" not in args: if "action" not in args or "roomid" not in args:
print "Must specify set|get and a room ID." print("Must specify set|get and a room ID.")
return return
if args["action"].lower() not in ["set", "get"]: if args["action"].lower() not in ["set", "get"]:
print "Must specify set|get, not %s" % args["action"] print("Must specify set|get, not %s" % args["action"])
return return
path = "/rooms/%s/topic" % urllib.quote(args["roomid"]) path = "/rooms/%s/topic" % urllib.quote(args["roomid"])
if args["action"].lower() == "set": if args["action"].lower() == "set":
if "topic" not in args: if "topic" not in args:
print "Must specify a new topic." print("Must specify a new topic.")
return return
body = { body = {
"topic": args["topic"] "topic": args["topic"]
@ -362,7 +363,7 @@ class SynapseCmd(cmd.Cmd):
elif args["action"].lower() == "get": elif args["action"].lower() == "get":
reactor.callFromThread(self._run_and_pprint, "GET", path) reactor.callFromThread(self._run_and_pprint, "GET", path)
except Exception as e: except Exception as e:
print e print(e)
def do_invite(self, line): def do_invite(self, line):
"""Invite a user to a room: "invite <userid> <roomid>" """ """Invite a user to a room: "invite <userid> <roomid>" """
@ -373,7 +374,7 @@ class SynapseCmd(cmd.Cmd):
reactor.callFromThread(self._do_invite, args["roomid"], user_id) reactor.callFromThread(self._do_invite, args["roomid"], user_id)
except Exception as e: except Exception as e:
print e print(e)
@defer.inlineCallbacks @defer.inlineCallbacks
def _do_invite(self, roomid, userstring): def _do_invite(self, roomid, userstring):
@ -393,29 +394,29 @@ class SynapseCmd(cmd.Cmd):
if 'public_key' in pubKeyObj: if 'public_key' in pubKeyObj:
pubKey = nacl.signing.VerifyKey(pubKeyObj['public_key'], encoder=nacl.encoding.HexEncoder) pubKey = nacl.signing.VerifyKey(pubKeyObj['public_key'], encoder=nacl.encoding.HexEncoder)
else: else:
print "No public key found in pubkey response!" print("No public key found in pubkey response!")
sigValid = False sigValid = False
if pubKey: if pubKey:
for signame in json_res['signatures']: for signame in json_res['signatures']:
if signame not in TRUSTED_ID_SERVERS: if signame not in TRUSTED_ID_SERVERS:
print "Ignoring signature from untrusted server %s" % (signame) print("Ignoring signature from untrusted server %s" % (signame))
else: else:
try: try:
verify_signed_json(json_res, signame, pubKey) verify_signed_json(json_res, signame, pubKey)
sigValid = True sigValid = True
print "Mapping %s -> %s correctly signed by %s" % (userstring, json_res['mxid'], signame) print("Mapping %s -> %s correctly signed by %s" % (userstring, json_res['mxid'], signame))
break break
except SignatureVerifyException as e: except SignatureVerifyException as e:
print "Invalid signature from %s" % (signame) print("Invalid signature from %s" % (signame))
print e print(e)
if sigValid: if sigValid:
print "Resolved 3pid %s to %s" % (userstring, json_res['mxid']) print("Resolved 3pid %s to %s" % (userstring, json_res['mxid']))
mxid = json_res['mxid'] mxid = json_res['mxid']
else: else:
print "Got association for %s but couldn't verify signature" % (userstring) print("Got association for %s but couldn't verify signature" % (userstring))
if not mxid: if not mxid:
mxid = "@" + userstring + ":" + self._domain() mxid = "@" + userstring + ":" + self._domain()
@ -428,7 +429,7 @@ class SynapseCmd(cmd.Cmd):
args = self._parse(line, ["roomid"], force_keys=True) args = self._parse(line, ["roomid"], force_keys=True)
self._do_membership_change(args["roomid"], "leave", self._usr()) self._do_membership_change(args["roomid"], "leave", self._usr())
except Exception as e: except Exception as e:
print e print(e)
def do_send(self, line): def do_send(self, line):
"""Sends a message. "send <roomid> <body>" """ """Sends a message. "send <roomid> <body>" """
@ -453,10 +454,10 @@ class SynapseCmd(cmd.Cmd):
""" """
args = self._parse(line, ["type", "roomid", "qp"]) args = self._parse(line, ["type", "roomid", "qp"])
if not "type" in args or not "roomid" in args: if not "type" in args or not "roomid" in args:
print "Must specify type and room ID." print("Must specify type and room ID.")
return return
if args["type"] not in ["members", "messages"]: if args["type"] not in ["members", "messages"]:
print "Unrecognised type: %s" % args["type"] print("Unrecognised type: %s" % args["type"])
return return
room_id = args["roomid"] room_id = args["roomid"]
path = "/rooms/%s/%s" % (urllib.quote(room_id), args["type"]) path = "/rooms/%s/%s" % (urllib.quote(room_id), args["type"])
@ -468,7 +469,7 @@ class SynapseCmd(cmd.Cmd):
key_value = key_value_str.split("=") key_value = key_value_str.split("=")
qp[key_value[0]] = key_value[1] qp[key_value[0]] = key_value[1]
except: except:
print "Bad query param: %s" % key_value print("Bad query param: %s" % key_value)
return return
reactor.callFromThread(self._run_and_pprint, "GET", path, reactor.callFromThread(self._run_and_pprint, "GET", path,
@ -508,14 +509,14 @@ class SynapseCmd(cmd.Cmd):
args = self._parse(line, ["method", "path", "data"]) args = self._parse(line, ["method", "path", "data"])
# sanity check # sanity check
if "method" not in args or "path" not in args: if "method" not in args or "path" not in args:
print "Must specify path and method." print("Must specify path and method.")
return return
args["method"] = args["method"].upper() args["method"] = args["method"].upper()
valid_methods = ["PUT", "GET", "POST", "DELETE", valid_methods = ["PUT", "GET", "POST", "DELETE",
"XPUT", "XGET", "XPOST", "XDELETE"] "XPUT", "XGET", "XPOST", "XDELETE"]
if args["method"] not in valid_methods: if args["method"] not in valid_methods:
print "Unsupported method: %s" % args["method"] print("Unsupported method: %s" % args["method"])
return return
if "data" not in args: if "data" not in args:
@ -524,7 +525,7 @@ class SynapseCmd(cmd.Cmd):
try: try:
args["data"] = json.loads(args["data"]) args["data"] = json.loads(args["data"])
except Exception as e: except Exception as e:
print "Data is not valid JSON. %s" % e print("Data is not valid JSON. %s" % e)
return return
qp = {"access_token": self._tok()} qp = {"access_token": self._tok()}
@ -553,7 +554,7 @@ class SynapseCmd(cmd.Cmd):
try: try:
timeout = int(args["timeout"]) timeout = int(args["timeout"])
except ValueError: except ValueError:
print "Timeout must be in milliseconds." print("Timeout must be in milliseconds.")
return return
reactor.callFromThread(self._do_event_stream, timeout) reactor.callFromThread(self._do_event_stream, timeout)
@ -566,7 +567,7 @@ class SynapseCmd(cmd.Cmd):
"timeout": str(timeout), "timeout": str(timeout),
"from": self.event_stream_token "from": self.event_stream_token
}) })
print json.dumps(res, indent=4) print(json.dumps(res, indent=4))
if "chunk" in res: if "chunk" in res:
for event in res["chunk"]: for event in res["chunk"]:
@ -669,9 +670,9 @@ class SynapseCmd(cmd.Cmd):
data=data, data=data,
qparams=query_params) qparams=query_params)
if alt_text: if alt_text:
print alt_text print(alt_text)
else: else:
print json.dumps(json_res, indent=4) print(json.dumps(json_res, indent=4))
def save_config(config): def save_config(config):
@ -680,16 +681,16 @@ def save_config(config):
def main(server_url, identity_server_url, username, token, config_path): def main(server_url, identity_server_url, username, token, config_path):
print "Synapse command line client" print("Synapse command line client")
print "===========================" print("===========================")
print "Server: %s" % server_url print("Server: %s" % server_url)
print "Type 'help' to get started." print("Type 'help' to get started.")
print "Close this console with CTRL+C then CTRL+D." print("Close this console with CTRL+C then CTRL+D.")
if not username or not token: if not username or not token:
print "- 'register <username>' - Register an account" print("- 'register <username>' - Register an account")
print "- 'stream' - Connect to the event stream" print("- 'stream' - Connect to the event stream")
print "- 'create <roomid>' - Create a room" print("- 'create <roomid>' - Create a room")
print "- 'send <roomid> <message>' - Send a message" print("- 'send <roomid> <message>' - Send a message")
http_client = TwistedHttpClient() http_client = TwistedHttpClient()
# the command line client # the command line client
@ -705,7 +706,7 @@ def main(server_url, identity_server_url, username, token, config_path):
http_client.verbose = "on" == syn_cmd.config["verbose"] http_client.verbose = "on" == syn_cmd.config["verbose"]
except: except:
pass pass
print "Loaded config from %s" % config_path print("Loaded config from %s" % config_path)
except: except:
pass pass
@ -736,7 +737,7 @@ if __name__ == '__main__':
args = parser.parse_args() args = parser.parse_args()
if not args.server: if not args.server:
print "You must supply a server URL to communicate with." print("You must supply a server URL to communicate with.")
parser.print_help() parser.print_help()
sys.exit(1) sys.exit(1)

View file

@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
from __future__ import print_function
from twisted.web.client import Agent, readBody from twisted.web.client import Agent, readBody
from twisted.web.http_headers import Headers from twisted.web.http_headers import Headers
from twisted.internet import defer, reactor from twisted.internet import defer, reactor
@ -141,15 +142,15 @@ class TwistedHttpClient(HttpClient):
headers_dict["User-Agent"] = ["Synapse Cmd Client"] headers_dict["User-Agent"] = ["Synapse Cmd Client"]
retries_left = 5 retries_left = 5
print "%s to %s with headers %s" % (method, url, headers_dict) print("%s to %s with headers %s" % (method, url, headers_dict))
if self.verbose and producer: if self.verbose and producer:
if "password" in producer.data: if "password" in producer.data:
temp = producer.data["password"] temp = producer.data["password"]
producer.data["password"] = "[REDACTED]" producer.data["password"] = "[REDACTED]"
print json.dumps(producer.data, indent=4) print(json.dumps(producer.data, indent=4))
producer.data["password"] = temp producer.data["password"] = temp
else: else:
print json.dumps(producer.data, indent=4) print(json.dumps(producer.data, indent=4))
while True: while True:
try: try:
@ -161,7 +162,7 @@ class TwistedHttpClient(HttpClient):
) )
break break
except Exception as e: except Exception as e:
print "uh oh: %s" % e print("uh oh: %s" % e)
if retries_left: if retries_left:
yield self.sleep(2 ** (5 - retries_left)) yield self.sleep(2 ** (5 - retries_left))
retries_left -= 1 retries_left -= 1
@ -169,8 +170,8 @@ class TwistedHttpClient(HttpClient):
raise e raise e
if self.verbose: if self.verbose:
print "Status %s %s" % (response.code, response.phrase) print("Status %s %s" % (response.code, response.phrase))
print pformat(list(response.headers.getAllRawHeaders())) print(pformat(list(response.headers.getAllRawHeaders())))
defer.returnValue(response) defer.returnValue(response)
def sleep(self, seconds): def sleep(self, seconds):

View file

@ -1,3 +1,4 @@
from __future__ import print_function
# Copyright 2014-2016 OpenMarket Ltd # Copyright 2014-2016 OpenMarket Ltd
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
@ -48,7 +49,7 @@ def make_graph(pdus, room, filename_prefix):
c = colors.pop() c = colors.pop()
color_map[o] = c color_map[o] = c
except: except:
print "Run out of colours!" print("Run out of colours!")
color_map[o] = "black" color_map[o] = "black"
graph = pydot.Dot(graph_name="Test") graph = pydot.Dot(graph_name="Test")
@ -93,7 +94,7 @@ def make_graph(pdus, room, filename_prefix):
end_name = make_name(i, o) end_name = make_name(i, o)
if end_name not in node_map: if end_name not in node_map:
print "%s not in nodes" % end_name print("%s not in nodes" % end_name)
continue continue
edge = pydot.Edge(node_map[start_name], node_map[end_name]) edge = pydot.Edge(node_map[start_name], node_map[end_name])

View file

@ -1,3 +1,4 @@
from __future__ import print_function
# Copyright 2016 OpenMarket Ltd # Copyright 2016 OpenMarket Ltd
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
@ -26,19 +27,19 @@ from six import string_types
def make_graph(file_name, room_id, file_prefix, limit): def make_graph(file_name, room_id, file_prefix, limit):
print "Reading lines" print("Reading lines")
with open(file_name) as f: with open(file_name) as f:
lines = f.readlines() lines = f.readlines()
print "Read lines" print("Read lines")
events = [FrozenEvent(json.loads(line)) for line in lines] events = [FrozenEvent(json.loads(line)) for line in lines]
print "Loaded events." print("Loaded events.")
events.sort(key=lambda e: e.depth) events.sort(key=lambda e: e.depth)
print "Sorted events" print("Sorted events")
if limit: if limit:
events = events[-int(limit):] events = events[-int(limit):]
@ -55,7 +56,7 @@ def make_graph(file_name, room_id, file_prefix, limit):
content = json.dumps(unfreeze(event.get_dict()["content"]), indent=4) content = json.dumps(unfreeze(event.get_dict()["content"]), indent=4)
content = content.replace("\n", "<br/>\n") content = content.replace("\n", "<br/>\n")
print content print(content)
content = [] content = []
for key, value in unfreeze(event.get_dict()["content"]).items(): for key, value in unfreeze(event.get_dict()["content"]).items():
if value is None: if value is None:
@ -74,7 +75,7 @@ def make_graph(file_name, room_id, file_prefix, limit):
content = "<br/>\n".join(content) content = "<br/>\n".join(content)
print content print(content)
label = ( label = (
"<" "<"
@ -102,7 +103,7 @@ def make_graph(file_name, room_id, file_prefix, limit):
node_map[event.event_id] = node node_map[event.event_id] = node
graph.add_node(node) graph.add_node(node)
print "Created Nodes" print("Created Nodes")
for event in events: for event in events:
for prev_id, _ in event.prev_events: for prev_id, _ in event.prev_events:
@ -120,15 +121,15 @@ def make_graph(file_name, room_id, file_prefix, limit):
edge = pydot.Edge(node_map[event.event_id], end_node) edge = pydot.Edge(node_map[event.event_id], end_node)
graph.add_edge(edge) graph.add_edge(edge)
print "Created edges" print("Created edges")
graph.write('%s.dot' % file_prefix, format='raw', prog='dot') graph.write('%s.dot' % file_prefix, format='raw', prog='dot')
print "Created Dot" print("Created Dot")
graph.write_svg("%s.svg" % file_prefix, prog='dot') graph.write_svg("%s.svg" % file_prefix, prog='dot')
print "Created svg" print("Created svg")
if __name__ == "__main__": if __name__ == "__main__":
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(

View file

@ -8,8 +8,9 @@ we set the remote SDP at which point the stream ends. Our video never gets to
the bridge. the bridge.
Requires: Requires:
npm install jquery jsdom npm install jquery jsdom
""" """
from __future__ import print_function
import gevent import gevent
import grequests import grequests
@ -51,7 +52,7 @@ class TrivialMatrixClient:
req = grequests.get(url) req = grequests.get(url)
resps = grequests.map([req]) resps = grequests.map([req])
obj = json.loads(resps[0].content) obj = json.loads(resps[0].content)
print "incoming from matrix",obj print("incoming from matrix",obj)
if 'end' not in obj: if 'end' not in obj:
continue continue
self.token = obj['end'] self.token = obj['end']
@ -60,22 +61,22 @@ class TrivialMatrixClient:
def joinRoom(self, roomId): def joinRoom(self, roomId):
url = MATRIXBASE+'rooms/'+roomId+'/join?access_token='+self.access_token url = MATRIXBASE+'rooms/'+roomId+'/join?access_token='+self.access_token
print url print(url)
headers={ 'Content-Type': 'application/json' } headers={ 'Content-Type': 'application/json' }
req = grequests.post(url, headers=headers, data='{}') req = grequests.post(url, headers=headers, data='{}')
resps = grequests.map([req]) resps = grequests.map([req])
obj = json.loads(resps[0].content) obj = json.loads(resps[0].content)
print "response: ",obj print("response: ",obj)
def sendEvent(self, roomId, evType, event): def sendEvent(self, roomId, evType, event):
url = MATRIXBASE+'rooms/'+roomId+'/send/'+evType+'?access_token='+self.access_token url = MATRIXBASE+'rooms/'+roomId+'/send/'+evType+'?access_token='+self.access_token
print url print(url)
print json.dumps(event) print(json.dumps(event))
headers={ 'Content-Type': 'application/json' } headers={ 'Content-Type': 'application/json' }
req = grequests.post(url, headers=headers, data=json.dumps(event)) req = grequests.post(url, headers=headers, data=json.dumps(event))
resps = grequests.map([req]) resps = grequests.map([req])
obj = json.loads(resps[0].content) obj = json.loads(resps[0].content)
print "response: ",obj print("response: ",obj)
@ -85,31 +86,31 @@ xmppClients = {}
def matrixLoop(): def matrixLoop():
while True: while True:
ev = matrixCli.getEvent() ev = matrixCli.getEvent()
print ev print(ev)
if ev['type'] == 'm.room.member': if ev['type'] == 'm.room.member':
print 'membership event' print('membership event')
if ev['membership'] == 'invite' and ev['state_key'] == MYUSERNAME: if ev['membership'] == 'invite' and ev['state_key'] == MYUSERNAME:
roomId = ev['room_id'] roomId = ev['room_id']
print "joining room %s" % (roomId) print("joining room %s" % (roomId))
matrixCli.joinRoom(roomId) matrixCli.joinRoom(roomId)
elif ev['type'] == 'm.room.message': elif ev['type'] == 'm.room.message':
if ev['room_id'] in xmppClients: if ev['room_id'] in xmppClients:
print "already have a bridge for that user, ignoring" print("already have a bridge for that user, ignoring")
continue continue
print "got message, connecting" print("got message, connecting")
xmppClients[ev['room_id']] = TrivialXmppClient(ev['room_id'], ev['user_id']) xmppClients[ev['room_id']] = TrivialXmppClient(ev['room_id'], ev['user_id'])
gevent.spawn(xmppClients[ev['room_id']].xmppLoop) gevent.spawn(xmppClients[ev['room_id']].xmppLoop)
elif ev['type'] == 'm.call.invite': elif ev['type'] == 'm.call.invite':
print "Incoming call" print("Incoming call")
#sdp = ev['content']['offer']['sdp'] #sdp = ev['content']['offer']['sdp']
#print "sdp: %s" % (sdp) #print "sdp: %s" % (sdp)
#xmppClients[ev['room_id']] = TrivialXmppClient(ev['room_id'], ev['user_id']) #xmppClients[ev['room_id']] = TrivialXmppClient(ev['room_id'], ev['user_id'])
#gevent.spawn(xmppClients[ev['room_id']].xmppLoop) #gevent.spawn(xmppClients[ev['room_id']].xmppLoop)
elif ev['type'] == 'm.call.answer': elif ev['type'] == 'm.call.answer':
print "Call answered" print("Call answered")
sdp = ev['content']['answer']['sdp'] sdp = ev['content']['answer']['sdp']
if ev['room_id'] not in xmppClients: if ev['room_id'] not in xmppClients:
print "We didn't have a call for that room" print("We didn't have a call for that room")
continue continue
# should probably check call ID too # should probably check call ID too
xmppCli = xmppClients[ev['room_id']] xmppCli = xmppClients[ev['room_id']]
@ -146,7 +147,7 @@ class TrivialXmppClient:
return obj return obj
def sendAnswer(self, answer): def sendAnswer(self, answer):
print "sdp from matrix client",answer print("sdp from matrix client",answer)
p = subprocess.Popen(['node', 'unjingle/unjingle.js', '--sdp'], stdin=subprocess.PIPE, stdout=subprocess.PIPE) p = subprocess.Popen(['node', 'unjingle/unjingle.js', '--sdp'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
jingle, out_err = p.communicate(answer) jingle, out_err = p.communicate(answer)
jingle = jingle % { jingle = jingle % {
@ -156,28 +157,28 @@ class TrivialXmppClient:
'responder': self.jid, 'responder': self.jid,
'sid': self.callsid 'sid': self.callsid
} }
print "answer jingle from sdp",jingle print("answer jingle from sdp",jingle)
res = self.sendIq(jingle) res = self.sendIq(jingle)
print "reply from answer: ",res print("reply from answer: ",res)
self.ssrcs = {} self.ssrcs = {}
jingleSoup = BeautifulSoup(jingle) jingleSoup = BeautifulSoup(jingle)
for cont in jingleSoup.iq.jingle.findAll('content'): for cont in jingleSoup.iq.jingle.findAll('content'):
if cont.description: if cont.description:
self.ssrcs[cont['name']] = cont.description['ssrc'] self.ssrcs[cont['name']] = cont.description['ssrc']
print "my ssrcs:",self.ssrcs print("my ssrcs:",self.ssrcs)
gevent.joinall([ gevent.joinall([
gevent.spawn(self.advertiseSsrcs) gevent.spawn(self.advertiseSsrcs)
]) ])
def advertiseSsrcs(self): def advertiseSsrcs(self):
time.sleep(7) time.sleep(7)
print "SSRC spammer started" print("SSRC spammer started")
while self.running: while self.running:
ssrcMsg = "<presence to='%(tojid)s' xmlns='jabber:client'><x xmlns='http://jabber.org/protocol/muc'/><c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='http://jitsi.org/jitsimeet' ver='0WkSdhFnAUxrz4ImQQLdB80GFlE='/><nick xmlns='http://jabber.org/protocol/nick'>%(nick)s</nick><stats xmlns='http://jitsi.org/jitmeet/stats'><stat name='bitrate_download' value='175'/><stat name='bitrate_upload' value='176'/><stat name='packetLoss_total' value='0'/><stat name='packetLoss_download' value='0'/><stat name='packetLoss_upload' value='0'/></stats><media xmlns='http://estos.de/ns/mjs'><source type='audio' ssrc='%(assrc)s' direction='sendre'/><source type='video' ssrc='%(vssrc)s' direction='sendre'/></media></presence>" % { 'tojid': "%s@%s/%s" % (ROOMNAME, ROOMDOMAIN, self.shortJid), 'nick': self.userId, 'assrc': self.ssrcs['audio'], 'vssrc': self.ssrcs['video'] } ssrcMsg = "<presence to='%(tojid)s' xmlns='jabber:client'><x xmlns='http://jabber.org/protocol/muc'/><c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='http://jitsi.org/jitsimeet' ver='0WkSdhFnAUxrz4ImQQLdB80GFlE='/><nick xmlns='http://jabber.org/protocol/nick'>%(nick)s</nick><stats xmlns='http://jitsi.org/jitmeet/stats'><stat name='bitrate_download' value='175'/><stat name='bitrate_upload' value='176'/><stat name='packetLoss_total' value='0'/><stat name='packetLoss_download' value='0'/><stat name='packetLoss_upload' value='0'/></stats><media xmlns='http://estos.de/ns/mjs'><source type='audio' ssrc='%(assrc)s' direction='sendre'/><source type='video' ssrc='%(vssrc)s' direction='sendre'/></media></presence>" % { 'tojid': "%s@%s/%s" % (ROOMNAME, ROOMDOMAIN, self.shortJid), 'nick': self.userId, 'assrc': self.ssrcs['audio'], 'vssrc': self.ssrcs['video'] }
res = self.sendIq(ssrcMsg) res = self.sendIq(ssrcMsg)
print "reply from ssrc announce: ",res print("reply from ssrc announce: ",res)
time.sleep(10) time.sleep(10)
@ -186,19 +187,19 @@ class TrivialXmppClient:
self.matrixCallId = time.time() self.matrixCallId = time.time()
res = self.xmppPoke("<body rid='%s' xmlns='http://jabber.org/protocol/httpbind' to='%s' xml:lang='en' wait='60' hold='1' content='text/xml; charset=utf-8' ver='1.6' xmpp:version='1.0' xmlns:xmpp='urn:xmpp:xbosh'/>" % (self.nextRid(), HOST)) res = self.xmppPoke("<body rid='%s' xmlns='http://jabber.org/protocol/httpbind' to='%s' xml:lang='en' wait='60' hold='1' content='text/xml; charset=utf-8' ver='1.6' xmpp:version='1.0' xmlns:xmpp='urn:xmpp:xbosh'/>" % (self.nextRid(), HOST))
print res print(res)
self.sid = res.body['sid'] self.sid = res.body['sid']
print "sid %s" % (self.sid) print("sid %s" % (self.sid))
res = self.sendIq("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='ANONYMOUS'/>") res = self.sendIq("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='ANONYMOUS'/>")
res = self.xmppPoke("<body rid='%s' xmlns='http://jabber.org/protocol/httpbind' sid='%s' to='%s' xml:lang='en' xmpp:restart='true' xmlns:xmpp='urn:xmpp:xbosh'/>" % (self.nextRid(), self.sid, HOST)) res = self.xmppPoke("<body rid='%s' xmlns='http://jabber.org/protocol/httpbind' sid='%s' to='%s' xml:lang='en' xmpp:restart='true' xmlns:xmpp='urn:xmpp:xbosh'/>" % (self.nextRid(), self.sid, HOST))
res = self.sendIq("<iq type='set' id='_bind_auth_2' xmlns='jabber:client'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/></iq>") res = self.sendIq("<iq type='set' id='_bind_auth_2' xmlns='jabber:client'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/></iq>")
print res print(res)
self.jid = res.body.iq.bind.jid.string self.jid = res.body.iq.bind.jid.string
print "jid: %s" % (self.jid) print("jid: %s" % (self.jid))
self.shortJid = self.jid.split('-')[0] self.shortJid = self.jid.split('-')[0]
res = self.sendIq("<iq type='set' id='_session_auth_2' xmlns='jabber:client'><session xmlns='urn:ietf:params:xml:ns:xmpp-session'/></iq>") res = self.sendIq("<iq type='set' id='_session_auth_2' xmlns='jabber:client'><session xmlns='urn:ietf:params:xml:ns:xmpp-session'/></iq>")
@ -217,13 +218,13 @@ class TrivialXmppClient:
if p.c and p.c.nick: if p.c and p.c.nick:
u['nick'] = p.c.nick.string u['nick'] = p.c.nick.string
self.muc['users'].append(u) self.muc['users'].append(u)
print "muc: ",self.muc print("muc: ",self.muc)
# wait for stuff # wait for stuff
while True: while True:
print "waiting..." print("waiting...")
res = self.sendIq("") res = self.sendIq("")
print "got from stream: ",res print("got from stream: ",res)
if res.body.iq: if res.body.iq:
jingles = res.body.iq.findAll('jingle') jingles = res.body.iq.findAll('jingle')
if len(jingles): if len(jingles):
@ -232,15 +233,15 @@ class TrivialXmppClient:
elif 'type' in res.body and res.body['type'] == 'terminate': elif 'type' in res.body and res.body['type'] == 'terminate':
self.running = False self.running = False
del xmppClients[self.matrixRoom] del xmppClients[self.matrixRoom]
return return
def handleInvite(self, jingle): def handleInvite(self, jingle):
self.initiator = jingle['initiator'] self.initiator = jingle['initiator']
self.callsid = jingle['sid'] self.callsid = jingle['sid']
p = subprocess.Popen(['node', 'unjingle/unjingle.js', '--jingle'], stdin=subprocess.PIPE, stdout=subprocess.PIPE) p = subprocess.Popen(['node', 'unjingle/unjingle.js', '--jingle'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
print "raw jingle invite",str(jingle) print("raw jingle invite",str(jingle))
sdp, out_err = p.communicate(str(jingle)) sdp, out_err = p.communicate(str(jingle))
print "transformed remote offer sdp",sdp print("transformed remote offer sdp",sdp)
inviteEvent = { inviteEvent = {
'offer': { 'offer': {
'type': 'offer', 'type': 'offer',
@ -252,7 +253,7 @@ class TrivialXmppClient:
} }
matrixCli.sendEvent(self.matrixRoom, 'm.call.invite', inviteEvent) matrixCli.sendEvent(self.matrixRoom, 'm.call.invite', inviteEvent)
matrixCli = TrivialMatrixClient(ACCESS_TOKEN) matrixCli = TrivialMatrixClient(ACCESS_TOKEN) # Undefined name
gevent.joinall([ gevent.joinall([
gevent.spawn(matrixLoop) gevent.spawn(matrixLoop)

View file

@ -1,10 +1,16 @@
#!/usr/bin/env python #!/usr/bin/env python
from __future__ import print_function
from argparse import ArgumentParser from argparse import ArgumentParser
import json import json
import requests import requests
import sys import sys
import urllib import urllib
try:
raw_input
except NameError: # Python 3
raw_input = input
def _mkurl(template, kws): def _mkurl(template, kws):
for key in kws: for key in kws:
template = template.replace(key, kws[key]) template = template.replace(key, kws[key])
@ -13,7 +19,7 @@ def _mkurl(template, kws):
def main(hs, room_id, access_token, user_id_prefix, why): def main(hs, room_id, access_token, user_id_prefix, why):
if not why: if not why:
why = "Automated kick." why = "Automated kick."
print "Kicking members on %s in room %s matching %s" % (hs, room_id, user_id_prefix) print("Kicking members on %s in room %s matching %s" % (hs, room_id, user_id_prefix))
room_state_url = _mkurl( room_state_url = _mkurl(
"$HS/_matrix/client/api/v1/rooms/$ROOM/state?access_token=$TOKEN", "$HS/_matrix/client/api/v1/rooms/$ROOM/state?access_token=$TOKEN",
{ {
@ -22,13 +28,13 @@ def main(hs, room_id, access_token, user_id_prefix, why):
"$TOKEN": access_token "$TOKEN": access_token
} }
) )
print "Getting room state => %s" % room_state_url print("Getting room state => %s" % room_state_url)
res = requests.get(room_state_url) res = requests.get(room_state_url)
print "HTTP %s" % res.status_code print("HTTP %s" % res.status_code)
state_events = res.json() state_events = res.json()
if "error" in state_events: if "error" in state_events:
print "FATAL" print("FATAL")
print state_events print(state_events)
return return
kick_list = [] kick_list = []
@ -44,15 +50,15 @@ def main(hs, room_id, access_token, user_id_prefix, why):
kick_list.append(event["state_key"]) kick_list.append(event["state_key"])
if len(kick_list) == 0: if len(kick_list) == 0:
print "No user IDs match the prefix '%s'" % user_id_prefix print("No user IDs match the prefix '%s'" % user_id_prefix)
return return
print "The following user IDs will be kicked from %s" % room_name print("The following user IDs will be kicked from %s" % room_name)
for uid in kick_list: for uid in kick_list:
print uid print(uid)
doit = raw_input("Continue? [Y]es\n") doit = raw_input("Continue? [Y]es\n")
if len(doit) > 0 and doit.lower() == 'y': if len(doit) > 0 and doit.lower() == 'y':
print "Kicking members..." print("Kicking members...")
# encode them all # encode them all
kick_list = [urllib.quote(uid) for uid in kick_list] kick_list = [urllib.quote(uid) for uid in kick_list]
for uid in kick_list: for uid in kick_list:
@ -69,14 +75,14 @@ def main(hs, room_id, access_token, user_id_prefix, why):
"membership": "leave", "membership": "leave",
"reason": why "reason": why
} }
print "Kicking %s" % uid print("Kicking %s" % uid)
res = requests.put(kick_url, data=json.dumps(kick_body)) res = requests.put(kick_url, data=json.dumps(kick_body))
if res.status_code != 200: if res.status_code != 200:
print "ERROR: HTTP %s" % res.status_code print("ERROR: HTTP %s" % res.status_code)
if res.json().get("error"): if res.json().get("error"):
print "ERROR: JSON %s" % res.json() print("ERROR: JSON %s" % res.json())
if __name__ == "__main__": if __name__ == "__main__":
parser = ArgumentParser("Kick members in a room matching a certain user ID prefix.") parser = ArgumentParser("Kick members in a room matching a certain user ID prefix.")