예제 #1
0
def ownNotice_cb(time, server, target, message):
    """
		if query channel with ``target`` exists, print
		the notice there, else print it on the current
		channel of the network which is identified by
		`server`
	"""
    server_tab, tab = gui.tabs.search_tabs(server, target)
    ownNickColor = color.get_color_by_key("own_nick")
    ownNick = server_tab.nick

    if tab:
        tab.write(
            time,
            "&gt;<font foreground='%s' weight='bold'>%s</font>&lt; "
            "<font foreground='%s'>%s</font>"
            % (
                color.get_nick_color(target),
                markup.escape(target),
                color.get_text_color(target),
                markup.escape(message),
            ),
        )
    else:
        server_tab.current_write(
            time,
            "&gt;<font foreground='%s' weight='bold'>%s</font>&lt; "
            "<font foreground='%s'>%s</font>"
            % (
                color.get_nick_color(target),
                markup.escape(target),
                color.get_text_color(target),
                markup.escape(message),
            ),
        )
예제 #2
0
def queryNotice_cb(time, server, from_str, message):
    """
		A user sends a notice directly to the maki user.
	"""
    nick = parse_from(from_str)[0]

    (server_tab, tab) = gui.tabs.search_tabs(server, nick)

    if tab:
        if tab.name != nick:
            # correct notation of tab name
            tab.name = nick

    if tab:
        tab.write(
            time,
            "-<font foreground='%s' weight='bold'>%s</font>- "
            "<font foreground='%s'>%s</font>"
            % (color.get_nick_color(nick), markup.escape(nick), color.get_text_color(nick), markup.escape(message)),
        )
    else:
        server_tab.current_write(
            time,
            "-<font foreground='%s' weight='bold'>%s</font>- "
            "<font foreground='%s'>%s</font>"
            % (color.get_nick_color(nick), markup.escape(nick), color.get_text_color(nick), markup.escape(message)),
        )
예제 #3
0
def queryNotice_cb(time, server, from_str, message):
    """
		A user sends a notice directly to the maki user.
	"""
    nick = parse_from(from_str)[0]

    (server_tab, tab) = gui.tabs.search_tabs(server, nick)

    if tab:
        if tab.name != nick:
            # correct notation of tab name
            tab.name = nick

    if tab:
        tab.write(
            time, "-<font foreground='%s' weight='bold'>%s</font>- "
            "<font foreground='%s'>%s</font>" %
            (color.get_nick_color(nick), markup.escape(nick),
             color.get_text_color(nick), markup.escape(message)))
    else:
        server_tab.current_write(
            time, "-<font foreground='%s' weight='bold'>%s</font>- "
            "<font foreground='%s'>%s</font>" %
            (color.get_nick_color(nick), markup.escape(nick),
             color.get_text_color(nick), markup.escape(message)))
예제 #4
0
def userAction_cb(time, server, from_str, channel, action):
    """ normal action """

    nick = parse_from(from_str)[0]
    (server_tab, channel_tab) = gui.tabs.search_tabs(server, channel)

    if nick.lower() == server_tab.nick.lower():
        ownAction_cb(time, server, channel, action)
        return

    elif channel.lower() == server_tab.nick.lower():
        actionQuery_cb(time, server, from_str, action)
        return

    action = markup.escape(action)

    if isHighlighted(server_tab, action):
        type = gui.tabs.HIGHACTION
        actionString = action
        gui.mgmt.set_urgent(True)

    else:
        type = gui.tabs.ACTION
        actionString = "<font foreground='%s'>%s</font>" % (color.get_text_color(nick), action)

    channel_tab.write(
        time,
        "<font foreground='%s' weight='bold'>%s</font> %s" % (color.get_nick_color(nick), nick, actionString),
        type,
        group_string=nick,
    )
예제 #5
0
def userNotice_cb(time, server, from_str, target, message):
    """ An incoming notice """
    nick = parse_from(from_str)[0]
    (server_tab, target_tab) = gui.tabs.search_tabs(server, target)

    if nick.lower() == server_tab.nick.lower():
        # we wrote that notice
        ownNotice_cb(time, server, target, message)
        return

    elif target.lower() == server_tab.nick.lower():
        # it's supposed to be a private (query) message
        queryNotice_cb(time, server, from_str, message)
        return

    message = "-<font foreground='%s' weight='bold'>%s</font>- " "<font foreground='%s'>%s</font>" % (
        color.get_nick_color(nick),
        markup.escape(nick),
        color.get_text_color(nick),
        markup.escape(message),
    )

    if target_tab == None:
        # global notice
        server_tab.current_write(time, message)
    else:
        # channel/query notice
        target_tab.write(time, message)
예제 #6
0
def userNotice_cb(time, server, from_str, target, message):
    """ An incoming notice """
    nick = parse_from(from_str)[0]
    (server_tab, target_tab) = gui.tabs.search_tabs(server, target)

    if nick.lower() == server_tab.nick.lower():
        # we wrote that notice
        ownNotice_cb(time, server, target, message)
        return

    elif target.lower() == server_tab.nick.lower():
        # it's supposed to be a private (query) message
        queryNotice_cb(time, server, from_str, message)
        return

    message = "-<font foreground='%s' weight='bold'>%s</font>- "\
        "<font foreground='%s'>%s</font>" % (
       color.get_nick_color(nick),
       markup.escape(nick),
       color.get_text_color(nick),
       markup.escape(message))

    if target_tab == None:
        # global notice
        server_tab.current_write(time, message)
    else:
        # channel/query notice
        target_tab.write(time, message)
예제 #7
0
def userAction_cb(time, server, from_str, channel, action):
    """ normal action """

    nick = parse_from(from_str)[0]
    (server_tab, channel_tab) = gui.tabs.search_tabs(server, channel)

    if nick.lower() == server_tab.nick.lower():
        ownAction_cb(time, server, channel, action)
        return

    elif channel.lower() == server_tab.nick.lower():
        actionQuery_cb(time, server, from_str, action)
        return

    action = markup.escape(action)

    if isHighlighted(server_tab, action):
        type = gui.tabs.HIGHACTION
        actionString = action
        gui.mgmt.set_urgent(True)

    else:
        type = gui.tabs.ACTION
        actionString = "<font foreground='%s'>%s</font>" % (
            color.get_text_color(nick), action)

    channel_tab.write(time,
                      "<font foreground='%s' weight='bold'>%s</font> %s" %
                      (color.get_nick_color(nick), nick, actionString),
                      type,
                      group_string=nick)
예제 #8
0
def action_nick_color(nick):
    """ return the nick color if color_action_nicks is activated,
		otherwise return the default text color
	"""
    if config.get_bool("colors", "color_action_nicks"):
        return color.get_nick_color(nick)
    return color.get_color_by_key("text_action")
예제 #9
0
def action_nick_color(nick):
    """ return the nick color if color_action_nicks is activated,
		otherwise return the default text color
	"""
    if config.get_bool("colors", "color_action_nicks"):
        return color.get_nick_color(nick)
    return color.get_color_by_key("text_action")
예제 #10
0
def userPart_cb(timestamp, server, from_str, channel, reason):
    """
	A user parted the channel.

	If we are the user who parted, mark the channel
	as parted (joined=False)
	"""
    nick = parse_from(from_str)[0]

    stab, tab = gui.tabs.search_tabs(server, channel)

    if not tab:
        # tab was closed
        return

    channelString = markup.escape(channel)
    reasonString = markup.escape(reason)

    if nick == stab.nick:
        # we parted

        tab.joined = False

        if _show_output_exclusive(stab, tab, "part", own=True):

            if reason:
                message = _(u"« You have left %(channel)s (%(reason)s).")
            else:
                message = _(u"« You have left %(channel)s.")

            tab.write(timestamp, message % {"channel": channelString, "reason": reasonString}, gui.tabs.ACTION)

    else:  # another user parted

        tab.nickList.remove_nick(nick)

        if tab.is_active():
            gui.mgmt.set_user_count(len(tab.nickList), tab.nickList.get_operator_count())

        if _show_output_exclusive(stab, tab, "part", False):

            nickString = "<font foreground='%s' weight='bold'>" "%s</font>" % (
                color.get_nick_color(nick),
                markup.escape(nick),
            )

            if reason:
                message = _(u"« %(nick)s has left %(channel)s " "(%(reason)s).")
            else:
                message = _(u"« %(nick)s has left %(channel)s.")

            tab.write(
                timestamp,
                message % {"nick": nickString, "channel": channelString, "reason": reasonString},
                gui.tabs.ACTION,
            )
예제 #11
0
def userKick_cb(time, server, from_str, channel, who, reason):
    """
		signal emitted if a user got kicked.
		If the kicked user is ourself mark the channel as
		joined=False
	"""
    nick = parse_from(from_str)[0]
    server_tab, tab = gui.tabs.search_tabs(server, channel)

    if not tab:
        logging.debug("userKick: channel '%s' does not exist." % (channel))
        return

    channelString = markup.escape(channel)

    nickString = "<font foreground='%s' weight='bold'>%s</font>" % (
        action_nick_color(nick), markup.escape(nick))

    reasonString = markup.escape(reason)

    if who == server_tab.nick:
        tab.joined = False

        if _show_output_exclusive(server_tab, tab, "kick", own=True):

            message = _(
                u"« You have been kicked from %(channel)s "
                u"by %(nick)s (%(reason)s)." % {
                    "channel": channelString,
                    "nick": nickString,
                    "reason": reasonString
                })

            tab.write(time, message, gui.tabs.HIGHACTION)

    else:
        tab.nickList.remove_nick(who)

        if tab.is_active():
            gui.mgmt.set_user_count(len(tab.nickList),
                                    tab.nickList.get_operator_count())

        if _show_output_exclusive(server_tab, tab, "kick"):

            whoString = "<font foreground='%s' weight='bold'>%s</font>" % (
                color.get_nick_color(who), markup.escape(who))

            message = _(u"« %(who)s was kicked from %(channel)s by "
                        u"%(nick)s (%(reason)s).") % {
                            "who": whoString,
                            "channel": channelString,
                            "nick": nickString,
                            "reason": reasonString
                        }

            tab.write(time, message, gui.tabs.ACTION)
예제 #12
0
def queryCTCP_cb(time, server, from_str, message):
    """
		A user sends us a CTCP request over a query.

		If no query window is open, send it to the server tab.
	"""
    nick = parse_from(from_str)[0]
    (server_tab, tab) = gui.tabs.search_tabs(server, nick)

    if tab:
        tab.write(
            time, "&lt;CTCP:<font foreground='%s' weight='bold'>%s"
            "</font>&gt; <font foreground='%s'>%s</font>" %
            (color.get_nick_color(nick), markup.escape(nick),
             color.get_text_color(nick), markup.escape(message)))
    else:
        server_tab.current_write(
            time, "&lt;CTCP:<font foreground='%s' weight='bold'>%s"
            "</font>&gt; <font foreground='%s'>%s</font>" %
            (color.get_nick_color(nick), markup.escape(nick),
             color.get_text_color(nick), markup.escape(message)))
