示例#1
0
    def command_say(self, line, attention=False, correct=False):
        msg = self.core.xmpp.make_message(self.get_dest_jid())
        msg['type'] = 'chat'
        msg['body'] = line
        if not self.nick_sent:
            msg['nick'] = self.core.own_nick
            self.nick_sent = True
        # trigger the event BEFORE looking for colors.
        # and before displaying the message in the window
        # This lets a plugin insert \x19xxx} colors, that will
        # be converted in xhtml.
        self.core.events.trigger('conversation_say', msg, self)
        if not msg['body']:
            self.cancel_paused_delay()
            self.text_win.refresh()
            self.input.refresh()
            return
        replaced = False
        if correct or msg['replace']['id']:
            msg['replace']['id'] = self.last_sent_message['id']
            if config.get_by_tabname('group_corrections', self.name):
                try:
                    self.modify_message(msg['body'], self.last_sent_message['id'], msg['id'], jid=self.core.xmpp.boundjid,
                            nickname=self.core.own_nick)
                    replaced = True
                except:
                    log.error('Unable to correct a message', exc_info=True)
        else:
            del msg['replace']
        if msg['body'].find('\x19') != -1:
            msg.enable('html')
            msg['html']['body'] = xhtml.poezio_colors_to_html(msg['body'])
            msg['body'] = xhtml.clean_text(msg['body'])
        if (config.get_by_tabname('send_chat_states', self.general_jid) and
                self.remote_wants_chatstates is not False):
            needed = 'inactive' if self.inactive else 'active'
            msg['chat_state'] = needed
        if attention and self.remote_supports_attention:
            msg['attention'] = True
        self.core.events.trigger('conversation_say_after', msg, self)
        if not msg['body']:
            self.cancel_paused_delay()
            self.text_win.refresh()
            self.input.refresh()
            return
        if not replaced:
            self.add_message(msg['body'],
                    nickname=self.core.own_nick,
                    nick_color=get_theme().COLOR_OWN_NICK,
                    identifier=msg['id'],
                    jid=self.core.xmpp.boundjid,
                    typ=1)

        self.last_sent_message = msg
        if self.remote_supports_receipts:
            msg._add_receipt = True
        msg.send()
        self.cancel_paused_delay()
        self.text_win.refresh()
        self.input.refresh()
示例#2
0
文件: handlers.py 项目: Perdu/poezio
def on_mood_event(self, message):
    """
    Called when a pep notification for an user mood
    is received.
    """
    contact = roster[message['from'].bare]
    if not contact:
        return
    roster.modified()
    item = message['pubsub_event']['items']['item']
    old_mood = contact.mood
    if item.xml.find('{http://jabber.org/protocol/mood}mood'):
        mood = item['mood']['value']
        if mood:
            mood = pep.MOODS.get(mood, mood)
            text = item['mood']['text']
            if text:
                mood = '%s (%s)' % (mood, text)
            contact.mood = mood
        else:
            contact.mood = ''
    else:
        contact.mood = ''

    if contact.mood:
        logger.log_roster_change(contact.bare_jid, 'has now the mood: %s' % contact.mood)

    if old_mood != contact.mood and config.get_by_tabname('display_mood_notifications', contact.bare_jid):
        if contact.mood:
            self.information('Mood from '+ contact.bare_jid + ': ' + contact.mood, 'Mood')
        else:
            self.information(contact.bare_jid + ' stopped having his/her mood.', 'Mood')
示例#3
0
 def check_and_create_log_dir(self, room, open_fd=True):
     """
     Check that the directory where we want to log the messages
     exists. if not, create it
     """
     if not config.get_by_tabname('use_log', room):
         return
     try:
         makedirs(log_dir)
     except OSError as e:
         if e.errno != 17:  # file exists
             log.error('Unable to create the log dir', exc_info=True)
     except:
         log.error('Unable to create the log dir', exc_info=True)
         return
     if not open_fd:
         return
     try:
         fd = open(os.path.join(log_dir, room), 'a')
         self.fds[room] = fd
         return fd
     except IOError:
         log.error('Unable to open the log file (%s)',
                   os.path.join(log_dir, room),
                   exc_info=True)
示例#4
0
文件: logger.py 项目: Perdu/poezio
 def log_roster_change(self, jid, message):
     """
     Log a roster change
     """
     if not config.get_by_tabname('use_log', jid):
         return True
     self.check_and_create_log_dir('', open_fd=False)
     if not self.roster_logfile:
         try:
             self.roster_logfile = open(os.path.join(log_dir, 'roster.log'), 'a')
         except IOError:
             log.error('Unable to create the log file (%s)',
                     os.path.join(log_dir, 'roster.log'),
                     exc_info=True)
             return False
     try:
         str_time = common.get_utc_time().strftime('%Y%m%dT%H:%M:%SZ')
         message = clean_text(message)
         lines = message.split('\n')
         first_line = lines.pop(0)
         nb_lines = str(len(lines)).zfill(3)
         self.roster_logfile.write('MI %s %s %s %s\n' % (str_time, nb_lines, jid, first_line))
         for line in lines:
             self.roster_logfile.write(' %s\n' % line)
         self.roster_logfile.flush()
     except:
         log.error('Unable to write in the log file (%s)',
                 os.path.join(log_dir, 'roster.log'),
                 exc_info=True)
         return False
     return True
示例#5
0
文件: handlers.py 项目: Perdu/poezio
def on_tune_event(self, message):
    """
    Called when a pep notification for an user tune
    is received
    """
    contact = roster[message['from'].bare]
    if not contact:
        return
    roster.modified()
    item = message['pubsub_event']['items']['item']
    old_tune = contact.tune
    if item.xml.find('{http://jabber.org/protocol/tune}tune'):
        item = item['tune']
        contact.tune = {
                'artist': item['artist'],
                'length': item['length'],
                'rating': item['rating'],
                'source': item['source'],
                'title': item['title'],
                'track': item['track'],
                'uri': item['uri']
            }
    else:
        contact.tune = {}

    if contact.tune:
        logger.log_roster_change(message['from'].bare, 'is now listening to %s' % common.format_tune_string(contact.tune))

    if old_tune != contact.tune and config.get_by_tabname('display_tune_notifications', contact.bare_jid):
        if contact.tune:
            self.information(
                    'Tune from '+ message['from'].bare + ': ' + common.format_tune_string(contact.tune),
                    'Tune')
        else:
            self.information(contact.bare_jid + ' stopped listening to music.', 'Tune')
