Esempio n. 1
0
async def on_incoming_message(msg):
    # find the guild/channel it belongs to and add it
    if isinstance(msg.channel, DMChannel) or \
            isinstance(msg.channel, GroupChannel):
        guild_log = gc.guild_log_tree[0]
        for channel_log in guild_log.logs:
            users = []
            for user in channel_log.channel.members:
                users.append(user)
            if msg.author in users and \
                    msg.channel is channel_log.channel._channel:
                await process_message(msg, channel_log)
                return
        log("Could not find matching channel log")
    elif isinstance(msg.channel, TextChannel):
        doBreak = False
        for guild_log in gc.guild_log_tree:
            if guild_log.guild == msg.guild:
                for channel_log in guild_log.logs:
                    if channel_log.channel == msg.channel:
                        await process_message(msg, channel_log)
                        doBreak = True
                        break
            if doBreak:
                break
Esempio n. 2
0
def parseCommand(command, arg=None):
    if arg is None:
        if command in ("refresh", "update"):
            ui.draw_screen()
            log("Manual update done", logging.info)
        elif command in ("quit", "exit"):
            try:
                gc.exit_thread.start()
            except SystemExit:
                pass
        elif command in ("help", 'h'):
            ui.draw_help()
        elif command in ("guilds", "glds", "servers", "servs"):
            ui.draw_guildlist()
        elif command in ("channels", "chans"):
            ui.draw_channellist()
        elif command == "emojis":
            ui.draw_emojilist()
        elif command in ("users", "members"):
            ui.draw_userlist()
        elif command == "nick":
            change_nick()
        elif command == "dm":
            change_guild("private messages")
        elif command in ("del", "rm"):
            gc.client.remove_last_message()
        elif command[0] == 'c':
            try:
                if command[1].isdigit():
                    channel_jump(command)
                    ui.draw_screen()
            except IndexError:
                pass
        return

    if command in ('guild', 'g', 'server', 's'):
        change_guild(arg)
    elif command in ("channel", 'c'):
        gc.client.current_channel = arg
        gc.ui.channel_log_offset = -1
        ui.draw_screen()
    elif command == "nick":
        change_nick(arg)
        return
    elif command in ("game", "activity"):
        gc.client.wait_until_client_task_completes(
            (gc.client.set_activity, arg))
    elif command == "file":
        send_file(arg)
    elif command == "status":
        status = arg.lower()
        if status in ("away", "afk"):
            status = "idle"
        elif "disturb" in status:
            status = "dnd"

        if status in ("online", "offline", "idle", "dnd"):
            gc.client.wait_until_client_task_completes(\
                    (gc.client.set_status, status))
Esempio n. 3
0
def change_guild(arg):
    prev_guild = gc.client.current_guild
    gc.client.set_current_guild(arg)
    if gc.client.current_guild is prev_guild:
        return
    log("changed guild")
    gc.ui.channel_log_offset = -1
    ui.draw_screen()
