Esempio n. 1
0
  def messageHandler(self, msg):
    if(self.opt('matrix.debug')):
      self.log.debug(str(msg))

    try:
      # Create a new Message to send to Sibyl
      u = self.new_user(msg['sender'], Message.GROUP)
      r = self.new_room(msg['room_id'])

      msgtype = msg['content']['msgtype']

      if(msgtype == 'm.text'):
        m = Message(u, msg['content']['body'], room=r, typ=Message.GROUP)
        self.log.debug('Handling m.text: ' + msg['content']['body'])
        self.msg_queue.put(m)

      elif(msgtype == 'm.emote'):
        m = Message(u, msg['content']['body'], room=r, typ=Message.GROUP,
            emote=True)
        self.log.debug('Handling m.emote: ' + msg['content']['body'])
        self.msg_queue.put(m)

      elif(msgtype == 'm.image' or msgtype == 'm.audio' or msgtype == 'm.file' or msgtype == 'm.video'):
        media_url = urlparse(msg['content']['url'])
        http_url = self.client.api.base_url + "/_matrix/media/r0/download/{0}{1}".format(media_url.netloc, media_url.path)
        if(msgtype == 'm.image'):
          body = "{0} uploaded {1}: {2}".format(msg['sender'], msg['content'].get('body', 'an image'), http_url)
        elif(msgtype == 'm.audio'):
          body = "{0} uploaded {1}: {2}".format(msg['sender'], msg['content'].get('body', 'an audio file'), http_url)
        elif(msgtype == 'm.video'):
          body = "{0} uploaded {1}: {2}".format(msg['sender'], msg['content'].get('body', 'a video file'), http_url)
        elif(msgtype == 'm.file'):
          body = "{0} uploaded {1}: {2}".format(msg['sender'], msg['content'].get('body', 'a file'), http_url)
        m = Message(u, body, room=r, typ=Message.GROUP)
        self.log.debug("Handling " + msgtype + ": " + body)
        self.msg_queue.put(m)

      elif(msgtype == 'm.location'):
        body = "{0} sent a location: {1}".format(msg['sender'], msg['content']['geo_uri'])
        m = Message(u, body, room=r, typ=Message.GROUP)
        self.log.debug('Handling m.location: ' + body)
        self.msg_queue.put(m)


      else:
        self.log.debug('Not handling message, unknown msgtype')



    except KeyError as e:
      self.log.debug("Incoming message did not have all required fields: " + e.message)
Esempio n. 2
0
    def process(self):

        while not self.thread.msgs.empty():

            mail = self.thread.msgs.get()
            if isinstance(mail, Exception):
                raise mail

            frm = email.utils.parseaddr(mail['From'])[1]
            user = MailUser(self, frm)
            body = mail.get_payload().split('\n')[0].strip()
            msg = Message(user, body)
            self.log.debug('Got mail from "%s"' % frm)
            self.bot._cb_message(msg)
Esempio n. 3
0
  def send(self,text,to,broadcast=False,frm=None,users=None,
      hook=True,emote=False):
    """send a message (this function is thread-safe)"""

    broadcast = (broadcast and isinstance(to,Room))
    frm = (frm if broadcast else to.get_protocol().get_user())
    users = (users if broadcast else None)

    msg = Message(frm,text,
                  to=to,
                  broadcast=broadcast,
                  users=users,
                  hook=hook,
                  emote=emote)
    self.__pending_send.put(msg)
Esempio n. 4
0
    def process(self):

        if not self.event_data.is_set():
            return

        (address, text) = self.queue.get()
        usr = Client(self, address)

        if self.special_cmds(text):
            return

        msg = Message(usr, text)
        self.bot._cb_message(msg)

        if self.queue.empty():
            self.event_data.clear()