示例#6
0
文件: logger.py 项目: Perdu/poezio
 def check_and_create_log_dir(self, room, open_fd=True):
     """
     Check that the directory where we want to log the messages
     exists. if not, create it
     """
     if not config.get_by_tabname('use_log', room):
         return
     try:
         makedirs(log_dir)
     except OSError as e:
         if e.errno != 17: # file exists
             log.error('Unable to create the log dir', exc_info=True)
     except:
         log.error('Unable to create the log dir', exc_info=True)
         return
     if not open_fd:
         return
     try:
         fd = open(os.path.join(log_dir, room), 'a')
         self.fds[room] = fd
         return fd
     except IOError:
         log.error('Unable to open the log file (%s)',
                 os.path.join(log_dir, room),
                 exc_info=True)
示例#7
0
 def log_roster_change(self, jid, message):
     """
     Log a roster change
     """
     if not config.get_by_tabname('use_log', jid):
         return True
     self.check_and_create_log_dir('', open_fd=False)
     if not self.roster_logfile:
         try:
             self.roster_logfile = open(os.path.join(log_dir, 'roster.log'),
                                        'a')
         except IOError:
             log.error('Unable to create the log file (%s)',
                       os.path.join(log_dir, 'roster.log'),
                       exc_info=True)
             return False
     try:
         str_time = common.get_utc_time().strftime('%Y%m%dT%H:%M:%SZ')
         message = clean_text(message)
         lines = message.split('\n')
         first_line = lines.pop(0)
         nb_lines = str(len(lines)).zfill(3)
         self.roster_logfile.write('MI %s %s %s %s\n' %
                                   (str_time, nb_lines, jid, first_line))
         for line in lines:
             self.roster_logfile.write(' %s\n' % line)
         self.roster_logfile.flush()
     except:
         log.error('Unable to write in the log file (%s)',
                   os.path.join(log_dir, 'roster.log'),
                   exc_info=True)
         return False
     return True
示例#8
0
 def on_gain_focus(self):
     self.state = 'current'
     curses.curs_set(1)
     tab = self.core.get_tab_by_name(safeJID(self.name).bare, MucTab)
     if tab and tab.joined and config.get_by_tabname('send_chat_states',
             self.general_jid,) and not self.input.get_text() and self.on:
         self.send_chat_state('active')
示例#9
0
文件: handlers.py 项目: Perdu/poezio
def on_gaming_event(self, message):
    """
    Called when a pep notification for user gaming
    is received
    """
    contact = roster[message['from'].bare]
    if not contact:
        return
    item = message['pubsub_event']['items']['item']
    old_gaming = contact.gaming
    if item.xml.find('{urn:xmpp:gaming:0}gaming'):
        item = item['gaming']
        # only name and server_address are used for now
        contact.gaming = {
                'character_name': item['character_name'],
                'character_profile': item['character_profile'],
                'name': item['name'],
                'level': item['level'],
                'uri': item['uri'],
                'server_name': item['server_name'],
                'server_address': item['server_address'],
            }
    else:
        contact.gaming = {}

    if contact.gaming:
        logger.log_roster_change(contact.bare_jid, 'is playing %s' % (common.format_gaming_string(contact.gaming)))

    if old_gaming != contact.gaming and config.get_by_tabname('display_gaming_notifications', contact.bare_jid):
        if contact.gaming:
            self.information('%s is playing %s' % (contact.bare_jid, common.format_gaming_string(contact.gaming)), 'Gaming')
        else:
            self.information(contact.bare_jid + ' stopped playing.', 'Gaming')
示例#10
0
文件: otr.py 项目: Perdu/poezio
def hl(tab):
    if tab.state != 'current':
        tab.state = 'private'

    conv_jid = safeJID(tab.name)
    if 'private' in config.get('beep_on', 'highlight private').split():
        if not config.get_by_tabname('disable_beep', conv_jid.bare, default=False):
            curses.beep()
示例#11
0
    def log_message(self, jid, nick, msg, date=None, typ=1):
        """
        log the message in the appropriate jid's file
        type:
              0 = Don’t log
              1 = Message
              2 = Status/whatever
        """
        if not typ:
            return True

        jid = str(jid).replace('/', '\\')
        if not config.get_by_tabname('use_log', jid):
            return True
        if jid in self.fds.keys():
            fd = self.fds[jid]
        else:
            fd = self.check_and_create_log_dir(jid)
        if not fd:
            return True
        try:
            msg = clean_text(msg)
            if date is None:
                str_time = common.get_utc_time().strftime('%Y%m%dT%H:%M:%SZ')
            else:
                str_time = common.get_utc_time(date).strftime(
                    '%Y%m%dT%H:%M:%SZ')
            if typ == 1:
                prefix = 'MR'
            else:
                prefix = 'MI'
            lines = msg.split('\n')
            first_line = lines.pop(0)
            nb_lines = str(len(lines)).zfill(3)

            if nick:
                nick = '<' + nick + '>'
                fd.write(' '.join((prefix, str_time, nb_lines, nick,
                                   ' ' + first_line, '\n')))
            else:
                fd.write(' '.join(
                    (prefix, str_time, nb_lines, first_line, '\n')))
            for line in lines:
                fd.write(' %s\n' % line)
        except:
            log.error('Unable to write in the log file (%s)',
                      os.path.join(log_dir, jid),
                      exc_info=True)
            return False
        else:
            try:
                fd.flush()  # TODO do something better here?
            except:
                log.error('Unable to flush the log file (%s)',
                          os.path.join(log_dir, jid),
                          exc_info=True)
                return False
        return True
示例#12
0
 def on_gain_focus(self):
     self.state = 'current'
     curses.curs_set(1)
     tab = self.core.get_tab_by_name(safeJID(self.name).bare, MucTab)
     if tab and tab.joined and config.get_by_tabname(
             'send_chat_states',
             self.general_jid,
     ) and not self.input.get_text() and self.on:
         self.send_chat_state('active')
示例#13
0
文件: otr.py 项目: Perdu/poezio
def hl(tab):
    if tab.state != 'current':
        tab.state = 'private'

    conv_jid = safeJID(tab.name)
    if 'private' in config.get('beep_on', 'highlight private').split():
        if not config.get_by_tabname(
                'disable_beep', conv_jid.bare, default=False):
            curses.beep()