Esempio n. 4
0
def key_input():
    # if the next two aren't here, input does not work
    curses.cbreak()
    curses.noecho()
    editWin = gc.ui.editWin
    gc.ui_thread.wait_until_ui_task_completes((ui.draw_edit_win, True))
    while not gc.doExit:
        ch = editWin.getch()
        if ch == -1 or not gc.ui.displayPanel.hidden():
            time.sleep(0.01)
            continue

        if chr(ch) != '\n' and len(gc.ui.messageEdit.inputBuffer) > 0 and \
                gc.ui.messageEdit.inputBuffer[0] != ord('/'):
            gc.typingBeingHandled = True
        # prevents crashes when enter is hit and input buf is empty
        if chr(ch) == '\n' and not gc.ui.messageEdit.inputBuffer:
            continue
        if ch == curses.KEY_PPAGE:
            gc.ui.channel_log_offset -= gc.settings["scroll_lines"]
            ui.draw_screen()
            continue
        elif ch == curses.KEY_NPAGE:
            gc.ui.channel_log_offset += gc.settings["scroll_lines"]
            ui.draw_screen()
            continue
        elif ch == curses.KEY_RESIZE:
            gc.ui.resize()
            ui.draw_screen()
            continue
        elif ch == curses.KEY_DC:
            # TODO: Add functionality here
            ui.draw_screen()
            continue
        # if ESC is pressed, clear messageEdit buffer
        elif ch == 27:
            ch = editWin.getch()
            if ch in (0x7f, ord('\b'), curses.KEY_BACKSPACE):
                gc.ui.messageEdit.reset()
                gc.ui_thread.wait_until_ui_task_completes(
                    (ui.draw_edit_win, True))
            continue
        ret = gc.ui.messageEdit.addKey(ch)
        if ret is not None:
            input_handler(ret)
            gc.ui.messageEdit.reset()
        call = (ui.draw_edit_win, True)
        gc.ui_thread.funcs.append(call)
        while not gc.doExit and (call in gc.ui_thread.funcs or \
                call[0].__name__ in gc.ui_thread.locks):
            time.sleep(0.01)
    log("key_input finished")
    gc.tasksExited += 1
Esempio n. 5
0
 async def init_channel(self, channel=None):
     clog = None
     if channel is None:
         clog = self.current_channel_log
         log("Initializing current channel")
     else:
         log("Initializing channel {}".format(channel.name))
         try:
             for gldlog in gc.guild_log_tree:
                 for chllog in gldlog.logs:
                     if chllog.channel == channel:
                         clog = chllog
                         raise Found
         except Found:
             pass
     if isinstance(clog.channel, PrivateChannel) or \
             isinstance(clog.channel, discord.TextChannel) and \
             clog.channel.permissions_for(clog.guild.me).read_messages:
         try: #TODO: Remove try/except once bug is fixed
             async for msg in clog.channel.history(limit=gc.settings["max_log_entries"]):
                 if msg.edited_at is not None:
                     msg.content += " **(edited)**"
                 # needed for modification of past messages
                 #self.messages.append(msg)
                 clog.insert(0, calc_mutations(msg))
         except discord.Forbidden:
             log("Cannot enter channel {}: Forbidden.".format(clog.channel.name))
             init_view(gc, clog.channel)
             return
         except Exception as e:
             log("error: {}".format(e))
         gc.channels_entered.append(clog.channel)
         init_view(gc, clog.channel) # initialize view
         for msg in clog.logs:
             gc.ui.views[str(clog.channel.id)].formattedText.addMessage(msg)
Esempio n. 6
0
 def set_current_guild(self, guild):
     if isinstance(guild, str):
         for gldlog in gc.guild_log_tree:
             gld = gldlog.guild
             if guild.lower() in gld.name.lower():
                 if not gld.channels:
                     set_display("This guild is empty!")
                     return
                 self._current_guild = gld
                 # find first non-ignored channel, set channel, mark flags as False
                 def_chan = None
                 lowest = 999
                 for chan in gld.channels:
                     if isinstance(chan, discord.TextChannel) and \
                             chan.permissions_for(gld.me).read_messages and \
                             chan.position < lowest:
                         try:
                             # Skip over ignored channels
                             for serv_key in gc.settings["channel_ignore_list"]:
                                 if serv_key["guild_name"].lower() == gld.name:
                                     for name in serv_key["ignores"]:
                                         if chan.name.lower() == name.lower():
                                             raise Found
                         except Found:
                             continue
                         except:
                             e = sys.exc_info()[0]
                             log("Exception raised during channel ignore list parsing: {}".format(e),
                                     logging.error)
                             return
                         lowest = chan.position
                         def_chan = chan
                     elif isinstance(chan, PrivateChannel):
                         def_chan = chan
                     else:
                         continue
                     try:
                         if def_chan is None:
                             raise NoChannelsFoundException
                         self.current_channel = def_chan
                         for chanlog in gldlog.logs:
                             if chanlog.channel is def_chan:
                                 chanlog.unread = False
                                 chanlog.mentioned_in = False
                                 return
                     except NoChannelsFoundException:
                         log("No channels found.")
                         return
                     except AttributeError as e:
                         log("Attribute error: {}".format(e))
                         return
                     except:
                         e = sys.exc_info()[0]
                         log("Error when setting channel flags!: {}".format(e), logging.error)
                         continue
                 return
         return
     self._current_guild = guild