Esempio n. 5
0
    def process(self):

        # every time SibylBot calls process(), this method synchronously checks for
        # new messages that the IMAPThread added while we were doing other things
        while not self.thread.msgs.empty():

            # check if there was a problem connecting and raise it syncronously
            mail = self.thread.msgs.get()
            if isinstance(mail, Exception):
                raise mail

            # parse the sender
            frm = email.utils.parseaddr(mail['From'])[1]
            user = MailUser(self, frm)

            # handle multi-part messages
            body = mail.get_payload()
            if isinstance(body, list):
                for b in body:
                    if b.get_content_type() == 'plain':
                        body = b.replace('\r', '').strip()
            if isinstance(body, list):
                self.log.warning(
                    'Ignoring multi-part from "%s"; no plaintext' % frm)
                self._send(
                    'Unable to process multi-part message; no plaintext', user)
                return

            # check for authentication key if configured
            if self.opt('email.key') and self.opt(
                    'email.key').get() not in body:
                self.log.warning('Invalid key from "%s"; dropping message' %
                                 user)
                self._send('Invalid or missing key; commands forbidden', user)
                continue

            # finish parsing the e-mail and send it
            body = body.split('\n')[0].strip()
            msg = Message(user, body)
            ellip = ('...' if len(body) > 20 else '')
            self.log.debug('mail from "%s" with body "%.20s%s"' %
                           (user, body, ellip))

            # pass the message on to the bot for command execution
            self.bot._cb_message(msg)
Esempio n. 6
0
  def broadcast(self,mess):
    """send a message to every user in a room"""

    (text,room,frm) = (mess.get_text(),mess.get_to(),mess.get_user())
    users = self.get_occupants(room)+(mess.get_users() or [])

    # Matrix has no built-in broadcast, so we'll just highlight everyone
    s = 'all: %s --- ' % text
    if frm:
      self.log.debug('Broadcast message from: ' + str(frm))
      s += frm.get_name()+' --- '

    me = self.get_user()
    names = [u.get_name() for u in users if (u!=me and (not frm or u!=frm))]
    s += ', '.join(set(names))

    self.send(Message(self.get_user(),s,to=room))
    return s
Esempio n. 7
0
    def process(self):

        if not self.event_data.is_set():
            return

        usr = Admin(self, USER)
        text = self.queue.get()

        if self.special_cmds(text):
            return

        msg = Message(usr, text)
        self.bot._cb_message(msg)

        if self.queue.empty():
            self.event_data.clear()

        if self.bot._SibylBot__finished:
            self.event_close.set()
        self.event_proc.set()
Esempio n. 8
0
    def broadcast(self, mess):
        """send a message to every user in a room"""

        (text, room, frm) = (mess.get_text(), mess.get_to(), mess.get_user())
        users = self.get_occupants(room) + (mess.get_users() or [])

        # XMPP has no built-in broadcast, so we'll just highlight everyone
        s = 'all: %s --- ' % text
        if frm:
            s += frm.get_name() + ' --- '

        me = JID(self,
                 room.get_name() + '/' + self.get_nick(room),
                 typ=Message.GROUP)
        names = [
            u.get_name() for u in users if (u != me and (not frm or u != frm))
        ]
        s += ', '.join(set(names))

        self.send(Message(self.get_user(), s, to=room))
        return s
Esempio n. 9
0
    def _send(self, text, to):

        msg = Message(self.get_user(), text, to=to)
        self.bot.send(msg)
Esempio n. 10
0
    def callback_message(self, conn, mess):
        """Messages sent to the bot will arrive here.
    Command handling + routing is done in this function."""

        typ = mess.getType()
        jid = mess.getFrom()
        props = mess.getProperties()
        text = mess.getBody()
        username = self.__get_sender_username(mess)
        room = None
        emote = False

        if text is None:
            return

        if typ not in ("groupchat", "chat"):
            self.log.debug("unhandled message type: %s" % typ)
            return

        if typ == 'groupchat':

            # Ignore messages from before we joined
            if xmpp.NS_DELAY in props:
                return

            # Ignore messages from myself
            room = jid.getStripped()
            if ((self.jid == jid)
                    or (room in self.__get_current_mucs()
                        and jid.getResource() == self.mucs[room]['nick'])):
                return

        # Ignore messages from users not seen by this bot
        real = [j.getStripped() for j in self.real_jids.values()]
        if (jid not in self.seen) and (jid.getStripped() not in real):
            self.log.info('Ignoring message from unseen guest: %s' % jid)
            self.log.debug("I've seen: %s" %
                           ["%s" % x for x in self.seen.keys() + real])
            return

        if len(text) > 40:
            txt = text[:40] + '...'
        else:
            txt = text
        self.log.debug('Got %s from %s: "%s"' % (typ, jid, txt))

        typ = self.TYPES[typ]
        real = None
        if jid in self.real_jids:
            real = JID(self, self.real_jids[jid])
        user = JID(self, jid, typ=typ, real=real)

        if room:
            room = MUC(self, room)

        # handle /me messages
        if text.startswith('/me '):
            text = text[3:].strip()
            emote = True

        self.bot._cb_message(
            Message(user, text, typ=typ, room=room, emote=emote))