示例#14
0
文件: logger.py 项目: Perdu/poezio
    def log_message(self, jid, nick, msg, date=None, typ=1):
        """
        log the message in the appropriate jid's file
        type:
              0 = Don’t log
              1 = Message
              2 = Status/whatever
        """
        if not typ:
            return True

        jid = str(jid).replace('/', '\\')
        if not config.get_by_tabname('use_log', jid):
            return True
        if jid in self.fds.keys():
            fd = self.fds[jid]
        else:
            fd = self.check_and_create_log_dir(jid)
        if not fd:
            return True
        try:
            msg = clean_text(msg)
            if date is None:
                str_time = common.get_utc_time().strftime('%Y%m%dT%H:%M:%SZ')
            else:
                str_time = common.get_utc_time(date).strftime('%Y%m%dT%H:%M:%SZ')
            if typ == 1:
                prefix = 'MR'
            else:
                prefix = 'MI'
            lines = msg.split('\n')
            first_line = lines.pop(0)
            nb_lines = str(len(lines)).zfill(3)

            if nick:
                nick = '<' + nick + '>'
                fd.write(' '.join((prefix, str_time, nb_lines, nick, ' '+first_line, '\n')))
            else:
                fd.write(' '.join((prefix, str_time, nb_lines, first_line, '\n')))
            for line in lines:
                fd.write(' %s\n' % line)
        except:
            log.error('Unable to write in the log file (%s)',
                    os.path.join(log_dir, jid),
                    exc_info=True)
            return False
        else:
            try:
                fd.flush()          # TODO do something better here?
            except:
                log.error('Unable to flush the log file (%s)',
                        os.path.join(log_dir, jid),
                        exc_info=True)
                return False
        return True
示例#15
0
文件: handlers.py 项目: Perdu/poezio
 def try_modify():
     replaced_id = message['replace']['id']
     if replaced_id and config.get_by_tabname('group_corrections',
                                              conv_jid.bare):
         try:
             conversation.modify_message(body, replaced_id, message['id'], jid=jid,
                     nickname=remote_nick)
             return True
         except CorrectionError:
             log.debug('Unable to correct a message', exc_info=True)
     return False
示例#16
0
    def on_lose_focus(self):
        if self.input.text:
            self.state = 'nonempty'
        else:
            self.state = 'normal'

        self.text_win.remove_line_separator()
        self.text_win.add_line_separator(self._text_buffer)
        tab = self.core.get_tab_by_name(safeJID(self.name).bare, MucTab)
        if tab and tab.joined and config.get_by_tabname('send_chat_states',
                self.general_jid) and not self.input.get_text() and self.on:
            self.send_chat_state('inactive')
        self.check_scrolled()
示例#17
0
文件: basetabs.py 项目: Perdu/poezio
 def set_paused_delay(self, composing):
     """
     we create a timed event that will put us to paused
     in a few seconds
     """
     if not config.get_by_tabname('send_chat_states', self.general_jid):
         return
     # First, cancel the delay if it already exists, before rescheduling
     # it at a new date
     self.cancel_paused_delay()
     new_event = timed_events.DelayedEvent(4, self.send_chat_state, 'paused')
     self.core.add_timed_event(new_event)
     self.timed_event_paused = new_event
示例#18
0
    def on_lose_focus(self):
        if self.input.text:
            self.state = 'nonempty'
        else:
            self.state = 'normal'

        self.text_win.remove_line_separator()
        self.text_win.add_line_separator(self._text_buffer)
        tab = self.core.get_tab_by_name(safeJID(self.name).bare, MucTab)
        if tab and tab.joined and config.get_by_tabname(
                'send_chat_states',
                self.general_jid) and not self.input.get_text() and self.on:
            self.send_chat_state('inactive')
        self.check_scrolled()
示例#19
0
 def set_paused_delay(self, composing):
     """
     we create a timed event that will put us to paused
     in a few seconds
     """
     if not config.get_by_tabname('send_chat_states', self.general_jid):
         return
     # First, cancel the delay if it already exists, before rescheduling
     # it at a new date
     self.cancel_paused_delay()
     new_event = timed_events.DelayedEvent(4, self.send_chat_state,
                                           'paused')
     self.core.add_timed_event(new_event)
     self.timed_event_paused = new_event
示例#20
0
 def user_rejoined(self, nick):
     """
     The user (or at least someone with the same nick) came back in the MUC
     """
     self.activate()
     self.check_features()
     tab = self.core.get_tab_by_name(safeJID(self.name).bare, MucTab)
     color = 3
     if tab and config.get_by_tabname('display_user_color_in_join_part',
                                      self.general_jid):
         user = tab.get_user_by_name(nick)
         if user:
             color = dump_tuple(user.color)
     self.add_message('\x194}%(spec)s \x19%(color)s}%(nick)s\x19%(info_col)s} joined the room' % {'nick':nick, 'color': color, 'spec':get_theme().CHAR_JOIN, 'info_col': dump_tuple(get_theme().COLOR_INFORMATION_TEXT)}, typ=2)
     return self.core.current_tab() is self
示例#21
0
文件: basetabs.py 项目: Perdu/poezio
 def send_chat_state(self, state, always_send=False):
     """
     Send an empty chatstate message
     """
     if not self.is_muc or self.joined:
         if state in ('active', 'inactive', 'gone') and self.inactive and not always_send:
             return
         if (config.get_by_tabname('send_chat_states', self.general_jid)
                 and self.remote_wants_chatstates is not False):
             msg = self.core.xmpp.make_message(self.get_dest_jid())
             msg['type'] = self.message_type
             msg['chat_state'] = state
             self.chat_state = state
             msg.send()
             return True
示例#22
0
 def send_composing_chat_state(self, empty_after):
     """
     Send the "active" or "composing" chatstate, depending
     on the the current status of the input
     """
     name = self.general_jid
     if (config.get_by_tabname('send_chat_states', name)
             and self.remote_wants_chatstates):
         needed = 'inactive' if self.inactive else 'active'
         self.cancel_paused_delay()
         if not empty_after:
             if self.chat_state != "composing":
                 self.send_chat_state("composing")
             self.set_paused_delay(True)
         elif empty_after and self.chat_state != needed:
             self.send_chat_state(needed, True)
示例#23
0
 def send_chat_state(self, state, always_send=False):
     """
     Send an empty chatstate message
     """
     if not self.is_muc or self.joined:
         if state in ('active', 'inactive',
                      'gone') and self.inactive and not always_send:
             return
         if (config.get_by_tabname('send_chat_states', self.general_jid)
                 and self.remote_wants_chatstates is not False):
             msg = self.core.xmpp.make_message(self.get_dest_jid())
             msg['type'] = self.message_type
             msg['chat_state'] = state
             self.chat_state = state
             msg.send()
             return True
示例#24
0
文件: basetabs.py 项目: Perdu/poezio
 def send_composing_chat_state(self, empty_after):
     """
     Send the "active" or "composing" chatstate, depending
     on the the current status of the input
     """
     name = self.general_jid
     if (config.get_by_tabname('send_chat_states', name)
             and self.remote_wants_chatstates):
         needed = 'inactive' if self.inactive else 'active'
         self.cancel_paused_delay()
         if not empty_after:
             if self.chat_state != "composing":
                 self.send_chat_state("composing")
             self.set_paused_delay(True)
         elif empty_after and self.chat_state != needed:
             self.send_chat_state(needed, True)
示例#25
0
 def get_local(self):
     """Add the locally stored bookmarks to the list."""
     rooms = config.get("rooms")
     if not rooms:
         return
     rooms = rooms.split(":")
     for room in rooms:
         jid = safeJID(room)
         if jid.bare == "":
             continue
         if jid.resource != "":
             nick = jid.resource
         else:
             nick = None
         passwd = config.get_by_tabname("password", jid.bare, fallback=False) or None
         b = Bookmark(jid.bare, autojoin=True, nick=nick, password=passwd, method="local")
         self.append(b)
示例#26
0
    def on_gain_focus(self):
        contact = roster[self.get_dest_jid()]
        jid = safeJID(self.get_dest_jid())
        if contact:
            if jid.resource:
                resource = contact[jid.full]
            else:
                resource = contact.get_highest_priority_resource()
        else:
            resource = None

        self.state = 'current'
        curses.curs_set(1)
        if (config.get_by_tabname('send_chat_states', self.general_jid)
                and (not self.input.get_text()
                     or not self.input.get_text().startswith('//'))):
            if resource:
                self.send_chat_state('active')
示例#27
0
    def on_gain_focus(self):
        contact = roster[self.get_dest_jid()]
        jid = safeJID(self.get_dest_jid())
        if contact:
            if jid.resource:
                resource = contact[jid.full]
            else:
                resource = contact.get_highest_priority_resource()
        else:
            resource = None

        self.state = 'current'
        curses.curs_set(1)
        if (config.get_by_tabname('send_chat_states', self.general_jid)
                and (not self.input.get_text()
                    or not self.input.get_text().startswith('//'))):
            if resource:
                self.send_chat_state('active')
示例#28
0
文件: bookmark.py 项目: Perdu/poezio
def get_local():
    """Add the locally stored bookmarks to the list."""
    rooms = config.get('rooms')
    if not rooms:
        return
    rooms = rooms.split(':')
    for room in rooms:
        jid = safeJID(room)
        if jid.bare == '':
            continue
        if jid.resource != '':
            nick = jid.resource
        else:
            nick = None
        passwd = config.get_by_tabname('password', jid.bare, fallback=False) or None
        b = Bookmark(jid.bare, autojoin=True, nick=nick, password=passwd, method='local')
        if not get_by_jid(b.jid):
            bookmarks.append(b)
示例#29
0
 def on_lose_focus(self):
     contact = roster[self.get_dest_jid()]
     jid = safeJID(self.get_dest_jid())
     if contact:
         if jid.resource:
             resource = contact[jid.full]
         else:
             resource = contact.get_highest_priority_resource()
     else:
         resource = None
     if self.input.text:
         self.state = 'nonempty'
     else:
         self.state = 'normal'
     self.text_win.remove_line_separator()
     self.text_win.add_line_separator(self._text_buffer)
     if (config.get_by_tabname('send_chat_states', self.general_jid)
             and (not self.input.get_text()
                 or not self.input.get_text().startswith('//'))):
         if resource:
             self.send_chat_state('inactive')
     self.check_scrolled()
示例#30
0
 def on_lose_focus(self):
     contact = roster[self.get_dest_jid()]
     jid = safeJID(self.get_dest_jid())
     if contact:
         if jid.resource:
             resource = contact[jid.full]
         else:
             resource = contact.get_highest_priority_resource()
     else:
         resource = None
     if self.input.text:
         self.state = 'nonempty'
     else:
         self.state = 'normal'
     self.text_win.remove_line_separator()
     self.text_win.add_line_separator(self._text_buffer)
     if (config.get_by_tabname('send_chat_states', self.general_jid)
             and (not self.input.get_text()
                  or not self.input.get_text().startswith('//'))):
         if resource:
             self.send_chat_state('inactive')
     self.check_scrolled()
示例#31
0
文件: handlers.py 项目: Perdu/poezio
def on_activity_event(self, message):
    """
    Called when a pep notification for an user activity
    is received.
    """
    contact = roster[message['from'].bare]
    if not contact:
        return
    roster.modified()
    item = message['pubsub_event']['items']['item']
    old_activity = contact.activity
    if item.xml.find('{http://jabber.org/protocol/activity}activity'):
        try:
            activity = item['activity']['value']
        except ValueError:
            return
        if activity[0]:
            general = pep.ACTIVITIES.get(activity[0])
            s = general['category']
            if activity[1]:
                s = s + '/' + general.get(activity[1], 'other')
            text = item['activity']['text']
            if text:
                s = '%s (%s)' % (s, text)
            contact.activity = s
        else:
            contact.activity = ''
    else:
        contact.activity = ''

    if contact.activity:
        logger.log_roster_change(contact.bare_jid, 'has now the activity %s' % contact.activity)

    if old_activity != contact.activity and config.get_by_tabname('display_activity_notifications', contact.bare_jid):
        if contact.activity:
            self.information('Activity from '+ contact.bare_jid + ': ' + contact.activity, 'Activity')
        else:
            self.information(contact.bare_jid + ' stopped doing his/her activity.', 'Activity')
示例#32
0
 def user_rejoined(self, nick):
     """
     The user (or at least someone with the same nick) came back in the MUC
     """
     self.activate()
     self.check_features()
     tab = self.core.get_tab_by_name(safeJID(self.name).bare, MucTab)
     color = 3
     if tab and config.get_by_tabname('display_user_color_in_join_part',
                                      self.general_jid):
         user = tab.get_user_by_name(nick)
         if user:
             color = dump_tuple(user.color)
     self.add_message(
         '\x194}%(spec)s \x19%(color)s}%(nick)s\x19%(info_col)s} joined the room'
         % {
             'nick': nick,
             'color': color,
             'spec': get_theme().CHAR_JOIN,
             'info_col': dump_tuple(get_theme().COLOR_INFORMATION_TEXT)
         },
         typ=2)
     return self.core.current_tab() is self
