Esempio n. 1
0
    def _join(self, sock, source, name):
        user = models.User.objects.filter(sock=sock).first()

        if name and name[0] not in self.parent.chantypes:
            return ERR_NOSUCHCHANNEL(name)

        if VALID_CHANNEL_REGEX.match(name) is None:
            return ERR_NOSUCHCHANNEL(name)

        if len(name) > self.parent.channellen:
            return ERR_NOSUCHCHANNEL(name)

        replies = [JOIN(name, prefix=user.prefix)]

        channel = models.Channel.objects.filter(name=name).first()
        if channel is None:
            channel = models.Channel(name=name)
            channel.save()

        if user in channel.users:
            return

        type = name[0]
        nchannels = len([x for x in user.channels if channel.type == type])
        chanlimit = self.parent.chanlimit.get(type, None)
        if chanlimit and nchannels >= chanlimit:
            return ERR_TOOMANYCHANNELS(name)

        self.notify(channel.users[:], JOIN(name, prefix=user.prefix))

        user.channels.append(channel)
        user.save()

        if not channel.users:
            replies.append(
                MODE(name,
                     u"+o {0}".format(user.nick),
                     prefix=self.server.host))
            channel.operators.append(user)
            channel.save()

        channel.users.append(user)
        channel.save()

        self.fire(
            response.create("topic", sock, source, channel.name, joined=True),
            "server")
        self.fire(response.create("names", sock, source, channel.name),
                  "server")

        return replies
Esempio n. 2
0
    def who(self, sock, source, mask):
        if mask.startswith(u"#"):
            channel = models.Channel.objects.filter(name=mask).first()
            if channel is None:
                return ERR_NOSUCHCHANNEL(mask)

            replies = []
            for user in channel.users:
                userinfo = user.userinfo

                status = u("G") if user.away else u("H")
                status += (u("*") if user.oper else u(""))
                status += (u("@") if user in channel.operators else u(""))
                status += (u("+") if user in channel.voiced else u(""))

                replies.append(
                    RPL_WHOREPLY(channel.name, userinfo.user, userinfo.host,
                                 self.parent.server.host, user.nick, status, 0,
                                 userinfo.name or ""))
            replies.append(RPL_ENDOFWHO(mask))
            return replies
        else:
            user = models.User.objects.filter(nick=mask).first()
            if user is None:
                return ERR_NOSUCHNICK(mask)

            userinfo = user.userinfo

            status = u("G") if user.away else u("H")
            status += (u("*") if user.oper else u(""))

            return (RPL_WHOREPLY(mask, userinfo.user, userinfo.host,
                                 self.parent.server.host, user.nick, status, 0,
                                 userinfo.naem), RPL_ENDOFWHO(mask))
Esempio n. 3
0
    def topic(self, sock, source, name, topic=None, **kwargs):
        user = models.User.objects.filter(sock=sock).first()

        channel = models.Channel.objects.filter(name=name).first()
        if channel is None:
            return ERR_NOSUCHCHANNEL(name)

        _topic, _topic_setter, _topic_timestamp = channel.topic

        if topic is None and not _topic:
            if kwargs.get("joined", False):
                return
            return RPL_NOTOPIC(channel.name)

        if topic is None:
            return (RPL_TOPIC(channel.name, _topic),
                    RPL_TOPICWHO(channel.name, _topic_setter,
                                 _topic_timestamp))

        if not user.oper and u"t" in channel.modes and user not in channel.operators:
            return ERR_CHANOPRIVSNEEDED(channel.name)

        channel.topic = (topic, user.prefix)

        self.notify(channel.users[:],
                    TOPIC(channel.name, topic, prefix=user.prefix))
Esempio n. 4
0
    def kick(self, sock, source, name, nick, reason=None):
        user = models.User.objects.filter(sock=sock).first()

        channel = models.Channel.objects.filter(name=name).first()
        if channel is None:
            return ERR_NOSUCHCHANNEL(name)

        if not user.oper and user not in channel.operators:
            return ERR_CHANOPRIVSNEEDED(channel.name)

        if nick not in imap(attrgetter("nick"), channel.users):
            return ERR_USERNOTINCHANNEL(nick, channel.name)

        nick = models.User.objects.filter(nick=nick).first()

        self.notify(
            channel.users[:],
            Message(u"KICK",
                    channel.name,
                    nick.nick,
                    reason or nick.nick,
                    prefix=user.prefix))

        nick.channels.remove(channel)
        nick.save()

        channel.users.remove(nick)
        if user in channel.operators:
            channel.operators.remove(user)
        if user in channel.voiced:
            channel.voiced.remove(user)
        channel.save()

        if not channel.users:
            channel.delete()