Esempio n. 7
0
def draw_screen():
    log("Updating")
    # init current channel if needed
    if gc.client.current_channel not in gc.channels_entered:
        gc.client.wait_until_client_task_completes(\
                (gc.client.init_channel,gc.client.current_channel))
    if gc.ui.topWinVisible:
        gc.ui_thread.wait_until_ui_task_completes((draw_top_win, ))
    if gc.ui.leftWinVisible:
        gc.ui_thread.wait_until_ui_task_completes((draw_left_win, ))
    if gc.ui.userWinVisible:
        gc.ui_thread.wait_until_ui_task_completes((draw_user_win, ))
    if gc.guild_log_tree is not None:
        gc.ui_thread.wait_until_ui_task_completes((draw_channel_log, ))
    gc.ui_thread.wait_until_ui_task_completes((draw_edit_win, ))
    curses.doupdate()
Esempio n. 8
0
 def resize(self):
     self.max_y, self.max_x = self.screen.getmaxyx()
     self.clearWins()
     try:
         if self.separatorsVisible:
             self.makeFrameWin(resize=True)
         if self.topWinVisible:
             self.makeTopWin(resize=True)
         self.makeBottomWin(resize=True)
         if self.leftWinVisible:
             self.makeLeftWin(resize=True)
         if self.userWinVisible:
             self.makeUserWin(resize=True)
         self.makeChatWin(resize=True)
         self.makeDisplay(resize=True)
     except Exception as e:
         log("Failed to resize windows. Error: {}".format(e))
     self.messageEdit.termWidth = self.messageEdit.width = self.max_x
     self.redrawFrames()
     draw_screen()
Esempio n. 9
0
async def process_message(msg, channel_log):
    if channel_log.channel not in gc.channels_entered:
        await gc.client.init_channel(channel_log.channel)
    else:
        channel_log.append(calc_mutations(msg))
        gc.ui.channel_log_offset += 1
    if msg.guild is not None and \
            channel_log.channel is not gc.client.current_channel:
        if msg.guild.me.mention in msg.content:
            channel_log.mentioned_in = True
        else:
            channel_log.unread = True
    if msg.guild is not None and \
            msg.guild.me.mention in msg.content and \
            "beep_mentions" in gc.settings and \
            gc.settings["beep_mentions"]:
        curses.beep()
        log("Beep!")
    if channel_log is gc.client.current_channel_log:
        ui.draw_screen()
Esempio n. 10
0
def typing_handler():
    if not gc.settings["send_is_typing"]: return

    log("typing_handler started")
    while not gc.doExit:
        if gc.typingBeingHandled:
            call = (gc.client.current_channel.trigger_typing, )
            gc.client.async_funcs.append(call)
            while not gc.doExit and (call in gc.client.async_funcs or \
                    call[0].__name__ in gc.client.locks):
                time.sleep(0.1)
            for second in range(50):
                if gc.doExit:
                    break
                time.sleep(0.1)
            gc.typingBeingHandled = False
            if gc.doExit:
                break
        time.sleep(0.1)
    log("typing_handler finished")
    gc.tasksExited += 1
Esempio n. 11
0
def draw_user_win():
    userWin = gc.ui.userWin
    height, width = userWin.getmaxyx()

    userWin.erase()

    for idx, member in enumerate(gc.client.current_channel.members):
        try:
            if idx + 2 > height:
                userWin.addstr(idx, 0, "(more)", gc.ui.colors["green"])
                break
            name = member.display_name
            if len(name) >= width:
                name = name[:width - 4] + "..."

            userWin.addstr(idx, 0, name)
        except Exception as e:
            # if we're here, text has failed to draw
            log("Failed to draw user window. Error: {}".format(e))

    userWin.noutrefresh()
