summaryrefslogtreecommitdiff
path: root/src/room.py
blob: 674e2d65baa4ecc188d969c73a40b60d9893ae46 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# Copyright 2010-2011 Florent Le Coz <louiz@louiz.org>
#
# This file is part of Poezio.
#
# Poezio is free software: you can redistribute it and/or modify
# it under the terms of the zlib license. See the COPYING file.

from text_buffer import TextBuffer, Message
from datetime import datetime
from random import randrange
from config import config
from logger import logger

import common
import theme

import logging
import curses

log = logging.getLogger(__name__)

class Room(TextBuffer):
    def __init__(self, name, nick, messages_nb_limit=config.get('max_messages_in_memory', 2048)):
        TextBuffer.__init__(self, messages_nb_limit)
        self.name = name
        self.own_nick = nick
        self.color_state = theme.COLOR_TAB_NORMAL   # color used in RoomInfo
        self.joined = False     # false until self presence is receied
        self.users = []         # User objects
        self.topic = ''

    def disconnect(self):
        """
        Set the state of the room as not joined, so
        we can know if we can join it, send messages to it, etc
        """
        self.users = []
        self.joined = False

    def get_single_line_topic(self):
        """
        Return the topic as a single-line string (for the window header)
        """
        return self.topic.replace('\n', '|')

    def log_message(self, txt, time, nickname):
        """
        Log the messages in the archives, if it needs
        to be
        """
        if time is None and self.joined:        # don't log the history messages
            logger.log_message(self.name, nickname, txt)

    def do_highlight(self, txt, time, nickname):
        """
        Set the tab color and returns the nick color
        """
        color = None
        if not time and nickname and nickname != self.own_nick and self.joined:
            if self.own_nick.lower() in txt.lower():
                if self.color_state != theme.COLOR_TAB_CURRENT:
                    self.set_color_state(theme.COLOR_TAB_HIGHLIGHT)
                color = theme.COLOR_HIGHLIGHT_NICK
            else:
                highlight_words = config.get('highlight_on', '').split(':')
                for word in highlight_words:
                    if word and word.lower() in txt.lower():
                        if self.color_state != theme.COLOR_TAB_CURRENT:
                            self.set_color_state(theme.COLOR_TAB_HIGHLIGHT)
                        color = theme.COLOR_HIGHLIGHT_NICK
                        break
        if color:
            beep_on = config.get('beep_on', 'highlight private').split()
            if 'highlight' in beep_on and 'message' not in beep_on:
                curses.beep()
        return color

    def get_user_by_name(self, nick):
        """
        Gets the user associated with the given nick, or None if not found
        """
        for user in self.users:
            if user.nick == nick:
                return user
        return None

    def set_color_state(self, color):
        """
        Set the color that will be used to display the room's
        number in the RoomInfo window
        """
        self.color_state = color

    def add_message(self, txt, time=None, nickname=None, forced_user=None, nick_color=None, history=None):
        """
        Note that user can be None even if nickname is not None. It happens
        when we receive an history message said by someone who is not
        in the room anymore
        """
        self.log_message(txt, time, nickname)
        if txt.startswith('/me '):
            txt = "\x192* \x195" + nickname + ' ' + txt[4:]
            nickname = None
        user = self.get_user_by_name(nickname) if nickname is not None else None
        if user:
            user.set_last_talked(datetime.now())
        if not user and forced_user:
            user = forced_user
        if not time and nickname and\
                nickname != self.own_nick and\
                self.color_state != theme.COLOR_TAB_CURRENT:
            if self.color_state != theme.COLOR_TAB_HIGHLIGHT:
                self.set_color_state(theme.COLOR_TAB_NEW_MESSAGE)
        nick_color = nick_color or None
        if not nickname or time:
            txt = '\x195%s' % (txt,)
        else:                   # TODO
            highlight = self.do_highlight(txt, time, nickname)
            if highlight:
                nick_color = highlight
        time = time or datetime.now()
        message = Message(txt='%s\x19o'%(txt,), nick_color=nick_color,
                          time=time, str_time=time.strftime("%Y-%m-%d %H:%M:%S")\
                                          if history else time.strftime("%H:%M:%S"),\
                          nickname=nickname, user=user)
        while len(self.messages) > self.messages_nb_limit:
            self.messages.pop(0)
        self.messages.append(message)
        for window in self.windows: # make the associated windows
            # build the lines from the new message
            nb = window.build_new_message(message, history=history)
            if window.pos != 0:
                window.scroll_up(nb)
        return nb