Run Black. (#5482)
This commit is contained in:
@@ -5,8 +5,8 @@ steps:
|
||||
|
||||
- command:
|
||||
- "python -m pip install tox"
|
||||
- "tox -e pep8"
|
||||
label: "\U0001F9F9 PEP-8"
|
||||
- "tox -e check_codestyle"
|
||||
label: "\U0001F9F9 Check Style"
|
||||
plugins:
|
||||
- docker#v3.0.1:
|
||||
image: "python:3.6"
|
||||
|
||||
1
changelog.d/5482.misc
Normal file
1
changelog.d/5482.misc
Normal file
@@ -0,0 +1 @@
|
||||
Synapse's codebase is now formatted by `black`.
|
||||
@@ -37,9 +37,8 @@ from signedjson.sign import verify_signed_json, SignatureVerifyException
|
||||
|
||||
CONFIG_JSON = "cmdclient_config.json"
|
||||
|
||||
TRUSTED_ID_SERVERS = [
|
||||
'localhost:8001'
|
||||
]
|
||||
TRUSTED_ID_SERVERS = ["localhost:8001"]
|
||||
|
||||
|
||||
class SynapseCmd(cmd.Cmd):
|
||||
|
||||
@@ -59,7 +58,7 @@ class SynapseCmd(cmd.Cmd):
|
||||
"token": token,
|
||||
"verbose": "on",
|
||||
"complete_usernames": "on",
|
||||
"send_delivery_receipts": "on"
|
||||
"send_delivery_receipts": "on",
|
||||
}
|
||||
self.path_prefix = "/_matrix/client/api/v1"
|
||||
self.event_stream_token = "END"
|
||||
@@ -120,12 +119,11 @@ class SynapseCmd(cmd.Cmd):
|
||||
config_rules = [ # key, valid_values
|
||||
("verbose", ["on", "off"]),
|
||||
("complete_usernames", ["on", "off"]),
|
||||
("send_delivery_receipts", ["on", "off"])
|
||||
("send_delivery_receipts", ["on", "off"]),
|
||||
]
|
||||
for key, valid_vals in config_rules:
|
||||
if key == args["key"] and args["val"] not in valid_vals:
|
||||
print("%s value must be one of %s" % (args["key"],
|
||||
valid_vals))
|
||||
print("%s value must be one of %s" % (args["key"], valid_vals))
|
||||
return
|
||||
|
||||
# toggle the http client verbosity
|
||||
@@ -159,16 +157,13 @@ class SynapseCmd(cmd.Cmd):
|
||||
else:
|
||||
password = pwd
|
||||
|
||||
body = {
|
||||
"type": "m.login.password"
|
||||
}
|
||||
body = {"type": "m.login.password"}
|
||||
if "userid" in args:
|
||||
body["user"] = args["userid"]
|
||||
if password:
|
||||
body["password"] = password
|
||||
|
||||
reactor.callFromThread(self._do_register, body,
|
||||
"noupdate" not in args)
|
||||
reactor.callFromThread(self._do_register, body, "noupdate" not in args)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def _do_register(self, data, update_config):
|
||||
@@ -179,7 +174,9 @@ class SynapseCmd(cmd.Cmd):
|
||||
|
||||
passwordFlow = None
|
||||
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.")
|
||||
return
|
||||
if flow["type"] == "m.login.password" and "stages" not in flow:
|
||||
@@ -202,9 +199,7 @@ class SynapseCmd(cmd.Cmd):
|
||||
"""
|
||||
try:
|
||||
args = self._parse(line, ["user_id"], force_keys=True)
|
||||
can_login = threads.blockingCallFromThread(
|
||||
reactor,
|
||||
self._check_can_login)
|
||||
can_login = threads.blockingCallFromThread(reactor, self._check_can_login)
|
||||
if can_login:
|
||||
p = getpass.getpass("Enter your password: ")
|
||||
user = args["user_id"]
|
||||
@@ -212,20 +207,16 @@ class SynapseCmd(cmd.Cmd):
|
||||
domain = self._domain()
|
||||
if domain:
|
||||
user = "@" + user + ":" + domain
|
||||
|
||||
|
||||
reactor.callFromThread(self._do_login, user, p)
|
||||
#print " got %s " % p
|
||||
# print " got %s " % p
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def _do_login(self, user, password):
|
||||
path = "/login"
|
||||
data = {
|
||||
"user": user,
|
||||
"password": password,
|
||||
"type": "m.login.password"
|
||||
}
|
||||
data = {"user": user, "password": password, "type": "m.login.password"}
|
||||
url = self._url() + path
|
||||
json_res = yield self.http_client.do_request("POST", url, data=data)
|
||||
print(json_res)
|
||||
@@ -249,12 +240,13 @@ class SynapseCmd(cmd.Cmd):
|
||||
print("Failed to find any login flows.")
|
||||
defer.returnValue(False)
|
||||
|
||||
flow = json_res["flows"][0] # assume first is the one we want.
|
||||
if ("type" not in flow or "m.login.password" != flow["type"] or
|
||||
"stages" in flow):
|
||||
flow = json_res["flows"][0] # assume first is the one we want.
|
||||
if "type" not in flow or "m.login.password" != flow["type"] or "stages" in flow:
|
||||
fallback_url = self._url() + "/login/fallback"
|
||||
print ("Unable to login via the command line client. Please visit "
|
||||
"%s to login." % fallback_url)
|
||||
print(
|
||||
"Unable to login via the command line client. Please visit "
|
||||
"%s to login." % fallback_url
|
||||
)
|
||||
defer.returnValue(False)
|
||||
defer.returnValue(True)
|
||||
|
||||
@@ -264,21 +256,33 @@ class SynapseCmd(cmd.Cmd):
|
||||
<clientSecret> A string of characters generated when requesting an email that you'll supply in subsequent calls to identify yourself
|
||||
<sendAttempt> The number of times the user has requested an email. Leave this the same between requests to retry the request at the transport level. Increment it to request that the email be sent again.
|
||||
"""
|
||||
args = self._parse(line, ['address', 'clientSecret', 'sendAttempt'])
|
||||
args = self._parse(line, ["address", "clientSecret", "sendAttempt"])
|
||||
|
||||
postArgs = {'email': args['address'], 'clientSecret': args['clientSecret'], 'sendAttempt': args['sendAttempt']}
|
||||
postArgs = {
|
||||
"email": args["address"],
|
||||
"clientSecret": args["clientSecret"],
|
||||
"sendAttempt": args["sendAttempt"],
|
||||
}
|
||||
|
||||
reactor.callFromThread(self._do_emailrequest, postArgs)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def _do_emailrequest(self, args):
|
||||
url = self._identityServerUrl()+"/_matrix/identity/api/v1/validate/email/requestToken"
|
||||
url = (
|
||||
self._identityServerUrl()
|
||||
+ "/_matrix/identity/api/v1/validate/email/requestToken"
|
||||
)
|
||||
|
||||
json_res = yield self.http_client.do_request("POST", url, data=urllib.urlencode(args), jsonreq=False,
|
||||
headers={'Content-Type': ['application/x-www-form-urlencoded']})
|
||||
json_res = yield self.http_client.do_request(
|
||||
"POST",
|
||||
url,
|
||||
data=urllib.urlencode(args),
|
||||
jsonreq=False,
|
||||
headers={"Content-Type": ["application/x-www-form-urlencoded"]},
|
||||
)
|
||||
print(json_res)
|
||||
if 'sid' in json_res:
|
||||
print("Token sent. Your session ID is %s" % (json_res['sid']))
|
||||
if "sid" in json_res:
|
||||
print("Token sent. Your session ID is %s" % (json_res["sid"]))
|
||||
|
||||
def do_emailvalidate(self, line):
|
||||
"""Validate and associate a third party ID
|
||||
@@ -286,18 +290,30 @@ class SynapseCmd(cmd.Cmd):
|
||||
<token> The token sent to your third party identifier address
|
||||
<clientSecret> The same clientSecret you supplied in requestToken
|
||||
"""
|
||||
args = self._parse(line, ['sid', 'token', 'clientSecret'])
|
||||
args = self._parse(line, ["sid", "token", "clientSecret"])
|
||||
|
||||
postArgs = { 'sid' : args['sid'], 'token' : args['token'], 'clientSecret': args['clientSecret'] }
|
||||
postArgs = {
|
||||
"sid": args["sid"],
|
||||
"token": args["token"],
|
||||
"clientSecret": args["clientSecret"],
|
||||
}
|
||||
|
||||
reactor.callFromThread(self._do_emailvalidate, postArgs)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def _do_emailvalidate(self, args):
|
||||
url = self._identityServerUrl()+"/_matrix/identity/api/v1/validate/email/submitToken"
|
||||
url = (
|
||||
self._identityServerUrl()
|
||||
+ "/_matrix/identity/api/v1/validate/email/submitToken"
|
||||
)
|
||||
|
||||
json_res = yield self.http_client.do_request("POST", url, data=urllib.urlencode(args), jsonreq=False,
|
||||
headers={'Content-Type': ['application/x-www-form-urlencoded']})
|
||||
json_res = yield self.http_client.do_request(
|
||||
"POST",
|
||||
url,
|
||||
data=urllib.urlencode(args),
|
||||
jsonreq=False,
|
||||
headers={"Content-Type": ["application/x-www-form-urlencoded"]},
|
||||
)
|
||||
print(json_res)
|
||||
|
||||
def do_3pidbind(self, line):
|
||||
@@ -305,19 +321,24 @@ class SynapseCmd(cmd.Cmd):
|
||||
<sid> The session ID (sid) given to you in the response to requestToken
|
||||
<clientSecret> The same clientSecret you supplied in requestToken
|
||||
"""
|
||||
args = self._parse(line, ['sid', 'clientSecret'])
|
||||
args = self._parse(line, ["sid", "clientSecret"])
|
||||
|
||||
postArgs = { 'sid' : args['sid'], 'clientSecret': args['clientSecret'] }
|
||||
postArgs['mxid'] = self.config["user"]
|
||||
postArgs = {"sid": args["sid"], "clientSecret": args["clientSecret"]}
|
||||
postArgs["mxid"] = self.config["user"]
|
||||
|
||||
reactor.callFromThread(self._do_3pidbind, postArgs)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def _do_3pidbind(self, args):
|
||||
url = self._identityServerUrl()+"/_matrix/identity/api/v1/3pid/bind"
|
||||
url = self._identityServerUrl() + "/_matrix/identity/api/v1/3pid/bind"
|
||||
|
||||
json_res = yield self.http_client.do_request("POST", url, data=urllib.urlencode(args), jsonreq=False,
|
||||
headers={'Content-Type': ['application/x-www-form-urlencoded']})
|
||||
json_res = yield self.http_client.do_request(
|
||||
"POST",
|
||||
url,
|
||||
data=urllib.urlencode(args),
|
||||
jsonreq=False,
|
||||
headers={"Content-Type": ["application/x-www-form-urlencoded"]},
|
||||
)
|
||||
print(json_res)
|
||||
|
||||
def do_join(self, line):
|
||||
@@ -356,9 +377,7 @@ class SynapseCmd(cmd.Cmd):
|
||||
if "topic" not in args:
|
||||
print("Must specify a new topic.")
|
||||
return
|
||||
body = {
|
||||
"topic": args["topic"]
|
||||
}
|
||||
body = {"topic": args["topic"]}
|
||||
reactor.callFromThread(self._run_and_pprint, "PUT", path, body)
|
||||
elif args["action"].lower() == "get":
|
||||
reactor.callFromThread(self._run_and_pprint, "GET", path)
|
||||
@@ -378,45 +397,60 @@ class SynapseCmd(cmd.Cmd):
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def _do_invite(self, roomid, userstring):
|
||||
if (not userstring.startswith('@') and
|
||||
self._is_on("complete_usernames")):
|
||||
url = self._identityServerUrl()+"/_matrix/identity/api/v1/lookup"
|
||||
if not userstring.startswith("@") and self._is_on("complete_usernames"):
|
||||
url = self._identityServerUrl() + "/_matrix/identity/api/v1/lookup"
|
||||
|
||||
json_res = yield self.http_client.do_request("GET", url, qparams={'medium':'email','address':userstring})
|
||||
json_res = yield self.http_client.do_request(
|
||||
"GET", url, qparams={"medium": "email", "address": userstring}
|
||||
)
|
||||
|
||||
mxid = None
|
||||
|
||||
if 'mxid' in json_res and 'signatures' in json_res:
|
||||
url = self._identityServerUrl()+"/_matrix/identity/api/v1/pubkey/ed25519"
|
||||
if "mxid" in json_res and "signatures" in json_res:
|
||||
url = (
|
||||
self._identityServerUrl()
|
||||
+ "/_matrix/identity/api/v1/pubkey/ed25519"
|
||||
)
|
||||
|
||||
pubKey = None
|
||||
pubKeyObj = yield self.http_client.do_request("GET", url)
|
||||
if 'public_key' in pubKeyObj:
|
||||
pubKey = nacl.signing.VerifyKey(pubKeyObj['public_key'], encoder=nacl.encoding.HexEncoder)
|
||||
if "public_key" in pubKeyObj:
|
||||
pubKey = nacl.signing.VerifyKey(
|
||||
pubKeyObj["public_key"], encoder=nacl.encoding.HexEncoder
|
||||
)
|
||||
else:
|
||||
print("No public key found in pubkey response!")
|
||||
|
||||
sigValid = False
|
||||
|
||||
if pubKey:
|
||||
for signame in json_res['signatures']:
|
||||
for signame in json_res["signatures"]:
|
||||
if signame not in TRUSTED_ID_SERVERS:
|
||||
print("Ignoring signature from untrusted server %s" % (signame))
|
||||
print(
|
||||
"Ignoring signature from untrusted server %s"
|
||||
% (signame)
|
||||
)
|
||||
else:
|
||||
try:
|
||||
verify_signed_json(json_res, signame, pubKey)
|
||||
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
|
||||
except SignatureVerifyException as e:
|
||||
print("Invalid signature from %s" % (signame))
|
||||
print(e)
|
||||
|
||||
if sigValid:
|
||||
print("Resolved 3pid %s to %s" % (userstring, json_res['mxid']))
|
||||
mxid = json_res['mxid']
|
||||
print("Resolved 3pid %s to %s" % (userstring, json_res["mxid"]))
|
||||
mxid = json_res["mxid"]
|
||||
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:
|
||||
mxid = "@" + userstring + ":" + self._domain()
|
||||
@@ -435,12 +469,11 @@ class SynapseCmd(cmd.Cmd):
|
||||
"""Sends a message. "send <roomid> <body>" """
|
||||
args = self._parse(line, ["roomid", "body"])
|
||||
txn_id = "txn%s" % int(time.time())
|
||||
path = "/rooms/%s/send/m.room.message/%s" % (urllib.quote(args["roomid"]),
|
||||
txn_id)
|
||||
body_json = {
|
||||
"msgtype": "m.text",
|
||||
"body": args["body"]
|
||||
}
|
||||
path = "/rooms/%s/send/m.room.message/%s" % (
|
||||
urllib.quote(args["roomid"]),
|
||||
txn_id,
|
||||
)
|
||||
body_json = {"msgtype": "m.text", "body": args["body"]}
|
||||
reactor.callFromThread(self._run_and_pprint, "PUT", path, body_json)
|
||||
|
||||
def do_list(self, line):
|
||||
@@ -472,8 +505,7 @@ class SynapseCmd(cmd.Cmd):
|
||||
print("Bad query param: %s" % key_value)
|
||||
return
|
||||
|
||||
reactor.callFromThread(self._run_and_pprint, "GET", path,
|
||||
query_params=qp)
|
||||
reactor.callFromThread(self._run_and_pprint, "GET", path, query_params=qp)
|
||||
|
||||
def do_create(self, line):
|
||||
"""Creates a room.
|
||||
@@ -513,8 +545,16 @@ class SynapseCmd(cmd.Cmd):
|
||||
return
|
||||
|
||||
args["method"] = args["method"].upper()
|
||||
valid_methods = ["PUT", "GET", "POST", "DELETE",
|
||||
"XPUT", "XGET", "XPOST", "XDELETE"]
|
||||
valid_methods = [
|
||||
"PUT",
|
||||
"GET",
|
||||
"POST",
|
||||
"DELETE",
|
||||
"XPUT",
|
||||
"XGET",
|
||||
"XPOST",
|
||||
"XDELETE",
|
||||
]
|
||||
if args["method"] not in valid_methods:
|
||||
print("Unsupported method: %s" % args["method"])
|
||||
return
|
||||
@@ -541,10 +581,13 @@ class SynapseCmd(cmd.Cmd):
|
||||
except:
|
||||
pass
|
||||
|
||||
reactor.callFromThread(self._run_and_pprint, args["method"],
|
||||
args["path"],
|
||||
args["data"],
|
||||
query_params=qp)
|
||||
reactor.callFromThread(
|
||||
self._run_and_pprint,
|
||||
args["method"],
|
||||
args["path"],
|
||||
args["data"],
|
||||
query_params=qp,
|
||||
)
|
||||
|
||||
def do_stream(self, line):
|
||||
"""Stream data from the server: "stream <longpoll timeout ms>" """
|
||||
@@ -561,19 +604,22 @@ class SynapseCmd(cmd.Cmd):
|
||||
@defer.inlineCallbacks
|
||||
def _do_event_stream(self, timeout):
|
||||
res = yield self.http_client.get_json(
|
||||
self._url() + "/events",
|
||||
{
|
||||
"access_token": self._tok(),
|
||||
"timeout": str(timeout),
|
||||
"from": self.event_stream_token
|
||||
})
|
||||
self._url() + "/events",
|
||||
{
|
||||
"access_token": self._tok(),
|
||||
"timeout": str(timeout),
|
||||
"from": self.event_stream_token,
|
||||
},
|
||||
)
|
||||
print(json.dumps(res, indent=4))
|
||||
|
||||
if "chunk" in res:
|
||||
for event in res["chunk"]:
|
||||
if (event["type"] == "m.room.message" and
|
||||
self._is_on("send_delivery_receipts") and
|
||||
event["user_id"] != self._usr()): # not sent by us
|
||||
if (
|
||||
event["type"] == "m.room.message"
|
||||
and self._is_on("send_delivery_receipts")
|
||||
and event["user_id"] != self._usr()
|
||||
): # not sent by us
|
||||
self._send_receipt(event, "d")
|
||||
|
||||
# update the position in the stram
|
||||
@@ -581,18 +627,28 @@ class SynapseCmd(cmd.Cmd):
|
||||
self.event_stream_token = res["end"]
|
||||
|
||||
def _send_receipt(self, event, feedback_type):
|
||||
path = ("/rooms/%s/messages/%s/%s/feedback/%s/%s" %
|
||||
(urllib.quote(event["room_id"]), event["user_id"], event["msg_id"],
|
||||
self._usr(), feedback_type))
|
||||
path = "/rooms/%s/messages/%s/%s/feedback/%s/%s" % (
|
||||
urllib.quote(event["room_id"]),
|
||||
event["user_id"],
|
||||
event["msg_id"],
|
||||
self._usr(),
|
||||
feedback_type,
|
||||
)
|
||||
data = {}
|
||||
reactor.callFromThread(self._run_and_pprint, "PUT", path, data=data,
|
||||
alt_text="Sent receipt for %s" % event["msg_id"])
|
||||
reactor.callFromThread(
|
||||
self._run_and_pprint,
|
||||
"PUT",
|
||||
path,
|
||||
data=data,
|
||||
alt_text="Sent receipt for %s" % event["msg_id"],
|
||||
)
|
||||
|
||||
def _do_membership_change(self, roomid, membership, userid):
|
||||
path = "/rooms/%s/state/m.room.member/%s" % (urllib.quote(roomid), urllib.quote(userid))
|
||||
data = {
|
||||
"membership": membership
|
||||
}
|
||||
path = "/rooms/%s/state/m.room.member/%s" % (
|
||||
urllib.quote(roomid),
|
||||
urllib.quote(userid),
|
||||
)
|
||||
data = {"membership": membership}
|
||||
reactor.callFromThread(self._run_and_pprint, "PUT", path, data=data)
|
||||
|
||||
def do_displayname(self, line):
|
||||
@@ -645,15 +701,20 @@ class SynapseCmd(cmd.Cmd):
|
||||
for i, arg in enumerate(line_args):
|
||||
for config_key in self.config:
|
||||
if ("$" + config_key) in arg:
|
||||
arg = arg.replace("$" + config_key,
|
||||
self.config[config_key])
|
||||
arg = arg.replace("$" + config_key, self.config[config_key])
|
||||
line_args[i] = arg
|
||||
|
||||
return dict(zip(keys, line_args))
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def _run_and_pprint(self, method, path, data=None,
|
||||
query_params={"access_token": None}, alt_text=None):
|
||||
def _run_and_pprint(
|
||||
self,
|
||||
method,
|
||||
path,
|
||||
data=None,
|
||||
query_params={"access_token": None},
|
||||
alt_text=None,
|
||||
):
|
||||
""" Runs an HTTP request and pretty prints the output.
|
||||
|
||||
Args:
|
||||
@@ -666,9 +727,9 @@ class SynapseCmd(cmd.Cmd):
|
||||
if "access_token" in query_params:
|
||||
query_params["access_token"] = self._tok()
|
||||
|
||||
json_res = yield self.http_client.do_request(method, url,
|
||||
data=data,
|
||||
qparams=query_params)
|
||||
json_res = yield self.http_client.do_request(
|
||||
method, url, data=data, qparams=query_params
|
||||
)
|
||||
if alt_text:
|
||||
print(alt_text)
|
||||
else:
|
||||
@@ -676,7 +737,7 @@ class SynapseCmd(cmd.Cmd):
|
||||
|
||||
|
||||
def save_config(config):
|
||||
with open(CONFIG_JSON, 'w') as out:
|
||||
with open(CONFIG_JSON, "w") as out:
|
||||
json.dump(config, out)
|
||||
|
||||
|
||||
@@ -700,7 +761,7 @@ def main(server_url, identity_server_url, username, token, config_path):
|
||||
global CONFIG_JSON
|
||||
CONFIG_JSON = config_path # bit cheeky, but just overwrite the global
|
||||
try:
|
||||
with open(config_path, 'r') as config:
|
||||
with open(config_path, "r") as config:
|
||||
syn_cmd.config = json.load(config)
|
||||
try:
|
||||
http_client.verbose = "on" == syn_cmd.config["verbose"]
|
||||
@@ -717,23 +778,33 @@ def main(server_url, identity_server_url, username, token, config_path):
|
||||
reactor.run()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser("Starts a synapse client.")
|
||||
parser.add_argument(
|
||||
"-s", "--server", dest="server", default="http://localhost:8008",
|
||||
help="The URL of the home server to talk to.")
|
||||
"-s",
|
||||
"--server",
|
||||
dest="server",
|
||||
default="http://localhost:8008",
|
||||
help="The URL of the home server to talk to.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-i", "--identity-server", dest="identityserver", default="http://localhost:8090",
|
||||
help="The URL of the identity server to talk to.")
|
||||
"-i",
|
||||
"--identity-server",
|
||||
dest="identityserver",
|
||||
default="http://localhost:8090",
|
||||
help="The URL of the identity server to talk to.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-u", "--username", dest="username",
|
||||
help="Your username on the server.")
|
||||
"-u", "--username", dest="username", help="Your username on the server."
|
||||
)
|
||||
parser.add_argument("-t", "--token", dest="token", help="Your access token.")
|
||||
parser.add_argument(
|
||||
"-t", "--token", dest="token",
|
||||
help="Your access token.")
|
||||
parser.add_argument(
|
||||
"-c", "--config", dest="config", default=CONFIG_JSON,
|
||||
help="The location of the config.json file to read from.")
|
||||
"-c",
|
||||
"--config",
|
||||
dest="config",
|
||||
default=CONFIG_JSON,
|
||||
help="The location of the config.json file to read from.",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.server:
|
||||
|
||||
@@ -73,9 +73,7 @@ class TwistedHttpClient(HttpClient):
|
||||
@defer.inlineCallbacks
|
||||
def put_json(self, url, data):
|
||||
response = yield self._create_put_request(
|
||||
url,
|
||||
data,
|
||||
headers_dict={"Content-Type": ["application/json"]}
|
||||
url, data, headers_dict={"Content-Type": ["application/json"]}
|
||||
)
|
||||
body = yield readBody(response)
|
||||
defer.returnValue((response.code, body))
|
||||
@@ -95,40 +93,34 @@ class TwistedHttpClient(HttpClient):
|
||||
"""
|
||||
|
||||
if "Content-Type" not in headers_dict:
|
||||
raise defer.error(
|
||||
RuntimeError("Must include Content-Type header for PUTs"))
|
||||
raise defer.error(RuntimeError("Must include Content-Type header for PUTs"))
|
||||
|
||||
return self._create_request(
|
||||
"PUT",
|
||||
url,
|
||||
producer=_JsonProducer(json_data),
|
||||
headers_dict=headers_dict
|
||||
"PUT", url, producer=_JsonProducer(json_data), headers_dict=headers_dict
|
||||
)
|
||||
|
||||
def _create_get_request(self, url, headers_dict={}):
|
||||
""" Wrapper of _create_request to issue a GET request
|
||||
"""
|
||||
return self._create_request(
|
||||
"GET",
|
||||
url,
|
||||
headers_dict=headers_dict
|
||||
)
|
||||
return self._create_request("GET", url, headers_dict=headers_dict)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def do_request(self, method, url, data=None, qparams=None, jsonreq=True, headers={}):
|
||||
def do_request(
|
||||
self, method, url, data=None, qparams=None, jsonreq=True, headers={}
|
||||
):
|
||||
if qparams:
|
||||
url = "%s?%s" % (url, urllib.urlencode(qparams, True))
|
||||
|
||||
if jsonreq:
|
||||
prod = _JsonProducer(data)
|
||||
headers['Content-Type'] = ["application/json"];
|
||||
headers["Content-Type"] = ["application/json"]
|
||||
else:
|
||||
prod = _RawProducer(data)
|
||||
|
||||
if method in ["POST", "PUT"]:
|
||||
response = yield self._create_request(method, url,
|
||||
producer=prod,
|
||||
headers_dict=headers)
|
||||
response = yield self._create_request(
|
||||
method, url, producer=prod, headers_dict=headers
|
||||
)
|
||||
else:
|
||||
response = yield self._create_request(method, url)
|
||||
|
||||
@@ -155,10 +147,7 @@ class TwistedHttpClient(HttpClient):
|
||||
while True:
|
||||
try:
|
||||
response = yield self.agent.request(
|
||||
method,
|
||||
url.encode("UTF8"),
|
||||
Headers(headers_dict),
|
||||
producer
|
||||
method, url.encode("UTF8"), Headers(headers_dict), producer
|
||||
)
|
||||
break
|
||||
except Exception as e:
|
||||
@@ -179,6 +168,7 @@ class TwistedHttpClient(HttpClient):
|
||||
reactor.callLater(seconds, d.callback, seconds)
|
||||
return d
|
||||
|
||||
|
||||
class _RawProducer(object):
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
@@ -195,9 +185,11 @@ class _RawProducer(object):
|
||||
def stopProducing(self):
|
||||
pass
|
||||
|
||||
|
||||
class _JsonProducer(object):
|
||||
""" Used by the twisted http client to create the HTTP body from json
|
||||
"""
|
||||
|
||||
def __init__(self, jsn):
|
||||
self.data = jsn
|
||||
self.body = json.dumps(jsn).encode("utf8")
|
||||
|
||||
@@ -19,13 +19,13 @@ from curses.ascii import isprint
|
||||
from twisted.internet import reactor
|
||||
|
||||
|
||||
class CursesStdIO():
|
||||
class CursesStdIO:
|
||||
def __init__(self, stdscr, callback=None):
|
||||
self.statusText = "Synapse test app -"
|
||||
self.searchText = ''
|
||||
self.searchText = ""
|
||||
self.stdscr = stdscr
|
||||
|
||||
self.logLine = ''
|
||||
self.logLine = ""
|
||||
|
||||
self.callback = callback
|
||||
|
||||
@@ -71,8 +71,7 @@ class CursesStdIO():
|
||||
i = 0
|
||||
index = len(self.lines) - 1
|
||||
while i < (self.rows - 3) and index >= 0:
|
||||
self.stdscr.addstr(self.rows - 3 - i, 0, self.lines[index],
|
||||
curses.A_NORMAL)
|
||||
self.stdscr.addstr(self.rows - 3 - i, 0, self.lines[index], curses.A_NORMAL)
|
||||
i = i + 1
|
||||
index = index - 1
|
||||
|
||||
@@ -85,15 +84,13 @@ class CursesStdIO():
|
||||
raise RuntimeError("TextTooLongError")
|
||||
|
||||
self.stdscr.addstr(
|
||||
self.rows - 2, 0,
|
||||
text + ' ' * (self.cols - len(text)),
|
||||
curses.A_STANDOUT)
|
||||
self.rows - 2, 0, text + " " * (self.cols - len(text)), curses.A_STANDOUT
|
||||
)
|
||||
|
||||
def printLogLine(self, text):
|
||||
self.stdscr.addstr(
|
||||
0, 0,
|
||||
text + ' ' * (self.cols - len(text)),
|
||||
curses.A_STANDOUT)
|
||||
0, 0, text + " " * (self.cols - len(text)), curses.A_STANDOUT
|
||||
)
|
||||
|
||||
def doRead(self):
|
||||
""" Input is ready! """
|
||||
@@ -105,7 +102,7 @@ class CursesStdIO():
|
||||
|
||||
elif c == curses.KEY_ENTER or c == 10:
|
||||
text = self.searchText
|
||||
self.searchText = ''
|
||||
self.searchText = ""
|
||||
|
||||
self.print_line(">> %s" % text)
|
||||
|
||||
@@ -122,11 +119,13 @@ class CursesStdIO():
|
||||
return
|
||||
self.searchText = self.searchText + chr(c)
|
||||
|
||||
self.stdscr.addstr(self.rows - 1, 0,
|
||||
self.searchText + (' ' * (
|
||||
self.cols - len(self.searchText) - 2)))
|
||||
self.stdscr.addstr(
|
||||
self.rows - 1,
|
||||
0,
|
||||
self.searchText + (" " * (self.cols - len(self.searchText) - 2)),
|
||||
)
|
||||
|
||||
self.paintStatus(self.statusText + ' %d' % len(self.searchText))
|
||||
self.paintStatus(self.statusText + " %d" % len(self.searchText))
|
||||
self.stdscr.move(self.rows - 1, len(self.searchText))
|
||||
self.stdscr.refresh()
|
||||
|
||||
@@ -143,7 +142,6 @@ class CursesStdIO():
|
||||
|
||||
|
||||
class Callback(object):
|
||||
|
||||
def __init__(self, stdio):
|
||||
self.stdio = stdio
|
||||
|
||||
@@ -152,7 +150,7 @@ class Callback(object):
|
||||
|
||||
|
||||
def main(stdscr):
|
||||
screen = CursesStdIO(stdscr) # create Screen object
|
||||
screen = CursesStdIO(stdscr) # create Screen object
|
||||
|
||||
callback = Callback(screen)
|
||||
|
||||
@@ -164,5 +162,5 @@ def main(stdscr):
|
||||
screen.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
curses.wrapper(main)
|
||||
|
||||
@@ -28,9 +28,7 @@ Currently assumes the local address is localhost:<port>
|
||||
"""
|
||||
|
||||
|
||||
from synapse.federation import (
|
||||
ReplicationHandler
|
||||
)
|
||||
from synapse.federation import ReplicationHandler
|
||||
|
||||
from synapse.federation.units import Pdu
|
||||
|
||||
@@ -38,7 +36,7 @@ from synapse.util import origin_from_ucid
|
||||
|
||||
from synapse.app.homeserver import SynapseHomeServer
|
||||
|
||||
#from synapse.util.logutils import log_function
|
||||
# from synapse.util.logutils import log_function
|
||||
|
||||
from twisted.internet import reactor, defer
|
||||
from twisted.python import log
|
||||
@@ -83,7 +81,7 @@ class InputOutput(object):
|
||||
room_name, = m.groups()
|
||||
self.print_line("%s joining %s" % (self.user, room_name))
|
||||
self.server.join_room(room_name, self.user, self.user)
|
||||
#self.print_line("OK.")
|
||||
# self.print_line("OK.")
|
||||
return
|
||||
|
||||
m = re.match("^invite (\S+) (\S+)$", line)
|
||||
@@ -92,7 +90,7 @@ class InputOutput(object):
|
||||
room_name, invitee = m.groups()
|
||||
self.print_line("%s invited to %s" % (invitee, room_name))
|
||||
self.server.invite_to_room(room_name, self.user, invitee)
|
||||
#self.print_line("OK.")
|
||||
# self.print_line("OK.")
|
||||
return
|
||||
|
||||
m = re.match("^send (\S+) (.*)$", line)
|
||||
@@ -101,7 +99,7 @@ class InputOutput(object):
|
||||
room_name, body = m.groups()
|
||||
self.print_line("%s send to %s" % (self.user, room_name))
|
||||
self.server.send_message(room_name, self.user, body)
|
||||
#self.print_line("OK.")
|
||||
# self.print_line("OK.")
|
||||
return
|
||||
|
||||
m = re.match("^backfill (\S+)$", line)
|
||||
@@ -125,7 +123,6 @@ class InputOutput(object):
|
||||
|
||||
|
||||
class IOLoggerHandler(logging.Handler):
|
||||
|
||||
def __init__(self, io):
|
||||
logging.Handler.__init__(self)
|
||||
self.io = io
|
||||
@@ -142,6 +139,7 @@ class Room(object):
|
||||
""" Used to store (in memory) the current membership state of a room, and
|
||||
which home servers we should send PDUs associated with the room to.
|
||||
"""
|
||||
|
||||
def __init__(self, room_name):
|
||||
self.room_name = room_name
|
||||
self.invited = set()
|
||||
@@ -175,6 +173,7 @@ class HomeServer(ReplicationHandler):
|
||||
""" A very basic home server implentation that allows people to join a
|
||||
room and then invite other people.
|
||||
"""
|
||||
|
||||
def __init__(self, server_name, replication_layer, output):
|
||||
self.server_name = server_name
|
||||
self.replication_layer = replication_layer
|
||||
@@ -197,26 +196,27 @@ class HomeServer(ReplicationHandler):
|
||||
elif pdu.content["membership"] == "invite":
|
||||
self._on_invite(pdu.origin, pdu.context, pdu.state_key)
|
||||
else:
|
||||
self.output.print_line("#%s (unrec) %s = %s" %
|
||||
(pdu.context, pdu.pdu_type, json.dumps(pdu.content))
|
||||
self.output.print_line(
|
||||
"#%s (unrec) %s = %s"
|
||||
% (pdu.context, pdu.pdu_type, json.dumps(pdu.content))
|
||||
)
|
||||
|
||||
#def on_state_change(self, pdu):
|
||||
##self.output.print_line("#%s (state) %s *** %s" %
|
||||
##(pdu.context, pdu.state_key, pdu.pdu_type)
|
||||
##)
|
||||
# def on_state_change(self, pdu):
|
||||
##self.output.print_line("#%s (state) %s *** %s" %
|
||||
##(pdu.context, pdu.state_key, pdu.pdu_type)
|
||||
##)
|
||||
|
||||
#if "joinee" in pdu.content:
|
||||
#self._on_join(pdu.context, pdu.content["joinee"])
|
||||
#elif "invitee" in pdu.content:
|
||||
#self._on_invite(pdu.origin, pdu.context, pdu.content["invitee"])
|
||||
# if "joinee" in pdu.content:
|
||||
# self._on_join(pdu.context, pdu.content["joinee"])
|
||||
# elif "invitee" in pdu.content:
|
||||
# self._on_invite(pdu.origin, pdu.context, pdu.content["invitee"])
|
||||
|
||||
def _on_message(self, pdu):
|
||||
""" We received a message
|
||||
"""
|
||||
self.output.print_line("#%s %s %s" %
|
||||
(pdu.context, pdu.content["sender"], pdu.content["body"])
|
||||
)
|
||||
self.output.print_line(
|
||||
"#%s %s %s" % (pdu.context, pdu.content["sender"], pdu.content["body"])
|
||||
)
|
||||
|
||||
def _on_join(self, context, joinee):
|
||||
""" Someone has joined a room, either a remote user or a local user
|
||||
@@ -224,9 +224,7 @@ class HomeServer(ReplicationHandler):
|
||||
room = self._get_or_create_room(context)
|
||||
room.add_participant(joinee)
|
||||
|
||||
self.output.print_line("#%s %s %s" %
|
||||
(context, joinee, "*** JOINED")
|
||||
)
|
||||
self.output.print_line("#%s %s %s" % (context, joinee, "*** JOINED"))
|
||||
|
||||
def _on_invite(self, origin, context, invitee):
|
||||
""" Someone has been invited
|
||||
@@ -234,9 +232,7 @@ class HomeServer(ReplicationHandler):
|
||||
room = self._get_or_create_room(context)
|
||||
room.add_invited(invitee)
|
||||
|
||||
self.output.print_line("#%s %s %s" %
|
||||
(context, invitee, "*** INVITED")
|
||||
)
|
||||
self.output.print_line("#%s %s %s" % (context, invitee, "*** INVITED"))
|
||||
|
||||
if not room.have_got_metadata and origin is not self.server_name:
|
||||
logger.debug("Get room state")
|
||||
@@ -272,14 +268,14 @@ class HomeServer(ReplicationHandler):
|
||||
|
||||
try:
|
||||
pdu = Pdu.create_new(
|
||||
context=room_name,
|
||||
pdu_type="sy.room.member",
|
||||
is_state=True,
|
||||
state_key=joinee,
|
||||
content={"membership": "join"},
|
||||
origin=self.server_name,
|
||||
destinations=destinations,
|
||||
)
|
||||
context=room_name,
|
||||
pdu_type="sy.room.member",
|
||||
is_state=True,
|
||||
state_key=joinee,
|
||||
content={"membership": "join"},
|
||||
origin=self.server_name,
|
||||
destinations=destinations,
|
||||
)
|
||||
yield self.replication_layer.send_pdu(pdu)
|
||||
except Exception as e:
|
||||
logger.exception(e)
|
||||
@@ -318,21 +314,21 @@ class HomeServer(ReplicationHandler):
|
||||
return self.replication_layer.backfill(dest, room_name, limit)
|
||||
|
||||
def _get_room_remote_servers(self, room_name):
|
||||
return [i for i in self.joined_rooms.setdefault(room_name,).servers]
|
||||
return [i for i in self.joined_rooms.setdefault(room_name).servers]
|
||||
|
||||
def _get_or_create_room(self, room_name):
|
||||
return self.joined_rooms.setdefault(room_name, Room(room_name))
|
||||
|
||||
def get_servers_for_context(self, context):
|
||||
return defer.succeed(
|
||||
self.joined_rooms.setdefault(context, Room(context)).servers
|
||||
)
|
||||
self.joined_rooms.setdefault(context, Room(context)).servers
|
||||
)
|
||||
|
||||
|
||||
def main(stdscr):
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('user', type=str)
|
||||
parser.add_argument('-v', '--verbose', action='count')
|
||||
parser.add_argument("user", type=str)
|
||||
parser.add_argument("-v", "--verbose", action="count")
|
||||
args = parser.parse_args()
|
||||
|
||||
user = args.user
|
||||
@@ -342,8 +338,9 @@ def main(stdscr):
|
||||
|
||||
root_logger = logging.getLogger()
|
||||
|
||||
formatter = logging.Formatter('%(asctime)s - %(name)s - %(lineno)d - '
|
||||
'%(levelname)s - %(message)s')
|
||||
formatter = logging.Formatter(
|
||||
"%(asctime)s - %(name)s - %(lineno)d - " "%(levelname)s - %(message)s"
|
||||
)
|
||||
if not os.path.exists("logs"):
|
||||
os.makedirs("logs")
|
||||
fh = logging.FileHandler("logs/%s" % user)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from __future__ import print_function
|
||||
|
||||
# Copyright 2014-2016 OpenMarket Ltd
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -58,9 +59,9 @@ def make_graph(pdus, room, filename_prefix):
|
||||
name = make_name(pdu.get("pdu_id"), pdu.get("origin"))
|
||||
pdu_map[name] = pdu
|
||||
|
||||
t = datetime.datetime.fromtimestamp(
|
||||
float(pdu["ts"]) / 1000
|
||||
).strftime('%Y-%m-%d %H:%M:%S,%f')
|
||||
t = datetime.datetime.fromtimestamp(float(pdu["ts"]) / 1000).strftime(
|
||||
"%Y-%m-%d %H:%M:%S,%f"
|
||||
)
|
||||
|
||||
label = (
|
||||
"<"
|
||||
@@ -80,11 +81,7 @@ def make_graph(pdus, room, filename_prefix):
|
||||
"depth": pdu.get("depth"),
|
||||
}
|
||||
|
||||
node = pydot.Node(
|
||||
name=name,
|
||||
label=label,
|
||||
color=color_map[pdu.get("origin")]
|
||||
)
|
||||
node = pydot.Node(name=name, label=label, color=color_map[pdu.get("origin")])
|
||||
node_map[name] = node
|
||||
graph.add_node(node)
|
||||
|
||||
@@ -108,14 +105,13 @@ def make_graph(pdus, room, filename_prefix):
|
||||
|
||||
if prev_state_name in node_map:
|
||||
state_edge = pydot.Edge(
|
||||
node_map[start_name], node_map[prev_state_name],
|
||||
style='dotted'
|
||||
node_map[start_name], node_map[prev_state_name], style="dotted"
|
||||
)
|
||||
graph.add_edge(state_edge)
|
||||
|
||||
graph.write('%s.dot' % filename_prefix, format='raw', prog='dot')
|
||||
# graph.write_png("%s.png" % filename_prefix, prog='dot')
|
||||
graph.write_svg("%s.svg" % filename_prefix, prog='dot')
|
||||
graph.write("%s.dot" % filename_prefix, format="raw", prog="dot")
|
||||
# graph.write_png("%s.png" % filename_prefix, prog='dot')
|
||||
graph.write_svg("%s.svg" % filename_prefix, prog="dot")
|
||||
|
||||
|
||||
def get_pdus(host, room):
|
||||
@@ -131,15 +127,14 @@ def get_pdus(host, room):
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Generate a PDU graph for a given room by talking "
|
||||
"to the given homeserver to get the list of PDUs. \n"
|
||||
"Requires pydot."
|
||||
"to the given homeserver to get the list of PDUs. \n"
|
||||
"Requires pydot."
|
||||
)
|
||||
parser.add_argument(
|
||||
"-p", "--prefix", dest="prefix",
|
||||
help="String to prefix output files with"
|
||||
"-p", "--prefix", dest="prefix", help="String to prefix output files with"
|
||||
)
|
||||
parser.add_argument('host')
|
||||
parser.add_argument('room')
|
||||
parser.add_argument("host")
|
||||
parser.add_argument("room")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
@@ -36,10 +36,7 @@ def make_graph(db_name, room_id, file_prefix, limit):
|
||||
args = [room_id]
|
||||
|
||||
if limit:
|
||||
sql += (
|
||||
" ORDER BY topological_ordering DESC, stream_ordering DESC "
|
||||
"LIMIT ?"
|
||||
)
|
||||
sql += " ORDER BY topological_ordering DESC, stream_ordering DESC " "LIMIT ?"
|
||||
|
||||
args.append(limit)
|
||||
|
||||
@@ -56,9 +53,8 @@ def make_graph(db_name, room_id, file_prefix, limit):
|
||||
|
||||
for event in events:
|
||||
c = conn.execute(
|
||||
"SELECT state_group FROM event_to_state_groups "
|
||||
"WHERE event_id = ?",
|
||||
(event.event_id,)
|
||||
"SELECT state_group FROM event_to_state_groups " "WHERE event_id = ?",
|
||||
(event.event_id,),
|
||||
)
|
||||
|
||||
res = c.fetchone()
|
||||
@@ -69,7 +65,7 @@ def make_graph(db_name, room_id, file_prefix, limit):
|
||||
|
||||
t = datetime.datetime.fromtimestamp(
|
||||
float(event.origin_server_ts) / 1000
|
||||
).strftime('%Y-%m-%d %H:%M:%S,%f')
|
||||
).strftime("%Y-%m-%d %H:%M:%S,%f")
|
||||
|
||||
content = json.dumps(unfreeze(event.get_dict()["content"]))
|
||||
|
||||
@@ -93,10 +89,7 @@ def make_graph(db_name, room_id, file_prefix, limit):
|
||||
"state_group": state_group,
|
||||
}
|
||||
|
||||
node = pydot.Node(
|
||||
name=event.event_id,
|
||||
label=label,
|
||||
)
|
||||
node = pydot.Node(name=event.event_id, label=label)
|
||||
|
||||
node_map[event.event_id] = node
|
||||
graph.add_node(node)
|
||||
@@ -106,10 +99,7 @@ def make_graph(db_name, room_id, file_prefix, limit):
|
||||
try:
|
||||
end_node = node_map[prev_id]
|
||||
except:
|
||||
end_node = pydot.Node(
|
||||
name=prev_id,
|
||||
label="<<b>%s</b>>" % (prev_id,),
|
||||
)
|
||||
end_node = pydot.Node(name=prev_id, label="<<b>%s</b>>" % (prev_id,))
|
||||
|
||||
node_map[prev_id] = end_node
|
||||
graph.add_node(end_node)
|
||||
@@ -121,36 +111,33 @@ def make_graph(db_name, room_id, file_prefix, limit):
|
||||
if len(event_ids) <= 1:
|
||||
continue
|
||||
|
||||
cluster = pydot.Cluster(
|
||||
str(group),
|
||||
label="<State Group: %s>" % (str(group),)
|
||||
)
|
||||
cluster = pydot.Cluster(str(group), label="<State Group: %s>" % (str(group),))
|
||||
|
||||
for event_id in event_ids:
|
||||
cluster.add_node(node_map[event_id])
|
||||
|
||||
graph.add_subgraph(cluster)
|
||||
|
||||
graph.write('%s.dot' % file_prefix, format='raw', prog='dot')
|
||||
graph.write_svg("%s.svg" % file_prefix, prog='dot')
|
||||
graph.write("%s.dot" % file_prefix, format="raw", prog="dot")
|
||||
graph.write_svg("%s.svg" % file_prefix, prog="dot")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Generate a PDU graph for a given room by talking "
|
||||
"to the given homeserver to get the list of PDUs. \n"
|
||||
"Requires pydot."
|
||||
"to the given homeserver to get the list of PDUs. \n"
|
||||
"Requires pydot."
|
||||
)
|
||||
parser.add_argument(
|
||||
"-p", "--prefix", dest="prefix",
|
||||
"-p",
|
||||
"--prefix",
|
||||
dest="prefix",
|
||||
help="String to prefix output files with",
|
||||
default="graph_output"
|
||||
default="graph_output",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-l", "--limit",
|
||||
help="Only retrieve the last N events.",
|
||||
)
|
||||
parser.add_argument('db')
|
||||
parser.add_argument('room')
|
||||
parser.add_argument("-l", "--limit", help="Only retrieve the last N events.")
|
||||
parser.add_argument("db")
|
||||
parser.add_argument("room")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from __future__ import print_function
|
||||
|
||||
# Copyright 2016 OpenMarket Ltd
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -42,7 +43,7 @@ def make_graph(file_name, room_id, file_prefix, limit):
|
||||
print("Sorted events")
|
||||
|
||||
if limit:
|
||||
events = events[-int(limit):]
|
||||
events = events[-int(limit) :]
|
||||
|
||||
node_map = {}
|
||||
|
||||
@@ -51,7 +52,7 @@ def make_graph(file_name, room_id, file_prefix, limit):
|
||||
for event in events:
|
||||
t = datetime.datetime.fromtimestamp(
|
||||
float(event.origin_server_ts) / 1000
|
||||
).strftime('%Y-%m-%d %H:%M:%S,%f')
|
||||
).strftime("%Y-%m-%d %H:%M:%S,%f")
|
||||
|
||||
content = json.dumps(unfreeze(event.get_dict()["content"]), indent=4)
|
||||
content = content.replace("\n", "<br/>\n")
|
||||
@@ -67,9 +68,10 @@ def make_graph(file_name, room_id, file_prefix, limit):
|
||||
value = json.dumps(value)
|
||||
|
||||
content.append(
|
||||
"<b>%s</b>: %s," % (
|
||||
cgi.escape(key, quote=True).encode("ascii", 'xmlcharrefreplace'),
|
||||
cgi.escape(value, quote=True).encode("ascii", 'xmlcharrefreplace'),
|
||||
"<b>%s</b>: %s,"
|
||||
% (
|
||||
cgi.escape(key, quote=True).encode("ascii", "xmlcharrefreplace"),
|
||||
cgi.escape(value, quote=True).encode("ascii", "xmlcharrefreplace"),
|
||||
)
|
||||
)
|
||||
|
||||
@@ -95,10 +97,7 @@ def make_graph(file_name, room_id, file_prefix, limit):
|
||||
"depth": event.depth,
|
||||
}
|
||||
|
||||
node = pydot.Node(
|
||||
name=event.event_id,
|
||||
label=label,
|
||||
)
|
||||
node = pydot.Node(name=event.event_id, label=label)
|
||||
|
||||
node_map[event.event_id] = node
|
||||
graph.add_node(node)
|
||||
@@ -110,10 +109,7 @@ def make_graph(file_name, room_id, file_prefix, limit):
|
||||
try:
|
||||
end_node = node_map[prev_id]
|
||||
except:
|
||||
end_node = pydot.Node(
|
||||
name=prev_id,
|
||||
label="<<b>%s</b>>" % (prev_id,),
|
||||
)
|
||||
end_node = pydot.Node(name=prev_id, label="<<b>%s</b>>" % (prev_id,))
|
||||
|
||||
node_map[prev_id] = end_node
|
||||
graph.add_node(end_node)
|
||||
@@ -123,31 +119,31 @@ def make_graph(file_name, room_id, file_prefix, limit):
|
||||
|
||||
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")
|
||||
|
||||
graph.write_svg("%s.svg" % file_prefix, prog='dot')
|
||||
graph.write_svg("%s.svg" % file_prefix, prog="dot")
|
||||
|
||||
print("Created svg")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Generate a PDU graph for a given room by reading "
|
||||
"from a file with line deliminated events. \n"
|
||||
"Requires pydot."
|
||||
"from a file with line deliminated events. \n"
|
||||
"Requires pydot."
|
||||
)
|
||||
parser.add_argument(
|
||||
"-p", "--prefix", dest="prefix",
|
||||
"-p",
|
||||
"--prefix",
|
||||
dest="prefix",
|
||||
help="String to prefix output files with",
|
||||
default="graph_output"
|
||||
default="graph_output",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-l", "--limit",
|
||||
help="Only retrieve the last N events.",
|
||||
)
|
||||
parser.add_argument('event_file')
|
||||
parser.add_argument('room')
|
||||
parser.add_argument("-l", "--limit", help="Only retrieve the last N events.")
|
||||
parser.add_argument("event_file")
|
||||
parser.add_argument("room")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
@@ -20,24 +20,25 @@ import urllib
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
#ACCESS_TOKEN="" #
|
||||
# ACCESS_TOKEN="" #
|
||||
|
||||
MATRIXBASE = 'https://matrix.org/_matrix/client/api/v1/'
|
||||
MYUSERNAME = '@davetest:matrix.org'
|
||||
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"
|
||||
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"
|
||||
HOST = "guest.jit.si"
|
||||
# HOST="jitsi.vuc.me"
|
||||
|
||||
TURNSERVER="turn.guest.jit.si"
|
||||
#TURNSERVER="turn.jitsi.vuc.me"
|
||||
TURNSERVER = "turn.guest.jit.si"
|
||||
# TURNSERVER="turn.jitsi.vuc.me"
|
||||
|
||||
ROOMDOMAIN = "meet.jit.si"
|
||||
# ROOMDOMAIN="conference.jitsi.vuc.me"
|
||||
|
||||
ROOMDOMAIN="meet.jit.si"
|
||||
#ROOMDOMAIN="conference.jitsi.vuc.me"
|
||||
|
||||
class TrivialMatrixClient:
|
||||
def __init__(self, access_token):
|
||||
@@ -46,38 +47,50 @@ class TrivialMatrixClient:
|
||||
|
||||
def getEvent(self):
|
||||
while True:
|
||||
url = MATRIXBASE+'events?access_token='+self.access_token+"&timeout=60000"
|
||||
url = (
|
||||
MATRIXBASE
|
||||
+ "events?access_token="
|
||||
+ self.access_token
|
||||
+ "&timeout=60000"
|
||||
)
|
||||
if self.token:
|
||||
url += "&from="+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:
|
||||
print("incoming from matrix", obj)
|
||||
if "end" not in obj:
|
||||
continue
|
||||
self.token = obj['end']
|
||||
if len(obj['chunk']):
|
||||
return obj['chunk'][0]
|
||||
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
|
||||
url = MATRIXBASE + "rooms/" + roomId + "/join?access_token=" + self.access_token
|
||||
print(url)
|
||||
headers={ 'Content-Type': 'application/json' }
|
||||
req = grequests.post(url, headers=headers, data='{}')
|
||||
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)
|
||||
print("response: ", obj)
|
||||
|
||||
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(json.dumps(event))
|
||||
headers={ 'Content-Type': 'application/json' }
|
||||
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)
|
||||
|
||||
print("response: ", obj)
|
||||
|
||||
|
||||
xmppClients = {}
|
||||
@@ -87,38 +100,39 @@ 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']
|
||||
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:
|
||||
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':
|
||||
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':
|
||||
# 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:
|
||||
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 = 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']]
|
||||
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):
|
||||
@@ -132,130 +146,155 @@ class TrivialXmppClient:
|
||||
|
||||
def nextRid(self):
|
||||
self.rid += 1
|
||||
return '%d' % (self.rid)
|
||||
return "%d" % (self.rid)
|
||||
|
||||
def sendIq(self, xml):
|
||||
fullXml = "<body rid='%s' xmlns='http://jabber.org/protocol/httpbind' sid='%s'>%s</body>" % (self.nextRid(), self.sid, xml)
|
||||
#print "\t>>>%s" % (fullXml)
|
||||
fullXml = (
|
||||
"<body rid='%s' xmlns='http://jabber.org/protocol/httpbind' sid='%s'>%s</body>"
|
||||
% (self.nextRid(), self.sid, xml)
|
||||
)
|
||||
# print "\t>>>%s" % (fullXml)
|
||||
return self.xmppPoke(fullXml)
|
||||
|
||||
def xmppPoke(self, xml):
|
||||
headers = {'Content-Type': 'application/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)
|
||||
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
|
||||
"tojid": self.callfrom,
|
||||
"action": "session-accept",
|
||||
"initiator": self.callfrom,
|
||||
"responder": self.jid,
|
||||
"sid": self.callsid,
|
||||
}
|
||||
print("answer jingle from sdp",jingle)
|
||||
print("answer jingle from sdp", jingle)
|
||||
res = self.sendIq(jingle)
|
||||
print("reply from answer: ",res)
|
||||
print("reply from answer: ", res)
|
||||
|
||||
self.ssrcs = {}
|
||||
jingleSoup = BeautifulSoup(jingle)
|
||||
for cont in jingleSoup.iq.jingle.findAll('content'):
|
||||
for cont in jingleSoup.iq.jingle.findAll("content"):
|
||||
if cont.description:
|
||||
self.ssrcs[cont['name']] = cont.description['ssrc']
|
||||
print("my ssrcs:",self.ssrcs)
|
||||
self.ssrcs[cont["name"]] = cont.description["ssrc"]
|
||||
print("my ssrcs:", self.ssrcs)
|
||||
|
||||
gevent.joinall([
|
||||
gevent.spawn(self.advertiseSsrcs)
|
||||
])
|
||||
gevent.joinall([gevent.spawn(self.advertiseSsrcs)])
|
||||
|
||||
def advertiseSsrcs(self):
|
||||
time.sleep(7)
|
||||
print("SSRC spammer started")
|
||||
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)
|
||||
print("reply from ssrc announce: ",res)
|
||||
print("reply from ssrc announce: ", res)
|
||||
time.sleep(10)
|
||||
|
||||
|
||||
|
||||
def xmppLoop(self):
|
||||
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)
|
||||
self.sid = res.body['sid']
|
||||
self.sid = res.body["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)
|
||||
|
||||
self.jid = res.body.iq.bind.jid.string
|
||||
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>"
|
||||
)
|
||||
|
||||
#randomthing = res.body.iq['to']
|
||||
#whatsitpart = randomthing.split('-')[0]
|
||||
# randomthing = res.body.iq['to']
|
||||
# whatsitpart = randomthing.split('-')[0]
|
||||
|
||||
#print "other random bind thing: %s" % (randomthing)
|
||||
# print "other random bind thing: %s" % (randomthing)
|
||||
|
||||
# advertise preence to the jitsi room, with our nick
|
||||
res = self.sendIq("<iq type='get' to='%s' xmlns='jabber:client' id='1:sendIQ'><services xmlns='urn:xmpp:extdisco:1'><service host='%s'/></services></iq><presence to='%s@%s/d98f6c40' 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'>%s</nick></presence>" % (HOST, TURNSERVER, ROOMNAME, ROOMDOMAIN, self.userId))
|
||||
self.muc = {'users': []}
|
||||
for p in res.body.findAll('presence'):
|
||||
res = self.sendIq(
|
||||
"<iq type='get' to='%s' xmlns='jabber:client' id='1:sendIQ'><services xmlns='urn:xmpp:extdisco:1'><service host='%s'/></services></iq><presence to='%s@%s/d98f6c40' 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'>%s</nick></presence>"
|
||||
% (HOST, TURNSERVER, ROOMNAME, ROOMDOMAIN, self.userId)
|
||||
)
|
||||
self.muc = {"users": []}
|
||||
for p in res.body.findAll("presence"):
|
||||
u = {}
|
||||
u['shortJid'] = p['from'].split('/')[1]
|
||||
u["shortJid"] = p["from"].split("/")[1]
|
||||
if p.c and p.c.nick:
|
||||
u['nick'] = p.c.nick.string
|
||||
self.muc['users'].append(u)
|
||||
print("muc: ",self.muc)
|
||||
u["nick"] = p.c.nick.string
|
||||
self.muc["users"].append(u)
|
||||
print("muc: ", self.muc)
|
||||
|
||||
# wait for stuff
|
||||
while True:
|
||||
print("waiting...")
|
||||
res = self.sendIq("")
|
||||
print("got from stream: ",res)
|
||||
print("got from stream: ", res)
|
||||
if res.body.iq:
|
||||
jingles = res.body.iq.findAll('jingle')
|
||||
jingles = res.body.iq.findAll("jingle")
|
||||
if len(jingles):
|
||||
self.callfrom = res.body.iq['from']
|
||||
self.callfrom = res.body.iq["from"]
|
||||
self.handleInvite(jingles[0])
|
||||
elif 'type' in res.body and res.body['type'] == 'terminate':
|
||||
elif "type" in res.body and res.body["type"] == "terminate":
|
||||
self.running = False
|
||||
del xmppClients[self.matrixRoom]
|
||||
return
|
||||
|
||||
def handleInvite(self, jingle):
|
||||
self.initiator = jingle['initiator']
|
||||
self.callsid = jingle['sid']
|
||||
p = subprocess.Popen(['node', 'unjingle/unjingle.js', '--jingle'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
||||
print("raw jingle invite",str(jingle))
|
||||
self.initiator = jingle["initiator"]
|
||||
self.callsid = jingle["sid"]
|
||||
p = subprocess.Popen(
|
||||
["node", "unjingle/unjingle.js", "--jingle"],
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
print("raw jingle invite", str(jingle))
|
||||
sdp, out_err = p.communicate(str(jingle))
|
||||
print("transformed remote offer sdp",sdp)
|
||||
print("transformed remote offer sdp", sdp)
|
||||
inviteEvent = {
|
||||
'offer': {
|
||||
'type': 'offer',
|
||||
'sdp': sdp
|
||||
},
|
||||
'call_id': self.matrixCallId,
|
||||
'version': 0,
|
||||
'lifetime': 30000
|
||||
"offer": {"type": "offer", "sdp": sdp},
|
||||
"call_id": self.matrixCallId,
|
||||
"version": 0,
|
||||
"lifetime": 30000,
|
||||
}
|
||||
matrixCli.sendEvent(self.matrixRoom, 'm.call.invite', inviteEvent)
|
||||
matrixCli.sendEvent(self.matrixRoom, "m.call.invite", inviteEvent)
|
||||
|
||||
|
||||
matrixCli = TrivialMatrixClient(ACCESS_TOKEN) # Undefined name
|
||||
|
||||
gevent.joinall([
|
||||
gevent.spawn(matrixLoop)
|
||||
])
|
||||
|
||||
gevent.joinall([gevent.spawn(matrixLoop)])
|
||||
|
||||
@@ -11,22 +11,22 @@ try:
|
||||
except NameError: # Python 3
|
||||
raw_input = input
|
||||
|
||||
|
||||
def _mkurl(template, kws):
|
||||
for key in kws:
|
||||
template = template.replace(key, kws[key])
|
||||
return template
|
||||
|
||||
|
||||
def main(hs, room_id, access_token, user_id_prefix, why):
|
||||
if not why:
|
||||
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(
|
||||
"$HS/_matrix/client/api/v1/rooms/$ROOM/state?access_token=$TOKEN",
|
||||
{
|
||||
"$HS": hs,
|
||||
"$ROOM": room_id,
|
||||
"$TOKEN": access_token
|
||||
}
|
||||
{"$HS": hs, "$ROOM": room_id, "$TOKEN": access_token},
|
||||
)
|
||||
print("Getting room state => %s" % room_state_url)
|
||||
res = requests.get(room_state_url)
|
||||
@@ -57,24 +57,16 @@ def main(hs, room_id, access_token, user_id_prefix, why):
|
||||
for uid in kick_list:
|
||||
print(uid)
|
||||
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...")
|
||||
# encode them all
|
||||
kick_list = [urllib.quote(uid) for uid in kick_list]
|
||||
for uid in kick_list:
|
||||
kick_url = _mkurl(
|
||||
"$HS/_matrix/client/api/v1/rooms/$ROOM/state/m.room.member/$UID?access_token=$TOKEN",
|
||||
{
|
||||
"$HS": hs,
|
||||
"$UID": uid,
|
||||
"$ROOM": room_id,
|
||||
"$TOKEN": access_token
|
||||
}
|
||||
{"$HS": hs, "$UID": uid, "$ROOM": room_id, "$TOKEN": access_token},
|
||||
)
|
||||
kick_body = {
|
||||
"membership": "leave",
|
||||
"reason": why
|
||||
}
|
||||
kick_body = {"membership": "leave", "reason": why}
|
||||
print("Kicking %s" % uid)
|
||||
res = requests.put(kick_url, data=json.dumps(kick_body))
|
||||
if res.status_code != 200:
|
||||
@@ -83,14 +75,15 @@ def main(hs, room_id, access_token, user_id_prefix, why):
|
||||
print("ERROR: JSON %s" % res.json())
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = ArgumentParser("Kick members in a room matching a certain user ID prefix.")
|
||||
parser.add_argument("-u","--user-id",help="The user ID prefix e.g. '@irc_'")
|
||||
parser.add_argument("-t","--token",help="Your access_token")
|
||||
parser.add_argument("-r","--room",help="The room ID to kick members in")
|
||||
parser.add_argument("-s","--homeserver",help="The base HS url e.g. http://matrix.org")
|
||||
parser.add_argument("-w","--why",help="Reason for the kick. Optional.")
|
||||
parser.add_argument("-u", "--user-id", help="The user ID prefix e.g. '@irc_'")
|
||||
parser.add_argument("-t", "--token", help="Your access_token")
|
||||
parser.add_argument("-r", "--room", help="The room ID to kick members in")
|
||||
parser.add_argument(
|
||||
"-s", "--homeserver", help="The base HS url e.g. http://matrix.org"
|
||||
)
|
||||
parser.add_argument("-w", "--why", help="Reason for the kick. Optional.")
|
||||
args = parser.parse_args()
|
||||
if not args.room or not args.token or not args.user_id or not args.homeserver:
|
||||
parser.print_help()
|
||||
|
||||
@@ -6,23 +6,25 @@ import cgi, logging
|
||||
|
||||
from daemonize import Daemonize
|
||||
|
||||
|
||||
class SimpleHTTPRequestHandlerWithPOST(SimpleHTTPServer.SimpleHTTPRequestHandler):
|
||||
UPLOAD_PATH = "upload"
|
||||
|
||||
"""
|
||||
Accept all post request as file upload
|
||||
"""
|
||||
|
||||
def do_POST(self):
|
||||
|
||||
path = os.path.join(self.UPLOAD_PATH, os.path.basename(self.path))
|
||||
length = self.headers['content-length']
|
||||
length = self.headers["content-length"]
|
||||
data = self.rfile.read(int(length))
|
||||
|
||||
with open(path, 'wb') as fh:
|
||||
with open(path, "wb") as fh:
|
||||
fh.write(data)
|
||||
|
||||
self.send_response(200)
|
||||
self.send_header('Content-Type', 'application/json')
|
||||
self.send_header("Content-Type", "application/json")
|
||||
self.end_headers()
|
||||
|
||||
# Return the absolute path of the uploaded file
|
||||
@@ -33,30 +35,25 @@ def setup():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("directory")
|
||||
parser.add_argument("-p", "--port", dest="port", type=int, default=8080)
|
||||
parser.add_argument('-P', "--pid-file", dest="pid", default="web.pid")
|
||||
parser.add_argument("-P", "--pid-file", dest="pid", default="web.pid")
|
||||
args = parser.parse_args()
|
||||
|
||||
# Get absolute path to directory to serve, as daemonize changes to '/'
|
||||
os.chdir(args.directory)
|
||||
dr = os.getcwd()
|
||||
|
||||
httpd = BaseHTTPServer.HTTPServer(
|
||||
('', args.port),
|
||||
SimpleHTTPRequestHandlerWithPOST
|
||||
)
|
||||
httpd = BaseHTTPServer.HTTPServer(("", args.port), SimpleHTTPRequestHandlerWithPOST)
|
||||
|
||||
def run():
|
||||
os.chdir(dr)
|
||||
httpd.serve_forever()
|
||||
|
||||
daemon = Daemonize(
|
||||
app="synapse-webclient",
|
||||
pid=args.pid,
|
||||
action=run,
|
||||
auto_close_fds=False,
|
||||
)
|
||||
app="synapse-webclient", pid=args.pid, action=run, auto_close_fds=False
|
||||
)
|
||||
|
||||
daemon.start()
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
if __name__ == "__main__":
|
||||
setup()
|
||||
|
||||
@@ -8,7 +8,10 @@ import glob
|
||||
import codecs
|
||||
|
||||
# Utility functions
|
||||
convert = lambda src, dst, environ: open(dst, "w").write(jinja2.Template(open(src).read()).render(**environ))
|
||||
convert = lambda src, dst, environ: open(dst, "w").write(
|
||||
jinja2.Template(open(src).read()).render(**environ)
|
||||
)
|
||||
|
||||
|
||||
def check_arguments(environ, args):
|
||||
for argument in args:
|
||||
@@ -16,18 +19,22 @@ def check_arguments(environ, args):
|
||||
print("Environment variable %s is mandatory, exiting." % argument)
|
||||
sys.exit(2)
|
||||
|
||||
|
||||
def generate_secrets(environ, secrets):
|
||||
for name, secret in secrets.items():
|
||||
if secret not in environ:
|
||||
filename = "/data/%s.%s.key" % (environ["SYNAPSE_SERVER_NAME"], name)
|
||||
if os.path.exists(filename):
|
||||
with open(filename) as handle: value = handle.read()
|
||||
with open(filename) as handle:
|
||||
value = handle.read()
|
||||
else:
|
||||
print("Generating a random secret for {}".format(name))
|
||||
value = codecs.encode(os.urandom(32), "hex").decode()
|
||||
with open(filename, "w") as handle: handle.write(value)
|
||||
with open(filename, "w") as handle:
|
||||
handle.write(value)
|
||||
environ[secret] = value
|
||||
|
||||
|
||||
# Prepare the configuration
|
||||
mode = sys.argv[1] if len(sys.argv) > 1 else None
|
||||
environ = os.environ.copy()
|
||||
@@ -36,12 +43,17 @@ args = ["python", "-m", "synapse.app.homeserver"]
|
||||
|
||||
# In generate mode, generate a configuration, missing keys, then exit
|
||||
if mode == "generate":
|
||||
check_arguments(environ, ("SYNAPSE_SERVER_NAME", "SYNAPSE_REPORT_STATS", "SYNAPSE_CONFIG_PATH"))
|
||||
check_arguments(
|
||||
environ, ("SYNAPSE_SERVER_NAME", "SYNAPSE_REPORT_STATS", "SYNAPSE_CONFIG_PATH")
|
||||
)
|
||||
args += [
|
||||
"--server-name", environ["SYNAPSE_SERVER_NAME"],
|
||||
"--report-stats", environ["SYNAPSE_REPORT_STATS"],
|
||||
"--config-path", environ["SYNAPSE_CONFIG_PATH"],
|
||||
"--generate-config"
|
||||
"--server-name",
|
||||
environ["SYNAPSE_SERVER_NAME"],
|
||||
"--report-stats",
|
||||
environ["SYNAPSE_REPORT_STATS"],
|
||||
"--config-path",
|
||||
environ["SYNAPSE_CONFIG_PATH"],
|
||||
"--generate-config",
|
||||
]
|
||||
os.execv("/usr/local/bin/python", args)
|
||||
|
||||
@@ -51,15 +63,19 @@ else:
|
||||
config_path = environ["SYNAPSE_CONFIG_PATH"]
|
||||
else:
|
||||
check_arguments(environ, ("SYNAPSE_SERVER_NAME", "SYNAPSE_REPORT_STATS"))
|
||||
generate_secrets(environ, {
|
||||
"registration": "SYNAPSE_REGISTRATION_SHARED_SECRET",
|
||||
"macaroon": "SYNAPSE_MACAROON_SECRET_KEY"
|
||||
})
|
||||
generate_secrets(
|
||||
environ,
|
||||
{
|
||||
"registration": "SYNAPSE_REGISTRATION_SHARED_SECRET",
|
||||
"macaroon": "SYNAPSE_MACAROON_SECRET_KEY",
|
||||
},
|
||||
)
|
||||
environ["SYNAPSE_APPSERVICES"] = glob.glob("/data/appservices/*.yaml")
|
||||
if not os.path.exists("/compiled"): os.mkdir("/compiled")
|
||||
if not os.path.exists("/compiled"):
|
||||
os.mkdir("/compiled")
|
||||
|
||||
config_path = "/compiled/homeserver.yaml"
|
||||
|
||||
|
||||
# Convert SYNAPSE_NO_TLS to boolean if exists
|
||||
if "SYNAPSE_NO_TLS" in environ:
|
||||
tlsanswerstring = str.lower(environ["SYNAPSE_NO_TLS"])
|
||||
@@ -69,19 +85,23 @@ else:
|
||||
if tlsanswerstring in ("false", "off", "0", "no"):
|
||||
environ["SYNAPSE_NO_TLS"] = False
|
||||
else:
|
||||
print("Environment variable \"SYNAPSE_NO_TLS\" found but value \"" + tlsanswerstring + "\" unrecognized; exiting.")
|
||||
print(
|
||||
'Environment variable "SYNAPSE_NO_TLS" found but value "'
|
||||
+ tlsanswerstring
|
||||
+ '" unrecognized; exiting.'
|
||||
)
|
||||
sys.exit(2)
|
||||
|
||||
convert("/conf/homeserver.yaml", config_path, environ)
|
||||
convert("/conf/log.config", "/compiled/log.config", environ)
|
||||
subprocess.check_output(["chown", "-R", ownership, "/data"])
|
||||
|
||||
|
||||
args += [
|
||||
"--config-path", config_path,
|
||||
|
||||
"--config-path",
|
||||
config_path,
|
||||
# tell synapse to put any generated keys in /data rather than /compiled
|
||||
"--keys-directory", "/data",
|
||||
"--keys-directory",
|
||||
"/data",
|
||||
]
|
||||
|
||||
# Generate missing keys and start synapse
|
||||
|
||||
@@ -18,226 +18,220 @@ import os
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
sys.path.insert(0, os.path.abspath('..'))
|
||||
sys.path.insert(0, os.path.abspath(".."))
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#needs_sphinx = '1.0'
|
||||
# needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.intersphinx',
|
||||
'sphinx.ext.coverage',
|
||||
'sphinx.ext.ifconfig',
|
||||
'sphinxcontrib.napoleon',
|
||||
"sphinx.ext.autodoc",
|
||||
"sphinx.ext.intersphinx",
|
||||
"sphinx.ext.coverage",
|
||||
"sphinx.ext.ifconfig",
|
||||
"sphinxcontrib.napoleon",
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
templates_path = ["_templates"]
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
source_suffix = ".rst"
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8-sig'
|
||||
# source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
master_doc = "index"
|
||||
|
||||
# General information about the project.
|
||||
project = u'Synapse'
|
||||
copyright = u'Copyright 2014-2017 OpenMarket Ltd, 2017 Vector Creations Ltd, 2017 New Vector Ltd'
|
||||
project = "Synapse"
|
||||
copyright = (
|
||||
"Copyright 2014-2017 OpenMarket Ltd, 2017 Vector Creations Ltd, 2017 New Vector Ltd"
|
||||
)
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '1.0'
|
||||
version = "1.0"
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '1.0'
|
||||
release = "1.0"
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#language = None
|
||||
# language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
# today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ['_build']
|
||||
exclude_patterns = ["_build"]
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all
|
||||
# documents.
|
||||
#default_role = None
|
||||
# default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
# add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
# add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
# show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
pygments_style = "sphinx"
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
# modindex_common_prefix = []
|
||||
|
||||
# If true, keep warnings as "system message" paragraphs in the built documents.
|
||||
#keep_warnings = False
|
||||
# keep_warnings = False
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = 'default'
|
||||
html_theme = "default"
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#html_theme_options = {}
|
||||
# html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
# html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
# html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
# html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
# html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
# html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
html_static_path = ["_static"]
|
||||
|
||||
# Add any extra paths that contain custom files (such as robots.txt or
|
||||
# .htaccess) here, relative to this directory. These files are copied
|
||||
# directly to the root of the documentation.
|
||||
#html_extra_path = []
|
||||
# html_extra_path = []
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
# html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
# html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
# html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
# html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_domain_indices = True
|
||||
# html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
# html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
# html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
# html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
#html_show_sphinx = True
|
||||
# html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
#html_show_copyright = True
|
||||
# html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
# html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = None
|
||||
# html_file_suffix = None
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'Synapsedoc'
|
||||
htmlhelp_basename = "Synapsedoc"
|
||||
|
||||
|
||||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#'preamble': '',
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#'papersize': 'letterpaper',
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#'pointsize': '10pt',
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#'preamble': '',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
('index', 'Synapse.tex', u'Synapse Documentation',
|
||||
u'TNG', 'manual'),
|
||||
]
|
||||
latex_documents = [("index", "Synapse.tex", "Synapse Documentation", "TNG", "manual")]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
# latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
# latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
#latex_show_pagerefs = False
|
||||
# latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
# latex_show_urls = False
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
# latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_domain_indices = True
|
||||
# latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output ---------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('index', 'synapse', u'Synapse Documentation',
|
||||
[u'TNG'], 1)
|
||||
]
|
||||
man_pages = [("index", "synapse", "Synapse Documentation", ["TNG"], 1)]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#man_show_urls = False
|
||||
# man_show_urls = False
|
||||
|
||||
|
||||
# -- Options for Texinfo output -------------------------------------------
|
||||
@@ -246,26 +240,32 @@ man_pages = [
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
('index', 'Synapse', u'Synapse Documentation',
|
||||
u'TNG', 'Synapse', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
(
|
||||
"index",
|
||||
"Synapse",
|
||||
"Synapse Documentation",
|
||||
"TNG",
|
||||
"Synapse",
|
||||
"One line description of project.",
|
||||
"Miscellaneous",
|
||||
)
|
||||
]
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#texinfo_appendices = []
|
||||
# texinfo_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#texinfo_domain_indices = True
|
||||
# texinfo_domain_indices = True
|
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||
#texinfo_show_urls = 'footnote'
|
||||
# texinfo_show_urls = 'footnote'
|
||||
|
||||
# If true, do not generate a @detailmenu in the "Top" node's menu.
|
||||
#texinfo_no_detailmenu = False
|
||||
# texinfo_no_detailmenu = False
|
||||
|
||||
|
||||
# Example configuration for intersphinx: refer to the Python standard library.
|
||||
intersphinx_mapping = {'http://docs.python.org/': None}
|
||||
intersphinx_mapping = {"http://docs.python.org/": None}
|
||||
|
||||
napoleon_include_special_with_doc = True
|
||||
napoleon_use_ivar = True
|
||||
|
||||
@@ -28,3 +28,22 @@
|
||||
directory = "misc"
|
||||
name = "Internal Changes"
|
||||
showcontent = true
|
||||
|
||||
[tool.black]
|
||||
target-version = ['py34']
|
||||
exclude = '''
|
||||
|
||||
(
|
||||
/(
|
||||
\.eggs # exclude a few common directories in the
|
||||
| \.git # root of the project
|
||||
| \.tox
|
||||
| \.venv
|
||||
| _build
|
||||
| _trial_temp.*
|
||||
| build
|
||||
| dist
|
||||
| debian
|
||||
)/
|
||||
)
|
||||
'''
|
||||
|
||||
@@ -39,11 +39,11 @@ def check_auth(auth, auth_chain, events):
|
||||
print("Success:", e.event_id, e.type, e.state_key)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument(
|
||||
'json', nargs='?', type=argparse.FileType('r'), default=sys.stdin
|
||||
"json", nargs="?", type=argparse.FileType("r"), default=sys.stdin
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
@@ -30,7 +30,7 @@ class dictobj(dict):
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"input_json", nargs="?", type=argparse.FileType('r'), default=sys.stdin
|
||||
"input_json", nargs="?", type=argparse.FileType("r"), default=sys.stdin
|
||||
)
|
||||
args = parser.parse_args()
|
||||
logging.basicConfig()
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import logging
|
||||
@@ -40,7 +39,7 @@ def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("signature_name")
|
||||
parser.add_argument(
|
||||
"input_json", nargs="?", type=argparse.FileType('r'), default=sys.stdin
|
||||
"input_json", nargs="?", type=argparse.FileType("r"), default=sys.stdin
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
@@ -69,5 +68,5 @@ def main():
|
||||
print("FAIL %s" % (key_id,))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -116,5 +116,5 @@ def main():
|
||||
connection.commit()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -19,10 +19,10 @@ class DefinitionVisitor(ast.NodeVisitor):
|
||||
self.names = {}
|
||||
self.attrs = set()
|
||||
self.definitions = {
|
||||
'def': self.functions,
|
||||
'class': self.classes,
|
||||
'names': self.names,
|
||||
'attrs': self.attrs,
|
||||
"def": self.functions,
|
||||
"class": self.classes,
|
||||
"names": self.names,
|
||||
"attrs": self.attrs,
|
||||
}
|
||||
|
||||
def visit_Name(self, node):
|
||||
@@ -47,23 +47,23 @@ class DefinitionVisitor(ast.NodeVisitor):
|
||||
|
||||
|
||||
def non_empty(defs):
|
||||
functions = {name: non_empty(f) for name, f in defs['def'].items()}
|
||||
classes = {name: non_empty(f) for name, f in defs['class'].items()}
|
||||
functions = {name: non_empty(f) for name, f in defs["def"].items()}
|
||||
classes = {name: non_empty(f) for name, f in defs["class"].items()}
|
||||
result = {}
|
||||
if functions:
|
||||
result['def'] = functions
|
||||
result["def"] = functions
|
||||
if classes:
|
||||
result['class'] = classes
|
||||
names = defs['names']
|
||||
result["class"] = classes
|
||||
names = defs["names"]
|
||||
uses = []
|
||||
for name in names.get('Load', ()):
|
||||
if name not in names.get('Param', ()) and name not in names.get('Store', ()):
|
||||
for name in names.get("Load", ()):
|
||||
if name not in names.get("Param", ()) and name not in names.get("Store", ()):
|
||||
uses.append(name)
|
||||
uses.extend(defs['attrs'])
|
||||
uses.extend(defs["attrs"])
|
||||
if uses:
|
||||
result['uses'] = uses
|
||||
result['names'] = names
|
||||
result['attrs'] = defs['attrs']
|
||||
result["uses"] = uses
|
||||
result["names"] = names
|
||||
result["attrs"] = defs["attrs"]
|
||||
return result
|
||||
|
||||
|
||||
@@ -81,33 +81,33 @@ def definitions_in_file(filepath):
|
||||
|
||||
|
||||
def defined_names(prefix, defs, names):
|
||||
for name, funcs in defs.get('def', {}).items():
|
||||
names.setdefault(name, {'defined': []})['defined'].append(prefix + name)
|
||||
for name, funcs in defs.get("def", {}).items():
|
||||
names.setdefault(name, {"defined": []})["defined"].append(prefix + name)
|
||||
defined_names(prefix + name + ".", funcs, names)
|
||||
|
||||
for name, funcs in defs.get('class', {}).items():
|
||||
names.setdefault(name, {'defined': []})['defined'].append(prefix + name)
|
||||
for name, funcs in defs.get("class", {}).items():
|
||||
names.setdefault(name, {"defined": []})["defined"].append(prefix + name)
|
||||
defined_names(prefix + name + ".", funcs, names)
|
||||
|
||||
|
||||
def used_names(prefix, item, defs, names):
|
||||
for name, funcs in defs.get('def', {}).items():
|
||||
for name, funcs in defs.get("def", {}).items():
|
||||
used_names(prefix + name + ".", name, funcs, names)
|
||||
|
||||
for name, funcs in defs.get('class', {}).items():
|
||||
for name, funcs in defs.get("class", {}).items():
|
||||
used_names(prefix + name + ".", name, funcs, names)
|
||||
|
||||
path = prefix.rstrip('.')
|
||||
for used in defs.get('uses', ()):
|
||||
path = prefix.rstrip(".")
|
||||
for used in defs.get("uses", ()):
|
||||
if used in names:
|
||||
if item:
|
||||
names[item].setdefault('uses', []).append(used)
|
||||
names[used].setdefault('used', {}).setdefault(item, []).append(path)
|
||||
names[item].setdefault("uses", []).append(used)
|
||||
names[used].setdefault("used", {}).setdefault(item, []).append(path)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
|
||||
parser = argparse.ArgumentParser(description='Find definitions.')
|
||||
parser = argparse.ArgumentParser(description="Find definitions.")
|
||||
parser.add_argument(
|
||||
"--unused", action="store_true", help="Only list unused definitions"
|
||||
)
|
||||
@@ -119,7 +119,7 @@ if __name__ == '__main__':
|
||||
)
|
||||
parser.add_argument(
|
||||
"directories",
|
||||
nargs='+',
|
||||
nargs="+",
|
||||
metavar="DIR",
|
||||
help="Directories to search for definitions",
|
||||
)
|
||||
@@ -164,7 +164,7 @@ if __name__ == '__main__':
|
||||
continue
|
||||
if ignore and any(pattern.match(name) for pattern in ignore):
|
||||
continue
|
||||
if args.unused and definition.get('used'):
|
||||
if args.unused and definition.get("used"):
|
||||
continue
|
||||
result[name] = definition
|
||||
|
||||
@@ -196,9 +196,9 @@ if __name__ == '__main__':
|
||||
continue
|
||||
result[name] = definition
|
||||
|
||||
if args.format == 'yaml':
|
||||
if args.format == "yaml":
|
||||
yaml.dump(result, sys.stdout, default_flow_style=False)
|
||||
elif args.format == 'dot':
|
||||
elif args.format == "dot":
|
||||
print("digraph {")
|
||||
for name, entry in result.items():
|
||||
print(name)
|
||||
|
||||
@@ -63,7 +63,7 @@ def encode_canonical_json(value):
|
||||
# Encode code-points outside of ASCII as UTF-8 rather than \u escapes
|
||||
ensure_ascii=False,
|
||||
# Remove unecessary white space.
|
||||
separators=(',', ':'),
|
||||
separators=(",", ":"),
|
||||
# Sort the keys of dictionaries.
|
||||
sort_keys=True,
|
||||
# Encode the resulting unicode as UTF-8 bytes.
|
||||
@@ -145,7 +145,7 @@ def request_json(method, origin_name, origin_key, destination, path, content):
|
||||
authorization_headers = []
|
||||
|
||||
for key, sig in signed_json["signatures"][origin_name].items():
|
||||
header = "X-Matrix origin=%s,key=\"%s\",sig=\"%s\"" % (origin_name, key, sig)
|
||||
header = 'X-Matrix origin=%s,key="%s",sig="%s"' % (origin_name, key, sig)
|
||||
authorization_headers.append(header.encode("ascii"))
|
||||
print("Authorization: %s" % header, file=sys.stderr)
|
||||
|
||||
@@ -161,11 +161,7 @@ def request_json(method, origin_name, origin_key, destination, path, content):
|
||||
headers["Content-Type"] = "application/json"
|
||||
|
||||
result = s.request(
|
||||
method=method,
|
||||
url=dest,
|
||||
headers=headers,
|
||||
verify=False,
|
||||
data=content,
|
||||
method=method, url=dest, headers=headers, verify=False, data=content
|
||||
)
|
||||
sys.stderr.write("Status Code: %d\n" % (result.status_code,))
|
||||
return result.json()
|
||||
@@ -241,18 +237,18 @@ def main():
|
||||
|
||||
|
||||
def read_args_from_config(args):
|
||||
with open(args.config, 'r') as fh:
|
||||
with open(args.config, "r") as fh:
|
||||
config = yaml.safe_load(fh)
|
||||
if not args.server_name:
|
||||
args.server_name = config['server_name']
|
||||
args.server_name = config["server_name"]
|
||||
if not args.signing_key_path:
|
||||
args.signing_key_path = config['signing_key_path']
|
||||
args.signing_key_path = config["signing_key_path"]
|
||||
|
||||
|
||||
class MatrixConnectionAdapter(HTTPAdapter):
|
||||
@staticmethod
|
||||
def lookup(s, skip_well_known=False):
|
||||
if s[-1] == ']':
|
||||
if s[-1] == "]":
|
||||
# ipv6 literal (with no port)
|
||||
return s, 8448
|
||||
|
||||
@@ -268,9 +264,7 @@ class MatrixConnectionAdapter(HTTPAdapter):
|
||||
if not skip_well_known:
|
||||
well_known = MatrixConnectionAdapter.get_well_known(s)
|
||||
if well_known:
|
||||
return MatrixConnectionAdapter.lookup(
|
||||
well_known, skip_well_known=True
|
||||
)
|
||||
return MatrixConnectionAdapter.lookup(well_known, skip_well_known=True)
|
||||
|
||||
try:
|
||||
srv = srvlookup.lookup("matrix", "tcp", s)[0]
|
||||
@@ -280,8 +274,8 @@ class MatrixConnectionAdapter(HTTPAdapter):
|
||||
|
||||
@staticmethod
|
||||
def get_well_known(server_name):
|
||||
uri = "https://%s/.well-known/matrix/server" % (server_name, )
|
||||
print("fetching %s" % (uri, ), file=sys.stderr)
|
||||
uri = "https://%s/.well-known/matrix/server" % (server_name,)
|
||||
print("fetching %s" % (uri,), file=sys.stderr)
|
||||
|
||||
try:
|
||||
resp = requests.get(uri)
|
||||
@@ -294,12 +288,12 @@ class MatrixConnectionAdapter(HTTPAdapter):
|
||||
raise Exception("not a dict")
|
||||
if "m.server" not in parsed_well_known:
|
||||
raise Exception("Missing key 'm.server'")
|
||||
new_name = parsed_well_known['m.server']
|
||||
print("well-known lookup gave %s" % (new_name, ), file=sys.stderr)
|
||||
new_name = parsed_well_known["m.server"]
|
||||
print("well-known lookup gave %s" % (new_name,), file=sys.stderr)
|
||||
return new_name
|
||||
|
||||
except Exception as e:
|
||||
print("Invalid response from %s: %s" % (uri, e, ), file=sys.stderr)
|
||||
print("Invalid response from %s: %s" % (uri, e), file=sys.stderr)
|
||||
return None
|
||||
|
||||
def get_connection(self, url, proxies=None):
|
||||
|
||||
@@ -79,5 +79,5 @@ def main():
|
||||
conn.commit()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -35,11 +35,11 @@ def find_patterns_in_file(filepath):
|
||||
find_patterns_in_code(f.read())
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(description='Find url patterns.')
|
||||
parser = argparse.ArgumentParser(description="Find url patterns.")
|
||||
|
||||
parser.add_argument(
|
||||
"directories",
|
||||
nargs='+',
|
||||
nargs="+",
|
||||
metavar="DIR",
|
||||
help="Directories to search for definitions",
|
||||
)
|
||||
|
||||
@@ -63,5 +63,5 @@ def main():
|
||||
streams[update.name] = update.position
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -24,14 +24,14 @@ if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument(
|
||||
"-o", "--output_file",
|
||||
|
||||
type=argparse.FileType('w'),
|
||||
"-o",
|
||||
"--output_file",
|
||||
type=argparse.FileType("w"),
|
||||
default=sys.stdout,
|
||||
help="Where to write the output to",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
key_id = "a_" + random_string(4)
|
||||
key = generate_signing_key(key_id),
|
||||
key = (generate_signing_key(key_id),)
|
||||
write_signing_keys(args.output_file, key)
|
||||
|
||||
@@ -50,7 +50,7 @@ def main(src_repo, dest_repo):
|
||||
dest_paths = MediaFilePaths(dest_repo)
|
||||
for line in sys.stdin:
|
||||
line = line.strip()
|
||||
parts = line.split('|')
|
||||
parts = line.split("|")
|
||||
if len(parts) != 2:
|
||||
print("Unable to parse input line %s" % line, file=sys.stderr)
|
||||
exit(1)
|
||||
@@ -107,7 +107,7 @@ if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
|
||||
)
|
||||
parser.add_argument("-v", action='store_true', help='enable debug logging')
|
||||
parser.add_argument("-v", action="store_true", help="enable debug logging")
|
||||
parser.add_argument("src_repo", help="Path to source content repo")
|
||||
parser.add_argument("dest_repo", help="Path to source content repo")
|
||||
args = parser.parse_args()
|
||||
|
||||
@@ -15,18 +15,17 @@ ignore =
|
||||
tox.ini
|
||||
|
||||
[flake8]
|
||||
max-line-length = 90
|
||||
|
||||
# see https://pycodestyle.readthedocs.io/en/latest/intro.html#error-codes
|
||||
# for error codes. The ones we ignore are:
|
||||
# W503: line break before binary operator
|
||||
# W504: line break after binary operator
|
||||
# E203: whitespace before ':' (which is contrary to pep8?)
|
||||
# E731: do not assign a lambda expression, use a def
|
||||
ignore=W503,W504,E203,E731
|
||||
# E501: Line too long (black enforces this for us)
|
||||
ignore=W503,W504,E203,E731,E501
|
||||
|
||||
[isort]
|
||||
line_length = 89
|
||||
line_length = 88
|
||||
not_skip = __init__.py
|
||||
sections=FUTURE,STDLIB,COMPAT,THIRDPARTY,TWISTED,FIRSTPARTY,TESTS,LOCALFOLDER
|
||||
default_section=THIRDPARTY
|
||||
|
||||
31
setup.py
31
setup.py
@@ -60,9 +60,12 @@ class TestCommand(Command):
|
||||
pass
|
||||
|
||||
def run(self):
|
||||
print ("""Synapse's tests cannot be run via setup.py. To run them, try:
|
||||
print(
|
||||
"""Synapse's tests cannot be run via setup.py. To run them, try:
|
||||
PYTHONPATH="." trial tests
|
||||
""")
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def read_file(path_segments):
|
||||
"""Read a file from the package. Takes a list of strings to join to
|
||||
@@ -84,9 +87,9 @@ version = exec_file(("synapse", "__init__.py"))["__version__"]
|
||||
dependencies = exec_file(("synapse", "python_dependencies.py"))
|
||||
long_description = read_file(("README.rst",))
|
||||
|
||||
REQUIREMENTS = dependencies['REQUIREMENTS']
|
||||
CONDITIONAL_REQUIREMENTS = dependencies['CONDITIONAL_REQUIREMENTS']
|
||||
ALL_OPTIONAL_REQUIREMENTS = dependencies['ALL_OPTIONAL_REQUIREMENTS']
|
||||
REQUIREMENTS = dependencies["REQUIREMENTS"]
|
||||
CONDITIONAL_REQUIREMENTS = dependencies["CONDITIONAL_REQUIREMENTS"]
|
||||
ALL_OPTIONAL_REQUIREMENTS = dependencies["ALL_OPTIONAL_REQUIREMENTS"]
|
||||
|
||||
# Make `pip install matrix-synapse[all]` install all the optional dependencies.
|
||||
CONDITIONAL_REQUIREMENTS["all"] = list(ALL_OPTIONAL_REQUIREMENTS)
|
||||
@@ -102,16 +105,16 @@ setup(
|
||||
include_package_data=True,
|
||||
zip_safe=False,
|
||||
long_description=long_description,
|
||||
python_requires='~=3.5',
|
||||
python_requires="~=3.5",
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Topic :: Communications :: Chat',
|
||||
'License :: OSI Approved :: Apache Software License',
|
||||
'Programming Language :: Python :: 3 :: Only',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"Topic :: Communications :: Chat",
|
||||
"License :: OSI Approved :: Apache Software License",
|
||||
"Programming Language :: Python :: 3 :: Only",
|
||||
"Programming Language :: Python :: 3.5",
|
||||
"Programming Language :: Python :: 3.6",
|
||||
"Programming Language :: Python :: 3.7",
|
||||
],
|
||||
scripts=["synctl"] + glob.glob("scripts/*"),
|
||||
cmdclass={'test': TestCommand},
|
||||
cmdclass={"test": TestCommand},
|
||||
)
|
||||
|
||||
@@ -31,40 +31,40 @@ class Membership(object):
|
||||
|
||||
"""Represents the membership states of a user in a room."""
|
||||
|
||||
INVITE = u"invite"
|
||||
JOIN = u"join"
|
||||
KNOCK = u"knock"
|
||||
LEAVE = u"leave"
|
||||
BAN = u"ban"
|
||||
INVITE = "invite"
|
||||
JOIN = "join"
|
||||
KNOCK = "knock"
|
||||
LEAVE = "leave"
|
||||
BAN = "ban"
|
||||
LIST = (INVITE, JOIN, KNOCK, LEAVE, BAN)
|
||||
|
||||
|
||||
class PresenceState(object):
|
||||
"""Represents the presence state of a user."""
|
||||
|
||||
OFFLINE = u"offline"
|
||||
UNAVAILABLE = u"unavailable"
|
||||
ONLINE = u"online"
|
||||
OFFLINE = "offline"
|
||||
UNAVAILABLE = "unavailable"
|
||||
ONLINE = "online"
|
||||
|
||||
|
||||
class JoinRules(object):
|
||||
PUBLIC = u"public"
|
||||
KNOCK = u"knock"
|
||||
INVITE = u"invite"
|
||||
PRIVATE = u"private"
|
||||
PUBLIC = "public"
|
||||
KNOCK = "knock"
|
||||
INVITE = "invite"
|
||||
PRIVATE = "private"
|
||||
|
||||
|
||||
class LoginType(object):
|
||||
PASSWORD = u"m.login.password"
|
||||
EMAIL_IDENTITY = u"m.login.email.identity"
|
||||
MSISDN = u"m.login.msisdn"
|
||||
RECAPTCHA = u"m.login.recaptcha"
|
||||
TERMS = u"m.login.terms"
|
||||
DUMMY = u"m.login.dummy"
|
||||
PASSWORD = "m.login.password"
|
||||
EMAIL_IDENTITY = "m.login.email.identity"
|
||||
MSISDN = "m.login.msisdn"
|
||||
RECAPTCHA = "m.login.recaptcha"
|
||||
TERMS = "m.login.terms"
|
||||
DUMMY = "m.login.dummy"
|
||||
|
||||
# Only for C/S API v1
|
||||
APPLICATION_SERVICE = u"m.login.application_service"
|
||||
SHARED_SECRET = u"org.matrix.login.shared_secret"
|
||||
APPLICATION_SERVICE = "m.login.application_service"
|
||||
SHARED_SECRET = "org.matrix.login.shared_secret"
|
||||
|
||||
|
||||
class EventTypes(object):
|
||||
|
||||
@@ -44,15 +44,15 @@ class Ratelimiter(object):
|
||||
"""
|
||||
self.prune_message_counts(time_now_s)
|
||||
message_count, time_start, _ignored = self.message_counts.get(
|
||||
key, (0., time_now_s, None)
|
||||
key, (0.0, time_now_s, None)
|
||||
)
|
||||
time_delta = time_now_s - time_start
|
||||
sent_count = message_count - time_delta * rate_hz
|
||||
if sent_count < 0:
|
||||
allowed = True
|
||||
time_start = time_now_s
|
||||
message_count = 1.
|
||||
elif sent_count > burst_count - 1.:
|
||||
message_count = 1.0
|
||||
elif sent_count > burst_count - 1.0:
|
||||
allowed = False
|
||||
else:
|
||||
allowed = True
|
||||
|
||||
@@ -42,7 +42,7 @@ class AccountValidityConfig(Config):
|
||||
else:
|
||||
self.renew_email_subject = "Renew your %(app)s account"
|
||||
|
||||
self.startup_job_max_delta = self.period * 10. / 100.
|
||||
self.startup_job_max_delta = self.period * 10.0 / 100.0
|
||||
|
||||
if self.renew_by_email_enabled:
|
||||
if "public_baseurl" not in synapse_config:
|
||||
|
||||
@@ -43,7 +43,7 @@ class TlsConfig(Config):
|
||||
|
||||
# hyperlink complains on py2 if this is not a Unicode
|
||||
self.acme_url = six.text_type(
|
||||
acme_config.get("url", u"https://acme-v01.api.letsencrypt.org/directory")
|
||||
acme_config.get("url", "https://acme-v01.api.letsencrypt.org/directory")
|
||||
)
|
||||
self.acme_port = acme_config.get("port", 80)
|
||||
self.acme_bind_addresses = acme_config.get("bind_addresses", ["::", "0.0.0.0"])
|
||||
@@ -211,7 +211,7 @@ class TlsConfig(Config):
|
||||
sha256_fingerprint = encode_base64(sha256(x509_certificate_bytes).digest())
|
||||
sha256_fingerprints = set(f["sha256"] for f in self.tls_fingerprints)
|
||||
if sha256_fingerprint not in sha256_fingerprints:
|
||||
self.tls_fingerprints.append({u"sha256": sha256_fingerprint})
|
||||
self.tls_fingerprints.append({"sha256": sha256_fingerprint})
|
||||
|
||||
def default_config(self, config_dir_path, server_name, **kwargs):
|
||||
base_key_name = os.path.join(config_dir_path, server_name)
|
||||
|
||||
@@ -505,7 +505,7 @@ class BaseV2KeyFetcher(object):
|
||||
Returns:
|
||||
Deferred[dict[str, FetchKeyResult]]: map from key_id to result object
|
||||
"""
|
||||
ts_valid_until_ms = response_json[u"valid_until_ts"]
|
||||
ts_valid_until_ms = response_json["valid_until_ts"]
|
||||
|
||||
# start by extracting the keys from the response, since they may be required
|
||||
# to validate the signature on the response.
|
||||
@@ -656,9 +656,9 @@ class PerspectivesKeyFetcher(BaseV2KeyFetcher):
|
||||
destination=perspective_name,
|
||||
path="/_matrix/key/v2/query",
|
||||
data={
|
||||
u"server_keys": {
|
||||
"server_keys": {
|
||||
server_name: {
|
||||
key_id: {u"minimum_valid_until_ts": min_valid_ts}
|
||||
key_id: {"minimum_valid_until_ts": min_valid_ts}
|
||||
for key_id, min_valid_ts in server_keys.items()
|
||||
}
|
||||
for server_name, server_keys in keys_to_fetch.items()
|
||||
@@ -729,13 +729,13 @@ class PerspectivesKeyFetcher(BaseV2KeyFetcher):
|
||||
return
|
||||
|
||||
if (
|
||||
u"signatures" not in response
|
||||
or perspective_name not in response[u"signatures"]
|
||||
"signatures" not in response
|
||||
or perspective_name not in response["signatures"]
|
||||
):
|
||||
raise KeyLookupError("Response not signed by the notary server")
|
||||
|
||||
verified = False
|
||||
for key_id in response[u"signatures"][perspective_name]:
|
||||
for key_id in response["signatures"][perspective_name]:
|
||||
if key_id in perspective_keys:
|
||||
verify_signed_json(response, perspective_name, perspective_keys[key_id])
|
||||
verified = True
|
||||
@@ -744,7 +744,7 @@ class PerspectivesKeyFetcher(BaseV2KeyFetcher):
|
||||
raise KeyLookupError(
|
||||
"Response not signed with a known key: signed with: %r, known keys: %r"
|
||||
% (
|
||||
list(response[u"signatures"][perspective_name].keys()),
|
||||
list(response["signatures"][perspective_name].keys()),
|
||||
list(perspective_keys.keys()),
|
||||
)
|
||||
)
|
||||
|
||||
@@ -45,7 +45,7 @@ sent_pdus_destination_dist_count = Counter(
|
||||
|
||||
sent_pdus_destination_dist_total = Counter(
|
||||
"synapse_federation_client_sent_pdu_destinations:total",
|
||||
"" "Total number of PDUs queued for sending across all destinations",
|
||||
"Total number of PDUs queued for sending across all destinations",
|
||||
)
|
||||
|
||||
|
||||
@@ -109,7 +109,9 @@ class FederationSender(object):
|
||||
# awaiting a call to flush_read_receipts_for_room. The presence of an entry
|
||||
# here for a given room means that we are rate-limiting RR flushes to that room,
|
||||
# and that there is a pending call to _flush_rrs_for_room in the system.
|
||||
self._queues_awaiting_rr_flush_by_room = {} # type: dict[str, set[PerDestinationQueue]]
|
||||
self._queues_awaiting_rr_flush_by_room = (
|
||||
{}
|
||||
) # type: dict[str, set[PerDestinationQueue]]
|
||||
|
||||
self._rr_txn_interval_per_room_ms = (
|
||||
1000.0 / hs.get_config().federation_rr_transactions_per_room_per_second
|
||||
|
||||
@@ -82,7 +82,7 @@ def shortstr(iterable, maxitems=5):
|
||||
items = list(itertools.islice(iterable, maxitems + 1))
|
||||
if len(items) <= maxitems:
|
||||
return str(items)
|
||||
return u"[" + u", ".join(repr(r) for r in items[:maxitems]) + u", ...]"
|
||||
return "[" + ", ".join(repr(r) for r in items[:maxitems]) + ", ...]"
|
||||
|
||||
|
||||
class FederationHandler(BaseHandler):
|
||||
|
||||
@@ -489,11 +489,7 @@ class RegistrationHandler(BaseHandler):
|
||||
threepid["address"],
|
||||
)
|
||||
|
||||
if not (
|
||||
yield check_3pid_allowed(
|
||||
self.hs, threepid["medium"], threepid["address"]
|
||||
)
|
||||
):
|
||||
if not check_3pid_allowed(self.hs, threepid["medium"], threepid["address"]):
|
||||
raise RegistrationError(403, "Third party identifier is not allowed")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
|
||||
@@ -813,7 +813,7 @@ class RoomContextHandler(object):
|
||||
Returns:
|
||||
dict, or None if the event isn't found
|
||||
"""
|
||||
before_limit = math.floor(limit / 2.)
|
||||
before_limit = math.floor(limit / 2.0)
|
||||
after_limit = limit - before_limit
|
||||
|
||||
users = yield self.store.get_users_in_room(room_id)
|
||||
|
||||
@@ -339,7 +339,7 @@ class Notifier(object):
|
||||
listener = user_stream.new_listener(prev_token)
|
||||
listener.deferred = timeout_deferred(
|
||||
listener.deferred,
|
||||
(end_time - now) / 1000.,
|
||||
(end_time - now) / 1000.0,
|
||||
self.hs.get_reactor(),
|
||||
)
|
||||
with PreserveLoggingContext():
|
||||
|
||||
@@ -42,7 +42,9 @@ from synapse.visibility import filter_events_for_client
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
MESSAGE_FROM_PERSON_IN_ROOM = "You have a message on %(app)s from %(person)s " "in the %(room)s room..."
|
||||
MESSAGE_FROM_PERSON_IN_ROOM = (
|
||||
"You have a message on %(app)s from %(person)s " "in the %(room)s room..."
|
||||
)
|
||||
MESSAGE_FROM_PERSON = "You have a message on %(app)s from %(person)s..."
|
||||
MESSAGES_FROM_PERSON = "You have messages on %(app)s from %(person)s..."
|
||||
MESSAGES_IN_ROOM = "You have messages on %(app)s in the %(room)s room..."
|
||||
@@ -52,7 +54,9 @@ MESSAGES_IN_ROOM_AND_OTHERS = (
|
||||
MESSAGES_FROM_PERSON_AND_OTHERS = (
|
||||
"You have messages on %(app)s from %(person)s and others..."
|
||||
)
|
||||
INVITE_FROM_PERSON_TO_ROOM = "%(person)s has invited you to join the " "%(room)s room on %(app)s..."
|
||||
INVITE_FROM_PERSON_TO_ROOM = (
|
||||
"%(person)s has invited you to join the " "%(room)s room on %(app)s..."
|
||||
)
|
||||
INVITE_FROM_PERSON = "%(person)s has invited you to chat on %(app)s..."
|
||||
|
||||
CONTEXT_BEFORE = 1
|
||||
|
||||
@@ -57,15 +57,15 @@ class AccountValidityRenewServlet(RestServlet):
|
||||
|
||||
if token_valid:
|
||||
status_code = 200
|
||||
response = self.success_html
|
||||
else:
|
||||
status_code = 404
|
||||
response = self.failure_html
|
||||
|
||||
request.setResponseCode(status_code)
|
||||
request.setHeader(b"Content-Type", b"text/html; charset=utf-8")
|
||||
request.setHeader(b"Content-Length", b"%d" % (len(response),))
|
||||
request.write(response.encode("utf8"))
|
||||
request.setHeader(
|
||||
b"Content-Length", b"%d" % (len(AccountValidityRenewServlet.SUCCESS_HTML),)
|
||||
)
|
||||
request.write(AccountValidityRenewServlet.SUCCESS_HTML)
|
||||
finish_request(request)
|
||||
defer.returnValue(None)
|
||||
|
||||
|
||||
@@ -80,24 +80,24 @@ class LocalKey(Resource):
|
||||
for key in self.config.signing_key:
|
||||
verify_key_bytes = key.verify_key.encode()
|
||||
key_id = "%s:%s" % (key.alg, key.version)
|
||||
verify_keys[key_id] = {u"key": encode_base64(verify_key_bytes)}
|
||||
verify_keys[key_id] = {"key": encode_base64(verify_key_bytes)}
|
||||
|
||||
old_verify_keys = {}
|
||||
for key_id, key in self.config.old_signing_keys.items():
|
||||
verify_key_bytes = key.encode()
|
||||
old_verify_keys[key_id] = {
|
||||
u"key": encode_base64(verify_key_bytes),
|
||||
u"expired_ts": key.expired_ts,
|
||||
"key": encode_base64(verify_key_bytes),
|
||||
"expired_ts": key.expired_ts,
|
||||
}
|
||||
|
||||
tls_fingerprints = self.config.tls_fingerprints
|
||||
|
||||
json_object = {
|
||||
u"valid_until_ts": self.valid_until_ts,
|
||||
u"server_name": self.config.server_name,
|
||||
u"verify_keys": verify_keys,
|
||||
u"old_verify_keys": old_verify_keys,
|
||||
u"tls_fingerprints": tls_fingerprints,
|
||||
"valid_until_ts": self.valid_until_ts,
|
||||
"server_name": self.config.server_name,
|
||||
"verify_keys": verify_keys,
|
||||
"old_verify_keys": old_verify_keys,
|
||||
"tls_fingerprints": tls_fingerprints,
|
||||
}
|
||||
for key in self.config.signing_key:
|
||||
json_object = sign_json(json_object, self.config.server_name, key)
|
||||
|
||||
@@ -706,5 +706,5 @@ def summarize_paragraphs(text_nodes, min_size=200, max_size=500):
|
||||
|
||||
# We always add an ellipsis because at the very least
|
||||
# we chopped mid paragraph.
|
||||
description = new_desc.strip() + u"…"
|
||||
description = new_desc.strip() + "…"
|
||||
return description if description else None
|
||||
|
||||
@@ -35,7 +35,7 @@ class ResponseCache(object):
|
||||
self.pending_result_cache = {} # Requests that haven't finished yet.
|
||||
|
||||
self.clock = hs.get_clock()
|
||||
self.timeout_sec = timeout_ms / 1000.
|
||||
self.timeout_sec = timeout_ms / 1000.0
|
||||
|
||||
self._name = name
|
||||
self._metrics = register_cache("response_cache", name, self)
|
||||
|
||||
@@ -96,8 +96,8 @@ class ContextResourceUsage(object):
|
||||
return ContextResourceUsage(copy_from=self)
|
||||
|
||||
def reset(self):
|
||||
self.ru_stime = 0.
|
||||
self.ru_utime = 0.
|
||||
self.ru_stime = 0.0
|
||||
self.ru_utime = 0.0
|
||||
self.db_txn_count = 0
|
||||
|
||||
self.db_txn_duration_sec = 0
|
||||
|
||||
@@ -106,7 +106,7 @@ def exception_to_unicode(e):
|
||||
# and instead look at what is in the args member.
|
||||
|
||||
if len(e.args) == 0:
|
||||
return u""
|
||||
return ""
|
||||
elif len(e.args) > 1:
|
||||
return six.text_type(repr(e.args))
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ class UserRegisterTestCase(unittest.HomeserverTestCase):
|
||||
|
||||
self.hs = self.setup_test_homeserver()
|
||||
|
||||
self.hs.config.registration_shared_secret = u"shared"
|
||||
self.hs.config.registration_shared_secret = "shared"
|
||||
|
||||
self.hs.get_media_repository = Mock()
|
||||
self.hs.get_deactivate_account_handler = Mock()
|
||||
@@ -270,7 +270,7 @@ class UserRegisterTestCase(unittest.HomeserverTestCase):
|
||||
self.assertEqual("Invalid username", channel.json_body["error"])
|
||||
|
||||
# Must not have null bytes
|
||||
body = json.dumps({"nonce": nonce(), "username": u"abcd\u0000"})
|
||||
body = json.dumps({"nonce": nonce(), "username": "abcd\u0000"})
|
||||
request, channel = self.make_request("POST", self.url, body.encode("utf8"))
|
||||
self.render(request)
|
||||
|
||||
@@ -306,9 +306,7 @@ class UserRegisterTestCase(unittest.HomeserverTestCase):
|
||||
self.assertEqual("Invalid password", channel.json_body["error"])
|
||||
|
||||
# Must not have null bytes
|
||||
body = json.dumps(
|
||||
{"nonce": nonce(), "username": "a", "password": u"abcd\u0000"}
|
||||
)
|
||||
body = json.dumps({"nonce": nonce(), "username": "a", "password": "abcd\u0000"})
|
||||
request, channel = self.make_request("POST", self.url, body.encode("utf8"))
|
||||
self.render(request)
|
||||
|
||||
|
||||
@@ -694,7 +694,7 @@ class AccountValidityBackgroundJobTestCase(unittest.HomeserverTestCase):
|
||||
|
||||
def make_homeserver(self, reactor, clock):
|
||||
self.validity_period = 10
|
||||
self.max_delta = self.validity_period * 10. / 100.
|
||||
self.max_delta = self.validity_period * 10.0 / 100.0
|
||||
|
||||
config = self.default_config()
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ class RelationsTestCase(unittest.HomeserverTestCase):
|
||||
creates the right shape of event.
|
||||
"""
|
||||
|
||||
channel = self._send_relation(RelationTypes.ANNOTATION, "m.reaction", key=u"👍")
|
||||
channel = self._send_relation(RelationTypes.ANNOTATION, "m.reaction", key="👍")
|
||||
self.assertEquals(200, channel.code, channel.json_body)
|
||||
|
||||
event_id = channel.json_body["event_id"]
|
||||
@@ -76,7 +76,7 @@ class RelationsTestCase(unittest.HomeserverTestCase):
|
||||
"content": {
|
||||
"m.relates_to": {
|
||||
"event_id": self.parent_id,
|
||||
"key": u"👍",
|
||||
"key": "👍",
|
||||
"rel_type": RelationTypes.ANNOTATION,
|
||||
}
|
||||
},
|
||||
@@ -187,7 +187,7 @@ class RelationsTestCase(unittest.HomeserverTestCase):
|
||||
access_tokens.append(token)
|
||||
|
||||
idx = 0
|
||||
sent_groups = {u"👍": 10, u"a": 7, u"b": 5, u"c": 3, u"d": 2, u"e": 1}
|
||||
sent_groups = {"👍": 10, "a": 7, "b": 5, "c": 3, "d": 2, "e": 1}
|
||||
for key in itertools.chain.from_iterable(
|
||||
itertools.repeat(key, num) for key, num in sent_groups.items()
|
||||
):
|
||||
@@ -259,7 +259,7 @@ class RelationsTestCase(unittest.HomeserverTestCase):
|
||||
channel = self._send_relation(
|
||||
RelationTypes.ANNOTATION,
|
||||
"m.reaction",
|
||||
key=u"👍",
|
||||
key="👍",
|
||||
access_token=access_tokens[idx],
|
||||
)
|
||||
self.assertEquals(200, channel.code, channel.json_body)
|
||||
@@ -273,7 +273,7 @@ class RelationsTestCase(unittest.HomeserverTestCase):
|
||||
|
||||
prev_token = None
|
||||
found_event_ids = []
|
||||
encoded_key = six.moves.urllib.parse.quote_plus(u"👍".encode("utf-8"))
|
||||
encoded_key = six.moves.urllib.parse.quote_plus("👍".encode("utf-8"))
|
||||
for _ in range(20):
|
||||
from_token = ""
|
||||
if prev_token:
|
||||
|
||||
@@ -21,12 +21,12 @@ from tests import unittest
|
||||
class GetFileNameFromHeadersTests(unittest.TestCase):
|
||||
# input -> expected result
|
||||
TEST_CASES = {
|
||||
b"inline; filename=abc.txt": u"abc.txt",
|
||||
b'inline; filename="azerty"': u"azerty",
|
||||
b'inline; filename="aze%20rty"': u"aze%20rty",
|
||||
b'inline; filename="aze"rty"': u'aze"rty',
|
||||
b'inline; filename="azer;ty"': u"azer;ty",
|
||||
b"inline; filename*=utf-8''foo%C2%A3bar": u"foo£bar",
|
||||
b"inline; filename=abc.txt": "abc.txt",
|
||||
b'inline; filename="azerty"': "azerty",
|
||||
b'inline; filename="aze%20rty"': "aze%20rty",
|
||||
b'inline; filename="aze"rty"': 'aze"rty',
|
||||
b'inline; filename="azer;ty"': "azer;ty",
|
||||
b"inline; filename*=utf-8''foo%C2%A3bar": "foo£bar",
|
||||
}
|
||||
|
||||
def tests(self):
|
||||
|
||||
@@ -204,7 +204,7 @@ class MediaRepoTests(unittest.HomeserverTestCase):
|
||||
correctly decode it as the UTF-8 string, and use filename* in the
|
||||
response.
|
||||
"""
|
||||
filename = parse.quote(u"\u2603".encode("utf8")).encode("ascii")
|
||||
filename = parse.quote("\u2603".encode("utf8")).encode("ascii")
|
||||
channel = self._req(b"inline; filename*=utf-8''" + filename + b".png")
|
||||
|
||||
headers = channel.headers
|
||||
|
||||
@@ -212,7 +212,7 @@ class URLPreviewTests(unittest.HomeserverTestCase):
|
||||
|
||||
self.pump()
|
||||
self.assertEqual(channel.code, 200)
|
||||
self.assertEqual(channel.json_body["og:title"], u"\u0434\u043a\u0430")
|
||||
self.assertEqual(channel.json_body["og:title"], "\u0434\u043a\u0430")
|
||||
|
||||
def test_non_ascii_preview_content_type(self):
|
||||
self.lookups["matrix.org"] = [(IPv4Address, "8.8.8.8")]
|
||||
@@ -245,7 +245,7 @@ class URLPreviewTests(unittest.HomeserverTestCase):
|
||||
|
||||
self.pump()
|
||||
self.assertEqual(channel.code, 200)
|
||||
self.assertEqual(channel.json_body["og:title"], u"\u0434\u043a\u0430")
|
||||
self.assertEqual(channel.json_body["og:title"], "\u0434\u043a\u0430")
|
||||
|
||||
def test_ipaddr(self):
|
||||
"""
|
||||
@@ -396,7 +396,7 @@ class URLPreviewTests(unittest.HomeserverTestCase):
|
||||
non-blacklisted one, it will be rejected.
|
||||
"""
|
||||
# Hardcode the URL resolving to the IP we want.
|
||||
self.lookups[u"example.com"] = [
|
||||
self.lookups["example.com"] = [
|
||||
(IPv4Address, "1.1.1.2"),
|
||||
(IPv4Address, "8.8.8.8"),
|
||||
]
|
||||
|
||||
@@ -82,7 +82,7 @@ class RedactionTestCase(unittest.TestCase):
|
||||
"sender": user.to_string(),
|
||||
"state_key": user.to_string(),
|
||||
"room_id": room.to_string(),
|
||||
"content": {"body": body, "msgtype": u"message"},
|
||||
"content": {"body": body, "msgtype": "message"},
|
||||
},
|
||||
)
|
||||
|
||||
@@ -118,7 +118,7 @@ class RedactionTestCase(unittest.TestCase):
|
||||
def test_redact(self):
|
||||
yield self.inject_room_member(self.room1, self.u_alice, Membership.JOIN)
|
||||
|
||||
msg_event = yield self.inject_message(self.room1, self.u_alice, u"t")
|
||||
msg_event = yield self.inject_message(self.room1, self.u_alice, "t")
|
||||
|
||||
# Check event has not been redacted:
|
||||
event = yield self.store.get_event(msg_event.event_id)
|
||||
|
||||
@@ -128,4 +128,4 @@ class TokenGenerator:
|
||||
|
||||
def generate(self, user_id):
|
||||
self._last_issued_token += 1
|
||||
return u"%s-%d" % (user_id, self._last_issued_token)
|
||||
return "%s-%d" % (user_id, self._last_issued_token)
|
||||
|
||||
@@ -78,7 +78,7 @@ class RoomEventsStoreTestCase(unittest.TestCase):
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def STALE_test_room_name(self):
|
||||
name = u"A-Room-Name"
|
||||
name = "A-Room-Name"
|
||||
|
||||
yield self.inject_room_event(
|
||||
etype=EventTypes.Name, name=name, content={"name": name}, depth=1
|
||||
@@ -94,7 +94,7 @@ class RoomEventsStoreTestCase(unittest.TestCase):
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def STALE_test_room_topic(self):
|
||||
topic = u"A place for things"
|
||||
topic = "A place for things"
|
||||
|
||||
yield self.inject_room_event(
|
||||
etype=EventTypes.Topic, topic=topic, content={"topic": topic}, depth=1
|
||||
|
||||
@@ -24,14 +24,14 @@ from . import unittest
|
||||
class PreviewTestCase(unittest.TestCase):
|
||||
def test_long_summarize(self):
|
||||
example_paras = [
|
||||
u"""Tromsø (Norwegian pronunciation: [ˈtrʊmsœ] ( listen); Northern Sami:
|
||||
"""Tromsø (Norwegian pronunciation: [ˈtrʊmsœ] ( listen); Northern Sami:
|
||||
Romsa; Finnish: Tromssa[2] Kven: Tromssa) is a city and municipality in
|
||||
Troms county, Norway. The administrative centre of the municipality is
|
||||
the city of Tromsø. Outside of Norway, Tromso and Tromsö are
|
||||
alternative spellings of the city.Tromsø is considered the northernmost
|
||||
city in the world with a population above 50,000. The most populous town
|
||||
north of it is Alta, Norway, with a population of 14,272 (2013).""",
|
||||
u"""Tromsø lies in Northern Norway. The municipality has a population of
|
||||
"""Tromsø lies in Northern Norway. The municipality has a population of
|
||||
(2015) 72,066, but with an annual influx of students it has over 75,000
|
||||
most of the year. It is the largest urban area in Northern Norway and the
|
||||
third largest north of the Arctic Circle (following Murmansk and Norilsk).
|
||||
@@ -44,7 +44,7 @@ class PreviewTestCase(unittest.TestCase):
|
||||
Sandnessund Bridge. Tromsø Airport connects the city to many destinations
|
||||
in Europe. The city is warmer than most other places located on the same
|
||||
latitude, due to the warming effect of the Gulf Stream.""",
|
||||
u"""The city centre of Tromsø contains the highest number of old wooden
|
||||
"""The city centre of Tromsø contains the highest number of old wooden
|
||||
houses in Northern Norway, the oldest house dating from 1789. The Arctic
|
||||
Cathedral, a modern church from 1965, is probably the most famous landmark
|
||||
in Tromsø. The city is a cultural centre for its region, with several
|
||||
@@ -58,87 +58,87 @@ class PreviewTestCase(unittest.TestCase):
|
||||
|
||||
self.assertEquals(
|
||||
desc,
|
||||
u"Tromsø (Norwegian pronunciation: [ˈtrʊmsœ] ( listen); Northern Sami:"
|
||||
u" Romsa; Finnish: Tromssa[2] Kven: Tromssa) is a city and municipality in"
|
||||
u" Troms county, Norway. The administrative centre of the municipality is"
|
||||
u" the city of Tromsø. Outside of Norway, Tromso and Tromsö are"
|
||||
u" alternative spellings of the city.Tromsø is considered the northernmost"
|
||||
u" city in the world with a population above 50,000. The most populous town"
|
||||
u" north of it is Alta, Norway, with a population of 14,272 (2013).",
|
||||
"Tromsø (Norwegian pronunciation: [ˈtrʊmsœ] ( listen); Northern Sami:"
|
||||
" Romsa; Finnish: Tromssa[2] Kven: Tromssa) is a city and municipality in"
|
||||
" Troms county, Norway. The administrative centre of the municipality is"
|
||||
" the city of Tromsø. Outside of Norway, Tromso and Tromsö are"
|
||||
" alternative spellings of the city.Tromsø is considered the northernmost"
|
||||
" city in the world with a population above 50,000. The most populous town"
|
||||
" north of it is Alta, Norway, with a population of 14,272 (2013).",
|
||||
)
|
||||
|
||||
desc = summarize_paragraphs(example_paras[1:], min_size=200, max_size=500)
|
||||
|
||||
self.assertEquals(
|
||||
desc,
|
||||
u"Tromsø lies in Northern Norway. The municipality has a population of"
|
||||
u" (2015) 72,066, but with an annual influx of students it has over 75,000"
|
||||
u" most of the year. It is the largest urban area in Northern Norway and the"
|
||||
u" third largest north of the Arctic Circle (following Murmansk and Norilsk)."
|
||||
u" Most of Tromsø, including the city centre, is located on the island of"
|
||||
u" Tromsøya, 350 kilometres (217 mi) north of the Arctic Circle. In 2012,"
|
||||
u" Tromsøya had a population of 36,088. Substantial parts of the urban…",
|
||||
"Tromsø lies in Northern Norway. The municipality has a population of"
|
||||
" (2015) 72,066, but with an annual influx of students it has over 75,000"
|
||||
" most of the year. It is the largest urban area in Northern Norway and the"
|
||||
" third largest north of the Arctic Circle (following Murmansk and Norilsk)."
|
||||
" Most of Tromsø, including the city centre, is located on the island of"
|
||||
" Tromsøya, 350 kilometres (217 mi) north of the Arctic Circle. In 2012,"
|
||||
" Tromsøya had a population of 36,088. Substantial parts of the urban…",
|
||||
)
|
||||
|
||||
def test_short_summarize(self):
|
||||
example_paras = [
|
||||
u"Tromsø (Norwegian pronunciation: [ˈtrʊmsœ] ( listen); Northern Sami:"
|
||||
u" Romsa; Finnish: Tromssa[2] Kven: Tromssa) is a city and municipality in"
|
||||
u" Troms county, Norway.",
|
||||
u"Tromsø lies in Northern Norway. The municipality has a population of"
|
||||
u" (2015) 72,066, but with an annual influx of students it has over 75,000"
|
||||
u" most of the year.",
|
||||
u"The city centre of Tromsø contains the highest number of old wooden"
|
||||
u" houses in Northern Norway, the oldest house dating from 1789. The Arctic"
|
||||
u" Cathedral, a modern church from 1965, is probably the most famous landmark"
|
||||
u" in Tromsø.",
|
||||
"Tromsø (Norwegian pronunciation: [ˈtrʊmsœ] ( listen); Northern Sami:"
|
||||
" Romsa; Finnish: Tromssa[2] Kven: Tromssa) is a city and municipality in"
|
||||
" Troms county, Norway.",
|
||||
"Tromsø lies in Northern Norway. The municipality has a population of"
|
||||
" (2015) 72,066, but with an annual influx of students it has over 75,000"
|
||||
" most of the year.",
|
||||
"The city centre of Tromsø contains the highest number of old wooden"
|
||||
" houses in Northern Norway, the oldest house dating from 1789. The Arctic"
|
||||
" Cathedral, a modern church from 1965, is probably the most famous landmark"
|
||||
" in Tromsø.",
|
||||
]
|
||||
|
||||
desc = summarize_paragraphs(example_paras, min_size=200, max_size=500)
|
||||
|
||||
self.assertEquals(
|
||||
desc,
|
||||
u"Tromsø (Norwegian pronunciation: [ˈtrʊmsœ] ( listen); Northern Sami:"
|
||||
u" Romsa; Finnish: Tromssa[2] Kven: Tromssa) is a city and municipality in"
|
||||
u" Troms county, Norway.\n"
|
||||
u"\n"
|
||||
u"Tromsø lies in Northern Norway. The municipality has a population of"
|
||||
u" (2015) 72,066, but with an annual influx of students it has over 75,000"
|
||||
u" most of the year.",
|
||||
"Tromsø (Norwegian pronunciation: [ˈtrʊmsœ] ( listen); Northern Sami:"
|
||||
" Romsa; Finnish: Tromssa[2] Kven: Tromssa) is a city and municipality in"
|
||||
" Troms county, Norway.\n"
|
||||
"\n"
|
||||
"Tromsø lies in Northern Norway. The municipality has a population of"
|
||||
" (2015) 72,066, but with an annual influx of students it has over 75,000"
|
||||
" most of the year.",
|
||||
)
|
||||
|
||||
def test_small_then_large_summarize(self):
|
||||
example_paras = [
|
||||
u"Tromsø (Norwegian pronunciation: [ˈtrʊmsœ] ( listen); Northern Sami:"
|
||||
u" Romsa; Finnish: Tromssa[2] Kven: Tromssa) is a city and municipality in"
|
||||
u" Troms county, Norway.",
|
||||
u"Tromsø lies in Northern Norway. The municipality has a population of"
|
||||
u" (2015) 72,066, but with an annual influx of students it has over 75,000"
|
||||
u" most of the year."
|
||||
u" The city centre of Tromsø contains the highest number of old wooden"
|
||||
u" houses in Northern Norway, the oldest house dating from 1789. The Arctic"
|
||||
u" Cathedral, a modern church from 1965, is probably the most famous landmark"
|
||||
u" in Tromsø.",
|
||||
"Tromsø (Norwegian pronunciation: [ˈtrʊmsœ] ( listen); Northern Sami:"
|
||||
" Romsa; Finnish: Tromssa[2] Kven: Tromssa) is a city and municipality in"
|
||||
" Troms county, Norway.",
|
||||
"Tromsø lies in Northern Norway. The municipality has a population of"
|
||||
" (2015) 72,066, but with an annual influx of students it has over 75,000"
|
||||
" most of the year."
|
||||
" The city centre of Tromsø contains the highest number of old wooden"
|
||||
" houses in Northern Norway, the oldest house dating from 1789. The Arctic"
|
||||
" Cathedral, a modern church from 1965, is probably the most famous landmark"
|
||||
" in Tromsø.",
|
||||
]
|
||||
|
||||
desc = summarize_paragraphs(example_paras, min_size=200, max_size=500)
|
||||
self.assertEquals(
|
||||
desc,
|
||||
u"Tromsø (Norwegian pronunciation: [ˈtrʊmsœ] ( listen); Northern Sami:"
|
||||
u" Romsa; Finnish: Tromssa[2] Kven: Tromssa) is a city and municipality in"
|
||||
u" Troms county, Norway.\n"
|
||||
u"\n"
|
||||
u"Tromsø lies in Northern Norway. The municipality has a population of"
|
||||
u" (2015) 72,066, but with an annual influx of students it has over 75,000"
|
||||
u" most of the year. The city centre of Tromsø contains the highest number"
|
||||
u" of old wooden houses in Northern Norway, the oldest house dating from"
|
||||
u" 1789. The Arctic Cathedral, a modern church from…",
|
||||
"Tromsø (Norwegian pronunciation: [ˈtrʊmsœ] ( listen); Northern Sami:"
|
||||
" Romsa; Finnish: Tromssa[2] Kven: Tromssa) is a city and municipality in"
|
||||
" Troms county, Norway.\n"
|
||||
"\n"
|
||||
"Tromsø lies in Northern Norway. The municipality has a population of"
|
||||
" (2015) 72,066, but with an annual influx of students it has over 75,000"
|
||||
" most of the year. The city centre of Tromsø contains the highest number"
|
||||
" of old wooden houses in Northern Norway, the oldest house dating from"
|
||||
" 1789. The Arctic Cathedral, a modern church from…",
|
||||
)
|
||||
|
||||
|
||||
class PreviewUrlTestCase(unittest.TestCase):
|
||||
def test_simple(self):
|
||||
html = u"""
|
||||
html = """
|
||||
<html>
|
||||
<head><title>Foo</title></head>
|
||||
<body>
|
||||
@@ -149,10 +149,10 @@ class PreviewUrlTestCase(unittest.TestCase):
|
||||
|
||||
og = decode_and_calc_og(html, "http://example.com/test.html")
|
||||
|
||||
self.assertEquals(og, {u"og:title": u"Foo", u"og:description": u"Some text."})
|
||||
self.assertEquals(og, {"og:title": "Foo", "og:description": "Some text."})
|
||||
|
||||
def test_comment(self):
|
||||
html = u"""
|
||||
html = """
|
||||
<html>
|
||||
<head><title>Foo</title></head>
|
||||
<body>
|
||||
@@ -164,10 +164,10 @@ class PreviewUrlTestCase(unittest.TestCase):
|
||||
|
||||
og = decode_and_calc_og(html, "http://example.com/test.html")
|
||||
|
||||
self.assertEquals(og, {u"og:title": u"Foo", u"og:description": u"Some text."})
|
||||
self.assertEquals(og, {"og:title": "Foo", "og:description": "Some text."})
|
||||
|
||||
def test_comment2(self):
|
||||
html = u"""
|
||||
html = """
|
||||
<html>
|
||||
<head><title>Foo</title></head>
|
||||
<body>
|
||||
@@ -185,13 +185,13 @@ class PreviewUrlTestCase(unittest.TestCase):
|
||||
self.assertEquals(
|
||||
og,
|
||||
{
|
||||
u"og:title": u"Foo",
|
||||
u"og:description": u"Some text.\n\nSome more text.\n\nText\n\nMore text",
|
||||
"og:title": "Foo",
|
||||
"og:description": "Some text.\n\nSome more text.\n\nText\n\nMore text",
|
||||
},
|
||||
)
|
||||
|
||||
def test_script(self):
|
||||
html = u"""
|
||||
html = """
|
||||
<html>
|
||||
<head><title>Foo</title></head>
|
||||
<body>
|
||||
@@ -203,10 +203,10 @@ class PreviewUrlTestCase(unittest.TestCase):
|
||||
|
||||
og = decode_and_calc_og(html, "http://example.com/test.html")
|
||||
|
||||
self.assertEquals(og, {u"og:title": u"Foo", u"og:description": u"Some text."})
|
||||
self.assertEquals(og, {"og:title": "Foo", "og:description": "Some text."})
|
||||
|
||||
def test_missing_title(self):
|
||||
html = u"""
|
||||
html = """
|
||||
<html>
|
||||
<body>
|
||||
Some text.
|
||||
@@ -216,10 +216,10 @@ class PreviewUrlTestCase(unittest.TestCase):
|
||||
|
||||
og = decode_and_calc_og(html, "http://example.com/test.html")
|
||||
|
||||
self.assertEquals(og, {u"og:title": None, u"og:description": u"Some text."})
|
||||
self.assertEquals(og, {"og:title": None, "og:description": "Some text."})
|
||||
|
||||
def test_h1_as_title(self):
|
||||
html = u"""
|
||||
html = """
|
||||
<html>
|
||||
<meta property="og:description" content="Some text."/>
|
||||
<body>
|
||||
@@ -230,10 +230,10 @@ class PreviewUrlTestCase(unittest.TestCase):
|
||||
|
||||
og = decode_and_calc_og(html, "http://example.com/test.html")
|
||||
|
||||
self.assertEquals(og, {u"og:title": u"Title", u"og:description": u"Some text."})
|
||||
self.assertEquals(og, {"og:title": "Title", "og:description": "Some text."})
|
||||
|
||||
def test_missing_title_and_broken_h1(self):
|
||||
html = u"""
|
||||
html = """
|
||||
<html>
|
||||
<body>
|
||||
<h1><a href="foo"/></h1>
|
||||
@@ -244,4 +244,4 @@ class PreviewUrlTestCase(unittest.TestCase):
|
||||
|
||||
og = decode_and_calc_og(html, "http://example.com/test.html")
|
||||
|
||||
self.assertEquals(og, {u"og:title": None, u"og:description": u"Some text."})
|
||||
self.assertEquals(og, {"og:title": None, "og:description": "Some text."})
|
||||
|
||||
@@ -69,8 +69,8 @@ class JsonResourceTests(unittest.TestCase):
|
||||
)
|
||||
render(request, res, self.reactor)
|
||||
|
||||
self.assertEqual(request.args, {b"a": [u"\N{SNOWMAN}".encode("utf8")]})
|
||||
self.assertEqual(got_kwargs, {u"room_id": u"\N{SNOWMAN}"})
|
||||
self.assertEqual(request.args, {b"a": ["\N{SNOWMAN}".encode("utf8")]})
|
||||
self.assertEqual(got_kwargs, {"room_id": "\N{SNOWMAN}"})
|
||||
|
||||
def test_callback_direct_exception(self):
|
||||
"""
|
||||
|
||||
@@ -109,9 +109,9 @@ class MapUsernameTestCase(unittest.TestCase):
|
||||
|
||||
def testNonAscii(self):
|
||||
# this should work with either a unicode or a bytes
|
||||
self.assertEqual(map_username_to_mxid_localpart(u"têst"), "t=c3=aast")
|
||||
self.assertEqual(map_username_to_mxid_localpart("têst"), "t=c3=aast")
|
||||
self.assertEqual(
|
||||
map_username_to_mxid_localpart(u"têst".encode("utf-8")), "t=c3=aast"
|
||||
map_username_to_mxid_localpart("têst".encode("utf-8")), "t=c3=aast"
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -389,7 +389,7 @@ class HomeserverTestCase(TestCase):
|
||||
Returns:
|
||||
The MXID of the new user (unicode).
|
||||
"""
|
||||
self.hs.config.registration_shared_secret = u"shared"
|
||||
self.hs.config.registration_shared_secret = "shared"
|
||||
|
||||
# Create the user
|
||||
request, channel = self.make_request("GET", "/_matrix/client/r0/admin/register")
|
||||
|
||||
9
tox.ini
9
tox.ini
@@ -1,5 +1,5 @@
|
||||
[tox]
|
||||
envlist = packaging, py35, py36, py37, pep8, check_isort
|
||||
envlist = packaging, py35, py36, py37, check_codestyle, check_isort
|
||||
|
||||
[base]
|
||||
deps =
|
||||
@@ -112,12 +112,15 @@ deps =
|
||||
commands =
|
||||
check-manifest
|
||||
|
||||
[testenv:pep8]
|
||||
[testenv:check_codestyle]
|
||||
skip_install = True
|
||||
basepython = python3.6
|
||||
deps =
|
||||
flake8
|
||||
commands = /bin/sh -c "flake8 synapse tests scripts scripts-dev scripts/hash_password scripts/register_new_matrix_user scripts/synapse_port_db synctl {env:PEP8SUFFIX:}"
|
||||
black
|
||||
commands =
|
||||
python -m black --check --diff .
|
||||
/bin/sh -c "flake8 synapse tests scripts scripts-dev scripts/hash_password scripts/register_new_matrix_user scripts/synapse_port_db synctl {env:PEP8SUFFIX:}"
|
||||
|
||||
[testenv:check_isort]
|
||||
skip_install = True
|
||||
|
||||
Reference in New Issue
Block a user