예제 #13
0
def userKick_cb(time, server, from_str, channel, who, reason):
    """
		signal emitted if a user got kicked.
		If the kicked user is ourself mark the channel as
		joined=False
	"""
    nick = parse_from(from_str)[0]
    server_tab, tab = gui.tabs.search_tabs(server, channel)

    if not tab:
        logging.debug("userKick: channel '%s' does not exist." % (channel))
        return

    channelString = markup.escape(channel)

    nickString = "<font foreground='%s' weight='bold'>%s</font>" % (action_nick_color(nick), markup.escape(nick))

    reasonString = markup.escape(reason)

    if who == server_tab.nick:
        tab.joined = False

        if _show_output_exclusive(server_tab, tab, "kick", own=True):

            message = _(
                u"« You have been kicked from %(channel)s "
                u"by %(nick)s (%(reason)s)." % {"channel": channelString, "nick": nickString, "reason": reasonString}
            )

            tab.write(time, message, gui.tabs.HIGHACTION)

    else:
        tab.nickList.remove_nick(who)

        if tab.is_active():
            gui.mgmt.set_user_count(len(tab.nickList), tab.nickList.get_operator_count())

        if _show_output_exclusive(server_tab, tab, "kick"):

            whoString = "<font foreground='%s' weight='bold'>%s</font>" % (
                color.get_nick_color(who),
                markup.escape(who),
            )

            message = _(u"« %(who)s was kicked from %(channel)s by " u"%(nick)s (%(reason)s).") % {
                "who": whoString,
                "channel": channelString,
                "nick": nickString,
                "reason": reasonString,
            }

            tab.write(time, message, gui.tabs.ACTION)
예제 #14
0
		def names_cb(time, server, channel, nicks, prefixes):

			self = names_cb

			def print_message(message):
				if self.tab.is_active():
					# print in the channel we query
					self.tab.write(time, message, "action")
				elif self.tab.is_server():
					self.tab.current_write(time, message, "action")
				else:
					# print in the current channel
					self.tab.server.current_write(time, message, "action")

			if self.first:
				print_message(_("• Begin of names"))
				self.first = False

			if not nicks: # eol
				signals.disconnect_signal("names", self)
				print_message(_("• End of names"))

			else:
				max_nicklen = max([len(n)+len(p)
					for (p,n) in self.tab.nickList.get_nicks_mode()])

				message = ""
				for i in xrange(len(nicks)):
					nick_color = color.get_nick_color(nicks[i])

					c_start = "<font foreground='%s'>" % (nick_color)
					c_end = "</font>"

					tmp = "[{prefix}{cstart}{nick}{cend}]".format(
						prefix=prefixes[i],
						nick=nicks[i],
						cstart=c_start,
						cend=c_end)

					overhead = len(tmp) - len(nicks[i]) - len(prefixes[i])

					message += "{0:{align}<{fill}}".format(tmp,
									align=" ", fill=max_nicklen + overhead)

					if (i+1) % self.max_col == 0:
						print_message(message)
						message = ""
					else:
						message += " "

				print_message(message)
예제 #15
0
def ownNotice_cb(time, server, target, message):
    """
		if query channel with ``target`` exists, print
		the notice there, else print it on the current
		channel of the network which is identified by
		`server`
	"""
    server_tab, tab = gui.tabs.search_tabs(server, target)
    ownNickColor = color.get_color_by_key("own_nick")
    ownNick = server_tab.nick

    if tab:
        tab.write(
            time, "&gt;<font foreground='%s' weight='bold'>%s</font>&lt; "
            "<font foreground='%s'>%s</font>" %
            (color.get_nick_color(target), markup.escape(target),
             color.get_text_color(target), markup.escape(message)))
    else:
        server_tab.current_write(
            time, "&gt;<font foreground='%s' weight='bold'>%s</font>&lt; "
            "<font foreground='%s'>%s</font>" %
            (color.get_nick_color(target), markup.escape(target),
             color.get_text_color(target), markup.escape(message)))
예제 #16
0
def queryCTCP_cb(time, server, from_str, message):
    """
		A user sends us a CTCP request over a query.

		If no query window is open, send it to the server tab.
	"""
    nick = parse_from(from_str)[0]
    (server_tab, tab) = gui.tabs.search_tabs(server, nick)

    if tab:
        tab.write(
            time,
            "&lt;CTCP:<font foreground='%s' weight='bold'>%s"
            "</font>&gt; <font foreground='%s'>%s</font>"
            % (color.get_nick_color(nick), markup.escape(nick), color.get_text_color(nick), markup.escape(message)),
        )
    else:
        server_tab.current_write(
            time,
            "&lt;CTCP:<font foreground='%s' weight='bold'>%s"
            "</font>&gt; <font foreground='%s'>%s</font>"
            % (color.get_nick_color(nick), markup.escape(nick), color.get_text_color(nick), markup.escape(message)),
        )
예제 #17
0
def userMessage_cb(timestamp, server, from_str, channel, message):
    """
		PRIVMSGs are coming in here.
	"""
    nick = parse_from(from_str)[0]
    (server_tab, channel_tab) = gui.tabs.search_tabs(server, channel)

    if server_tab == None:
        return  # happens if the target server does not exist

    if nick.lower() == server_tab.nick.lower():
        ownMessage_cb(timestamp, server, channel, message)
        return

    elif channel.lower() == server_tab.nick.lower():
        userQuery_cb(timestamp, server, from_str, message)
        return

    message = markup.escape(message)

    if isHighlighted(server_tab, message):
        # set mode to highlight and disable setting
        # of text color for the main message (would
        # override channelPrint() highlight color)

        type = gui.tabs.HIGHMESSAGE
        messageString = message
        gui.mgmt.set_urgent(True)
    else:
        # no highlight, normal message type and
        # text color is allowed.

        type = gui.tabs.MESSAGE
        messageString = "<font foreground='%s'>%s</font>" % (
            color.get_text_color(nick), message)

    channel_tab.write(
        timestamp,
        "&lt;%s<font foreground='%s' weight='bold'>%s</font>&gt; %s" % (
            _getPrefix(server, channel, nick),
            color.get_nick_color(nick),
            markup.escape(nick),
            messageString,
        ),
        type,
        group_string=nick)
예제 #18
0
def userMessage_cb(timestamp, server, from_str, channel, message):
    """
		PRIVMSGs are coming in here.
	"""
    nick = parse_from(from_str)[0]
    (server_tab, channel_tab) = gui.tabs.search_tabs(server, channel)

    if server_tab == None:
        return  # happens if the target server does not exist

    if nick.lower() == server_tab.nick.lower():
        ownMessage_cb(timestamp, server, channel, message)
        return

    elif channel.lower() == server_tab.nick.lower():
        userQuery_cb(timestamp, server, from_str, message)
        return

    message = markup.escape(message)

    if isHighlighted(server_tab, message):
        # set mode to highlight and disable setting
        # of text color for the main message (would
        # override channelPrint() highlight color)

        type = gui.tabs.HIGHMESSAGE
        messageString = message
        gui.mgmt.set_urgent(True)
    else:
        # no highlight, normal message type and
        # text color is allowed.

        type = gui.tabs.MESSAGE
        messageString = "<font foreground='%s'>%s</font>" % (color.get_text_color(nick), message)

    channel_tab.write(
        timestamp,
        "&lt;%s<font foreground='%s' weight='bold'>%s</font>&gt; %s"
        % (_getPrefix(server, channel, nick), color.get_nick_color(nick), markup.escape(nick), messageString),
        type,
        group_string=nick,
    )
예제 #19
0
def userQuery_cb(timestamp, server, from_str, message):
    """
		A user writes to us in a query.
	"""
    nick = parse_from(from_str)[0]

    tab = _createTab(server, nick)

    if isHighlighted(tab.server, message):
        mtype = gui.tabs.HIGHMESSAGE
    else:
        mtype = gui.tabs.MESSAGE

    tab.write(timestamp,
              "&lt;<font foreground='%s' weight='bold'>%s</font>&gt; %s" %
              (color.get_nick_color(nick), markup.escape(nick),
               markup.escape(message)),
              mtype,
              group_string=nick)

    # queries are important
    gui.mgmt.set_urgent(True)