示例#33
0
def command_join(self, args):
    """
    /join [room][/nick] [password]
    """
    password = None
    if len(args) == 0:
        tab = self.current_tab()
        if not isinstance(tab, (tabs.MucTab, tabs.PrivateTab)):
            return
        room = safeJID(tab.name).bare
        nick = tab.own_nick
    else:
        if args[0].startswith('@'): # we try to join a server directly
            server_root = True
            info = safeJID(args[0][1:])
        else:
            info = safeJID(args[0])
            server_root = False
        if info == '' and len(args[0]) > 1 and args[0][0] == '/':
            nick = args[0][1:]
        elif info.resource == '':
            nick = self.own_nick
        else:
            nick = info.resource
        if info.bare == '':   # happens with /join /nickname, which is OK
            tab = self.current_tab()
            if not isinstance(tab, tabs.MucTab):
                return
            room = tab.name
            if nick == '':
                nick = tab.own_nick
        else:
            room = info.bare
            # no server is provided, like "/join hello":
            # use the server of the current room if available
            # check if the current room's name has a server
            if room.find('@') == -1 and not server_root:
                if isinstance(self.current_tab(), tabs.MucTab) and\
                        self.current_tab().name.find('@') != -1:
                    domain = safeJID(self.current_tab().name).domain
                    room += '@%s' % domain
                else:
                    room = args[0]
    room = room.lower()
    if room in self.pending_invites:
        del self.pending_invites[room]
    tab = self.get_tab_by_name(room, tabs.MucTab)
    if tab is not None and tab.joined:       # if we are already in the room
        self.focus_tab_named(tab.name)
        if tab.own_nick == nick:
            self.information('/join: Nothing to do.', 'Info')
        else:
            tab.own_nick = nick
            tab.command_cycle('')
        return

    if room.startswith('@'):
        room = room[1:]
    if len(args) == 2:       # a password is provided
        password = args[1]
    if password is None: # try to use a saved password
        password = config.get_by_tabname('password', room, fallback=False)
    if tab is not None:
        if password:
            tab.password = password
        tab.join()
    else:
        tab = self.open_new_room(room, nick, password=password)
        tab.join()

    if tab.joined:
        self.enable_private_tabs(room)
        tab.state = "normal"
        if tab == self.current_tab():
            tab.refresh()
            self.doupdate()
示例#34
0
文件: handlers.py 项目: Perdu/poezio
def on_groupchat_message(self, message):
    """
    Triggered whenever a message is received from a multi-user chat room.
    """
    if message['subject']:
        return
    room_from = message['from'].bare

    if message['type'] == 'error': # Check if it's an error
        return self.room_error(message, room_from)

    tab = self.get_tab_by_name(room_from, tabs.MucTab)
    if not tab:
        self.information(_("message received for a non-existing room: %s") % (room_from))
        muc.leave_groupchat(self.xmpp, room_from, self.own_nick, msg='')
        return

    nick_from = message['mucnick']
    user = tab.get_user_by_name(nick_from)
    if user and user in tab.ignores:
        return

    self.events.trigger('muc_msg', message, tab)
    use_xhtml = config.get('enable_xhtml_im')
    tmp_dir = config.get('tmp_image_dir') or path.join(CACHE_DIR, 'images')
    extract_images = config.get('extract_inline_images')
    body = xhtml.get_body_from_message_stanza(message, use_xhtml=use_xhtml,
                                              tmp_dir=tmp_dir,
                                              extract_images=extract_images)
    if not body:
        return

    old_state = tab.state
    delayed, date = common.find_delayed_tag(message)
    replaced_id = message['replace']['id']
    replaced = False
    if replaced_id is not '' and config.get_by_tabname('group_corrections',
                                                       message['from'].bare):
        try:
            if tab.modify_message(body, replaced_id, message['id'], time=date,
                    nickname=nick_from, user=user):
                self.events.trigger('highlight', message, tab)
            replaced = True
        except CorrectionError:
            log.debug('Unable to correct a message', exc_info=True)
    if not replaced and tab.add_message(body, date, nick_from, history=delayed, identifier=message['id'], jid=message['from'], typ=1):
        self.events.trigger('highlight', message, tab)

    if message['from'].resource == tab.own_nick:
        tab.last_sent_message = message

    if tab is self.current_tab():
        tab.text_win.refresh()
        tab.info_header.refresh(tab, tab.text_win)
        tab.input.refresh()
        self.doupdate()
    elif tab.state != old_state:
        self.refresh_tab_win()
        current = self.current_tab()
        if hasattr(current, 'input') and current.input:
            current.input.refresh()
        self.doupdate()

    if 'message' in config.get('beep_on').split():
        if (not config.get_by_tabname('disable_beep', room_from)
                and self.own_nick != message['from'].resource):
            curses.beep()
