Exemple #1
0
 def on_transaction_typing(self, transaction_id, event):
   """Routes typing notifications from Matrix server to the client."""
   del transaction_id # Unused.
   room_id = query_json_path(event, "room_id")
   if room_id in self.base.rooms and self.base.rooms[room_id].members:
     user = self.base.rooms[room_id].user
     typing_user_ids = set(query_json_path(event, "content", "user_ids"))
     # Note: the implementation assumes 1:1 chat.
     contact = next(iter(self.base.rooms[room_id].members))
     account = self.base.find_account_for_contact(user, contact)
     if account:
       conv_id = self.base.rooms[room_id].conv_id
       # We cannot operate without conv_id as it's required by
       # the client for sending the typing state.
       if not conv_id:
         ext_contact = self.base.mxid_to_ext_contact(account.network, contact)
         conv_id = account.client.create_conversation(
             account.network, account.ext_user, ext_contact)
         self.base.rooms[room_id].conv_id = conv_id
       if conv_id:
         # Note: we can get here via feedback loop, that is - when Matrix server
         # receives our typing notification from the external client, it will send
         # us the transaction and we'll end up here. We cannot distinguish it from
         # the "genuine" update for the user and discard, though, so the best we
         # can do is to send the correct current typing state for the user.
         account.client.set_typing(
             account.network, account.ext_user, conv_id, user in typing_user_ids)
         return
     logger.info(
         "Cannot figure out conversation id or account "
         "for room '{0}', cannot set typing state", room_id)
   else:
     logger.info("Room '{0}' is unknown, cannot set typing state", room_id)
Exemple #2
0
 def on_transaction_presence(self, transaction_id, event):
     """Routes user presence changes from Matrix to the client."""
     del transaction_id  # Unused.
     user = query_json_path(event, "content", "user_id")
     presence = query_json_path(event, "content", "presence")
     if user in self.base.accounts:
         for account in self.base.accounts[user]:
             account.client.set_account_status(account.network,
                                               account.ext_user, presence)
Exemple #3
0
def _get_joined_members(state):
  if state and "rooms" in state and "join" in state["rooms"]:
    for room_id, room_state in state["rooms"]["join"].items():
      members = set()
      events = query_json_path(room_state, "state", "events")
      if events:
        for event in events:
          state_key = query_json_path(event, "state_key")
          if state_key and query_json_path(event, "content", "membership") == "join":
            members.add(state_key)
      yield room_id, members
Exemple #4
0
    def process_transaction_message(self, transaction_id, event):
        """Processes messagereceived from Matrix.

    Note: this function is not registered directly as a callback but is called
    from 'ServiceLayer' if it determines the message should be handled as the
    'normal' one."""
        del transaction_id  # Unused.
        sender = event["sender"]
        room_id = event["room_id"]
        payload = query_json_path(event, "content")
        if sender in self.base.accounts:
            if event["event_id"] in self.sent_ids:
                self.sent_ids.remove(event["event_id"])
                return
            if room_id in self.base.rooms:
                for member in self.base.rooms[room_id].members:
                    self.send_message_to_client(room_id, sender, member,
                                                payload)
            else:
                # Unknown room_id - potentially we're not currently tracking
                # the recipient contact, so we cannot determine the exact account to use.
                # Store message as offline so that once the contact is online and its room state
                # is fetched - we can deliver the message.
                self._store_offline_message_to_clients_without_account(
                    room_id, sender, get_event_datetime(event), payload)
Exemple #5
0
def _render_payload_for_client(account, payload):
    body = query_json_path(payload, "body")
    fmt = query_json_path(payload, "format")
    formatted_body = query_json_path(payload, "formatted_body")
    rendered_body = body
    if "format" in account.config and fmt and account.config["format"] == fmt:
        rendered_body = formatted_body
    else:
        if "convert_from_text" in account.config:
            if account.config["convert_from_text"] == "markdown":
                rendered_body = markdown.markdown(body)
            else:
                logger.error(
                    "PuMaDuct misconfiguration: from text converter '{0}'"
                    " for the network '{1}' is unknown.",
                    account.config["convert_from_text"], account.network)
    return rendered_body
Exemple #6
0
    def start(self):
        self.presence_refresh_cb = self.base.glib.timeout_add_seconds(
            self.presence_refresh_interval, self.on_presence_refresh)

        # Determine which users are on our presence list.
        presence_list = self.base.matrix_client.get_presence_list(
            self.service.user)
        for presence in presence_list:
            user = query_json_path(presence, "content", "user_id")
            if user is not None:
                self.presence_list.add(user)

        # Add to presence list everybody who's not yet on it.
        for user in self.base.accounts:
            if user not in self.presence_list:
                logger.info(
                    "Service {0} doesn't have the presence for user {1}, requesting",
                    self.service.user, user)
                self.base.matrix_client.add_to_presence_list(
                    user, self.service.user)

        self.base.matrix_client.set_user_presence(self.service.user, "online")
Exemple #7
0
 def test_query_json_path(self):
   json = {"a": {"b": {"c": 1}}}
   self.assertEqual(query_json_path(json, "a", "b", "c"), 1)
   self.assertIsNone(query_json_path(json, "a", "b", "d"))