Beispiel #1
0
 def command_info(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 resource:
         status = (_('Status: %s') %
                   resource.status) if resource.status else ''
         self._text_buffer.add_message(
             "\x19%(info_col)s}Show: %(show)s, %(status)s\x19o" % {
                 'show': resource.show or 'available',
                 'status': status,
                 'info_col': dump_tuple(get_theme().COLOR_INFORMATION_TEXT)
             })
         return True
     else:
         self._text_buffer.add_message(
             "\x19%(info_col)s}No information available\x19o" %
             {'info_col': dump_tuple(get_theme().COLOR_INFORMATION_TEXT)})
         return True
Beispiel #2
0
 def build_message(self, message, timestamp=False):
     txt = message.txt
     ret = []
     default_color = None
     nick = truncate_nick(message.nickname)
     offset = 0
     if nick:
         offset += poopt.wcswidth(nick) + 1  # + nick + ' ' length
     if message.str_time:
         offset += 1 + len(message.str_time)
     if get_theme().CHAR_TIME_LEFT and message.str_time:
         offset += 1
     if get_theme().CHAR_TIME_RIGHT and message.str_time:
         offset += 1
     lines = poopt.cut_text(txt, self.width - offset - 1)
     prepend = default_color if default_color else ''
     attrs = []
     for line in lines:
         saved = Line(msg=message,
                      start_pos=line[0],
                      end_pos=line[1],
                      prepend=prepend)
         attrs = parse_attrs(message.txt[line[0]:line[1]], attrs)
         if attrs:
             prepend = FORMAT_CHAR + FORMAT_CHAR.join(attrs)
         else:
             if default_color:
                 prepend = default_color
             else:
                 prepend = ''
         ret.append(saved)
     return ret
Beispiel #3
0
 def go_to_previous_input(self):
     if not self.inputs:
         return
     if self.current_input == 0:
         return
     self.inputs[self.current_input]['input'].set_color(
         get_theme().COLOR_NORMAL_TEXT)
     self.inputs[self.current_input]['label'].set_color(
         get_theme().COLOR_NORMAL_TEXT)
     self.current_input -= 1
     jump = 0
     while self.current_input - jump > 0 and self.inputs[
             self.current_input + jump]['input'].is_dummy():
         jump += 1
     if self.inputs[self.current_input + jump]['input'].is_dummy():
         return
     # Adjust the scroll position if the current_input would be outside
     # of the visible area
     if self.current_input < self.scroll_pos:
         self.scroll_pos = self.current_input
         self.refresh()
     self.current_input -= jump
     self.inputs[self.current_input]['input'].set_color(
         get_theme().COLOR_SELECTED_ROW)
     self.inputs[self.current_input]['label'].set_color(
         get_theme().COLOR_SELECTED_ROW)
Beispiel #4
0
 def go_to_next_input(self):
     if not self.inputs:
         return
     if self.current_input == len(self.inputs) - 1:
         return
     self.inputs[self.current_input]['input'].set_color(
         get_theme().COLOR_NORMAL_TEXT)
     self.inputs[self.current_input]['label'].set_color(
         get_theme().COLOR_NORMAL_TEXT)
     self.current_input += 1
     jump = 0
     while self.current_input + jump != len(
             self.inputs) - 1 and self.inputs[self.current_input +
                                              jump]['input'].is_dummy():
         jump += 1
     if self.inputs[self.current_input + jump]['input'].is_dummy():
         return
     self.current_input += jump
     # If moving made the current input out of the visible screen, we
     # adjust the scroll position and we redraw the whole thing. We don’t
     # call refresh() if this is not the case, because
     # refresh_current_input() is always called anyway, so this is not
     # needed
     if self.current_input - self.scroll_pos > self.height - 1:
         self.scroll_pos += 1
         self.refresh()
     self.inputs[self.current_input]['input'].set_color(
         get_theme().COLOR_SELECTED_ROW)
     self.inputs[self.current_input]['label'].set_color(
         get_theme().COLOR_SELECTED_ROW)
Beispiel #5
0
 def refresh(self):
     self._win.erase()
     y = -self.scroll_pos
     i = 0
     for name, field in self._form.getFields().items():
         if field['type'] == 'hidden':
             continue
         self.inputs[i]['label'].resize(1, self.width//2, y + 1, 0)
         self.inputs[i]['input'].resize(1, self.width//2, y+1, self.width//2)
         # TODO: display the field description
         y += 1
         i += 1
     self._win.refresh()
     for i, inp in enumerate(self.inputs):
         if i < self.scroll_pos:
             continue
         if i >= self.height + self.scroll_pos:
             break
         inp['label'].refresh()
         inp['input'].refresh()
         inp['label'].refresh()
     if self.current_input < self.height-1:
         self.inputs[self.current_input]['input'].set_color(get_theme().COLOR_SELECTED_ROW)
         self.inputs[self.current_input]['input'].refresh()
         self.inputs[self.current_input]['label'].set_color(get_theme().COLOR_SELECTED_ROW)
         self.inputs[self.current_input]['label'].refresh()
Beispiel #6
0
 def write_nack(self):
     color = get_theme().COLOR_CHAR_NACK
     self._win.attron(to_curses_attr(color))
     self.addstr(get_theme().CHAR_NACK)
     self._win.attroff(to_curses_attr(color))
     self.addstr(' ')
     return poopt.wcswidth(get_theme().CHAR_NACK) + 1
Beispiel #7
0
def on_groupchat_subject(self, message):
    """
    Triggered when the topic is changed.
    """
    nick_from = message['mucnick']
    room_from = message.get_mucroom()
    tab = self.get_tab_by_name(room_from, tabs.MucTab)
    subject = message['subject']
    if subject is None or not tab:
        return
    if subject != tab.topic:
        # Do not display the message if the subject did not change or if we
        # receive an empty topic when joining the room.
        if nick_from:
            tab.add_message(_("\x19%(info_col)s}%(nick)s set the subject to: %(subject)s") %
                    {'info_col': dump_tuple(get_theme().COLOR_INFORMATION_TEXT), 'nick':nick_from, 'subject':subject},
                    time=None,
                    typ=2)
        else:
            tab.add_message(_("\x19%(info_col)s}The subject is: %(subject)s") %
                    {'subject':subject, 'info_col': dump_tuple(get_theme().COLOR_INFORMATION_TEXT)},
                    time=None,
                    typ=2)
    tab.topic = subject
    tab.topic_from = nick_from
    if self.get_tab_by_name(room_from, tabs.MucTab) is self.current_tab():
        self.refresh_window()
Beispiel #8
0
 def callback(iq):
     if iq['type'] != 'result':
         if iq['error']['type'] == 'auth':
             self.core.information(
                 'You are not allowed to see the activity of this contact.',
                 'Error')
         else:
             self.core.information('Error retrieving the activity',
                                   'Error')
         return
     seconds = iq['last_activity']['seconds']
     status = iq['last_activity']['status']
     from_ = iq['from']
     msg = '\x19%s}The last activity of %s was %s ago%s'
     if not safeJID(from_).user:
         msg = '\x19%s}The uptime of %s is %s.' % (
             dump_tuple(get_theme().COLOR_INFORMATION_TEXT), from_,
             common.parse_secs_to_str(seconds))
     else:
         msg = '\x19%s}The last activity of %s was %s ago%s' % (
             dump_tuple(get_theme().COLOR_INFORMATION_TEXT),
             from_,
             common.parse_secs_to_str(seconds),
             (' and his/her last status was %s' %
              status) if status else '',
         )
     self.add_message(msg)
     self.core.refresh_window()
Beispiel #9
0
 def user_left(self, status_message, from_nick):
     """
     The user left the associated MUC
     """
     self.deactivate()
     if not status_message:
         self.add_message(
             '\x191}%(spec)s \x193}%(nick)s\x19%(info_col)s} has left the room'
             % {
                 'nick': from_nick,
                 'spec': get_theme().CHAR_QUIT,
                 'info_col': dump_tuple(get_theme().COLOR_INFORMATION_TEXT)
             },
             typ=2)
     else:
         self.add_message(
             '\x191}%(spec)s \x193}%(nick)s\x19%(info_col)s} has left the room (%(status)s)"'
             % {
                 'nick': from_nick,
                 'spec': get_theme().CHAR_QUIT,
                 'status': status_message,
                 'info_col': dump_tuple(get_theme().COLOR_INFORMATION_TEXT)
             },
             typ=2)
     return self.core.current_tab() is self
Beispiel #10
0
 def draw_group_info(self, group):
     """
     draw the group information
     """
     self.addstr(0, 0, group.name,
                 to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
     self.finish_line(get_theme().COLOR_INFORMATION_BAR)
Beispiel #11
0
 def refresh(self):
     self._win.erase()
     y = -self.scroll_pos
     i = 0
     for name, field in self._form.getFields().items():
         if field['type'] == 'hidden':
             continue
         self.inputs[i]['label'].resize(1, self.width//2, y + 1, 0)
         self.inputs[i]['input'].resize(1, self.width//2, y+1, self.width//2)
         # TODO: display the field description
         y += 1
         i += 1
     self._win.refresh()
     for i, inp in enumerate(self.inputs):
         if i < self.scroll_pos:
             continue
         if i >= self.height + self.scroll_pos:
             break
         inp['label'].refresh()
         inp['input'].refresh()
         inp['label'].refresh()
     if self.current_input < self.height-1:
         self.inputs[self.current_input]['input'].set_color(get_theme().COLOR_SELECTED_ROW)
         self.inputs[self.current_input]['input'].refresh()
         self.inputs[self.current_input]['label'].set_color(get_theme().COLOR_SELECTED_ROW)
         self.inputs[self.current_input]['label'].refresh()
Beispiel #12
0
 def write_contact_jid(self, jid):
     """
     Just write the jid that we are talking to
     """
     self.addstr('[', to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
     self.addstr(jid.full, to_curses_attr(get_theme().COLOR_CONVERSATION_NAME))
     self.addstr('] ', to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
Beispiel #13
0
 def write_nack(self):
     color = get_theme().COLOR_CHAR_NACK
     self._win.attron(to_curses_attr(color))
     self.addstr(get_theme().CHAR_NACK)
     self._win.attroff(to_curses_attr(color))
     self.addstr(' ')
     return poopt.wcswidth(get_theme().CHAR_NACK) + 1
Beispiel #14
0
    def features_checked(self, iq):
        "Features check callback"
        features = iq['disco_info'].get_features() or []
        before = ('correct' in self.commands, self.remote_supports_attention,
                  self.remote_supports_receipts)
        correct = self._feature_correct(features)
        attention = self._feature_attention(features)
        receipts = self._feature_receipts(features)

        if (correct, attention, receipts) == before and self.__initial_disco:
            return
        else:
            self.__initial_disco = True

        if not (correct or attention or receipts):
            return  # don’t display anything

        ok = get_theme().CHAR_OK
        nope = get_theme().CHAR_EMPTY

        correct = ok if correct else nope
        attention = ok if attention else nope
        receipts = ok if receipts else nope

        msg = ('\x19%s}Contact supports: correction [%s], '
               'attention [%s], receipts [%s].')
        color = dump_tuple(get_theme().COLOR_INFORMATION_TEXT)
        msg = msg % (color, correct, attention, receipts)
        self.add_message(msg, typ=0)
        self.core.refresh_window()
Beispiel #15
0
 def build_message(self, message, timestamp=False):
     txt = message.txt
     ret = []
     default_color = None
     nick = truncate_nick(message.nickname)
     offset = 0
     if nick:
         offset += poopt.wcswidth(nick) + 1 # + nick + ' ' length
     if message.str_time:
         offset += 1 + len(message.str_time)
     if get_theme().CHAR_TIME_LEFT and message.str_time:
         offset += 1
     if get_theme().CHAR_TIME_RIGHT and message.str_time:
         offset += 1
     lines = poopt.cut_text(txt, self.width-offset-1)
     prepend = default_color if default_color else ''
     attrs = []
     for line in lines:
         saved = Line(msg=message, start_pos=line[0], end_pos=line[1], prepend=prepend)
         attrs = parse_attrs(message.txt[line[0]:line[1]], attrs)
         if attrs:
             prepend = FORMAT_CHAR + FORMAT_CHAR.join(attrs)
         else:
             if default_color:
                 prepend = default_color
             else:
                 prepend = ''
         ret.append(saved)
     return ret
Beispiel #16
0
    def features_checked(self, iq):
        "Features check callback"
        features = iq['disco_info'].get_features() or []
        before = ('correct' in self.commands,
                  self.remote_supports_attention,
                  self.remote_supports_receipts)
        correct = self._feature_correct(features)
        attention = self._feature_attention(features)
        receipts = self._feature_receipts(features)

        if (correct, attention, receipts) == before and self.__initial_disco:
            return
        else:
            self.__initial_disco = True

        if not (correct or attention or receipts):
            return # don’t display anything

        ok = get_theme().CHAR_OK
        nope = get_theme().CHAR_EMPTY

        correct = ok if correct else nope
        attention = ok if attention else nope
        receipts = ok if receipts else nope

        msg = _('\x19%s}Contact supports: correction [%s], '
                'attention [%s], receipts [%s].')
        color = dump_tuple(get_theme().COLOR_INFORMATION_TEXT)
        msg = msg % (color, correct, attention, receipts)
        self.add_message(msg, typ=0)
        self.core.refresh_window()
Beispiel #17
0
 def go_to_next_horizontal_input(self):
     if not self.lines:
         return
     self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_NORMAL_TEXT)
     self.current_horizontal_input += 1
     if self.current_horizontal_input > 3:
         self.current_horizontal_input = 0
     self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_SELECTED_ROW)
Beispiel #18
0
 def go_to_previous_horizontal_input(self):
     if not self.lines:
         return
     if self.current_horizontal_input == 0:
         return
     self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_NORMAL_TEXT)
     self.current_horizontal_input -= 1
     self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_SELECTED_ROW)
Beispiel #19
0
 def write_contact_jid(self, jid):
     """
     Just write the jid that we are talking to
     """
     self.addstr('[', to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
     self.addstr(jid.full,
                 to_curses_attr(get_theme().COLOR_CONVERSATION_NAME))
     self.addstr('] ', to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
Beispiel #20
0
 def refresh(self, txt=None):
     log.debug('Refresh: %s', self.__class__.__name__)
     if txt:
         self.txt = txt
     self._win.erase()
     self.addstr(0, 0, self.txt[:self.width-1], to_curses_attr(get_theme().COLOR_WARNING_PROMPT))
     self.finish_line(get_theme().COLOR_WARNING_PROMPT)
     self._refresh()
Beispiel #21
0
 def refresh(self, txt=None):
     log.debug('Refresh: %s', self.__class__.__name__)
     if txt:
         self.txt = txt
     self._win.erase()
     self.addstr(0, 0, self.txt[:self.width - 1],
                 to_curses_attr(get_theme().COLOR_WARNING_PROMPT))
     self.finish_line(get_theme().COLOR_WARNING_PROMPT)
     self._refresh()
Beispiel #22
0
 def draw_roster_information(self, roster):
     """
     The header at the top
     """
     self.addstr(
         'Roster: %s/%s contacts' %
         (roster.get_nb_connected_contacts(), len(roster)),
         to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
     self.finish_line(get_theme().COLOR_INFORMATION_BAR)
Beispiel #23
0
 def draw_roster_information(self, roster):
     """
     The header at the top
     """
     self.addstr('Roster: %s/%s contacts' % (
             roster.get_nb_connected_contacts(),
             len(roster)),
         to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
     self.finish_line(get_theme().COLOR_INFORMATION_BAR)
Beispiel #24
0
 def write_contact_informations(self, contact):
     """
     Write the informations about the contact
     """
     if not contact:
         self.addstr("(contact not in roster)", to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
         return
     display_name = contact.name
     if display_name:
         self.addstr('%s '%(display_name), to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
Beispiel #25
0
 def draw_status_chatstate(self, y, user):
     show_col = get_theme().color_show(user.show)
     if user.chatstate == 'composing':
         char = get_theme().CHAR_CHATSTATE_COMPOSING
     elif user.chatstate == 'active':
         char = get_theme().CHAR_CHATSTATE_ACTIVE
     elif user.chatstate == 'paused':
         char = get_theme().CHAR_CHATSTATE_PAUSED
     else:
         char = get_theme().CHAR_STATUS
     self.addstr(y, 0, char, to_curses_attr(show_col))
Beispiel #26
0
 def write_contact_jid(self, jid):
     """
     Just displays the resource in an other color
     """
     log.debug("write_contact_jid DynamicConversationInfoWin, jid: %s",
             jid.resource)
     self.addstr('[', to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
     self.addstr(jid.bare, to_curses_attr(get_theme().COLOR_CONVERSATION_NAME))
     if jid.resource:
         self.addstr("/%s" % (jid.resource,), to_curses_attr(get_theme().COLOR_CONVERSATION_RESOURCE))
     self.addstr('] ', to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
Beispiel #27
0
 def draw_status_chatstate(self, y, user):
     show_col = get_theme().color_show(user.show)
     if user.chatstate == 'composing':
         char = get_theme().CHAR_CHATSTATE_COMPOSING
     elif user.chatstate == 'active':
         char = get_theme().CHAR_CHATSTATE_ACTIVE
     elif user.chatstate == 'paused':
         char = get_theme().CHAR_CHATSTATE_PAUSED
     else:
         char = get_theme().CHAR_STATUS
     self.addstr(y, 0, char, to_curses_attr(show_col))
Beispiel #28
0
 def build_message(self, message, timestamp=False, nick_size=10):
     """
     Build a list of lines from a message, without adding it
     to a list
     """
     if message is None:  # line separator
         return [None]
     txt = message.txt
     if not txt:
         return []
     if len(message.str_time) > 8:
         default_color = (FORMAT_CHAR +
                          dump_tuple(get_theme().COLOR_LOG_MSG) + '}')
     else:
         default_color = None
     ret = []
     nick = truncate_nick(message.nickname, nick_size)
     offset = 0
     if message.ack:
         if message.ack > 0:
             offset += poopt.wcswidth(get_theme().CHAR_ACK_RECEIVED) + 1
         else:
             offset += poopt.wcswidth(get_theme().CHAR_NACK) + 1
     if nick:
         offset += poopt.wcswidth(nick) + 2  # + nick + '> ' length
     if message.revisions > 0:
         offset += ceil(log10(message.revisions + 1))
     if message.me:
         offset += 1  # '* ' before and ' ' after
     if timestamp:
         if message.str_time:
             offset += 1 + len(message.str_time)
         if get_theme().CHAR_TIME_LEFT and message.str_time:
             offset += 1
         if get_theme().CHAR_TIME_RIGHT and message.str_time:
             offset += 1
     lines = poopt.cut_text(txt, self.width - offset - 1)
     prepend = default_color if default_color else ''
     attrs = []
     for line in lines:
         saved = Line(msg=message,
                      start_pos=line[0],
                      end_pos=line[1],
                      prepend=prepend)
         attrs = parse_attrs(message.txt[line[0]:line[1]], attrs)
         if attrs:
             prepend = FORMAT_CHAR + FORMAT_CHAR.join(attrs)
         else:
             if default_color:
                 prepend = default_color
             else:
                 prepend = ''
         ret.append(saved)
     return ret
Beispiel #29
0
 def refresh(self, name=None, window=None):
     log.debug('Refresh: %s', self.__class__.__name__)
     self._win.erase()
     if name:
         self.addstr(name, to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
     else:
         self.addstr(self.message, to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
     if window:
         self.print_scroll_position(window)
     self.finish_line(get_theme().COLOR_INFORMATION_BAR)
     self._refresh()
Beispiel #30
0
 def draw_resource_line(self, y, resource, colored):
     """
     Draw a specific resource line
     """
     color = get_theme().color_show(resource.presence)
     self.addstr(y, 4, get_theme().CHAR_STATUS, to_curses_attr(color))
     if colored:
         self.addstr(y, 6, self.truncate_name(str(resource.jid), 6), to_curses_attr(get_theme().COLOR_SELECTED_ROW))
     else:
         self.addstr(y, 6, self.truncate_name(str(resource.jid), 6))
     self.finish_line()
Beispiel #31
0
 def go_to_next_horizontal_input(self):
     if not self.lines:
         return
     self.lines[self.current_input][
         self.current_horizontal_input].set_color(
             get_theme().COLOR_NORMAL_TEXT)
     self.current_horizontal_input += 1
     if self.current_horizontal_input > 3:
         self.current_horizontal_input = 0
     self.lines[self.current_input][
         self.current_horizontal_input].set_color(
             get_theme().COLOR_SELECTED_ROW)
Beispiel #32
0
 def write_resource_information(self, resource):
     """
     Write the informations about the resource
     """
     if not resource:
         presence = "unavailable"
     else:
         presence = resource.presence
     color = get_theme().color_show(presence)
     self.addstr('[', to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
     self.addstr(get_theme().CHAR_STATUS, to_curses_attr(color))
     self.addstr(']', to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
Beispiel #33
0
 def go_to_previous_horizontal_input(self):
     if not self.lines:
         return
     if self.current_horizontal_input == 0:
         return
     self.lines[self.current_input][
         self.current_horizontal_input].set_color(
             get_theme().COLOR_NORMAL_TEXT)
     self.current_horizontal_input -= 1
     self.lines[self.current_input][
         self.current_horizontal_input].set_color(
             get_theme().COLOR_SELECTED_ROW)
Beispiel #34
0
 def refresh(self, filter_t='', filter='', window=None):
     log.debug('Refresh: %s', self.__class__.__name__)
     self._win.erase()
     bar = to_curses_attr(get_theme().COLOR_INFORMATION_BAR)
     if not filter_t:
         self.addstr('[No filter]', bar)
     else:
         info = '[%s] %s' % (filter_t, filter)
         self.addstr(info, bar)
     self.print_scroll_position(window)
     self.finish_line(get_theme().COLOR_INFORMATION_BAR)
     self._refresh()
Beispiel #35
0
 def write_resource_information(self, resource):
     """
     Write the informations about the resource
     """
     if not resource:
         presence = "unavailable"
     else:
         presence = resource.presence
     color = get_theme().color_show(presence)
     self.addstr('[', to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
     self.addstr(get_theme().CHAR_STATUS, to_curses_attr(color))
     self.addstr(']', to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
Beispiel #36
0
 def write_contact_informations(self, contact):
     """
     Write the informations about the contact
     """
     if not contact:
         self.addstr("(contact not in roster)",
                     to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
         return
     display_name = contact.name
     if display_name:
         self.addstr('%s ' % (display_name),
                     to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
Beispiel #37
0
 def refresh(self, filter_t='', filter='', window=None):
     log.debug('Refresh: %s', self.__class__.__name__)
     self._win.erase()
     bar = to_curses_attr(get_theme().COLOR_INFORMATION_BAR)
     if not filter_t:
         self.addstr('[No filter]', bar)
     else:
         info = '[%s] %s' % (filter_t, filter)
         self.addstr(info, bar)
     self.print_scroll_position(window)
     self.finish_line(get_theme().COLOR_INFORMATION_BAR)
     self._refresh()
Beispiel #38
0
 def draw_resource_line(self, y, resource, colored):
     """
     Draw a specific resource line
     """
     color = get_theme().color_show(resource.presence)
     self.addstr(y, 4, get_theme().CHAR_STATUS, to_curses_attr(color))
     if colored:
         self.addstr(y, 6, self.truncate_name(str(resource.jid), 6),
                     to_curses_attr(get_theme().COLOR_SELECTED_ROW))
     else:
         self.addstr(y, 6, self.truncate_name(str(resource.jid), 6))
     self.finish_line()
Beispiel #39
0
    def command_smp(self, args):
        """
        /otrsmp <ask|answer|abort> [question] [secret]
        """
        if args is None or not args:
            return self.core.command_help('otrsmp')
        length = len(args)
        action = args.pop(0)
        if length == 2:
            question = None
            secret = args.pop(0).encode('utf-8')
        elif length == 3:
            question = args.pop(0).encode('utf-8')
            secret = args.pop(0).encode('utf-8')
        else:
            question = secret = None

        tab = self.api.current_tab()
        name = tab.name
        if isinstance(tab, DynamicConversationTab) and tab.locked_resource:
            name = safeJID(tab.name)
            name.resource = tab.locked_resource
            name = name.full

        format_dict = {
            'jid_c': '\x19%s}' % dump_tuple(get_theme().COLOR_MUC_JID),
            'info': '\x19%s}' % dump_tuple(get_theme().COLOR_INFORMATION_TEXT),
            'jid': name,
            'bare_jid': safeJID(name).bare
        }

        ctx = self.get_context(name)
        if ctx.state != STATE_ENCRYPTED:
            self.api.information('The current conversation is not encrypted',
                                 'Error')
            return

        if action == 'ask':
            ctx.in_smp = True
            ctx.smp_own = True
            if question:
                ctx.smpInit(secret, question)
            else:
                ctx.smpInit(secret)
            tab.add_message(SMP_INITIATED % format_dict, typ=0)
        elif action == 'answer':
            ctx.smpGotSecret(secret)
        elif action == 'abort':
            if ctx.in_smp:
                ctx.smpAbort()
                tab.add_message(SMP_ABORTED % format_dict, typ=0)
        self.core.refresh_window()
Beispiel #40
0
    def command_smp(self, args):
        """
        /otrsmp <ask|answer|abort> [question] [secret]
        """
        if args is None or not args:
            return self.core.command_help('otrsmp')
        length = len(args)
        action = args.pop(0)
        if length == 2:
            question = None
            secret = args.pop(0).encode('utf-8')
        elif length == 3:
            question = args.pop(0).encode('utf-8')
            secret = args.pop(0).encode('utf-8')
        else:
            question = secret = None

        tab = self.api.current_tab()
        name = tab.name
        if isinstance(tab, DynamicConversationTab) and tab.locked_resource:
            name = safeJID(tab.name)
            name.resource = tab.locked_resource
            name = name.full

        format_dict = {
            'jid_c': '\x19%s}' % dump_tuple(get_theme().COLOR_MUC_JID),
            'info': '\x19%s}' % dump_tuple(get_theme().COLOR_INFORMATION_TEXT),
            'jid': name,
            'bare_jid': safeJID(name).bare
        }

        ctx = self.get_context(name)
        if ctx.state != STATE_ENCRYPTED:
            self.api.information('The current conversation is not encrypted',
                                 'Error')
            return

        if action == 'ask':
            ctx.in_smp = True
            ctx.smp_own = True
            if question:
                ctx.smpInit(secret, question)
            else:
                ctx.smpInit(secret)
            tab.add_message(SMP_INITIATED % format_dict, typ=0)
        elif action == 'answer':
            ctx.smpGotSecret(secret)
        elif action == 'abort':
            if ctx.in_smp:
                ctx.smpAbort()
                tab.add_message(SMP_ABORTED % format_dict, typ=0)
        self.core.refresh_window()
Beispiel #41
0
 def refresh(self, name=None, window=None):
     log.debug('Refresh: %s', self.__class__.__name__)
     self._win.erase()
     if name:
         self.addstr(name,
                     to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
     else:
         self.addstr(self.message,
                     to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
     if window:
         self.print_scroll_position(window)
     self.finish_line(get_theme().COLOR_INFORMATION_BAR)
     self._refresh()
Beispiel #42
0
 def go_to_previous_line_input(self):
     if not self.lines:
         return
     if self.current_input == 0:
         return
     self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_NORMAL_TEXT)
     self.current_input -= 1
     # Adjust the scroll position if the current_input would be outside
     # of the visible area
     if self.current_input < self.scroll_pos:
         self.scroll_pos = self.current_input
         self.refresh()
     self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_SELECTED_ROW)
Beispiel #43
0
 def build_message(self, message, timestamp=False):
     """
     Build a list of lines from a message, without adding it
     to a list
     """
     if message is None:  # line separator
         return [None]
     txt = message.txt
     if not txt:
         return []
     if len(message.str_time) > 8:
         default_color = (FORMAT_CHAR + dump_tuple(get_theme().COLOR_LOG_MSG)
                 + '}')
     else:
         default_color = None
     ret = []
     nick = truncate_nick(message.nickname)
     offset = 0
     if message.ack:
         if message.ack > 0:
             offset += poopt.wcswidth(get_theme().CHAR_ACK_RECEIVED) + 1
         else:
             offset += poopt.wcswidth(get_theme().CHAR_NACK) + 1
     if nick:
         offset += poopt.wcswidth(nick) + 2 # + nick + '> ' length
     if message.revisions > 0:
         offset += ceil(log10(message.revisions + 1))
     if message.me:
         offset += 1 # '* ' before and ' ' after
     if timestamp:
         if message.str_time:
             offset += 1 + len(message.str_time)
         if get_theme().CHAR_TIME_LEFT and message.str_time:
             offset += 1
         if get_theme().CHAR_TIME_RIGHT and message.str_time:
             offset += 1
     lines = poopt.cut_text(txt, self.width-offset-1)
     prepend = default_color if default_color else ''
     attrs = []
     for line in lines:
         saved = Line(msg=message, start_pos=line[0], end_pos=line[1], prepend=prepend)
         attrs = parse_attrs(message.txt[line[0]:line[1]], attrs)
         if attrs:
             prepend = FORMAT_CHAR + FORMAT_CHAR.join(attrs)
         else:
             if default_color:
                 prepend = default_color
             else:
                 prepend = ''
         ret.append(saved)
     return ret
Beispiel #44
0
    def make_message(txt,
                     time,
                     nickname,
                     nick_color,
                     history,
                     user,
                     identifier,
                     str_time=None,
                     highlight=False,
                     old_message=None,
                     revisions=0,
                     jid=None,
                     ack=None):
        """
        Create a new Message object with parameters, check for /me messages,
        and delayed messages
        """
        time = time or datetime.now()
        if txt.startswith('/me '):
            me = True
            txt = '\x19%s}%s' % (dump_tuple(
                get_theme().COLOR_ME_MESSAGE), txt[4:])
        else:
            me = False
        if history:
            txt = txt.replace(
                '\x19o',
                '\x19o\x19%s}' % dump_tuple(get_theme().COLOR_LOG_MSG))
            str_time = time.strftime("%Y-%m-%d %H:%M:%S")
        else:
            if str_time is None:
                str_time = time.strftime("%H:%M:%S")
            else:
                str_time = ''

        msg = Message(txt='%s\x19o' % (txt.replace('\t', '    '), ),
                      nick_color=nick_color,
                      time=time,
                      str_time=str_time,
                      nickname=nickname,
                      user=user,
                      identifier=identifier,
                      highlight=highlight,
                      me=me,
                      old_message=old_message,
                      revisions=revisions,
                      jid=jid,
                      ack=ack)
        log.debug('Set message %s with %s.', identifier, msg)
        return msg
Beispiel #45
0
 def write_contact_jid(self, jid):
     """
     Just displays the resource in an other color
     """
     log.debug("write_contact_jid DynamicConversationInfoWin, jid: %s",
               jid.resource)
     self.addstr('[', to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
     self.addstr(jid.bare,
                 to_curses_attr(get_theme().COLOR_CONVERSATION_NAME))
     if jid.resource:
         self.addstr(
             "/%s" % (jid.resource, ),
             to_curses_attr(get_theme().COLOR_CONVERSATION_RESOURCE))
     self.addstr('] ', to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
Beispiel #46
0
 def refresh(self, topic=None):
     log.debug('Refresh: %s', self.__class__.__name__)
     self._win.erase()
     if topic:
         msg = topic[:self.width-1]
     else:
         msg = self._message[:self.width-1]
     self.addstr(0, 0, msg, to_curses_attr(get_theme().COLOR_TOPIC_BAR))
     (y, x) = self._win.getyx()
     remaining_size = self.width - x
     if remaining_size:
         self.addnstr(' '*remaining_size, remaining_size,
                      to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
     self._refresh()
Beispiel #47
0
 def refresh(self, topic=None):
     log.debug('Refresh: %s', self.__class__.__name__)
     self._win.erase()
     if topic:
         msg = topic[:self.width - 1]
     else:
         msg = self._message[:self.width - 1]
     self.addstr(0, 0, msg, to_curses_attr(get_theme().COLOR_TOPIC_BAR))
     (y, x) = self._win.getyx()
     remaining_size = self.width - x
     if remaining_size:
         self.addnstr(' ' * remaining_size, remaining_size,
                      to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
     self._refresh()
Beispiel #48
0
    def on_conversation_say(self, msg, tab):
        """
        On message sent
        """
        if isinstance(tab, DynamicConversationTab) and tab.locked_resource:
            jid = safeJID(tab.name)
            jid.resource = tab.locked_resource
            name = jid.full
        else:
            name = tab.name
            jid = safeJID(tab.name)

        format_dict = {
            'jid_c': '\x19%s}' % dump_tuple(get_theme().COLOR_MUC_JID),
            'info': '\x19%s}' % dump_tuple(get_theme().COLOR_INFORMATION_TEXT),
            'jid': name,
        }

        ctx = None
        default_ctx = self.get_context(name)

        if isinstance(tab, DynamicConversationTab) and not tab.locked_resource:
            log.debug('Unlocked tab %s found, falling back to the first encrypted chat we find.', name)
            ctx = self.find_encrypted_context_with_matching(jid.bare)

        if ctx is None:
            ctx = default_ctx

        if ctx and ctx.state == STATE_ENCRYPTED:
            ctx.sendMessage(0, msg['body'].encode('utf-8'))
            if not tab.send_chat_state('active'):
                tab.send_chat_state('inactive', always_send=True)

            tab.add_message(msg['body'],
                            nickname=self.core.own_nick or tab.own_nick,
                            nick_color=get_theme().COLOR_OWN_NICK,
                            identifier=msg['id'],
                            jid=self.core.xmpp.boundjid,
                            typ=ctx.log)
            # remove everything from the message so that it doesn’t get sent
            del msg['body']
            del msg['replace']
            del msg['html']
        elif ctx and ctx.getPolicy('REQUIRE_ENCRYPTION'):
            tab.add_message(MESSAGE_NOT_SENT % format_dict, typ=0)
            del msg['body']
            del msg['replace']
            del msg['html']
            self.otr_start(tab, name, format_dict)
Beispiel #49
0
 def go_to_next_line_input(self):
     if not self.lines:
         return
     if self.current_input == len(self.lines) - 1:
         return
     self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_NORMAL_TEXT)
     # Adjust the scroll position if the current_input would be outside
     # of the visible area
     if self.current_input + 1 - self.scroll_pos > self.height-1:
         self.current_input += 1
         self.scroll_pos += 1
         self.refresh()
     else:
         self.current_input += 1
         self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_SELECTED_ROW)
Beispiel #50
0
 def draw_group(self, y, group, colored):
     """
     Draw a groupname on a line
     """
     if colored:
         self._win.attron(to_curses_attr(get_theme().COLOR_SELECTED_ROW))
     if group.folded:
         self.addstr(y, 0, '[+] ')
     else:
         self.addstr(y, 0, '[-] ')
     contacts = " (%s/%s)" % (group.get_nb_connected_contacts(), len(group))
     self.addstr(y, 4, self.truncate_name(group.name, len(contacts)+4) + contacts)
     if colored:
         self._win.attroff(to_curses_attr(get_theme().COLOR_SELECTED_ROW))
     self.finish_line()
Beispiel #51
0
 def refresh(self, jid, contact, window, chatstate, informations):
     # contact can be None, if we receive a message
     # from someone not in our roster. In this case, we display
     # only the maximum information from the message we can get.
     log.debug('Refresh: %s', self.__class__.__name__)
     jid = safeJID(jid)
     if contact:
         if jid.resource:
             resource = contact[jid.full]
         else:
             resource = contact.get_highest_priority_resource()
     else:
         resource = None
     # if contact is None, then resource is None too:
     # user is not in the roster so we know almost nothing about it
     # If contact is a Contact, then
     # resource can now be a Resource: user is in the roster and online
     # or resource is None: user is in the roster but offline
     self._win.erase()
     self.write_contact_jid(jid)
     self.write_contact_informations(contact)
     self.write_resource_information(resource)
     self.print_scroll_position(window)
     self.write_chatstate(chatstate)
     self.write_additional_informations(informations, jid)
     self.finish_line(get_theme().COLOR_INFORMATION_BAR)
     self._refresh()
Beispiel #52
0
 def write_disconnected(self, room):
     """
     Shows a message if the room is not joined
     """
     if not room.joined:
         self.addstr(' -!- Not connected ',
                     to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
Beispiel #53
0
 def write_additional_informations(self, informations, jid):
     """
     Write all informations added by plugins by getting the
     value returned by the callbacks.
     """
     for key in informations:
         self.addstr(informations[key](jid), to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
Beispiel #54
0
    def refresh(self):
        # store the cursor status
        self._win.erase()
        y = - self.scroll_pos
        for i in range(len(self.lines)):
            self.lines[i][0].resize(1, self.width//3, y + 1, 0)
            self.lines[i][1].resize(1, self.width//3, y + 1, self.width//3)
            self.lines[i][2].resize(1, self.width//6, y + 1, 2*self.width//3)
            self.lines[i][3].resize(1, self.width//6, y + 1, 5*self.width//6)
            y += 1
        self._refresh()
        for i, inp in enumerate(self.lines):
            if i < self.scroll_pos:
                continue
            if i >= self.height + self.scroll_pos:
                break
            for j in range(4):
                inp[j].refresh()

        if self.lines and self.current_input < self.height-1:
            self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_SELECTED_ROW)
            self.lines[self.current_input][self.current_horizontal_input].refresh()
        if not self.lines:
            curses.curs_set(0)
        else:
            curses.curs_set(1)
Beispiel #55
0
 def refresh(self, jid, contact, window, chatstate, informations):
     # contact can be None, if we receive a message
     # from someone not in our roster. In this case, we display
     # only the maximum information from the message we can get.
     log.debug('Refresh: %s', self.__class__.__name__)
     jid = safeJID(jid)
     if contact:
         if jid.resource:
             resource = contact[jid.full]
         else:
             resource = contact.get_highest_priority_resource()
     else:
         resource = None
     # if contact is None, then resource is None too:
     # user is not in the roster so we know almost nothing about it
     # If contact is a Contact, then
     # resource can now be a Resource: user is in the roster and online
     # or resource is None: user is in the roster but offline
     self._win.erase()
     if config.get('show_jid_in_conversations'):
         self.write_contact_jid(jid)
     self.write_contact_informations(contact)
     self.write_resource_information(resource)
     self.print_scroll_position(window)
     self.write_chatstate(chatstate)
     self.write_additional_informations(informations, jid)
     self.finish_line(get_theme().COLOR_INFORMATION_BAR)
     self._refresh()
Beispiel #56
0
 def remote_wants_chatstates(self, value):
     old_value = self._remote_wants_chatstates
     self._remote_wants_chatstates = value
     if (old_value is None and value != None) or \
             (old_value != value and value != None):
         ok = get_theme().CHAR_OK
         nope = get_theme().CHAR_EMPTY
         support = ok if value else nope
         if value:
             msg = _('\x19%s}Contact supports chat states [%s].')
         else:
             msg = _('\x19%s}Contact does not support chat states [%s].')
         color = dump_tuple(get_theme().COLOR_INFORMATION_TEXT)
         msg = msg % (color, support)
         self.add_message(msg, typ=0)
         self.core.refresh_window()
Beispiel #57
0
    def on_conversation_say(self, msg, tab):
        """
        On message sent
        """
        if isinstance(tab, DynamicConversationTab) and tab.locked_resource:
            jid = safeJID(tab.name)
            jid.resource = tab.locked_resource
            name = jid.full
        else:
            name = tab.name
            jid = safeJID(tab.name)

        ctx = self.contexts.get(name)
        if isinstance(tab, DynamicConversationTab) and not tab.locked_resource:
            log.debug('Unlocked tab %s found, falling back to the first encrypted chat we find.', name)
            ctx = self.find_encrypted_context_with_matching(jid.bare)

        if ctx and ctx.state == STATE_ENCRYPTED:
            ctx.sendMessage(0, msg['body'].encode('utf-8'))
            if not tab.send_chat_state('active'):
                tab.send_chat_state('inactive', always_send=True)

            tab.add_message(msg['body'],
                    nickname=self.core.own_nick or tab.own_nick,
                    nick_color=get_theme().COLOR_OWN_NICK,
                    identifier=msg['id'],
                    jid=self.core.xmpp.boundjid,
                    typ=ctx.log)
            # remove everything from the message so that it doesn’t get sent
            del msg['body']
            del msg['replace']
            del msg['html']
Beispiel #58
0
 def __init__(self, field):
     FieldInput.__init__(self, field)
     Input.__init__(self)
     self.text = field.getValue() if isinstance(field.getValue(), str)\
         else ""
     self.pos = len(self.text)
     self.color = get_theme().COLOR_NORMAL_TEXT