示例#35
0
    def get_logs(self, jid, nb=10):
        """
        Get the nb last messages from the log history for the given jid.
        Note that a message may be more than one line in these files, so
        this function is a little bit more complicated than “read the last
        nb lines”.
        """
        if config.get_by_tabname('load_log', jid) <= 0:
            return

        if not config.get_by_tabname('use_log', jid):
            return

        if nb <= 0:
            return

        self.check_and_create_log_dir(jid, open_fd=False)

        try:
            fd = open(os.path.join(log_dir, jid), 'rb')
        except FileNotFoundError:
            log.info('Non-existing log file (%s)',
                     os.path.join(log_dir, jid),
                     exc_info=True)
            return
        except OSError:
            log.error('Unable to open the log file (%s)',
                      os.path.join(log_dir, jid),
                      exc_info=True)
            return
        if not fd:
            return

        # read the needed data from the file, we just search nb messages by
        # searching "\nM" nb times from the end of the file.  We use mmap to
        # do that efficiently, instead of seek()s and read()s which are costly.
        with fd:
            try:
                m = mmap.mmap(fd.fileno(), 0, prot=mmap.PROT_READ)
            except Exception:  # file probably empty
                log.error('Unable to mmap the log file for (%s)',
                          os.path.join(log_dir, jid),
                          exc_info=True)
                return
            pos = m.rfind(b"\nM")  # start of messages begin with MI or MR,
            # after a \n
            # number of message found so far
            count = 0
            while pos != -1 and count < nb - 1:
                count += 1
                pos = m.rfind(b"\nM", 0, pos)
            if pos == -1:  # If we don't have enough lines in the file
                pos = 1  # 1, because we do -1 just on the next line
                # to get 0 (start of the file)
            lines = m[pos - 1:].decode(errors='replace').splitlines()

        messages = []
        color = '\x19%s}' % dump_tuple(get_theme().COLOR_LOG_MSG)

        # now convert that data into actual Message objects
        idx = 0
        while idx < len(lines):
            if lines[idx].startswith(' '):  # should not happen ; skip
                idx += 1
                log.debug('fail?')
                continue
            tup = parse_message_line(lines[idx])
            idx += 1
            if not tup or 7 > len(tup) > 10:  # skip
                log.debug('format? %s', tup)
                continue
            time = [int(i) for index, i in enumerate(tup) if index < 6]
            message = {
                'lines': [],
                'history': True,
                'time': common.get_local_time(datetime(*time))
            }
            size = int(tup[6])
            if len(tup) == 8:  #info line
                message['lines'].append(color + tup[7])
            else:  # message line
                message['nickname'] = tup[7]
                message['lines'].append(color + tup[8])
            while size != 0 and idx < len(lines):
                message['lines'].append(lines[idx][1:])
                size -= 1
                idx += 1
            message['txt'] = '\n'.join(message['lines'])
            del message['lines']
            messages.append(message)

        return messages
示例#36
0
 def on_close(self):
     Tab.on_close(self)
     if config.get_by_tabname('send_chat_states', self.general_jid):
         self.send_chat_state('gone')
示例#37
0
def command_join(self, args):
    """
    /join [room][/nick] [password]
    """
    password = None
    if len(args) == 0:
        tab = self.current_tab()
        if not isinstance(tab, (tabs.MucTab, tabs.PrivateTab)):
            return
        room = safeJID(tab.name).bare
        nick = tab.own_nick
    else:
        if args[0].startswith('@'):  # we try to join a server directly
            server_root = True
            info = safeJID(args[0][1:])
        else:
            info = safeJID(args[0])
            server_root = False
        if info == '' and len(args[0]) > 1 and args[0][0] == '/':
            nick = args[0][1:]
        elif info.resource == '':
            nick = self.own_nick
        else:
            nick = info.resource
        if info.bare == '':  # happens with /join /nickname, which is OK
            tab = self.current_tab()
            if not isinstance(tab, tabs.MucTab):
                return
            room = tab.name
            if nick == '':
                nick = tab.own_nick
        else:
            room = info.bare
            # no server is provided, like "/join hello":
            # use the server of the current room if available
            # check if the current room's name has a server
            if room.find('@') == -1 and not server_root:
                if isinstance(self.current_tab(), tabs.MucTab) and\
                        self.current_tab().name.find('@') != -1:
                    domain = safeJID(self.current_tab().name).domain
                    room += '@%s' % domain
                else:
                    room = args[0]
    room = room.lower()
    if room in self.pending_invites:
        del self.pending_invites[room]
    tab = self.get_tab_by_name(room, tabs.MucTab)
    if tab is not None and tab.joined:  # if we are already in the room
        self.focus_tab_named(tab.name)
        if tab.own_nick == nick:
            self.information('/join: Nothing to do.', 'Info')
        else:
            tab.own_nick = nick
            tab.command_cycle('')
        return

    if room.startswith('@'):
        room = room[1:]
    if len(args) == 2:  # a password is provided
        password = args[1]
    if password is None:  # try to use a saved password
        password = config.get_by_tabname('password', room, fallback=False)
    if tab is not None:
        if password:
            tab.password = password
        tab.join()
    else:
        tab = self.open_new_room(room, nick, password=password)
        tab.join()

    if tab.joined:
        self.enable_private_tabs(room)
        tab.state = "normal"
        if tab == self.current_tab():
            tab.refresh()
            self.doupdate()
示例#38
0
文件: handlers.py 项目: Perdu/poezio
def on_normal_message(self, message):
    """
    When receiving "normal" messages (not a private message from a
    muc participant)
    """
    if message['type'] == 'error':
        return self.information(self.get_error_message(message, deprecated=True), 'Error')
    elif message['type'] == 'headline' and message['body']:
        return self.information('%s says: %s' % (message['from'], message['body']), 'Headline')

    use_xhtml = config.get('enable_xhtml_im')
    tmp_dir = config.get('tmp_image_dir') or path.join(CACHE_DIR, 'images')
    extract_images = config.get('extract_inline_images')
    body = xhtml.get_body_from_message_stanza(message, use_xhtml=use_xhtml,
                                              tmp_dir=tmp_dir,
                                              extract_images=extract_images)
    if not body:
        return

    remote_nick = ''
    # normal message, we are the recipient
    if message['to'].bare == self.xmpp.boundjid.bare:
        conv_jid = message['from']
        jid = conv_jid
        color = get_theme().COLOR_REMOTE_USER
        # check for a name
        if conv_jid.bare in roster:
            remote_nick = roster[conv_jid.bare].name
        # check for a received nick
        if not remote_nick and config.get('enable_user_nick'):
            if message.xml.find('{http://jabber.org/protocol/nick}nick') is not None:
                remote_nick = message['nick']['nick']
        if not remote_nick:
            remote_nick = conv_jid.user
            if not remote_nick:
                remote_nick = conv_jid.full
        own = False
    # we wrote the message (happens with carbons)
    elif message['from'].bare == self.xmpp.boundjid.bare:
        conv_jid = message['to']
        jid = self.xmpp.boundjid
        color = get_theme().COLOR_OWN_NICK
        remote_nick = self.own_nick
        own = True
    # we are not part of that message, drop it
    else:
        return

    conversation = self.get_conversation_by_jid(conv_jid, create=True)
    if isinstance(conversation, tabs.DynamicConversationTab) and conv_jid.resource:
        conversation.lock(conv_jid.resource)

    if not own and not conversation.nick:
        conversation.nick = remote_nick
    elif not own: # keep a fixed nick during the whole conversation
        remote_nick = conversation.nick

    self.events.trigger('conversation_msg', message, conversation)
    if not message['body']:
        return
    body = xhtml.get_body_from_message_stanza(message, use_xhtml=use_xhtml,
                                              tmp_dir=tmp_dir,
                                              extract_images=extract_images)
    delayed, date = common.find_delayed_tag(message)

    def try_modify():
        replaced_id = message['replace']['id']
        if replaced_id and config.get_by_tabname('group_corrections',
                                                 conv_jid.bare):
            try:
                conversation.modify_message(body, replaced_id, message['id'], jid=jid,
                        nickname=remote_nick)
                return True
            except CorrectionError:
                log.debug('Unable to correct a message', exc_info=True)
        return False

    if not try_modify():
        conversation.add_message(body, date,
                nickname=remote_nick,
                nick_color=color,
                history=delayed,
                identifier=message['id'],
                jid=jid,
                typ=1)

    if conversation.remote_wants_chatstates is None and not delayed:
        if message['chat_state']:
            conversation.remote_wants_chatstates = True
        else:
            conversation.remote_wants_chatstates = False
    if 'private' in config.get('beep_on').split():
        if not config.get_by_tabname('disable_beep', conv_jid.bare):
            curses.beep()
    if self.current_tab() is not conversation:
        conversation.state = 'private'
        self.refresh_tab_win()
    else:
        self.refresh_window()
示例#39
0
 def on_close(self):
     Tab.on_close(self)
     if config.get_by_tabname('send_chat_states', self.general_jid):
         self.send_chat_state('gone')
示例#40
0
文件: handlers.py 项目: Perdu/poezio
def on_groupchat_private_message(self, message):
    """
    We received a Private Message (from someone in a Muc)
    """
    jid = message['from']
    nick_from = jid.resource
    if not nick_from:
        return self.on_groupchat_message(message)

    room_from = jid.bare
    use_xhtml = config.get('enable_xhtml_im')
    tmp_dir = config.get('tmp_image_dir') or path.join(CACHE_DIR, 'images')
    extract_images = config.get('extract_inline_images')
    body = xhtml.get_body_from_message_stanza(message, use_xhtml=use_xhtml,
                                              tmp_dir=tmp_dir,
                                              extract_images=extract_images)
    tab = self.get_tab_by_name(jid.full, tabs.PrivateTab) # get the tab with the private conversation
    ignore = config.get_by_tabname('ignore_private', room_from)
    if not tab: # It's the first message we receive: create the tab
        if body and not ignore:
            tab = self.open_private_window(room_from, nick_from, False)
    if ignore:
        self.events.trigger('ignored_private', message, tab)
        msg = config.get_by_tabname('private_auto_response', room_from)
        if msg and body:
            self.xmpp.send_message(mto=jid.full, mbody=msg, mtype='chat')
        return
    self.events.trigger('private_msg', message, tab)
    body = xhtml.get_body_from_message_stanza(message, use_xhtml=use_xhtml,
                                              tmp_dir=tmp_dir,
                                              extract_images=extract_images)
    if not body or not tab:
        return
    replaced_id = message['replace']['id']
    replaced = False
    user = tab.parent_muc.get_user_by_name(nick_from)
    if replaced_id is not '' and config.get_by_tabname('group_corrections',
                                                       room_from):
        try:
            tab.modify_message(body, replaced_id, message['id'], user=user, jid=message['from'],
                    nickname=nick_from)
            replaced = True
        except CorrectionError:
            log.debug('Unable to correct a message', exc_info=True)
    if not replaced:
        tab.add_message(body, time=None, nickname=nick_from,
                        forced_user=user,
                        identifier=message['id'],
                        jid=message['from'],
                        typ=1)

    if tab.remote_wants_chatstates is None:
        if message['chat_state']:
            tab.remote_wants_chatstates = True
        else:
            tab.remote_wants_chatstates = False
    if 'private' in config.get('beep_on').split():
        if not config.get_by_tabname('disable_beep', jid.full):
            curses.beep()
    if tab is self.current_tab():
        self.refresh_window()
    else:
        tab.state = 'private'
        self.refresh_tab_win()
示例#41
0
文件: logger.py 项目: Perdu/poezio
    def get_logs(self, jid, nb=10):
        """
        Get the nb last messages from the log history for the given jid.
        Note that a message may be more than one line in these files, so
        this function is a little bit more complicated than “read the last
        nb lines”.
        """
        if config.get_by_tabname('load_log', jid) <= 0:
            return

        if not config.get_by_tabname('use_log', jid):
            return

        if nb <= 0:
            return

        self.check_and_create_log_dir(jid, open_fd=False)

        try:
            fd = open(os.path.join(log_dir, jid), 'rb')
        except:
            log.error('Unable to open the log file (%s)',
                    os.path.join(log_dir, jid),
                    exc_info=True)
            return
        if not fd:
            return

        # read the needed data from the file, we just search nb messages by
        # searching "\nM" nb times from the end of the file.  We use mmap to
        # do that efficiently, instead of seek()s and read()s which are costly.
        with fd:
            try:
                m = mmap.mmap(fd.fileno(), 0, prot=mmap.PROT_READ)
            except Exception: # file probably empty
                log.error('Unable to mmap the log file for (%s)',
                        os.path.join(log_dir, jid),
                        exc_info=True)
                return
            pos = m.rfind(b"\nM") # start of messages begin with MI or MR,
                                  # after a \n
            # number of message found so far
            count = 0
            while pos != -1 and count < nb-1:
                count += 1
                pos = m.rfind(b"\nM", 0, pos)
            if pos == -1:       # If we don't have enough lines in the file
                pos = 1         # 1, because we do -1 just on the next line
                                # to get 0 (start of the file)
            lines = m[pos-1:].decode(errors='replace').splitlines()

        messages = []
        color = '\x19%s}' % dump_tuple(get_theme().COLOR_LOG_MSG)

        # now convert that data into actual Message objects
        idx = 0
        while idx < len(lines):
            if lines[idx].startswith(' '): # should not happen ; skip
                idx += 1
                log.debug('fail?')
                continue
            tup = parse_message_line(lines[idx])
            idx += 1
            if not tup or 7 > len(tup) > 10: # skip
                log.debug('format? %s', tup)
                continue
            time = [int(i) for index, i in enumerate(tup) if index < 6]
            message = {'lines': [],
                       'history': True,
                       'time': common.get_local_time(datetime(*time))}
            size = int(tup[6])
            if len(tup) == 8: #info line
                message['lines'].append(color+tup[7])
            else: # message line
                message['nickname'] = tup[7]
                message['lines'].append(color+tup[8])
            while size != 0 and idx < len(lines):
                message['lines'].append(lines[idx][1:])
                size -= 1
                idx += 1
            message['txt'] = '\n'.join(message['lines'])
            del message['lines']
            messages.append(message)

        return messages
