Example #1
0
    def get(self):
        val = self.initController("MessageController.get()", [])
        if not val:
            logging.debug("InitController returned false")
            return self.response

        (cont, serverMessage) = getAndroidServerMessage(self.data)
        if not cont:
            self.response.out.write(
                json.dumps({'servermessage': serverMessage}))
            return self.response

        if "timestamp" not in self.data:
            self.data["timestamp"] = 0

        messageHandler = MessageHandler()
        messages = messageHandler.getMessages(self.data["timestamp"],
                                              self.irssiUser)
        messageJsons = []
        for message in messages:
            messageJsons.append(message.ToJson())
        responseJson = json.dumps({
            "servermessage": serverMessage,
            "messages": messageJsons
        })

        self.response.headers['Content-Type'] = 'application/json'
        self.response.out.write(responseJson)
Example #2
0
def runCmd(action):
    if action == 'notify':
        worker = MessageHandler()
        worker.notifySubs()
    elif action == 'update':
        PowerAlert().crawlPage()
    return 'OK'
Example #3
0
    def post(self):
        val = self.initController("MessageController.post()", ["message", "channel", "nick", "version"])
        if not val:
            logging.debug("InitController returned false")
            return self.response

        (cont, serverMessage) = getIrssiServerMessage(self.data)
        if not cont:
            self.response.out.write(serverMessage)
            return self.response

        messageHandler = MessageHandler()
        ok = messageHandler.handle(self.irssiUser, self.data)

        if not ok:
            self.response.status = '400 Bad Request'
            return False
        self.response.out.write(serverMessage)
Example #4
0
def parse_comand(text, data, bot_id, web_client, channel_id):
    message_handler = MessageHandler(data['channel'])
    user = data['user']

    if ("hello" in text) and (f'@{bot_id.lower()}' in text):
        web_client.chat_postMessage(**message_handler.get_message_hello(user))

    if ("do" in text) and (f'@{bot_id.lower()}' in text):
        print("I found file")
        file_shared(data, web_client, message_handler, channel_id)

    if ("help" in text) and (f'@{bot_id.lower()}' in text):
        web_client.chat_postMessage(**message_handler.get_help_message(user))

    if ("help" not in text) and ("do" not in text) and (
            "hello" not in text):  # изменить на свитч кейс
        web_client.chat_postMessage(
            **message_handler.get_no_such_command_message())
Example #5
0
    def post(self):
        val = self.initController("MessageController.post()",
                                  ["message", "channel", "nick", "version"])
        if not val:
            logging.debug("InitController returned false")
            return self.response

        (cont, serverMessage) = getIrssiServerMessage(self.data)
        if not cont:
            self.response.out.write(serverMessage)
            return self.response

        messageHandler = MessageHandler()
        ok = messageHandler.handle(self.irssiUser, self.data)

        if not ok:
            self.response.status = '400 Bad Request'
            return False
        self.response.out.write(serverMessage)
Example #6
0
    def __init__(self):
        super(Main, self).__init__()

        self.parse_args()

        logger.log_event("Download started.")

        self.pipeline = VideoTorrentPlayer(self.torrent_path,
                                           self.use_fake_sink, self.save_path,
                                           self.algorithm, self.stream_length,
                                           self.buffer_size)

        self.message_handler = MessageHandler(self, self.pipeline)
Example #7
0
 def __init__(self, connection, identity, debug=False):
     Thread.__init__(self)
     self.setDaemon(True)
     self.end_point = connection.get('endpoint', None)
     self.channels = connection.get('channels', ()) 
     self.plugins = connection.get('plugins', [])
     self.chatters = {}
     self.msg_handler = MessageHandler(self)
     self.identity = identity
     self.active = False
     self.plugins_loaded = False
     self.updating_chatters = False
     self.debug = debug                
Example #8
0
    def __init__(self, applet):
        self.applet = applet

        applet.tooltip.disable_toggle_on_click()

        self.backend = None
        for b in backends:
            if b.backend_useable():
                self.backend = b()
                break

        self.setup_context_menu()

        if self.backend is not None:
            self.__message_handler = MessageHandler(self)

            applet.timing.register(self.check_status_cb, check_status_interval)
            self.check_status_cb()
        else:
            self.set_battery_missing()

        applet.connect_size_changed(self.size_changed_cb)