Esempio n. 5
0
    def on_privmsg_or_notice(self, event, sock, source, target, message):
        user = User.objects.filter(sock=sock).first()

        prefix = user.prefix or joinprefix(*source)

        if target.startswith(u"#"):
            channel = Channel.objects.filter(name=target).first()
            if channel is None:
                return ERR_NOSUCHCHANNEL(target)

            if "n" in channel.modes:
                if not user.oper and user not in channel.users:
                    return ERR_CANNOTSENDTOCHAN(channel.name)

            if "m" in channel.modes:
                if not user.oper and user not in chain(channel.operators,
                                                       channel.voiced):
                    return ERR_CANNOTSENDTOCHAN(channel.name)

            self.notify(channel.users,
                        _Message(u"PRIVMSG", target, message, prefix=prefix),
                        user)
        else:
            user = User.objects.filter(nick=target).first()
            if user is None:
                return ERR_NOSUCHNICK(target)

            return reply(
                user.sock,
                _Message(event.name.upper(), target, message, prefix=prefix))
Esempio n. 6
0
 def mode(self, sock, source, mask, mode=None, params=None):
     if mask.startswith('#'):
         if mask not in self.channels:
             return self.fire(reply(sock, ERR_NOSUCHCHANNEL(mask)))
         channel = self.channels[mask]
         if not params:
             self.fire(reply(sock, RPL_CHANNELMODEIS(channel.name, channel.mode)))
     elif mask not in self.users:
         return self.fire(reply(sock, ERR_NOSUCHNICK(mask)))
Esempio n. 7
0
    def names(self, sock, source, name):
        channel = models.Channel.objects.filter(name=name).first()

        if channel is None:
            return ERR_NOSUCHCHANNEL(name)

        return [
            RPL_NAMEREPLY(channel.name, channel.userprefixes),
            RPL_ENDOFNAMES(name),
        ]
Esempio n. 8
0
    def who(self, sock, source, mask):
        if mask.startswith("#"):
            if mask not in self.channels:
                return self.fire(reply(sock, ERR_NOSUCHCHANNEL(mask)))

            channel = self.channels[mask]

            for user in channel.users:
                self.fire(reply(sock, RPL_WHOREPLY(user, mask, self.host)))
            self.fire(reply(sock, RPL_ENDOFWHO(mask)))
        else:
            if mask not in self.nicks:
                return self.fire(reply(sock, ERR_NOSUCHNICK(mask)))

            user = self.nicks[mask]

            self.fire(reply(sock, RPL_WHOREPLY(user, mask, self.host)))
            self.fire(reply(sock, RPL_ENDOFWHO(mask)))
Esempio n. 9
0
    def privmsg(self, sock, source, target, message):
        user = self.users[sock]

        if target.startswith("#"):
            if target not in self.channels:
                return self.fire(reply(sock, ERR_NOSUCHCHANNEL(target)))

            channel = self.channels[target]

            self._notify(
                channel.users,
                Message("PRIVMSG", target, message, prefix=user.prefix), user)
        else:
            if target not in self.nicks:
                return self.fire(reply(sock, ERR_NOSUCHNICK(target)))

            self.fire(
                reply(self.nicks[target].sock,
                      Message("PRIVMSG", target, message, prefix=user.prefix)))
Esempio n. 10
0
    def topic(self, sock, source, name, topic=None):
        user = models.User.objects.filter(sock=sock).first()

        channel = models.Channel.objects.filter(name=name).first()
        if channel is None:
            return ERR_NOSUCHCHANNEL(name)

        if topic is None and not channel.topic:
            return RPL_NOTOPIC(channel.name)

        if topic is None:
            return RPL_TOPIC(channel.name, channel.topic)

        if not user.oper and u"t" in channel.modes and user not in channel.operators:
            return ERR_CHANOPRIVSNEEDED(channel.name)

        channel.topic = topic
        channel.save()

        self.notify(channel.users[:],
                    TOPIC(channel.name, topic, prefix=user.prefix))
Esempio n. 11
0
    def mode(self, sock, source, *args):
        """MODE command

        This command allows the user to display modes of another user
        or channel and set modes of other users and channels.
        """

        if not args:
            return ERR_NEEDMOREPARAMS(u"MODE")

        user = User.objects.filter(sock=sock).first()

        args = iter(args)
        mask = next(args)

        if mask.startswith(u("#")):
            channel = Channel.objects.filter(name=mask).first()
            if channel is None:
                return ERR_NOSUCHCHANNEL(mask)

            mode = next(args, None)
            if mode is None:
                return RPL_CHANNELMODEIS(channel.name,
                                         u("+{0}").format(channel.modes))

            return self._process_channel_modes(user, channel,
                                               [mode] + list(args))
        else:
            nick = User.objects.filter(nick=mask).first()
            if nick is None:
                return ERR_NOSUCHNICK(mask)

            if user.nick != nick.nick:
                return ERR_USERSDONTMATCH()

            mode = next(args, None)
            if mode is None:
                return RPL_UMODEIS(u("+{0}").format(nick.modes))

            return process_user_modes(nick, [mode] + list(args))