Esempio n. 12
0
async def on_message_delete(msg):
    log("Attempting to delete")
    await gc.client.wait_until_ready()
    # TODO: PM's have 'None' as a guild -- fix this later
    if msg.guild is None: return

    try:
        for guildlog in gc.guild_log_tree:
            if guildlog.guild == msg.guild:
                for channellog in guildlog.logs:
                    if channellog.channel == msg.channel:
                        ft = gc.ui.views[str(
                            channellog.channel.id)].formattedText
                        channellog.logs.remove(msg)
                        ft.messages.remove(msg)
                        ft.refresh()
                        log("Deleted, updating")
                        if msg.channel is gc.client.current_channel:
                            draw_screen()
                        return
    except:
        # if the message cannot be found, an exception will be raised
        # this could be #1: if the message was already deleted,
        # (happens when multiple calls get excecuted within the same time)
        # or the user was banned, (in which case all their msgs disappear)
        pass
    log("Could not delete message: {}".format(msg.clean_content))
Esempio n. 13
0
def draw_edit_win(update=False):
    editWin = gc.ui.editWin
    promptText = gc.client.prompt
    offset = len(promptText) + 5
    width = gc.ui.max_x - offset
    edit = gc.ui.messageEdit

    borderColor = gc.ui.colors[gc.settings["prompt_border_color"]]
    hasHash = False
    hashColor = 0
    promptColor = 0
    if gc.client.prompt != gc.settings["default_prompt"]:
        hasHash = True
        hashColor = gc.ui.colors[gc.settings["prompt_hash_color"]]
    promptColor = gc.ui.colors[gc.settings["prompt_color"]]

    edit.setPrompt(gc.client.prompt)
    try:
        editWin.erase()
        editWin.addstr(0, 0, "[", borderColor)
        if not hasHash:
            editWin.addstr(gc.settings["default_prompt"], promptColor)
        else:
            editWin.addstr("#", hashColor)
            editWin.addstr(promptText, promptColor)
        editWin.addstr("]: ", borderColor)
        try:
            text_data, text_data_pos, start_pos = edit.getCurrentData()
        except:
            text_data, text_data_pos, start_pos = ('', 0, 0)
        pos = text_data_pos - start_pos
        data = (text_data[start_pos:start_pos + width - 1], pos)
        editWin.addstr(0, offset, data[0])
        editWin.move(0, offset + data[1])
        editWin.noutrefresh()
        if update:
            curses.doupdate()
    except Exception as e:
        # if we're here, text has failed to draw
        log("Failed to draw edit window. Error: {}".format(e))