Example #9
0
    def get(self):
        val = self.initController("MessageController.get()", [])
        if not val:
            logging.debug("InitController returned false")
            return self.response

        (cont, serverMessage) = getAndroidServerMessage(self.data)
        if not cont:
            self.response.out.write(json.dumps({ 'servermessage': serverMessage }))
            return self.response

        if "timestamp" not in self.data:
            self.data["timestamp"] = 0

        messageHandler = MessageHandler()
        messages = messageHandler.getMessages(self.data["timestamp"], self.irssiUser)
        messageJsons = []
        for message in messages:
            messageJsons.append(message.ToJson())
        responseJson = json.dumps({"servermessage": serverMessage, "messages": messageJsons})

        self.response.headers['Content-Type'] = 'application/json'
        self.response.out.write(responseJson)
Example #10
0
    def __init__(self, applet):
        self.applet = applet

        applet.tooltip.disable_toggle_on_click()

        self.backend = None
        for b in backends:
            if b.backend_useable():
                self.backend = b()
                break

        self.setup_context_menu()

        if self.backend is not None:
            self.__message_handler = MessageHandler(self)

            applet.timing.register(self.check_status_cb, check_status_interval)
            self.check_status_cb()
        else:
            self.set_battery_missing()

        applet.connect_size_changed(self.size_changed_cb)
Example #11
0
def on_adiing_user(**payload):
    data = payload['data']
    web_client = payload['web_client']
    message_handler = MessageHandler(data['channel'])
    web_client.chat_postMessage(
        **message_handler.get_help_message(data['user']))
Example #12
0
class ModRef:
    ''' helper class to store references to the global modules
	'''
    def __init__(self):
        self.server = None
        self.message_handler = None


def _(s):
    return s


logger = schnipsllogger.getLogger(__name__)

DirectoryMapper(
    os.path.abspath(os.path.dirname(__file__)), {
        'backup': 'volumes/backup',
        'runtime': 'volumes/runtime',
        'tmpfs': 'volumes/tmpfs',
        'videos': 'volumes/videos',
    })
modref = ModRef()  # create object to store all module instances
modref.message_handler = MessageHandler(modref)
modref.server = Webserver(modref)
plugin_manager = PluginManager(modref, 'plugins')

modref.server.run()

while (True):
    time.sleep(1)