예제 #20
0
def userQuery_cb(timestamp, server, from_str, message):
    """
		A user writes to us in a query.
	"""
    nick = parse_from(from_str)[0]

    tab = _createTab(server, nick)

    if isHighlighted(tab.server, message):
        mtype = gui.tabs.HIGHMESSAGE
    else:
        mtype = gui.tabs.MESSAGE

    tab.write(
        timestamp,
        "&lt;<font foreground='%s' weight='bold'>%s</font>&gt; %s"
        % (color.get_nick_color(nick), markup.escape(nick), markup.escape(message)),
        mtype,
        group_string=nick,
    )

    # queries are important
    gui.mgmt.set_urgent(True)
예제 #21
0
def userMode_cb(time, server, from_str, target, mode, param):
    """
		Mode change on target from nick detected.
		nick and param are optional arguments and
		can be empty.

		As nemo:
			/mode #xesio +o nemo
		will result in:
			userMode(<time>,<server>,"nemo","#xesio","+o","nemo")
	"""

    def n_updatePrefix(tab, nick, mode):
        """ checks if the mode is a prefix-mode (e.g. +o)
			If so, the prefix of the nick `nick` in channel `channel`
			will be updated (fetched).
		"""
        if not nick:
            return

        if mode[1] in tab.server.support_prefix[0]:
            tab.nickList.set_prefix(nick, sushi.user_channel_prefix(tab.server.name, tab.name, nick))

            if tab.is_active():
                gui.mgmt.set_user_count(len(tab.nickList), tab.nickList.get_operator_count())

    nick = parse_from(from_str)[0]

    # nick: /mode target +mode param
    server_tab = gui.tabs.search_tab(server)

    if not nick:
        # only a mode listing
        server_tab.current_write(
            time, _("• Modes for %(target)s: %(mode)s") % {"target": target, "mode": mode}, gui.tabs.ACTION
        )

    else:
        actor = nick
        own = nick == server_tab.nick

        if own:
            actor = "You"

        tab = gui.tabs.search_tab(server, target)

        if not tab:
            # no channel/query found

            if param:
                param = " " + param

            if not _hide_output(server_tab, "mode"):

                actor = "<font foreground='%s'>%s</font>" % (action_nick_color(actor), actor)
                target = "<font foreground='%s'>%s</font>" % (action_nick_color(target), target)

                server_tab.current_write(
                    time,
                    "• %(actor)s set %(mode)s%(param)s on %(target)s"
                    % {"actor": actor, "mode": mode, "param": param, "target": target},
                    gui.tabs.ACTION,
                )
        else:
            # suitable channel/query found, print it there

            n_updatePrefix(tab, param, mode)

            type = gui.tabs.ACTION
            victim = target
            own = target == server_tab.nick

            if (param == server_tab.nick) or own:
                type = gui.tabs.HIGHACTION
            elif own:
                victim = "you"

            if param:
                param = " " + param

            if _show_output_exclusive(server_tab, tab, "mode", own=own):

                actor = "<font foreground='%s'>%s</font>" % (color.get_nick_color(actor), actor)
                victim = "<font foreground='%s'>%s</font>" % (color.get_nick_color(victim), victim)

                tab.write(
                    time,
                    "• %(actor)s set %(mode)s%(param)s on %(victim)s."
                    % {"actor": actor, "mode": mode, "param": param, "victim": victim},
                    type,
                )