Esempio n. 11
0
        real = None
        room = None
        if jid.getStripped(
        ) in self.__get_current_mucs() + self.__get_pending_mucs():
            jid_typ = Message.GROUP
            room = MUC(self, jid.getStripped())
            if jid in self.real_jids:
                real = JID(self, self.real_jids[jid])
        frm = JID(self, jid, typ=jid_typ)
        if real:
            frm.set_real(real)

        # call SibylBot's message callback
        msg = Message(frm,
                      None,
                      typ=typ,
                      status=status,
                      msg=status_msg,
                      room=room)
        self.bot._cb_message(msg)

################################################################################
# Helper functions
################################################################################

    def __status_type_changed(self, jid, new_status_type):
        """Callback for tracking status types (dnd, away, offline, ...)"""
        self.log.debug('user %s changed status to %s' % (jid, new_status_type))

    def __status_message_changed(self, jid, new_status_message):
        """Callback for tracking status messages (the free-form status text)"""
        self.log.debug('user %s updated text to %s' %
Esempio n. 12
0
  def messageHandler(self, msg):
    if(self.opt('matrix.debug')):
      self.log.debug(str(msg))

    try:
      # Create a new Message to send to Sibyl
      u = self.new_user(msg['sender'], Message.GROUP)
      r = self.new_room(msg['room_id'])

      if(r in self.join_timestamps
         and datetime.datetime.fromtimestamp(msg['origin_server_ts']/1000, pytz.utc) < self.join_timestamps[r]):
        self.log.info('Message received in {} from before room join, ignoring'.format(msg['room_id']))
        return None

      if('msgtype' in msg['content']):
        msgtype = msg['content']['msgtype']

        if(msgtype == 'm.text'):
          m = Message(u, msg['content']['body'], room=r, typ=Message.GROUP)
          self.log.debug('Handling m.text: ' + msg['content']['body'])
          self.msg_queue.put(m)

        elif(msgtype == 'm.emote'):
          m = Message(u, msg['content']['body'], room=r, typ=Message.GROUP,
          emote=True)
          self.log.debug('Handling m.emote: ' + msg['content']['body'])
          self.msg_queue.put(m)

        elif(msgtype == 'm.image' or msgtype == 'm.audio' or msgtype == 'm.file' or msgtype == 'm.video'):
          media_url = urlparse(msg['content']['url'])
          http_url = self.client.api.base_url + "/_matrix/media/r0/download/{0}{1}".format(media_url.netloc, media_url.path)
          if(msgtype == 'm.image'):
            body = "{0} uploaded {1}: {2}".format(msg['sender'], msg['content'].get('body', 'an image'), http_url)
          elif(msgtype == 'm.audio'):
            body = "{0} uploaded {1}: {2}".format(msg['sender'], msg['content'].get('body', 'an audio file'), http_url)
          elif(msgtype == 'm.video'):
            body = "{0} uploaded {1}: {2}".format(msg['sender'], msg['content'].get('body', 'a video file'), http_url)
          elif(msgtype == 'm.file'):
            body = "{0} uploaded {1}: {2}".format(msg['sender'], msg['content'].get('body', 'a file'), http_url)
          m = Message(u, body, room=r, typ=Message.GROUP)
          self.log.debug("Handling " + msgtype + ": " + body)
          self.msg_queue.put(m)

        elif(msgtype == 'm.location'):
          body = "{0} sent a location: {1}".format(msg['sender'], msg['content']['geo_uri'])
          m = Message(u, body, room=r, typ=Message.GROUP)
          self.log.debug('Handling m.location: ' + body)
          self.msg_queue.put(m)


        else:
          self.log.debug('Not handling message, unknown msgtype')

      elif('membership' in msg):
        if(msg['membership'] == 'join'):
          self.room_occupants[r].add(self.new_user(msg['state_key'], Message.GROUP))
        elif(msg['membership'] == 'leave'):
          self.room_occupants[r].remove(self.new_user(msg['state_key'], Message.GROUP))

    except KeyError as e:
      self.log.debug("Incoming message did not have all required fields: " + e.message)