Esempio n. 14
0
def draw_top_win():
    topWin = gc.ui.topWin
    width = topWin.getmaxyx()[1]
    color = gc.ui.colors[gc.settings["guild_display_color"]]

    guildName = gc.client.current_guild.name

    topic = ""
    if gc.client.current_channel.topic is not None:
        topic = gc.client.current_channel.topic
    # if there is no channel topic, just print the channel name
    else:
        topic = gc.client.current_channel.name
    topic = topic.replace("\n", " ")
    if len(topic) >= width // 2:
        topic = topic[:width // 2 - 3] + "..."
    topicOffset = width // 2 - len(topic) // 2

    # sleep required to get accurate user count
    time.sleep(0.05)
    try:
        online = str(gc.client.online)
        online_text = "Users online: " + online
        onlineOffset = width - len(online_text) - 1

        topWin.erase()

        topWin.addstr(0, 0, "Guild: ")
        topWin.addstr(guildName, color)

        topWin.addstr(0, topicOffset, topic)

        topWin.addstr(0, onlineOffset, "Users online: ", color)
        topWin.addstr(online)
    except Exception as e:
        # if we're here, text has failed to draw
        log("Failed to draw top window. Error: {}".format(e))

    topWin.noutrefresh()
Esempio n. 15
0
 def redrawFrames(self):
     # redraw top frame
     y_offset = 0
     color = gc.ui.colors[gc.settings['separator_color']]
     self.frameWin.attron(color)
     try:
         if self.topWinVisible and self.separatorsVisible:
             y_offset = 1
             self.frameWin.hline(y_offset, 0, curses.ACS_HLINE, self.max_x)
         # redraw bottom frame
         if self.separatorsVisible:
             self.frameWin.hline(self.max_y - 2, 0, curses.ACS_HLINE,
                                 self.max_x)
         # redraw left frame
         if self.leftWinVisible and self.separatorsVisible:
             self.frameWin.vline(y_offset + 1, self.leftWinWidth,
                                 curses.ACS_VLINE,
                                 self.max_y - y_offset - 3)
             self.frameWin.addch(y_offset, self.leftWinWidth,
                                 curses.ACS_TTEE)
             self.frameWin.addch(self.max_y - 2, self.leftWinWidth,
                                 curses.ACS_BTEE)
         # redraw user frame
         if self.userWinVisible and self.separatorsVisible:
             self.frameWin.vline(y_offset + 1,
                                 self.max_x - self.userWinWidth - 1,
                                 curses.ACS_VLINE,
                                 self.max_y - y_offset - 3)
             self.frameWin.addch(y_offset,
                                 self.max_x - self.userWinWidth - 1,
                                 curses.ACS_TTEE)
             self.frameWin.addch(self.max_y - 2,
                                 self.max_x - self.userWinWidth - 1,
                                 curses.ACS_BTEE)
     except Exception as e:
         # if we're here, text has failed to draw
         log("Failed to draw frames. Error: {}".format(e))
     self.frameWin.attroff(color)
     self.frameWin.refresh()
Esempio n. 16
0
 def remove_last_message(self):
     log("Attempting to delete last message")
     messages = gc.ui.views[str(self.current_channel.id)].formattedText.messages
     message = None
     i = len(messages)-1
     while i >= 0:
         message = messages[i]
         if message.author.id == self.user.id:
             log("Deleting message '{}'".format(message.clean_content))
             self.wait_until_client_task_completes((message.delete,))
             gc.ui.views[str(self.current_channel.id)].formattedText.refresh()
             draw_screen()
             return
         i -= 1
     log("Could not delete last message")
Esempio n. 17
0
 def set_current_channel(self, channel):
     if isinstance(channel, str):
         try:
             gld = self.current_guild
             channel_found = None
             channel_score = 0.0
             for chl in gld.channels:
                 if channel.lower() in chl.name.lower() and \
                         isinstance(chl, discord.TextChannel) and \
                         chl.permissions_for(gld.me).read_messages:
                     score = len(channel) / len(chl.name)
                     if score > channel_score:
                         channel_found = chl
                         channel_score = score
                 elif isinstance(chl, PrivateChannel) and \
                         channel.lower() in chl.name.lower():
                     channel_found = chl
                     break
             if channel_found != None:
                 self._current_channel = channel_found
                 self._prompt = channel_found.name
                 if len(gc.channels_entered) > 0:
                     chanlog = self.current_channel_log
                     chanlog.unread = False
                     chanlog.mentioned_in = False
                 return
             raise RuntimeError("Could not find channel!")
         except RuntimeError as e:
             log("RuntimeError during channel setting: {}".format(e),
                 logging.error)
             return
         except AttributeError as e:
             log("Attribute error, chanlog is None: {}".format(e),
                 logging.error)
             return
         except:
             e = sys.exc_info()[0]
             log("Unknown exception during channel setting: {}".format(e),
                 logging.error)
             return
     self._current_channel = channel
     self._prompt = channel.name
     if len(gc.channels_entered) > 0:
         chanlog = self.current_channel_log
         chanlog.unread = False
         chanlog.mentioned_in = False
Esempio n. 18
0
 def run(self):
     log("Starting UI thread")
     curses.wrapper(self.ui.run)
     self.locks = []
     while not self.gc.doExit:
         try:
             if len(self.funcs) > 0:
                 call = self.funcs.pop()
                 func = call[0]
                 self.locks.append(func.__name__)
                 args = []
                 if len(call) > 1:
                     args = call[1:]
                 func(*args)
                 self.locks.remove(func.__name__)
             time.sleep(0.01)
         except Exception as e:
             log("Error: {}".format(e))
     log("Exiting UI thread")
Esempio n. 19
0
 async def run_calls(self):
     self.locks = []
     while not gc.doExit:
         if len(self.async_funcs) > 0:
             call = self.async_funcs.pop()
             func = call[0]
             self.locks.append(func.__name__)
             args = []
             opt_args = {}
             if len(call) > 1:
                 for arg in call[1:]:
                     if isinstance(arg, dict):
                         opt_args = arg
                     else:
                         args.append(arg)
             try:
                 await func(*args, **opt_args)
             except Exception as e:
                 log("Could not await {}".format(func))
                 log("\targs: {}\n\topt_args: {}".format(args, opt_args))
                 log("\terror: {}".format(e))
             self.locks.remove(func.__name__)
         await asyncio.sleep(0.01)
Esempio n. 20
0
def draw_channel_log():
    chatWin = gc.ui.chatWin
    ft = None
    doBreak = False
    for guild_log in gc.guild_log_tree:
        if guild_log.guild is gc.client.current_guild:
            for channel_log in guild_log.logs:
                if channel_log.channel is gc.client.current_channel:
                    if isinstance(channel_log.channel, VoiceChannel) or \
                            isinstance(channel_log.channel, CategoryChannel):
                        continue

                    try:
                        ft = gc.ui.views[str(
                            channel_log.channel.id)].formattedText
                    except Exception as e:
                        log("e: {}".format(e))
                    if len(ft.messages) > 0 and channel_log.logs[-1].id == \
                            ft.messages[-1].id:
                        doBreak = True
                        break
                    if len(channel_log.logs) > 0:
                        ft.addMessage(channel_log.logs[-1])
                    doBreak = True
                    break
        if doBreak:
            break
    lines = ft.getLines()
    for line in lines:
        words = []
        for word in line.words:
            words.append(word.content)
        #log("Line: {}".format(" ".join(words)))
    name_offset = 0
    chatWin_height, chatWin_width = chatWin.getmaxyx()
    # upon entering a new channel, scroll all the way down
    if gc.ui.channel_log_offset == -1:
        if len(lines) > chatWin_height:
            gc.ui.channel_log_offset = len(lines) - chatWin_height
        else:
            gc.ui.channel_log_offset = 0
    # check to see if scrolling is out of bounds
    elif len(lines) > chatWin_height and \
            gc.ui.channel_log_offset > len(lines)-chatWin_height:
        gc.ui.channel_log_offset = len(lines) - chatWin_height
    elif gc.ui.channel_log_offset < -1:
        gc.ui.channel_log_offset = 0
    color = 0
    chatWin.erase()
    if not len(lines):
        chatWin.noutrefresh()
        return
    for idx, line in enumerate(
            lines[gc.ui.channel_log_offset:gc.ui.channel_log_offset +
                  chatWin_height]):
        try:
            if line.isFirst:
                ts_str = ""
                if gc.settings["timestamps_enabled"]:
                    ts_now = time.time()
                    ts_offset = datetime.fromtimestamp(ts_now)-\
                            datetime.utcfromtimestamp(ts_now)
                    dt = line.date + ts_offset
                    ts_str = dt.strftime(gc.settings["timestamp_format"]) +\
                            " - "
                author_color = get_role_color(line.topRole, gc)
                chatWin.addstr(idx, 0, "{}{}: ".format(ts_str, line.user),
                               author_color)
                name_offset = chatWin.getyx()[1]
            elif name_offset == 0:
                # if line is at the top and it's not a "user" line
                for subline in reversed(lines[0:gc.ui.channel_log_offset]):
                    if subline.isFirst:
                        name_offset = len(subline.user) + 2
                        break
            chatWin.move(idx, name_offset)
            for idy, word in enumerate(line.words):
                color = 0
                if "@" + gc.client.current_guild.me.display_name in word.content:
                    color = gc.ui.colors[gc.settings["mention_color"]]
                if not word.content:
                    continue
                try:
                    # if the next word attrs are the same
                    if idy < len(line.words) - 1 and word.attrs == line.words[
                            idy + 1].attrs:
                        chatWin.addstr(word.content + ' ', word.attrs | color)
                    else:
                        chatWin.addstr(word.content, word.attrs | color)
                        chatWin.addstr(' ', curses.A_NORMAL)
                except:
                    log("Text drawing failed at {}".format(word.content))
            chatWin.noutrefresh()
        except Exception as e:
            # if we're here, text has failed to draw
            log("Failed to draw channel log. Error: {}".format(e))
Esempio n. 21
0
 def run(self):
     log("Starting {} thread".format(self.func.__name__))
     try:
         self.func()
     except Exception as e:
         log("Error in {}: {}".format(self.func.__name__, e))
Esempio n. 22
0
def draw_left_win():
    leftWin = gc.ui.leftWin
    left_win_height, left_win_width = leftWin.getmaxyx()

    if gc.ui.separatorsVisible:
        length = 0
        length = gc.term.height - gc.settings["margin"]

    # Create a new list so we can preserve the guild's channel order
    channel_logs = []

    for servlog in gc.guild_log_tree:
        if servlog.guild is gc.client.current_guild:
            for chanlog in servlog.logs:
                channel_logs.append(chanlog)
            break

    channel_logs = quick_sort_channel_logs(channel_logs)

    leftWin.erase()

    # TODO: Incorperate guilds into list
    for idx, clog in enumerate(channel_logs):
        # should the guild have *too many channels!*, stop them
        # from spilling over the screen
        try:
            if idx == left_win_height - 1:
                leftWin.addstr(idx, 0, "(more)", gc.ui.colors["green"])
                break

            # don't print categories or voice chats
            # TODO: this will break on private messages
            if isinstance(clog.channel, VoiceChannel) or \
                    isinstance(clog.channel, CategoryChannel):
                continue
            text = clog.name
            length = len(text)

            offset = 0
            if gc.settings["number_channels"]:
                offset = 3
                if idx >= 9:
                    offset = 4

            if length > left_win_width - offset:
                if gc.settings["truncate_channels"]:
                    text = text[0:left_win_width - offset]
                else:
                    text = text[0:left_win_width - 3 - offset] + "..."

            leftWin.move(idx, 0)
            if gc.settings["number_channels"]:
                leftWin.addstr(str(idx + 1) + ". ")
            if clog.channel is gc.client.current_channel:
                leftWin.addstr(
                    text, gc.ui.colors[gc.settings["current_channel_color"]])
            else:
                if clog.channel is not channel_logs[0]:
                    pass

                if clog.unread and gc.settings["blink_unreads"]:
                    color = gc.settings["unread_channel_color"]
                    if "blink_" in color:
                        split = color.split("blink_")[1]
                        color = gc.ui.colors[split] | curses.A_BLINK
                    elif "on_" in color:
                        color = gc.ui.colors[color.split("on_")[1]]
                    leftWin.addstr(text, color)
                elif clog.mentioned_in and gc.settings["blink_mentions"]:
                    color = gc.settings["unread_mention_color"]
                    if "blink_" in color:
                        color = gc.ui.colors[color.split("blink_")[1]]
                    leftWin.addstr(text, color)
                else:
                    leftWin.addstr(text)
        except Exception as e:
            # if we're here, text has failed to draw
            log("Failed to draw left window. Error: {}".format(e))

    leftWin.noutrefresh()
Esempio n. 23
0
 async def on_error(self, event_method, *args, **kwargs):
     import traceback
     log('Ignoring exception in {}'.format(event_method))
     traceback.print_exc()