Example #13
0
class BatteryStatusApplet:

    """An applet which displays battery information.

    """

    # State of the icon (a tuple containing the icon path and size)
    __previous_state = None

    def __init__(self, applet):
        self.applet = applet

        applet.tooltip.disable_toggle_on_click()

        self.backend = None
        for b in backends:
            if b.backend_useable():
                self.backend = b()
                break

        self.setup_context_menu()

        if self.backend is not None:
            self.__message_handler = MessageHandler(self)

            applet.timing.register(self.check_status_cb, check_status_interval)
            self.check_status_cb()
        else:
            self.set_battery_missing()

        applet.connect_size_changed(self.size_changed_cb)

    def size_changed_cb(self):
        if self.backend is not None:
            self.check_status_cb()
        else:
            self.set_battery_missing()

    def set_battery_missing(self):
        self.applet.tooltip.set(_("No batteries"))

        icon = os.path.join(themes_dir, self.applet.settings["theme"], "battery-missing.svg")
        self.applet.icon.file(icon, size=awnlib.Icon.APPLET_SIZE)

    def setup_context_menu(self):
        prefs = gtk.Builder()
        prefs.add_from_file(ui_file)
        prefs.get_object("vbox-preferences").reparent(self.applet.dialog.new("preferences").vbox)

        """ Battery """
        if self.backend is not None:
            batteries = self.backend.get_batteries()

            self.combobox_battery = prefs.get_object("combobox-battery")
            awnlib.add_cell_renderer_text(self.combobox_battery)
            for model in batteries.values():
                self.combobox_battery.append_text(model)

            if self.applet.settings["battery-udi"] not in batteries:
                self.applet.settings["battery-udi"] = batteries.keys()[0]

            if len(self.applet.settings["low-level-unit"]) == 0:
                self.applet.settings["low-level-unit"] = _("Percent")

            battery_getter = lambda key_value: batteries[key_value]
            battery_setter = lambda widget_value: batteries.keys()[batteries.values().index(widget_value)]
        else:
            frame = prefs.get_object("frame-battery")
            frame.hide_all()
            frame.set_no_show_all(True)

            battery_getter = lambda v: v
            battery_setter = lambda v: v

        """ Display """
        # Only use themes that are likely to provide all the files
        self.themes = os.listdir(themes_dir)
        self.themes.sort()

        combobox_theme = prefs.get_object("combobox-theme")
        awnlib.add_cell_renderer_text(combobox_theme)
        for i in self.themes:
            combobox_theme.append_text(i)

        self.theme = self.applet.settings["theme"]
        if self.theme not in self.themes:
            self.applet.settings["theme"] = self.theme = default_theme

        """ Notifications """
        if self.backend is not None:
            self.hbox_low_level = prefs.get_object("hbox-low-level")
            self.hbox_low_level.set_sensitive(self.applet.settings["warn-low-level"])

            self.hbox_high_level = prefs.get_object("hbox-high-level")
            self.hbox_high_level.set_sensitive(self.applet.settings["notify-high-level"])
        else:
            frame = prefs.get_object("frame-notifications")
            frame.hide_all()
            frame.set_no_show_all(True)

        refresh_message = lambda v: self.__message_handler.evaluate()

        binder = self.applet.settings.get_binder(prefs)
        binder.bind("theme", "combobox-theme", key_callback=self.combobox_theme_changed_cb)
        binder.bind("battery-udi", "combobox-battery", getter_transform=battery_getter, setter_transform=battery_setter, key_callback=self.combobox_battery_changed_cb)
        binder.bind("warn-low-level", "checkbutton-warn-low-level", key_callback=self.toggled_warn_low_level_cb)
        binder.bind("notify-high-level", "checkbutton-notify-high-level", key_callback=self.toggled_notify_high_level_cb)
        binder.bind("level-warn-low", "spinbutton-low-level", key_callback=refresh_message)
        binder.bind("level-notify-high", "spinbutton-high-level", key_callback=refresh_message)
        binder.bind("low-level-unit", "combobox-low-level", key_callback=self.combobox_low_level_unit_changed_cb)
        self.applet.settings.load_bindings(binder)

    def toggled_warn_low_level_cb(self, active):
        self.hbox_low_level.set_sensitive(active)

        self.__message_handler.evaluate()

    def toggled_notify_high_level_cb(self, active):
        self.hbox_high_level.set_sensitive(active)

        self.__message_handler.evaluate()

    def combobox_low_level_unit_changed_cb(self, value):
        self.__message_handler.evaluate()

    def combobox_battery_changed_cb(self, udi):
        batteries = self.backend.get_batteries()

        try:
            self.backend.set_active_udi(udi)

            self.check_status_cb()
        except ValueError:
            pass
            # TODO restore combobox
#            udi = self.backend.get_active_udi()
#            self.combobox_battery.set_active(batteries.values().index(batteries[udi]))

    def combobox_theme_changed_cb(self, value):
        if self.backend is not None:
            self.check_status_cb()
        else:
            self.set_battery_missing()

    def check_status_cb(self):
        if not self.backend.is_present():
            self.set_battery_missing()
            return

        charge_percentage = self.backend.get_capacity_percentage()
        power_type = _("AC") if self.backend.is_on_ac_power() else _("battery")
        charge_message = _("Computer running on %s power") % power_type

        if self.backend.is_charged():
            charge_message += "\n" + _("Battery charged")
            icon = os.path.join(themes_dir, self.applet.settings["theme"], "battery-charged.svg")
        else:
            is_charging = self.backend.is_charging()

            if is_charging:
                actoggle = "charging"
                time = self.backend.get_charge_time()
                title_message_suffix = _("until charged")
            else:
                actoggle = "discharging"
                time = self.backend.get_remaining_time()
                title_message_suffix = _("remaining")

            # May be None because charge rate is not always known (when switching between charging and discharging)
            if time is not None:
                charge_message += "\n" + self.format_time(time, suffix=title_message_suffix)

            level = [key for key, value in charge_ranges.iteritems() if charge_percentage <= value[0] and charge_percentage >= value[1]][0]
            icon = os.path.join(themes_dir, self.applet.settings["theme"], "battery-" + actoggle + "-" + level + ".svg")

        self.applet.tooltip.set(" ".join([charge_message, "(" + str(charge_percentage) + "%)"]))

        self.draw_icon(icon)
        self.__message_handler.evaluate()

    def draw_icon(self, icon):
        new_state = (icon, self.applet.get_size())
        if self.__previous_state == new_state:
            return

        self.__previous_state = new_state

        self.applet.icon.file(icon, size=awnlib.Icon.APPLET_SIZE)

    def is_battery_low(self):
        if not self.backend.is_discharging():
            return False

        unit = self.applet.settings["low-level-unit"]

        if unit == _("Percent") and self.backend.get_capacity_percentage() <= self.applet.settings["level-warn-low"]:
            return True

        time = self.backend.get_remaining_time()

        if time is None:
            return None

        hours, minutes = time
        return unit == _("Time Remaining") and hours == 0 and minutes <= self.applet.settings["level-warn-low"]

    def is_battery_high(self):
        if self.backend.is_discharging():
            return False

        return self.backend.get_capacity_percentage() >= self.applet.settings["level-notify-high"]

    def format_time(self, time, suffix=""):
        hours, minutes = time

        message = []
        time = []

        if hours > 0:
            if hours > 1:
                message.append(_("%d hours"))
            else:
                message.append(_("%d hour"))
            time.append(hours)
        if minutes > 0:
            if minutes > 1:
                message.append(_("%d minutes"))
            else:
                message.append(_("%d minute"))
            time.append(minutes)

        message = " ".join(message) % tuple(time)
        return " ".join([message, suffix]).strip() if len(message) > 0 else ""
Example #14
0
class BatteryStatusApplet:
    """An applet which displays battery information.

    """

    # State of the icon (a tuple containing the icon path and size)
    __previous_state = None

    def __init__(self, applet):
        self.applet = applet

        applet.tooltip.disable_toggle_on_click()

        self.backend = None
        for b in backends:
            if b.backend_useable():
                self.backend = b()
                break

        self.setup_context_menu()

        if self.backend is not None:
            self.__message_handler = MessageHandler(self)

            applet.timing.register(self.check_status_cb, check_status_interval)
            self.check_status_cb()
        else:
            self.set_battery_missing()

        applet.connect_size_changed(self.size_changed_cb)

    def size_changed_cb(self):
        if self.backend is not None:
            self.check_status_cb()
        else:
            self.set_battery_missing()

    def set_battery_missing(self):
        self.applet.tooltip.set(_("No batteries"))

        icon = os.path.join(themes_dir, self.applet.settings["theme"],
                            "battery-missing.svg")
        self.applet.icon.file(icon, size=awnlib.Icon.APPLET_SIZE)

    def setup_context_menu(self):
        prefs = gtk.Builder()
        prefs.add_from_file(ui_file)
        prefs.get_object("vbox-preferences").reparent(
            self.applet.dialog.new("preferences").vbox)
        """ Battery """
        if self.backend is not None:
            batteries = self.backend.get_batteries()

            self.combobox_battery = prefs.get_object("combobox-battery")
            awnlib.add_cell_renderer_text(self.combobox_battery)
            for model in batteries.values():
                self.combobox_battery.append_text(model)

            if self.applet.settings["battery-udi"] not in batteries:
                self.applet.settings["battery-udi"] = batteries.keys()[0]

            if len(self.applet.settings["low-level-unit"]) == 0:
                self.applet.settings["low-level-unit"] = _("Percent")

            battery_getter = lambda key_value: batteries[key_value]
            battery_setter = lambda widget_value: batteries.keys()[
                batteries.values().index(widget_value)]
        else:
            frame = prefs.get_object("frame-battery")
            frame.hide_all()
            frame.set_no_show_all(True)

            battery_getter = lambda v: v
            battery_setter = lambda v: v
        """ Display """
        # Only use themes that are likely to provide all the files
        self.themes = os.listdir(themes_dir)
        self.themes.sort()

        combobox_theme = prefs.get_object("combobox-theme")
        awnlib.add_cell_renderer_text(combobox_theme)
        for i in self.themes:
            combobox_theme.append_text(i)

        self.theme = self.applet.settings["theme"]
        if self.theme not in self.themes:
            self.applet.settings["theme"] = self.theme = default_theme
        """ Notifications """
        if self.backend is not None:
            self.hbox_low_level = prefs.get_object("hbox-low-level")
            self.hbox_low_level.set_sensitive(
                self.applet.settings["warn-low-level"])

            self.hbox_high_level = prefs.get_object("hbox-high-level")
            self.hbox_high_level.set_sensitive(
                self.applet.settings["notify-high-level"])
        else:
            frame = prefs.get_object("frame-notifications")
            frame.hide_all()
            frame.set_no_show_all(True)

        refresh_message = lambda v: self.__message_handler.evaluate()

        binder = self.applet.settings.get_binder(prefs)
        binder.bind("theme",
                    "combobox-theme",
                    key_callback=self.combobox_theme_changed_cb)
        binder.bind("battery-udi",
                    "combobox-battery",
                    getter_transform=battery_getter,
                    setter_transform=battery_setter,
                    key_callback=self.combobox_battery_changed_cb)
        binder.bind("warn-low-level",
                    "checkbutton-warn-low-level",
                    key_callback=self.toggled_warn_low_level_cb)
        binder.bind("notify-high-level",
                    "checkbutton-notify-high-level",
                    key_callback=self.toggled_notify_high_level_cb)
        binder.bind("level-warn-low",
                    "spinbutton-low-level",
                    key_callback=refresh_message)
        binder.bind("level-notify-high",
                    "spinbutton-high-level",
                    key_callback=refresh_message)
        binder.bind("low-level-unit",
                    "combobox-low-level",
                    key_callback=self.combobox_low_level_unit_changed_cb)
        self.applet.settings.load_bindings(binder)

    def toggled_warn_low_level_cb(self, active):
        self.hbox_low_level.set_sensitive(active)

        self.__message_handler.evaluate()

    def toggled_notify_high_level_cb(self, active):
        self.hbox_high_level.set_sensitive(active)

        self.__message_handler.evaluate()

    def combobox_low_level_unit_changed_cb(self, value):
        self.__message_handler.evaluate()

    def combobox_battery_changed_cb(self, udi):
        batteries = self.backend.get_batteries()

        try:
            self.backend.set_active_udi(udi)

            self.check_status_cb()
        except ValueError:
            pass
            # TODO restore combobox


#            udi = self.backend.get_active_udi()
#            self.combobox_battery.set_active(batteries.values().index(batteries[udi]))

    def combobox_theme_changed_cb(self, value):
        if self.backend is not None:
            self.check_status_cb()
        else:
            self.set_battery_missing()

    def check_status_cb(self):
        if not self.backend.is_present():
            self.set_battery_missing()
            return

        charge_percentage = self.backend.get_capacity_percentage()
        power_type = _("AC") if self.backend.is_on_ac_power() else _("battery")
        charge_message = _("Computer running on %s power") % power_type

        if self.backend.is_charged():
            charge_message += "\n" + _("Battery charged")
            icon = os.path.join(themes_dir, self.applet.settings["theme"],
                                "battery-charged.svg")
        else:
            is_charging = self.backend.is_charging()

            if is_charging:
                actoggle = "charging"
                time = self.backend.get_charge_time()
                title_message_suffix = _("until charged")
            else:
                actoggle = "discharging"
                time = self.backend.get_remaining_time()
                title_message_suffix = _("remaining")

            # May be None because charge rate is not always known (when switching between charging and discharging)
            if time is not None:
                charge_message += "\n" + self.format_time(
                    time, suffix=title_message_suffix)

            level = [
                key for key, value in charge_ranges.iteritems() if
                charge_percentage <= value[0] and charge_percentage >= value[1]
            ][0]
            icon = os.path.join(themes_dir, self.applet.settings["theme"],
                                "battery-" + actoggle + "-" + level + ".svg")

        self.applet.tooltip.set(" ".join(
            [charge_message, "(" + str(charge_percentage) + "%)"]))

        self.draw_icon(icon)
        self.__message_handler.evaluate()

    def draw_icon(self, icon):
        new_state = (icon, self.applet.get_size())
        if self.__previous_state == new_state:
            return

        self.__previous_state = new_state

        self.applet.icon.file(icon, size=awnlib.Icon.APPLET_SIZE)

    def is_battery_low(self):
        if not self.backend.is_discharging():
            return False

        unit = self.applet.settings["low-level-unit"]

        if unit == _("Percent") and self.backend.get_capacity_percentage(
        ) <= self.applet.settings["level-warn-low"]:
            return True

        time = self.backend.get_remaining_time()

        if time is None:
            return None

        hours, minutes = time
        return unit == _(
            "Time Remaining"
        ) and hours == 0 and minutes <= self.applet.settings["level-warn-low"]

    def is_battery_high(self):
        if self.backend.is_discharging():
            return False

        return self.backend.get_capacity_percentage(
        ) >= self.applet.settings["level-notify-high"]

    def format_time(self, time, suffix=""):
        hours, minutes = time

        message = []
        time = []

        if hours > 0:
            if hours > 1:
                message.append(_("%d hours"))
            else:
                message.append(_("%d hour"))
            time.append(hours)
        if minutes > 0:
            if minutes > 1:
                message.append(_("%d minutes"))
            else:
                message.append(_("%d minute"))
            time.append(minutes)

        message = " ".join(message) % tuple(time)
        return " ".join([message, suffix]).strip() if len(message) > 0 else ""
Example #15
0
	def delegate(self, msg):
		log.info('starting new process')
		handler = MessageHandler(msg=msg)
		self.workers.append(handler)
		handler.start()
Example #16
0
def handleRequest():
    msg = request.json['message']
    worker = MessageHandler()
    worker.routeMessage(msg)
    return 'OK'
Example #17
0
class IRCConnection(Thread):
    def __init__(self, connection, identity, debug=False):
        Thread.__init__(self)
        self.setDaemon(True)
        self.end_point = connection.get('endpoint', None)
        self.channels = connection.get('channels', ()) 
        self.plugins = connection.get('plugins', [])
        self.chatters = {}
        self.msg_handler = MessageHandler(self)
        self.identity = identity
        self.active = False
        self.plugins_loaded = False
        self.updating_chatters = False
        self.debug = debug                
    
    def init_plugins(self):
        for plugin in self.plugins:
            # plugin is a (module, config) -tuple
            self.msg_handler.register_plugin(plugin[0].create_plugin(self, plugin[1]))

    def get_nick(self):
        return self.identity.nick
                   
    def make_connection(self):
        if not self.end_point:
            logging.warn('Endpoint does not exists')
            return False
        
        connection_ok = False
            
        if self.debug:
            logging.info("making connection in debug mode")
            return
        
        self.msg_handler.prepare_handler()
        self.active = True

        while not connection_ok:
            logging.warn("Connecting to %s:%s" % (self.end_point[0], self.end_point[1]))
            self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.socket.settimeout(1)
            try:
                self.socket.connect((self.end_point[0], self.end_point[1]))
                connection_ok = True
                break
            except socket.gaierror:
                continue
            except socket.timeout:
                continue
            except:
                logging.info("Connection refused, waiting a couple seconds before reconnecting")
                time.sleep(30)
                continue
    
        self.input = self.socket.makefile('rb', 0)
        self.output = self.socket.makefile('wb', 0)
        
        self.output.write('NICK %s \n' % self.identity.nick)
        self.output.write('USER %s 0 0 : %s \n' % (self.identity.nick, self.identity.realname))

        if self.plugins_loaded == False:
            self.init_plugins()
            self.plugins_loaded = True
        
        for channel in self.channels:
           self.chatters[channel] = set([])
           self.output.write('JOIN %s \n' % channel)
        
        self.active = True
        

    def run(self):
        while self.active:
            to_read, ignore, ignore = select.select([self.input], [], [], 360)
            if len(to_read) == 0:
                self.active = False
                self.make_connection()
            else:
                for input in to_read:
                    input_text = self.input.readline()
                    if input_text:
                        self.msg_handler.message(input_text)
                    else:
                        logging.warn("Connection lost to %s" % self.end_point[0])
                        self.active = False
                        self.make_connection()


    def update_messagehandler(self, plugins):
        self.msg_handler.unregister_plugins()
        for plugin in plugins:
            self.msg_handler.register_plugin(plugin)


    def send_to(self, output_text, channel=""):
        if self.debug:
            logging.warn("Pushing message to pipe: %s" % output_text)
        
        self.msg_handler.process_output(output_text, channel)
        self.output.write(output_text)

    def update_chatters(self, channel, nicklist):
        if not self.updating_chatters:
            self.chatters[channel] = set(nicklist)
        else:
            self.chatters[channel].add(nicklist)
        self.updating_chatters = True

    def update_chatters_ready(self):
        self.updating_chatters = False

    def change_chatter(self, nick, newnick):
        for chan in self.chatters.keys():
            if nick in self.chatters[chan]:
                self.chatters[chan].remove(nick)
                self.chatters[chan].add(newnick)

    def add_chatter(self, channel, nick):
        self.chatters[channel].add(nick)

    def remove_chatter(self, channel, nick):
        if nick in self.chatters[channel]:
            self.chatters[channel].remove(nick)

    def fully_remove_chatter(self, nick):
        for channel in self.chatters.keys():
            self.chatters[channel].discard(nick)