예제 #22
0
def userMode_cb(time, server, from_str, target, mode, param):
    """
		Mode change on target from nick detected.
		nick and param are optional arguments and
		can be empty.

		As nemo:
			/mode #xesio +o nemo
		will result in:
			userMode(<time>,<server>,"nemo","#xesio","+o","nemo")
	"""
    def n_updatePrefix(tab, nick, mode):
        """ checks if the mode is a prefix-mode (e.g. +o)
			If so, the prefix of the nick `nick` in channel `channel`
			will be updated (fetched).
		"""
        if not nick:
            return

        if mode[1] in tab.server.support_prefix[0]:
            tab.nickList.set_prefix(
                nick, sushi.user_channel_prefix(tab.server.name, tab.name,
                                                nick))

            if tab.is_active():
                gui.mgmt.set_user_count(len(tab.nickList),
                                        tab.nickList.get_operator_count())

    nick = parse_from(from_str)[0]

    # nick: /mode target +mode param
    server_tab = gui.tabs.search_tab(server)

    if not nick:
        # only a mode listing
        server_tab.current_write(
            time,
            _("• Modes for %(target)s: %(mode)s") % {
                "target": target,
                "mode": mode
            }, gui.tabs.ACTION)

    else:
        actor = nick
        own = (nick == server_tab.nick)

        if own:
            actor = "You"

        tab = gui.tabs.search_tab(server, target)

        if not tab:
            # no channel/query found

            if param: param = " " + param

            if not _hide_output(server_tab, "mode"):

                actor = "<font foreground='%s'>%s</font>" % (
                    action_nick_color(actor), actor)
                target = "<font foreground='%s'>%s</font>" % (
                    action_nick_color(target), target)

                server_tab.current_write(
                    time, "• %(actor)s set %(mode)s%(param)s on %(target)s" % {
                        "actor": actor,
                        "mode": mode,
                        "param": param,
                        "target": target
                    }, gui.tabs.ACTION)
        else:
            # suitable channel/query found, print it there

            n_updatePrefix(tab, param, mode)

            type = gui.tabs.ACTION
            victim = target
            own = (target == server_tab.nick)

            if (param == server_tab.nick) or own:
                type = gui.tabs.HIGHACTION
            elif own:
                victim = "you"

            if param: param = " " + param

            if _show_output_exclusive(server_tab, tab, "mode", own=own):

                actor = "<font foreground='%s'>%s</font>" % (
                    color.get_nick_color(actor), actor)
                victim = "<font foreground='%s'>%s</font>" % (
                    color.get_nick_color(victim), victim)

                tab.write(
                    time,
                    "• %(actor)s set %(mode)s%(param)s on %(victim)s." % {
                        "actor": actor,
                        "mode": mode,
                        "param": param,
                        "victim": victim
                    }, type)
예제 #23
0
def userPart_cb(timestamp, server, from_str, channel, reason):
    """
	A user parted the channel.

	If we are the user who parted, mark the channel
	as parted (joined=False)
	"""
    nick = parse_from(from_str)[0]

    stab, tab = gui.tabs.search_tabs(server, channel)

    if not tab:
        # tab was closed
        return

    channelString = markup.escape(channel)
    reasonString = markup.escape(reason)

    if nick == stab.nick:
        # we parted

        tab.joined = False

        if _show_output_exclusive(stab, tab, "part", own=True):

            if reason:
                message = _(u"« You have left %(channel)s (%(reason)s).")
            else:
                message = _(u"« You have left %(channel)s.")

            tab.write(
                timestamp, message % {
                    "channel": channelString,
                    "reason": reasonString
                }, gui.tabs.ACTION)

    else:  # another user parted

        tab.nickList.remove_nick(nick)

        if tab.is_active():
            gui.mgmt.set_user_count(len(tab.nickList),
                                    tab.nickList.get_operator_count())

        if _show_output_exclusive(stab, tab, "part", False):

            nickString = "<font foreground='%s' weight='bold'>"\
             "%s</font>" % (
             color.get_nick_color(nick), markup.escape(nick))

            if reason:
                message = _(u"« %(nick)s has left %(channel)s "\
                 "(%(reason)s).")
            else:
                message = _(u"« %(nick)s has left %(channel)s.")

            tab.write(
                timestamp, message % {
                    "nick": nickString,
                    "channel": channelString,
                    "reason": reasonString
                }, gui.tabs.ACTION)