-
Notifications
You must be signed in to change notification settings - Fork 121
Open
Labels
Description
Seems to always be at least a couple PEP8 issues on each pull request including mine. We should consider mandating the black formatter. Any formatting issues then can be resolved by the requester with a single simple command line invocation.
For reference, this is the diff produced by running black on the matrix_client directory currently:
--- matrix_client/client.py (original)
+++ matrix_client/client.py (formatted)
@@ -91,13 +91,19 @@
def global_callback(incoming_event):
pass
"""
- def __init__(self, base_url, token=None, user_id=None,
- valid_cert_check=True, sync_filter_limit=20,
- cache_level=CACHE.ALL):
+ def __init__(
+ self,
+ base_url,
+ token=None,
+ user_id=None,
+ valid_cert_check=True,
+ sync_filter_limit=20,
+ cache_level=CACHE.ALL,
+ ):
""" Create a new Matrix Client object.
Args:
base_url (str): The url of the HS preceding /_matrix.
e.g. (ex: https://localhost:8008 )
@@ -134,12 +140,13 @@
raise ValueError(
"cache_level must be one of CACHE.NONE, CACHE.SOME, CACHE.ALL"
)
self.sync_token = None
- self.sync_filter = '{ "room": { "timeline" : { "limit" : %i } } }' \
- % sync_filter_limit
+ self.sync_filter = (
+ '{ "room": { "timeline" : { "limit" : %i } } }' % sync_filter_limit
+ )
self.sync_thread = None
self.should_listen = False
""" Time to wait before attempting a /sync request after failing."""
self.bad_sync_timeout_limit = 60 * 60
@@ -150,22 +157,28 @@
check_user_id(user_id)
self.user_id = user_id
self._sync()
def get_sync_token(self):
- warn("get_sync_token is deprecated. Directly access MatrixClient.sync_token.",
- DeprecationWarning)
+ warn(
+ "get_sync_token is deprecated. Directly access MatrixClient.sync_token.",
+ DeprecationWarning,
+ )
return self.sync_token
def set_sync_token(self, token):
- warn("set_sync_token is deprecated. Directly access MatrixClient.sync_token.",
- DeprecationWarning)
+ warn(
+ "set_sync_token is deprecated. Directly access MatrixClient.sync_token.",
+ DeprecationWarning,
+ )
self.sync_token = token
def set_user_id(self, user_id):
- warn("set_user_id is deprecated. Directly access MatrixClient.user_id.",
- DeprecationWarning)
+ warn(
+ "set_user_id is deprecated. Directly access MatrixClient.user_id.",
+ DeprecationWarning,
+ )
self.user_id = user_id
# TODO: combine register methods into single register method controlled by kwargs
def register_as_guest(self):
""" Register a guest account on this HS.
@@ -173,11 +186,11 @@
Returns:
str: Access Token
Raises:
MatrixRequestError
"""
- response = self.api.register(kind='guest')
+ response = self.api.register(kind="guest")
return self._post_registration(response)
def register_with_password(self, username, password):
""" Register for a new account on this HS.
@@ -193,11 +206,11 @@
"""
response = self.api.register(
{
"auth": {"type": "m.login.dummy"},
"username": username,
- "password": password
+ "password": password,
}
)
return self._post_registration(response)
def _post_registration(self, response):
@@ -220,13 +233,11 @@
str: Access token
Raises:
MatrixRequestError
"""
- response = self.api.login(
- "m.login.password", user=username, password=password
- )
+ response = self.api.login("m.login.password", user=username, password=password)
self.user_id = response["user_id"]
self.token = response["access_token"]
self.hs = response["home_server"]
self.api.token = self.token
return self.token
@@ -289,23 +300,23 @@
Raises:
MatrixRequestError
"""
response = self.api.join_room(room_id_or_alias)
- room_id = (
- response["room_id"] if "room_id" in response else room_id_or_alias
- )
+ room_id = response["room_id"] if "room_id" in response else room_id_or_alias
return self._mkroom(room_id)
def get_rooms(self):
""" Return a dict of {room_id: Room objects} that the user has joined.
Returns:
Room{}: Rooms the user has joined.
"""
- warn("get_rooms is deprecated. Directly access MatrixClient.rooms.",
- DeprecationWarning)
+ warn(
+ "get_rooms is deprecated. Directly access MatrixClient.rooms.",
+ DeprecationWarning,
+ )
return self.rooms
# TODO: create Listener class and push as much of this logic there as possible
# NOTE: listeners related to things in rooms should be attached to Room objects
def add_listener(self, callback, event_type=None):
@@ -322,26 +333,23 @@
listener_uid = uuid4()
# TODO: listeners should be stored in dict and accessed/deleted directly. Add
# convenience method such that MatrixClient.listeners.new(Listener(...)) performs
# MatrixClient.listeners[uuid4()] = Listener(...)
self.listeners.append(
- {
- 'uid': listener_uid,
- 'callback': callback,
- 'event_type': event_type
- }
+ {"uid": listener_uid, "callback": callback, "event_type": event_type}
)
return listener_uid
def remove_listener(self, uid):
""" Remove listener with given uid.
Args:
uuid.UUID: Unique id of the listener to remove.
"""
- self.listeners[:] = (listener for listener in self.listeners
- if listener['uid'] != uid)
+ self.listeners[:] = (
+ listener for listener in self.listeners if listener["uid"] != uid
+ )
def add_presence_listener(self, callback):
""" Add a presence listener that will send a callback when the client receives
a presence update.
@@ -374,26 +382,23 @@
Returns:
uuid.UUID: Unique id of the listener, can be used to identify the listener.
"""
listener_id = uuid4()
self.ephemeral_listeners.append(
- {
- 'uid': listener_id,
- 'callback': callback,
- 'event_type': event_type
- }
+ {"uid": listener_id, "callback": callback, "event_type": event_type}
)
return listener_id
def remove_ephemeral_listener(self, uid):
""" Remove ephemeral listener with given uid.
Args:
uuid.UUID: Unique id of the listener to remove.
"""
- self.ephemeral_listeners[:] = (listener for listener in self.ephemeral_listeners
- if listener['uid'] != uid)
+ self.ephemeral_listeners[:] = (
+ listener for listener in self.ephemeral_listeners if listener["uid"] != uid
+ )
def add_invite_listener(self, callback):
""" Add a listener that will send a callback when the client receives
an invite.
@@ -424,12 +429,13 @@
retrying.
"""
# TODO: see docstring
self._sync(timeout_ms)
- def listen_forever(self, timeout_ms=30000, exception_handler=None,
- bad_sync_timeout=5):
+ def listen_forever(
+ self, timeout_ms=30000, exception_handler=None, bad_sync_timeout=5
+ ):
""" Keep listening for events forever.
Args:
timeout_ms (int): How long to poll the Home Server for before
retrying.
@@ -439,23 +445,26 @@
bad_sync_timeout (int): Base time to wait after an error before
retrying. Will be increased according to exponential backoff.
"""
_bad_sync_timeout = bad_sync_timeout
self.should_listen = True
- while (self.should_listen):
+ while self.should_listen:
try:
self._sync(timeout_ms)
_bad_sync_timeout = bad_sync_timeout
# TODO: we should also handle MatrixHttpLibError for retry in case no response
except MatrixRequestError as e:
logger.warning("A MatrixRequestError occured during sync.")
if e.code >= 500:
- logger.warning("Problem occured serverside. Waiting %i seconds",
- bad_sync_timeout)
+ logger.warning(
+ "Problem occured serverside. Waiting %i seconds",
+ bad_sync_timeout,
+ )
sleep(bad_sync_timeout)
- _bad_sync_timeout = min(_bad_sync_timeout * 2,
- self.bad_sync_timeout_limit)
+ _bad_sync_timeout = min(
+ _bad_sync_timeout * 2, self.bad_sync_timeout_limit
+ )
elif exception_handler is not None:
exception_handler(e)
else:
raise
except Exception as e:
@@ -474,12 +483,13 @@
exception_handler (func(exception)): Optional exception handler
function which can be used to handle exceptions in the caller
thread.
"""
try:
- thread = Thread(target=self.listen_forever,
- args=(timeout_ms, exception_handler))
+ thread = Thread(
+ target=self.listen_forever, args=(timeout_ms, exception_handler)
+ )
thread.daemon = True
self.sync_thread = thread
self.should_listen = True
thread.start()
except RuntimeError:
@@ -513,73 +523,70 @@
else:
raise MatrixUnexpectedResponse(
"The upload was successful, but content_uri wasn't found."
)
except MatrixRequestError as e:
- raise MatrixRequestError(
- code=e.code,
- content="Upload failed: %s" % e
- )
+ raise MatrixRequestError(code=e.code, content="Upload failed: %s" % e)
def _mkroom(self, room_id):
self.rooms[room_id] = Room(self, room_id)
return self.rooms[room_id]
def _sync(self, timeout_ms=30000):
response = self.api.sync(self.sync_token, timeout_ms, filter=self.sync_filter)
self.sync_token = response["next_batch"]
- for presence_update in response['presence']['events']:
+ for presence_update in response["presence"]["events"]:
for callback in self.presence_listeners.values():
callback(presence_update)
- for room_id, invite_room in response['rooms']['invite'].items():
+ for room_id, invite_room in response["rooms"]["invite"].items():
for listener in self.invite_listeners:
- listener(room_id, invite_room['invite_state'])
-
- for room_id, left_room in response['rooms']['leave'].items():
+ listener(room_id, invite_room["invite_state"])
+
+ for room_id, left_room in response["rooms"]["leave"].items():
for listener in self.left_listeners:
listener(room_id, left_room)
if room_id in self.rooms:
del self.rooms[room_id]
- for room_id, sync_room in response['rooms']['join'].items():
+ for room_id, sync_room in response["rooms"]["join"].items():
if room_id not in self.rooms:
self._mkroom(room_id)
room = self.rooms[room_id]
# TODO: the rest of this for loop should be in room object method
room.prev_batch = sync_room["timeline"]["prev_batch"]
for event in sync_room["state"]["events"]:
- event['room_id'] = room_id
+ event["room_id"] = room_id
room._process_state_event(event)
for event in sync_room["timeline"]["events"]:
- event['room_id'] = room_id
+ event["room_id"] = room_id
room._put_event(event)
# TODO: global listeners can still exist but work by each
# room.listeners[uuid] having reference to global listener
# Dispatch for client (global) listeners
for listener in self.listeners:
if (
- listener['event_type'] is None or
- listener['event_type'] == event['type']
+ listener["event_type"] is None
+ or listener["event_type"] == event["type"]
):
- listener['callback'](event)
-
- for event in sync_room['ephemeral']['events']:
- event['room_id'] = room_id
+ listener["callback"](event)
+
+ for event in sync_room["ephemeral"]["events"]:
+ event["room_id"] = room_id
room._put_ephemeral_event(event)
for listener in self.ephemeral_listeners:
if (
- listener['event_type'] is None or
- listener['event_type'] == event['type']
+ listener["event_type"] is None
+ or listener["event_type"] == event["type"]
):
- listener['callback'](event)
+ listener["callback"](event)
def get_user(self, user_id):
""" Return a User by their id.
NOTE: This function only returns a user object, it does not verify
--- matrix_client/errors.py (original)
+++ matrix_client/errors.py (formatted)
@@ -39,11 +39,11 @@
class MatrixHttpLibError(MatrixError):
"""The library used for http requests raised an exception."""
def __init__(self, original_exception, method, endpoint):
super(MatrixHttpLibError, self).__init__(
- "Something went wrong in {} requesting {}: {}".format(method,
- endpoint,
- original_exception)
+ "Something went wrong in {} requesting {}: {}".format(
+ method, endpoint, original_exception
+ )
)
self.original_exception = original_exception
--- matrix_client/room.py (original)
+++ matrix_client/room.py (formatted)
@@ -46,14 +46,16 @@
self.invite_only = None
self.guest_access = None
self._prev_batch = None
self._members = []
- def set_user_profile(self,
- displayname=None,
- avatar_url=None,
- reason="Changing room profile information"):
+ def set_user_profile(
+ self,
+ displayname=None,
+ avatar_url=None,
+ reason="Changing room profile information",
+ ):
"""Set user profile within a room.
This sets displayname and avatar_url for the logged in user only in a
specific room. It does not change the user's global user profile.
"""
@@ -65,15 +67,13 @@
if avatar_url is None:
avatar_url = member["avatar_url"]
self.client.api.set_membership(
self.room_id,
self.client.user_id,
- 'join',
- reason, {
- "displayname": displayname,
- "avatar_url": avatar_url
- }
+ "join",
+ reason,
+ {"displayname": displayname, "avatar_url": avatar_url},
)
@property
def display_name(self):
"""Calculates the display name for a room."""
@@ -82,23 +82,20 @@
elif self.canonical_alias:
return self.canonical_alias
members = self.get_joined_members()
# members without me
- members[:] = [u.get_display_name() for u in members if
- self.client.user_id != u.user_id]
+ members[:] = [
+ u.get_display_name() for u in members if self.client.user_id != u.user_id
+ ]
first_two = members[:2]
if len(first_two) == 1:
return first_two[0]
elif len(members) == 2:
- return "{0} and {1}".format(
- first_two[0],
- first_two[1])
+ return "{0} and {1}".format(first_two[0], first_two[1])
elif len(members) > 2:
- return "{0} and {1} others".format(
- first_two[0],
- len(members) - 1)
+ return "{0} and {1} others".format(first_two[0], len(members) - 1)
elif len(first_two) == 0:
# TODO i18n
return "Empty room"
# TODO i18n
return "Empty room"
@@ -107,42 +104,41 @@
"""Send a plain text message to the room."""
return self.client.api.send_message(self.room_id, text)
def get_html_content(self, html, body=None, msgtype="m.text"):
return {
- "body": body if body else re.sub('<[^<]+?>', '', html),
+ "body": body if body else re.sub("<[^<]+?>", "", html),
"msgtype": msgtype,
"format": "org.matrix.custom.html",
- "formatted_body": html
+ "formatted_body": html,
}
def send_html(self, html, body=None, msgtype="m.text"):
"""Send an html formatted message.
Args:
html (str): The html formatted message to be sent.
body (str): The unformatted body of the message to be sent.
"""
return self.client.api.send_message_event(
- self.room_id, "m.room.message", self.get_html_content(html, body, msgtype))
+ self.room_id, "m.room.message", self.get_html_content(html, body, msgtype)
+ )
def set_account_data(self, type, account_data):
return self.client.api.set_room_account_data(
- self.client.user_id, self.room_id, type, account_data)
+ self.client.user_id, self.room_id, type, account_data
+ )
def get_tags(self):
return self.client.api.get_user_tags(self.client.user_id, self.room_id)
def remove_tag(self, tag):
- return self.client.api.remove_user_tag(
- self.client.user_id, self.room_id, tag
- )
+ return self.client.api.remove_user_tag(self.client.user_id, self.room_id, tag)
def add_tag(self, tag, order=None, content=None):
return self.client.api.add_user_tag(
- self.client.user_id, self.room_id,
- tag, order, content
+ self.client.user_id, self.room_id, tag, order, content
)
def send_emote(self, text):
"""Send an emote (/me style) message to the room."""
return self.client.api.send_emote(self.room_id, text)
@@ -158,12 +154,11 @@
name (str): The filename of the image.
fileinfo (): Extra information about the file
"""
return self.client.api.send_content(
- self.room_id, url, name, "m.file",
- extra_information=fileinfo
+ self.room_id, url, name, "m.file", extra_information=fileinfo
)
def send_notice(self, text):
"""Send a notice (from bot) message to the room."""
return self.client.api.send_notice(self.room_id, text)
@@ -180,12 +175,11 @@
url (str): The mxc url of the image.
name (str): The filename of the image.
imageinfo (): Extra information about the image.
"""
return self.client.api.send_content(
- self.room_id, url, name, "m.image",
- extra_information=imageinfo
+ self.room_id, url, name, "m.image", extra_information=imageinfo
)
def send_location(self, geo_uri, name, thumb_url=None, **thumb_info):
"""Send a location to the room.
@@ -196,12 +190,13 @@
geo_uri (str): The geo uri representing the location.
name (str): Description for the location.
thumb_url (str): URL to the thumbnail of the location.
thumb_info (): Metadata about the thumbnail, type ImageInfo.
"""
- return self.client.api.send_location(self.room_id, geo_uri, name,
- thumb_url, thumb_info)
+ return self.client.api.send_location(
+ self.room_id, geo_uri, name, thumb_url, thumb_info
+ )
def send_video(self, url, name, **videoinfo):
"""Send a pre-uploaded video to the room.
See http://matrix.org/docs/spec/client_server/r0.2.0.html#m-video
@@ -210,12 +205,13 @@
Args:
url (str): The mxc url of the video.
name (str): The filename of the video.
videoinfo (): Extra information about the video.
"""
- return self.client.api.send_content(self.room_id, url, name, "m.video",
- extra_information=videoinfo)
+ return self.client.api.send_content(
+ self.room_id, url, name, "m.video", extra_information=videoinfo
+ )
def send_audio(self, url, name, **audioinfo):
"""Send a pre-uploaded audio to the room.
See http://matrix.org/docs/spec/client_server/r0.2.0.html#m-audio
@@ -224,12 +220,13 @@
Args:
url (str): The mxc url of the audio.
name (str): The filename of the audio.
audioinfo (): Extra information about the audio.
"""
- return self.client.api.send_content(self.room_id, url, name, "m.audio",
- extra_information=audioinfo)
+ return self.client.api.send_content(
+ self.room_id, url, name, "m.audio", extra_information=audioinfo
+ )
def redact_message(self, event_id, reason=None):
"""Redacts the message with specified event_id for the given reason.
See https://matrix.org/docs/spec/r0.0.1/client_server.html#id112
@@ -245,22 +242,19 @@
Returns:
uuid.UUID: Unique id of the listener, can be used to identify the listener.
"""
listener_id = uuid4()
self.listeners.append(
- {
- 'uid': listener_id,
- 'callback': callback,
- 'event_type': event_type
- }
+ {"uid": listener_id, "callback": callback, "event_type": event_type}
)
return listener_id
def remove_listener(self, uid):
"""Remove listener with given uid."""
- self.listeners[:] = (listener for listener in self.listeners
- if listener['uid'] != uid)
+ self.listeners[:] = (
+ listener for listener in self.listeners if listener["uid"] != uid
+ )
def add_ephemeral_listener(self, callback, event_type=None):
"""Add a callback handler for ephemeral events going to this room.
Args:
@@ -269,54 +263,52 @@
Returns:
uuid.UUID: Unique id of the listener, can be used to identify the listener.
"""
listener_id = uuid4()
self.ephemeral_listeners.append(
- {
- 'uid': listener_id,
- 'callback': callback,
- 'event_type': event_type
- }
+ {"uid": listener_id, "callback": callback, "event_type": event_type}
)
return listener_id
def remove_ephemeral_listener(self, uid):
"""Remove ephemeral listener with given uid."""
- self.ephemeral_listeners[:] = (listener for listener in self.ephemeral_listeners
- if listener['uid'] != uid)
+ self.ephemeral_listeners[:] = (
+ listener for listener in self.ephemeral_listeners if listener["uid"] != uid
+ )
def add_state_listener(self, callback, event_type=None):
"""Add a callback handler for state events going to this room.
Args:
callback (func(roomchunk)): Callback called when an event arrives.
event_type (str): The event_type to filter for.
"""
- self.state_listeners.append(
- {
- 'callback': callback,
- 'event_type': event_type
- }
- )
+ self.state_listeners.append({"callback": callback, "event_type": event_type})
def _put_event(self, event):
self.events.append(event)
if len(self.events) > self.event_history_limit:
self.events.pop(0)
- if 'state_key' in event:
+ if "state_key" in event:
self._process_state_event(event)
# Dispatch for room-specific listeners
for listener in self.listeners:
- if listener['event_type'] is None or listener['event_type'] == event['type']:
- listener['callback'](self, event)
+ if (
+ listener["event_type"] is None
+ or listener["event_type"] == event["type"]
+ ):
+ listener["callback"](self, event)
def _put_ephemeral_event(self, event):
# Dispatch for room-specific listeners
for listener in self.ephemeral_listeners:
- if listener['event_type'] is None or listener['event_type'] == event['type']:
- listener['callback'](self, event)
+ if (
+ listener["event_type"] is None
+ or listener["event_type"] == event["type"]
+ ):
+ listener["callback"](self, event)
def get_events(self):
"""Get the most recent events for this room."""
return self.events
@@ -418,14 +410,11 @@
event_type (str): The type of event that you are sending.
content (): An object with the content of the message.
state_key (str, optional): A unique key to identify the state.
"""
return self.client.api.send_state_event(
- self.room_id,
- event_type,
- content,
- state_key
+ self.room_id, event_type, content, state_key
)
def update_room_topic(self):
"""Updates self.topic and returns True if room topic has changed."""
try:
@@ -483,13 +472,15 @@
return self._members
response = self.client.api.get_room_members(self.room_id)
for event in response["chunk"]:
if event["content"]["membership"] == "join":
self._mkmembers(
- User(self.client.api,
- event["state_key"],
- event["content"].get("displayname"))
+ User(
+ self.client.api,
+ event["state_key"],
+ event["content"].get("displayname"),
+ )
)
return self._members
def _mkmembers(self, member):
if member.user_id not in [x.user_id for x in self._members]:
@@ -504,12 +495,13 @@
Args:
reverse (bool): When false messages will be backfilled in their original
order (old to new), otherwise the order will be reversed (new to old).
limit (int): Number of messages to go back.
"""
- res = self.client.api.get_room_messages(self.room_id, self.prev_batch,
- direction="b", limit=limit)
+ res = self.client.api.get_room_messages(
+ self.room_id, self.prev_batch, direction="b", limit=limit
+ )
events = res["chunk"]
if not reverse:
events = reversed(events)
for event in events:
self._put_event(event)
@@ -642,23 +634,25 @@
self.guest_access = econtent["guest_access"] == "can_join"
elif etype == "m.room.member" and clevel == clevel.ALL:
# tracking room members can be large e.g. #matrix:matrix.org
if econtent["membership"] == "join":
self._mkmembers(
- User(self.client.api,
- state_event["state_key"],
- econtent.get("displayname"))
+ User(
+ self.client.api,
+ state_event["state_key"],
+ econtent.get("displayname"),
+ )
)
elif econtent["membership"] in ("leave", "kick", "invite"):
self._rmmembers(state_event["state_key"])
for listener in self.state_listeners:
if (
- listener['event_type'] is None or
- listener['event_type'] == state_event['type']
+ listener["event_type"] is None
+ or listener["event_type"] == state_event["type"]
):
- listener['callback'](state_event)
+ listener["callback"](state_event)
@property
def prev_batch(self):
return self._prev_batch
--- matrix_client/api.py (original)
+++ matrix_client/api.py (formatted)
@@ -66,15 +66,23 @@
Perform /initialSync.
Args:
limit (int): The limit= param to provide.
"""
- warnings.warn("initial_sync is deprecated. Use sync instead.", DeprecationWarning)
+ warnings.warn(
+ "initial_sync is deprecated. Use sync instead.", DeprecationWarning
+ )
return self._send("GET", "/initialSync", query_params={"limit": limit})
- def sync(self, since=None, timeout_ms=30000, filter=None,
- full_state=None, set_presence=None):
+ def sync(
+ self,
+ since=None,
+ timeout_ms=30000,
+ filter=None,
+ full_state=None,
+ set_presence=None,
+ ):
""" Perform a sync request.
Args:
since (str): Optional. A token which specifies where to continue a sync from.
timeout_ms (int): Optional. The time in milliseconds to wait.
@@ -99,17 +107,18 @@
request["full_state"] = full_state
if set_presence:
request["set_presence"] = set_presence
- return self._send("GET", "/sync", query_params=request,
- api_path=MATRIX_V2_API_PATH)
+ return self._send(
+ "GET", "/sync", query_params=request, api_path=MATRIX_V2_API_PATH
+ )
def validate_certificate(self, valid):
self.validate_cert = valid
- def register(self, content={}, kind='user'):
+ def register(self, content={}, kind="user"):
"""Performs /register.
Args:
content (dict): The request payload.
@@ -133,26 +142,21 @@
| non-interactive type.
kind (str): Specify kind="guest" to register as guest.
"""
return self._send(
- "POST",
- "/register",
- content=content,
- query_params={'kind': kind}
+ "POST", "/register", content=content, query_params={"kind": kind}
)
def login(self, login_type, **kwargs):
"""Perform /login.
Args:
login_type (str): The value for the 'type' key.
**kwargs: Additional key/values to add to the JSON submitted.
"""
- content = {
- "type": login_type
- }
+ content = {"type": login_type}
for key in kwargs:
content[key] = kwargs[key]
return self._send("POST", "/login", content)
@@ -167,13 +171,11 @@
Args:
alias (str): Optional. The room alias name to set for this room.
is_public (bool): Optional. The public/private visibility.
invitees (list<str>): Optional. The list of user IDs to invite.
"""
- content = {
- "visibility": "public" if is_public else "private"
- }
+ content = {"visibility": "public" if is_public else "private"}
if alias:
content["room_alias_name"] = alias
if invitees:
content["invite"] = invitees
return self._send("POST", "/createRoom", content)
@@ -197,43 +199,41 @@
Args:
from_token (str): The 'from' query parameter.
timeout (int): Optional. The 'timeout' query parameter.
"""
- warnings.warn("event_stream is deprecated. Use sync instead.",
- DeprecationWarning)
+ warnings.warn(
+ "event_stream is deprecated. Use sync instead.", DeprecationWarning
+ )
path = "/events"
return self._send(
- "GET", path, query_params={
- "timeout": timeout,
- "from": from_token
- }
- )
-
- def send_state_event(self, room_id, event_type, content, state_key="",
- timestamp=None):
+ "GET", path, query_params={"timeout": timeout, "from": from_token}
+ )
+
+ def send_state_event(
+ self, room_id, event_type, content, state_key="", timestamp=None
+ ):
"""Perform PUT /rooms/$room_id/state/$event_type
Args:
room_id(str): The room ID to send the state event in.
event_type(str): The state event type to send.
content(dict): The JSON content to send.
state_key(str): Optional. The state key for the event.
timestamp (int): Set origin_server_ts (For application services only)
"""
- path = "/rooms/%s/state/%s" % (
- quote(room_id), quote(event_type),
- )
+ path = "/rooms/%s/state/%s" % (quote(room_id), quote(event_type))
if state_key:
path += "/%s" % (quote(state_key))
params = {}
if timestamp:
params["ts"] = timestamp
return self._send("PUT", path, content, query_params=params)
- def send_message_event(self, room_id, event_type, content, txn_id=None,
- timestamp=None):
+ def send_message_event(
+ self, room_id, event_type, content, txn_id=None, timestamp=None
+ ):
"""Perform PUT /rooms/$room_id/send/$event_type
Args:
room_id (str): The room ID to send the message event in.
event_type (str): The event type to send.
@@ -245,11 +245,13 @@
txn_id = str(self.txn_id) + str(int(time() * 1000))
self.txn_id = self.txn_id + 1
path = "/rooms/%s/send/%s/%s" % (
- quote(room_id), quote(event_type), quote(str(txn_id)),
+ quote(room_id),
+ quote(event_type),
+ quote(str(txn_id)),
)
params = {}
if timestamp:
params["ts"] = timestamp
return self._send("PUT", path, content, query_params=params)
@@ -266,76 +268,81 @@
"""
if not txn_id:
txn_id = str(self.txn_id) + str(int(time() * 1000))
self.txn_id = self.txn_id + 1
- path = '/rooms/%s/redact/%s/%s' % (
- room_id, event_id, txn_id
- )
+ path = "/rooms/%s/redact/%s/%s" % (room_id, event_id, txn_id)
content = {}
if reason:
- content['reason'] = reason
+ content["reason"] = reason
params = {}
if timestamp:
params["ts"] = timestamp
return self._send("PUT", path, content, query_params=params)
# content_type can be a image,audio or video
# extra information should be supplied, see
# https://matrix.org/docs/spec/r0.0.1/client_server.html
- def send_content(self, room_id, item_url, item_name, msg_type,
- extra_information=None, timestamp=None):
+ def send_content(
+ self,
+ room_id,
+ item_url,
+ item_name,
+ msg_type,
+ extra_information=None,
+ timestamp=None,
+ ):
if extra_information is None:
extra_information = {}
content_pack = {
"url": item_url,
"msgtype": msg_type,
"body": item_name,
- "info": extra_information
+ "info": extra_information,
}
- return self.send_message_event(room_id, "m.room.message", content_pack,
- timestamp=timestamp)
+ return self.send_message_event(
+ room_id, "m.room.message", content_pack, timestamp=timestamp
+ )
# http://matrix.org/docs/spec/client_server/r0.2.0.html#m-location
- def send_location(self, room_id, geo_uri, name, thumb_url=None, thumb_info=None,
- timestamp=None):
+ def send_location(
+ self, room_id, geo_uri, name, thumb_url=None, thumb_info=None, timestamp=None
+ ):
"""Send m.location message event
Args:
room_id (str): The room ID to send the event in.
geo_uri (str): The geo uri representing the location.
name (str): Description for the location.
thumb_url (str): URL to the thumbnail of the location.
thumb_info (dict): Metadata about the thumbnail, type ImageInfo.
timestamp (int): Set origin_server_ts (For application services only)
"""
- content_pack = {
- "geo_uri": geo_uri,
- "msgtype": "m.location",
- "body": name,
- }
+ content_pack = {"geo_uri": geo_uri, "msgtype": "m.location", "body": name}
if thumb_url:
content_pack["thumbnail_url"] = thumb_url
if thumb_info:
content_pack["thumbnail_info"] = thumb_info
- return self.send_message_event(room_id, "m.room.message", content_pack,
- timestamp=timestamp)
+ return self.send_message_event(
+ room_id, "m.room.message", content_pack, timestamp=timestamp
+ )
def send_message(self, room_id, text_content, msgtype="m.text", timestamp=None):
"""Perform PUT /rooms/$room_id/send/m.room.message
Args:
room_id (str): The room ID to send the event in.
text_content (str): The m.text body to send.
timestamp (int): Set origin_server_ts (For application services only)
"""
return self.send_message_event(
- room_id, "m.room.message",
+ room_id,
+ "m.room.message",
self.get_text_body(text_content, msgtype),
- timestamp=timestamp
+ timestamp=timestamp,
)
def send_emote(self, room_id, text_content, timestamp=None):
"""Perform PUT /rooms/$room_id/send/m.room.message with m.emote msgtype
@@ -343,29 +350,28 @@
room_id (str): The room ID to send the event in.
text_content (str): The m.emote body to send.
timestamp (int): Set origin_server_ts (For application services only)
"""
return self.send_message_event(
- room_id, "m.room.message",
+ room_id,
+ "m.room.message",
self.get_emote_body(text_content),
- timestamp=timestamp
+ timestamp=timestamp,
)
def send_notice(self, room_id, text_content, timestamp=None):
"""Perform PUT /rooms/$room_id/send/m.room.message with m.notice msgtype
Args:
room_id (str): The room ID to send the event in.
text_content (str): The m.notice body to send.
timestamp (int): Set origin_server_ts (For application services only)
"""
- body = {
- "msgtype": "m.notice",
- "body": text_content
- }
- return self.send_message_event(room_id, "m.room.message", body,
- timestamp=timestamp)
+ body = {"msgtype": "m.notice", "body": text_content}
+ return self.send_message_event(
+ room_id, "m.room.message", body, timestamp=timestamp
+ )
def get_room_messages(self, room_id, token, direction, limit=10, to=None):
"""Perform GET /rooms/{roomId}/messages.
Args:
@@ -373,22 +379,21 @@
token (str): The token to start returning events from.
direction (str): The direction to return events from. One of: ["b", "f"].
limit (int): The maximum number of events to return.
to (str): The token to stop returning events at.
"""
- query = {
- "roomId": room_id,
- "from": token,
- "dir": direction,
- "limit": limit,
- }
+ query = {"roomId": room_id, "from": token, "dir": direction, "limit": limit}
if to:
query["to"] = to
- return self._send("GET", "/rooms/{}/messages".format(quote(room_id)),
- query_params=query, api_path="/_matrix/client/r0")
+ return self._send(
+ "GET",
+ "/rooms/{}/messages".format(quote(room_id)),
+ query_params=query,
+ api_path="/_matrix/client/r0",
+ )
def get_room_name(self, room_id):
"""Perform GET /rooms/$room_id/state/m.room.name
Args:
room_id(str): The room ID
@@ -400,13 +405,11 @@
Args:
room_id (str): The room ID
name (str): The new room name
timestamp (int): Set origin_server_ts (For application services only)
"""
- body = {
- "name": name
- }
+ body = {"name": name}
return self.send_state_event(room_id, "m.room.name", body, timestamp=timestamp)
def get_room_topic(self, room_id):
"""Perform GET /rooms/$room_id/state/m.room.topic
Args:
@@ -419,23 +422,22 @@
Args:
room_id (str): The room ID
topic (str): The new room topic
timestamp (int): Set origin_server_ts (For application services only)
"""
- body = {
- "topic": topic
- }
+ body = {"topic": topic}
return self.send_state_event(room_id, "m.room.topic", body, timestamp=timestamp)
def get_power_levels(self, room_id):
"""Perform GET /rooms/$room_id/state/m.room.power_levels
Args:
room_id(str): The room ID
"""
- return self._send("GET", "/rooms/" + quote(room_id) +
- "/state/m.room.power_levels")
+ return self._send(
+ "GET", "/rooms/" + quote(room_id) + "/state/m.room.power_levels"
+ )
def set_power_levels(self, room_id, content):
"""Perform PUT /rooms/$room_id/state/m.room.power_levels
Note that any power levels which are not explicitly specified
@@ -495,13 +497,11 @@
Args:
room_id (str): The room ID
user_id (str): The user ID of the invitee
"""
- body = {
- "user_id": user_id
- }
+ body = {"user_id": user_id}
return self._send("POST", "/rooms/" + room_id + "/invite", body)
def kick_user(self, room_id, user_id, reason=""):
"""Calls set_membership with membership="leave" for the user_id provided
"""
@@ -513,100 +513,85 @@
Args:
room_id (str): The room ID
user_id (str): The user ID
"""
return self._send(
- "GET",
- "/rooms/%s/state/m.room.member/%s" % (room_id, user_id)
- )
-
- def set_membership(self, room_id, user_id, membership, reason="", profile={},
- timestamp=None):
+ "GET", "/rooms/%s/state/m.room.member/%s" % (room_id, user_id)
+ )
+
+ def set_membership(
+ self, room_id, user_id, membership, reason="", profile={}, timestamp=None
+ ):
"""Perform PUT /rooms/$room_id/state/m.room.member/$user_id
Args:
room_id (str): The room ID
user_id (str): The user ID
membership (str): New membership value
reason (str): The reason
timestamp (int): Set origin_server_ts (For application services only)
"""
- body = {
- "membership": membership,
- "reason": reason
- }
- if 'displayname' in profile:
+ body = {"membership": membership, "reason": reason}
+ if "displayname" in profile:
body["displayname"] = profile["displayname"]
- if 'avatar_url' in profile:
+ if "avatar_url" in profile:
body["avatar_url"] = profile["avatar_url"]
- return self.send_state_event(room_id, "m.room.member", body, state_key=user_id,
- timestamp=timestamp)
+ return self.send_state_event(
+ room_id, "m.room.member", body, state_key=user_id, timestamp=timestamp
+ )
def ban_user(self, room_id, user_id, reason=""):
"""Perform POST /rooms/$room_id/ban
Args:
room_id (str): The room ID
user_id (str): The user ID of the banee(sic)
reason (str): The reason for this ban
"""
- body = {
- "user_id": user_id,
- "reason": reason
- }
+ body = {"user_id": user_id, "reason": reason}
return self._send("POST", "/rooms/" + room_id + "/ban", body)
def unban_user(self, room_id, user_id):
"""Perform POST /rooms/$room_id/unban
Args:
room_id (str): The room ID
user_id (str): The user ID of the banee(sic)
"""
- body = {
- "user_id": user_id
- }
+ body = {"user_id": user_id}
return self._send("POST", "/rooms/" + room_id + "/unban", body)
def get_user_tags(self, user_id, room_id):
- return self._send(
- "GET",
- "/user/%s/rooms/%s/tags" % (user_id, room_id),
- )
+ return self._send("GET", "/user/%s/rooms/%s/tags" % (user_id, room_id))
def remove_user_tag(self, user_id, room_id, tag):
return self._send(
- "DELETE",
- "/user/%s/rooms/%s/tags/%s" % (user_id, room_id, tag),
+ "DELETE", "/user/%s/rooms/%s/tags/%s" % (user_id, room_id, tag)
)
def add_user_tag(self, user_id, room_id, tag, order=None, body=None):
if body:
pass
elif order:
body = {"order": order}
else:
body = {}
return self._send(
- "PUT",
- "/user/%s/rooms/%s/tags/%s" % (user_id, room_id, tag),
- body,
+ "PUT", "/user/%s/rooms/%s/tags/%s" % (user_id, room_id, tag), body
)
def set_account_data(self, user_id, type, account_data):
return self._send(
- "PUT",
- "/user/%s/account_data/%s" % (user_id, type),
- account_data,
+ "PUT", "/user/%s/account_data/%s" % (user_id, type), account_data
)
def set_room_account_data(self, user_id, room_id, type, account_data):
return self._send(
"PUT",
"/user/%s/rooms/%s/account_data/%s" % (user_id, room_id, type),
- account_data
+ account_data,
)
def get_room_state(self, room_id):
"""Perform GET /rooms/$room_id/state
@@ -614,32 +599,37 @@
room_id (str): The room ID
"""
return self._send("GET", "/rooms/" + room_id + "/state")
def get_text_body(self, text, msgtype="m.text"):
- return {
- "msgtype": msgtype,
- "body": text
- }
+ return {"msgtype": msgtype, "body": text}
def get_emote_body(self, text):
- return {
- "msgtype": "m.emote",
- "body": text
- }
+ return {"msgtype": "m.emote", "body": text}
def get_filter(self, user_id, filter_id):
- return self._send("GET", "/user/{userId}/filter/{filterId}"
- .format(userId=user_id, filterId=filter_id))
+ return self._send(
+ "GET",
+ "/user/{userId}/filter/{filterId}".format(
+ userId=user_id, filterId=filter_id
+ ),
+ )
def create_filter(self, user_id, filter_params):
- return self._send("POST",
- "/user/{userId}/filter".format(userId=user_id),
- filter_params)
-
- def _send(self, method, path, content=None, query_params={}, headers={},
- api_path=MATRIX_V2_API_PATH):
+ return self._send(
+ "POST", "/user/{userId}/filter".format(userId=user_id), filter_params
+ )
+
+ def _send(
+ self,
+ method,
+ path,
+ content=None,
+ query_params={},
+ headers={},
+ api_path=MATRIX_V2_API_PATH,
+ ):
method = method.upper()
if method not in ["GET", "PUT", "DELETE", "POST"]:
raise MatrixError("Unsupported HTTP method: %s" % method)
if "Content-Type" not in headers:
@@ -655,66 +645,66 @@
content = json.dumps(content)
while True:
try:
response = self.session.request(
- method, endpoint,
+ method,
+ endpoint,
params=query_params,
data=content,
headers=headers,
- verify=self.validate_cert
+ verify=self.validate_cert,
)
except RequestException as e:
raise MatrixHttpLibError(e, method, endpoint)
if response.status_code == 429:
waittime = self.default_429_wait_ms / 1000
try:
- waittime = response.json()['retry_after_ms'] / 1000
+ waittime = response.json()["retry_after_ms"] / 1000
except KeyError:
try:
- errordata = json.loads(response.json()['error'])
- waittime = errordata['retry_after_ms'] / 1000
+ errordata = json.loads(response.json()["error"])
+ waittime = errordata["retry_after_ms"] / 1000
except KeyError:
pass
sleep(waittime)
else:
break
if response.status_code < 200 or response.status_code >= 300:
- raise MatrixRequestError(
- code=response.status_code, content=response.text
- )
+ raise MatrixRequestError(code=response.status_code, content=response.text)
return response.json()
def media_upload(self, content, content_type):
return self._send(
- "POST", "",
+ "POST",
+ "",
content=content,
headers={"Content-Type": content_type},
- api_path="/_matrix/media/r0/upload"
+ api_path="/_matrix/media/r0/upload",
)
def get_display_name(self, user_id):
content = self._send("GET", "/profile/%s/displayname" % user_id)
- return content.get('displayname', None)
+ return content.get("displayname", None)
def set_display_name(self, user_id, display_name):
content = {"displayname": display_name}
return self._send("PUT", "/profile/%s/displayname" % user_id, content)
def get_avatar_url(self, user_id):
content = self._send("GET", "/profile/%s/avatar_url" % user_id)
- return content.get('avatar_url', None)
+ return content.get("avatar_url", None)
def set_avatar_url(self, user_id, avatar_url):
content = {"avatar_url": avatar_url}
return self._send("PUT", "/profile/%s/avatar_url" % user_id, content)
def get_download_url(self, mxcurl):
- if mxcurl.startswith('mxc://'):
+ if mxcurl.startswith("mxc://"):
return self.base_url + "/_matrix/media/r0/download/" + mxcurl[6:]
else:
raise ValueError("MXC URL did not begin with 'mxc://'")
def get_room_id(self, room_alias):
@@ -734,16 +724,15 @@
Args:
room_id (str): The room id.
room_alias (str): The room wanted alias name.
"""
- data = {
- "room_id": room_id
- }
-
- return self._send("PUT", "/directory/room/{}".format(quote(room_alias)),
- content=data)
+ data = {"room_id": room_id}
+
+ return self._send(
+ "PUT", "/directory/room/{}".format(quote(room_alias)), content=data
+ )
def remove_room_alias(self, room_alias):
"""Remove mapping of an alias
Args:
@@ -768,26 +757,22 @@
Args:
room_id(str): The room to set the rules for.
join_rule(str): The chosen rule. One of: ["public", "knock",
"invite", "private"]
"""
- content = {
- "join_rule": join_rule
- }
+ content = {"join_rule": join_rule}
return self.send_state_event(room_id, "m.room.join_rules", content)
def set_guest_access(self, room_id, guest_access):
"""Set the guest access policy of the room.
Args:
room_id(str): The room to set the rules for.
guest_access(str): Wether guests can join. One of: ["can_join",
"forbidden"]
"""
- content = {
- "guest_access": guest_access
- }
+ content = {"guest_access": guest_access}
return self.send_state_event(room_id, "m.room.guest_access", content)
def get_devices(self):
"""Gets information about all devices for the current user."""
return self._send("GET", "/devices")
@@ -801,13 +786,11 @@
Args:
device_id (str): The device ID of the device to update.
display_name (str): New display name for the device.
"""
- content = {
- "display_name": display_name
- }
+ content = {"display_name": display_name}
return self._send("PUT", "/devices/%s" % device_id, content=content)
def delete_device(self, auth_body, device_id):
"""Deletes the given device, and invalidates any access token associated with it.
@@ -815,13 +798,11 @@
Args:
auth_body (dict): Authentication params.
device_id (str): The device ID of the device to delete.
"""
- content = {
- "auth": auth_body
- }
+ content = {"auth": auth_body}
return self._send("DELETE", "/devices/%s" % device_id, content=content)
def delete_devices(self, auth_body, devices):
"""Bulk deletion of devices.
@@ -829,11 +810,8 @@
Args:
auth_body (dict): Authentication params.
devices (list): List of device ID"s to delete.
"""
- content = {
- "auth": auth_body,
- "devices": devices
- }
+ content = {"auth": auth_body, "devices": devices}
return self._send("POST", "/delete_devices", content=content)
6 files reformatted, 2 files left unchanged.
--- matrix_client/.ropeproject/config.py (original)
+++ matrix_client/.ropeproject/config.py (formatted)
@@ -12,101 +12,111 @@
# '*.pyc': matches 'test.pyc' and 'pkg/test.pyc'
# 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc'
# '.svn': matches 'pkg/.svn' and all of its children
# 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o'
# 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o'
- prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject',
- '.hg', '.svn', '_svn', '.git', '.tox']
+ prefs["ignored_resources"] = [
+ "*.pyc",
+ "*~",
+ ".ropeproject",
+ ".hg",
+ ".svn",
+ "_svn",
+ ".git",
+ ".tox",
+ ]
# Specifies which files should be considered python files. It is
# useful when you have scripts inside your project. Only files
# ending with ``.py`` are considered to be python files by
# default.
- #prefs['python_files'] = ['*.py']
+ # prefs['python_files'] = ['*.py']
# Custom source folders: By default rope searches the project
# for finding source folders (folders that should be searched
# for finding modules). You can add paths to that list. Note
# that rope guesses project source folders correctly most of the
# time; use this if you have any problems.
# The folders should be relative to project root and use '/' for
# separating folders regardless of the platform rope is running on.
# 'src/my_source_folder' for instance.
- #prefs.add('source_folders', 'src')
+ # prefs.add('source_folders', 'src')
# You can extend python path for looking up modules
- #prefs.add('python_path', '~/python/')
+ # prefs.add('python_path', '~/python/')
# Should rope save object information or not.
- prefs['save_objectdb'] = True
- prefs['compress_objectdb'] = False
+ prefs["save_objectdb"] = True
+ prefs["compress_objectdb"] = False
# If `True`, rope analyzes each module when it is being saved.
- prefs['automatic_soa'] = True
+ prefs["automatic_soa"] = True
# The depth of calls to follow in static object analysis
- prefs['soa_followed_calls'] = 0
+ prefs["soa_followed_calls"] = 0
# If `False` when running modules or unit tests "dynamic object
# analysis" is turned off. This makes them much faster.
- prefs['perform_doa'] = True
+ prefs["perform_doa"] = True
# Rope can check the validity of its object DB when running.
- prefs['validate_objectdb'] = True
+ prefs["validate_objectdb"] = True
# How many undos to hold?
- prefs['max_history_items'] = 32
+ prefs["max_history_items"] = 32
# Shows whether to save history across sessions.
- prefs['save_history'] = True
- prefs['compress_history'] = False
+ prefs["save_history"] = True
+ prefs["compress_history"] = False
# Set the number spaces used for indenting. According to
# :PEP:`8`, it is best to use 4 spaces. Since most of rope's
# unit-tests use 4 spaces it is more reliable, too.
- prefs['indent_size'] = 4
+ prefs["indent_size"] = 4
# Builtin and c-extension modules that are allowed to be imported
# and inspected by rope.
- prefs['extension_modules'] = []
+ prefs["extension_modules"] = []
# Add all standard c-extensions to extension_modules list.
- prefs['import_dynload_stdmods'] = True
+ prefs["import_dynload_stdmods"] = True
# If `True` modules with syntax errors are considered to be empty.
# The default value is `False`; When `False` syntax errors raise
# `rope.base.exceptions.ModuleSyntaxError` exception.
- prefs['ignore_syntax_errors'] = False
+ prefs["ignore_syntax_errors"] = False
# If `True`, rope ignores unresolvable imports. Otherwise, they
# appear in the importing namespace.
- prefs['ignore_bad_imports'] = False
+ prefs["ignore_bad_imports"] = False
# If `True`, rope will insert new module imports as
# `from <package> import <module>` by default.
- prefs['prefer_module_from_imports'] = False
+ prefs["prefer_module_from_imports"] = False
# If `True`, rope will transform a comma list of imports into
# multiple separate import statements when organizing
# imports.
- prefs['split_imports'] = False
+ prefs["split_imports"] = False
# If `True`, rope will remove all top-level import statements and
# reinsert them at the top of the module when making changes.
- prefs['pull_imports_to_top'] = True
+ prefs["pull_imports_to_top"] = True
# If `True`, rope will sort imports alphabetically by module name instead of
# alphabetically by import statement, with from imports after normal
# imports.
- prefs['sort_imports_alphabetically'] = False
+ prefs["sort_imports_alphabetically"] = False
# Location of implementation of rope.base.oi.type_hinting.interfaces.ITypeHintingFactory
# In general case, you don't have to change this value, unless you're an rope expert.
# Change this value to inject you own implementations of interfaces
# listed in module rope.base.oi.type_hinting.providers.interfaces
# For example, you can add you own providers for Django Models, or disable the search
# type-hinting in a class hierarchy, etc.
- prefs['type_hinting_factory'] = 'rope.base.oi.type_hinting.factory.default_type_hinting_factory'
+ prefs[
+ "type_hinting_factory"
+ ] = "rope.base.oi.type_hinting.factory.default_type_hinting_factory"
def project_opened(project):
"""This function is called after opening the project"""
# Do whatever you like here!
--- matrix_client/user.py (original)
+++ matrix_client/user.py (formatted)
@@ -16,10 +16,11 @@
class User(object):
""" The User class can be used to call user specific functions.
"""
+
def __init__(self, api, user_id, displayname=None):
check_user_id(user_id)
self.user_id = user_id
self.displayname = displayname
This would not get rid of the necessity of properly formatting docstrings.