示例#42
0
def command_join(self, args, histo_length=None):
    """
    /join [room][/nick] [password]
    """
    password = None
    if len(args) == 0:
        tab = self.current_tab()
        if not isinstance(tab, (tabs.MucTab, tabs.PrivateTab)):
            return
        room = safeJID(tab.name).bare
        nick = tab.own_nick
    else:
        if args[0].startswith('@'): # we try to join a server directly
            server_root = True
            info = safeJID(args[0][1:])
        else:
            info = safeJID(args[0])
            server_root = False
        if info == '' and len(args[0]) > 1 and args[0][0] == '/':
            nick = args[0][1:]
        elif info.resource == '':
            nick = self.own_nick
        else:
            nick = info.resource
        if info.bare == '':   # happens with /join /nickname, which is OK
            tab = self.current_tab()
            if not isinstance(tab, tabs.MucTab):
                return
            room = tab.name
            if nick == '':
                nick = tab.own_nick
        else:
            room = info.bare
            # no server is provided, like "/join hello":
            # use the server of the current room if available
            # check if the current room's name has a server
            if room.find('@') == -1 and not server_root:
                if isinstance(self.current_tab(), tabs.MucTab) and\
                        self.current_tab().name.find('@') != -1:
                    domain = safeJID(self.current_tab().name).domain
                    room += '@%s' % domain
                else:
                    room = args[0]
    room = room.lower()
    if room in self.pending_invites:
        del self.pending_invites[room]
    tab = self.get_tab_by_name(room, tabs.MucTab)
    if len(args) == 2:       # a password is provided
        password = args[1]
    if tab and tab.joined:       # if we are already in the room
        self.focus_tab_named(tab.name)
        if tab.own_nick == nick:
            self.information('/join: Nothing to do.', 'Info')
        else:
            tab.own_nick = nick
            tab.command_cycle('')
        return

    if room.startswith('@'):
        room = room[1:]
    current_status = self.get_status()
    if not histo_length:
        histo_length = config.get('muc_history_length')
        if histo_length == -1:
            histo_length = None
    if histo_length is not None:
        histo_length = str(histo_length)
    if password is None: # try to use a saved password
        password = config.get_by_tabname('password', room, fallback=False)
    if tab and not tab.joined:
        if tab.last_connection:
            if tab.last_connection is not None:
                delta = datetime.now() - tab.last_connection
                seconds = delta.seconds + delta.days * 24 * 3600
            else:
                seconds = 0
            seconds = int(seconds)
        else:
            seconds = 0
        muc.join_groupchat(self, room, nick, password,
                           histo_length,
                           current_status.message,
                           current_status.show,
                           seconds=seconds)
    if not tab:
        self.open_new_room(room, nick)
        muc.join_groupchat(self, room, nick, password,
                           histo_length,
                           current_status.message,
                           current_status.show)
    else:
        tab.own_nick = nick
        tab.users = []
    if tab and tab.joined:
        self.enable_private_tabs(room)
        tab.state = "normal"
        if tab == self.current_tab():
            tab.refresh()
            self.doupdate()
示例#43
0
def command_join(self, args, histo_length=None):
    """
    /join [room][/nick] [password]
    """
    password = None
    if len(args) == 0:
        tab = self.current_tab()
        if not isinstance(tab, (tabs.MucTab, tabs.PrivateTab)):
            return
        room = safeJID(tab.name).bare
        nick = tab.own_nick
    else:
        if args[0].startswith('@'): # we try to join a server directly
            server_root = True
            info = safeJID(args[0][1:])
        else:
            info = safeJID(args[0])
            server_root = False
        if info == '' and len(args[0]) > 1 and args[0][0] == '/':
            nick = args[0][1:]
        elif info.resource == '':
            nick = self.own_nick
        else:
            nick = info.resource
        if info.bare == '':   # happens with /join /nickname, which is OK
            tab = self.current_tab()
            if not isinstance(tab, tabs.MucTab):
                return
            room = tab.name
            if nick == '':
                nick = tab.own_nick
        else:
            room = info.bare
            # no server is provided, like "/join hello":
            # use the server of the current room if available
            # check if the current room's name has a server
            if room.find('@') == -1 and not server_root:
                if isinstance(self.current_tab(), tabs.MucTab) and\
                        self.current_tab().name.find('@') != -1:
                    domain = safeJID(self.current_tab().name).domain
                    room += '@%s' % domain
                else:
                    room = args[0]
    room = room.lower()
    if room in self.pending_invites:
        del self.pending_invites[room]
    tab = self.get_tab_by_name(room, tabs.MucTab)
    if len(args) == 2:       # a password is provided
        password = args[1]
    if tab and tab.joined:       # if we are already in the room
        self.focus_tab_named(tab.name)
        if tab.own_nick == nick:
            self.information('/join: Nothing to do.', 'Info')
        else:
            tab.own_nick = nick
            tab.command_cycle('')
        return

    if room.startswith('@'):
        room = room[1:]
    current_status = self.get_status()
    if not histo_length:
        histo_length = config.get('muc_history_length')
        if histo_length == -1:
            histo_length = None
    if histo_length is not None:
        histo_length = str(histo_length)
    if password is None: # try to use a saved password
        password = config.get_by_tabname('password', room, fallback=False)
    if tab and not tab.joined:
        if tab.last_connection:
            if tab.last_connection is not None:
                delta = datetime.now() - tab.last_connection
                seconds = delta.seconds + delta.days * 24 * 3600
            else:
                seconds = 0
            seconds = int(seconds)
        else:
            seconds = 0
        if password:
            tab.password = password
        muc.join_groupchat(self, room, nick, password,
                           histo_length,
                           current_status.message,
                           current_status.show,
                           seconds=seconds)
    if not tab:
        self.open_new_room(room, nick, password=password)
        muc.join_groupchat(self, room, nick, password,
                           histo_length,
                           current_status.message,
                           current_status.show)
    else:
        tab.own_nick = nick
        tab.users = []
    if tab and tab.joined:
        self.enable_private_tabs(room)
        tab.state = "normal"
        if tab == self.current_tab():
            tab.refresh()
            self.doupdate()