# Path: pyspades/constants.py
# MAX_CHAT_SIZE = 90 # more like 95, but just to make sure
# 
# Path: pyspades/types.py
# class AttributeSet(set):
#     """
#     set with attribute access, i.e.
#     
#         foo = AttributeSet()
#         foo.bar = True
#         foo.bar == 'bar' in foo == True
#         foo.bar = False
#         foo.bar == 'bar' in foo == False
#     
#     This works as a quick shorthand for membership testing.
#     """
#     
#     def __getattr__(self, name):
#         return name in self
#     
#     def __setattr__(self, name, value):
#         if value:
#             self.add(name)
#         else:
#             self.discard(name)


from twisted.words.protocols import irc
from twisted.internet import reactor, protocol
from pyspades.constants import MAX_CHAT_SIZE
from pyspades.common import encode, decode
from pyspades.types import AttributeSet
from itertools import groupby, chain, izip
from operator import attrgetter
import commands
import random
import string

    
    def irc_RPL_NAMREPLY(self, *arg):
        if not arg[1][2].lower() == self.factory.channel:
            return
        for name in arg[1][3].split():
            mode = name[0]
            l = {'@': self.ops, '+': self.voices}
            if mode in l: 
                l[mode].add(name[1:])
    
    def left(self, channel):
        if channel.lower() == self.factory.channel:
            self.ops = None
            self.voices = None
    
    @channel
    def modeChanged(self, user, channel, set, modes, args):
        ll = {'o' : self.ops, 'v' : self.voices}
        for i in range(len(args)):
            mode, name = modes[i], args[i]
            if mode not in ll:
                continue
            l = ll[mode]
            if set:
                l.add(name)
            elif not set:
                l.discard(name)
    
    @channel
    def privmsg(self, user, channel, msg):

# Path: pyspades/constants.py
# MAX_CHAT_SIZE = 90 # more like 95, but just to make sure
# 
# Path: pyspades/types.py
# class AttributeSet(set):
#     """
#     set with attribute access, i.e.
#     
#         foo = AttributeSet()
#         foo.bar = True
#         foo.bar == 'bar' in foo == True
#         foo.bar = False
#         foo.bar == 'bar' in foo == False
#     
#     This works as a quick shorthand for membership testing.
#     """
#     
#     def __getattr__(self, name):
#         return name in self
#     
#     def __setattr__(self, name, value):
#         if value:
#             self.add(name)
#         else:
#             self.discard(name)


# Path: feature_server/irc.py
from twisted.words.protocols import irc
from twisted.internet import reactor, protocol
from pyspades.constants import MAX_CHAT_SIZE
from pyspades.common import encode, decode
from pyspades.types import AttributeSet
from itertools import groupby, chain, izip
from operator import attrgetter
import commands
import random
import string

    
    def irc_RPL_NAMREPLY(self, *arg):
        if not arg[1][2].lower() == self.factory.channel:
            return
        for name in arg[1][3].split():
            mode = name[0]
            l = {'@': self.ops, '+': self.voices}
            if mode in l: 
                l[mode].add(name[1:])
    
    def left(self, channel):
        if channel.lower() == self.factory.channel:
            self.ops = None
            self.voices = None
    
    @channel
    def modeChanged(self, user, channel, set, modes, args):
        ll = {'o' : self.ops, 'v' : self.voices}
        for i in range(len(args)):
            mode, name = modes[i], args[i]
            if mode not in ll:
                continue
            l = ll[mode]
            if set:
                l.add(name)
            elif not set:
                l.discard(name)
    
    @channel
    def privmsg(self, user, channel, msg):

        if user in self.ops or user in self.voices:
