#!/usr/bin/env python
#
# This file is part of aDBa.
#
# aDBa is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# aDBa is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with aDBa.  If not, see <http://www.gnu.org/licenses/>.

from types import FunctionType
from aniDBmaper import AniDBMaper


class ResponseResolver:
    def __init__(self, data):
        restag, rescode, resstr, datalines = self.parse(data)

        self.restag = restag
        self.rescode = rescode
        self.resstr = resstr
        self.datalines = datalines

    def parse(self, data):
        resline = data.split('\n', 1)[0]
        lines = data.split('\n')[1:-1]

        rescode, resstr = resline.split(' ', 1)
        if rescode[0] == 'T':
            restag = rescode
            rescode, resstr = resstr.split(' ', 1)
        else:
            restag = None

        datalines = []
        for line in lines:
            datalines.append(line.split('|'))

        return restag, rescode, resstr, datalines

    def resolve(self, cmd):
        return responses[self.rescode](cmd, self.restag, self.rescode, self.resstr, self.datalines)


class Response:
    def __init__(self, cmd, restag, rescode, resstr, rawlines):
        self.req = cmd
        self.restag = restag
        self.rescode = rescode
        self.resstr = resstr
        self.rawlines = rawlines
        self.maper = AniDBMaper()

    def __repr__(self):
        tmp = "%s(%s,%s,%s) %s\n" % (
        self.__class__.__name__, repr(self.restag), repr(self.rescode), repr(self.resstr), repr(self.attrs))

        m = 0
        for line in self.datalines:
            for k, v in line.iteritems():
                if len(k) > m:
                    m = len(k)

        for line in self.datalines:
            tmp += "  Line:\n"
            for k, v in line.iteritems():
                tmp += "    %s:%s %s\n" % (k, (m - len(k)) * ' ', v)
        return tmp

    def parse(self):
        tmp = self.resstr.split(' ', len(self.codehead))
        self.attrs = dict(zip(self.codehead, tmp[:-1]))
        self.resstr = tmp[-1]

        self.datalines = []
        for rawline in self.rawlines:
            normal = dict(zip(self.codetail, rawline))
            rawline = rawline[len(self.codetail):]
            rep = []
            if len(self.coderep):
                while rawline:
                    tmp = dict(zip(self.coderep, rawline))
                    rawline = rawline[len(self.coderep):]
                    rep.append(tmp)
            # normal['rep']=rep
            self.datalines.append(normal)

    def handle(self):
        if self.req:
            self.req.handle(self)


class LoginAcceptedResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:
        sesskey	- session key
        address	- your address (ip:port) as seen by the server

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'LOGIN_ACCEPTED'
        self.codetail = ()
        self.coderep = ()

        nat = cmd.parameters['nat']
        nat = int(nat == None and nat or '0')
        if nat:
            self.codehead = ('sesskey', 'address')
        else:
            self.codehead = ('sesskey',)


class LoginAcceptedNewVerResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:
        sesskey	- session key
        address	- your address (ip:port) as seen by the server

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'LOGIN_ACCEPTED_NEW_VER'
        self.codetail = ()
        self.coderep = ()

        nat = cmd.parameters['nat']
        nat = int(nat == None and nat or '0')
        if nat:
            self.codehead = ('sesskey', 'address')
        else:
            self.codehead = ('sesskey',)


class LoggedOutResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'LOGGED_OUT'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class ResourceResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'RESOURCE'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class StatsResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'STATS'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class TopResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'TOP'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class UptimeResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        uptime	- udpserver uptime in milliseconds

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'UPTIME'
        self.codehead = ()
        self.codetail = ('uptime',)
        self.coderep = ()


class EncryptionEnabledResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:
        salt	- salt

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'ENCRYPTION_ENABLED'
        self.codehead = ('salt',)
        self.codetail = ()
        self.coderep = ()


class MylistEntryAddedResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        entrycnt - number of entries added

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'MYLIST_ENTRY_ADDED'
        self.codehead = ()
        self.codetail = ('entrycnt',)
        self.coderep = ()


class MylistEntryDeletedResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        entrycnt - number of entries

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'MYLIST_ENTRY_DELETED'
        self.codehead = ()
        self.codetail = ('entrycnt',)
        self.coderep = ()


class AddedFileResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'ADDED_FILE'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class AddedStreamResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'ADDED_STREAM'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class EncodingChangedResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'ENCODING_CHANGED'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class FileResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        eid		episode id
        gid		group id
        lid		mylist id
        state		state
        size		size
        ed2k		ed2k
        md5		md5
        sha1		sha1
        crc32		crc32
        dublang		dub language
        sublang		sub language
        quality		quality
        source		source
        audiocodec	audio codec
        audiobitrate	audio bitrate
        videocodec	video codec
        videobitrate	video bitrate
        resolution	video resolution
        filetype	file type (extension)
        length		length in seconds
        description	description
        filename	anidb file name
        gname		group name
        gshortname	group short name
        epno		number of episode
        epname		ep english name
        epromaji	ep romaji name
        epkanji		ep kanji name
        totaleps	anime total episodes
        lastep		last episode nr (highest, not special)
        year		year
        type		type
        romaji		romaji name
        kanji		kanji name
        name		english name
        othername	other name
        shortnames	short name list
        synonyms	synonym list
        categories	category list
        relatedaids	related aid list
        producernames	producer name list
        producerids	producer id list

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'FILE'
        self.codehead = ()
        self.coderep = ()

        fmask = cmd.parameters['fmask']
        amask = cmd.parameters['amask']

        codeListF = self.maper.getFileCodesF(fmask)
        codeListA = self.maper.getFileCodesA(amask)
        # print "File - codelistF: "+str(codeListF)
        #print "File - codelistA: "+str(codeListA)


        self.codetail = tuple(['fid'] + codeListF + codeListA)


class MylistResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        lid	 - mylist id
        fid	 - file id
        eid	 - episode id
        aid	 - anime id
        gid	 - group id
        date	 - date when you added this to mylist
        state	 - the location of the file
        viewdate - date when you marked this watched
        storage	 - for example the title of the cd you have this on
        source	 - where you got the file (bittorrent,dc++,ed2k,...)
        other	 - other data regarding this file
        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'MYLIST'
        self.codehead = ()
        self.codetail = ('lid', 'fid', 'eid', 'aid', 'gid', 'date', 'state', 'viewdate', 'storage', 'source', 'other')
        self.coderep = ()


class MylistStatsResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        animes		- animes
        eps		- eps
        files		- files
        filesizes	- size of files
        animesadded	- added animes
        epsadded	- added eps
        filesadded	- added files
        groupsadded	- added groups
        leechperc	- leech %
        lameperc	- lame %
        viewedofdb	- viewed % of db
        mylistofdb	- mylist % of db
        viewedofmylist	- viewed % of mylist
        viewedeps	- number of viewed eps
        votes		- votes
        reviews		- reviews

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'MYLIST_STATS'
        self.codehead = ()
        self.codetail = (
        'animes', 'eps', 'files', 'filesizes', 'animesadded', 'epsadded', 'filesadded', 'groupsadded', 'leechperc',
        'lameperc', 'viewedofdb', 'mylistofdb', 'viewedofmylist', 'viewedeps', 'votes', 'reviews')
        self.coderep = ()


class NotificationResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        nid         - notification id
        unknown     - unsure what this parameter is
        type        - Type of notification: type=>  0=all, 1=new, 2=group, 3=complete
        aid         - anime id
        priority    - low = 0, medium = 1, high = 2 (unconfirmed)
        date        - date notification subscribed to

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NOTIFICATION'
        self.codehead = ()
        self.codetail = ('nid', 'unknown', 'type', 'aid', 'priority', 'date')
        self.coderep = ()


class AnimeResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'ANIME'
        self.codehead = ()
        self.coderep = ()

        # TODO: impl random anime
        amask = cmd.parameters['amask']
        codeList = self.maper.getAnimeCodesA(amask)
        self.codetail = tuple(codeList)


class AnimeBestMatchResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'ANIME_BEST_MATCH'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class RandomanimeResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'RANDOMANIME'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class EpisodeResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        eid	- episode id
        aid	- anime id
        length	- length
        rating	- rating
        votes	- votes
        epno	- number of episode
        name	- english name of episode
        romaji	- romaji name of episode
        kanji	- kanji name of episode

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'EPISODE'
        self.codehead = ()
        self.codetail = ('eid', 'aid', 'length', 'rating', 'votes', 'epno', 'name', 'romaji', 'kanji')
        self.coderep = ()


class ProducerResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        pid	  - producer id
        name	  - name of producer
        shortname - short name
        othername - other name
        type	  - type
        pic	  - picture name
        url	  - home page url

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'PRODUCER'
        self.codehead = ()
        self.codetail = ('pid', 'name', 'shortname', 'othername', 'type', 'pic', 'url')
        self.coderep = ()


class GroupResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        gid	   - group id
        rating	   - rating
        votes	   - votes
        animes	   - anime count
        files	   - file count
        name	   - name
        shortname  - short
        ircchannel - irc channel
        ircserver  - irc server
        url	   - url

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'GROUP'
        self.codehead = ()
        self.codetail = (
        'gid', 'rating', 'votes', 'animes', 'files', 'name', 'shortname', 'ircchannel', 'ircserver', 'url')
        self.coderep = ()


class GroupstatusResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        gid	   - group id
        rating	   - rating
        votes	   - votes
        animes	   - anime count
        files	   - file count
        name	   - name
        shortname  - short
        ircchannel - irc channel
        ircserver  - irc server
        url	   - url

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'GROUPSTATUS'
        self.codehead = ()
        self.codetail = ('gid', 'name', 'state', ' last_episode_number', 'rating', 'votes', 'episode_range')
        self.coderep = ()


class BuddyListResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:
        start	- mylist entry number of first buddy on this packet
        end	- mylist entry number of last buddy on this packet
        total	- total number of buddies on mylist

        data:
        uid	- uid
        name	- username
        state	- state

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'BUDDY_LIST'
        self.codehead = ('start', 'end', 'total')
        self.codetail = ('uid', 'username', 'state')
        self.coderep = ()


class BuddyStateResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:
        start	- mylist entry number of first buddy on this packet
        end	- mylist entry number of last buddy on this packet
        total	- total number of buddies on mylist

        data:
        uid	- uid
        state	- online state

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'BUDDY_STATE'
        self.codehead = ('start', 'end', 'total')
        self.codetail = ('uid', 'state')
        self.coderep = ()


class BuddyAddedResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'BUDDY_ADDED'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class BuddyDeletedResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'BUDDY_DELETED'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class BuddyAcceptedResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'BUDDY_ACCEPTED'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class BuddyDeniedResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'BUDDY_DENIED'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class VotedResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        name	- aname/ename/gname

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'VOTED'
        self.codehead = ()
        self.codetail = ('name',)
        self.coderep = ()


class VoteFoundResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        name	- aname/ename/gname
        value	- vote value

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'VOTE_FOUND'
        self.codehead = ()
        self.codetail = ('name', 'value')
        self.coderep = ()


class VoteUpdatedResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        name	- aname/ename/gname
        value	- vote value

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'VOTE_UPDATED'
        self.codehead = ()
        self.codetail = ('name', 'value')
        self.coderep = ()


class VoteRevokedResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        name	- aname/ename/gname
        value	- vote value

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'VOTE_REVOKED'
        self.codehead = ()
        self.codetail = ('name', 'value')
        self.coderep = ()


class NotificationAddedResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        nid - notofication id

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NOTIFICATION_ITEM_ADDED'
        self.codehead = ()
        self.codetail = ('nid')
        self.coderep = ()

class NotificationDeletedResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        nid - notofication id

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NOTIFICATION_ITEM_DELETED'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class NotificationUpdatedResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        nid - notofication id

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NOTIFICATION_ITEM_UPDATED'
        self.codehead = ()
        self.codetail = ('nid')
        self.coderep = ()


class MultipleNotificationResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        nid         - notification id
        type        -
        priority    -


        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'MULTIPLE NOTIFICATION ITEMS'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ('nid', 'type', 'priority',)


class NotificationEnabledResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NOTIFICATION_ENABLED'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class NotificationNotifyResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:
        nid	- notify packet id

        data:
        aid	- anime id
        date	- date
        count	- count
        name	- name of the anime

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NOTIFICATION_NOTIFY'
        self.codehead = ('nid',)
        self.codetail = ('aid', 'date', 'count', 'name')
        self.coderep = ()


class NotificationMessageResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:
        nid	- notify packet id

        data:
        type	- type
        date	- date
        uid	- user id of the sender
        name	- name of the sender
        subject	- subject

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NOTIFICATION_MESSAGE'
        self.codehead = ('nid',)
        self.codetail = ('type', 'date', 'uid', 'name', 'subject')
        self.coderep = ()


class NotificationBuddyResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:
        nid	- notify packet id

        data:
        uid	- buddy uid
        type	- event type

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NOTIFICATION_BUDDY'
        self.codehead = ('notify_packet_id',)
        self.codetail = ('uid', 'type')
        self.coderep = ()


class NotificationShutdownResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:
        nid	- notify packet id

        data:
        time	- time offline
        comment	- comment

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NOTIFICATION_SHUTDOWN'
        self.codehead = ('nid',)
        self.codetail = ('time', 'comment')
        self.coderep = ()


class PushackConfirmedResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'PUSHACK_CONFIRMED'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class NotifyackSuccessfulMResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NOTIFYACK_SUCCESSFUL_M'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class NotifyackSuccessfulNResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NOTIFYACK_SUCCESSFUL_N'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class NotificationStateResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        notifies - pending notifies
        msgs	 - pending msgs
        buddys	 - number of online buddys

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NOTIFICATION'
        self.codehead = ()
        self.coderep = ()

        buddy = cmd.parameters['buddy']
        buddy = int(buddy != None and buddy or '0')
        if buddy:
            self.codetail = ('notifies', 'msgs', 'buddys')
        else:
            self.codetail = ('notifies', 'msgs')


class NotifylistResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        type	- type
        nid	- notify id

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NOTIFYLIST'
        self.codehead = ()
        self.codetail = ('type', 'nid')
        self.coderep = ()


class NotifygetMessageResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        nid	- notify id
        uid	- from user id
        uname	- from username
        date	- date
        type	- type
        title	- title
        body	- body

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NOTIFYGET_MESSAGE'
        self.codehead = ()
        self.codetail = ('nid', 'uid', 'uname', 'date', 'type', 'title', 'body')
        self.coderep = ()


class NotifygetNotifyResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        aid	- aid
        type	- type
        count	- count
        date	- date
        name	- anime name
        fid     - comma separated list of fids
        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NOTIFYGET_NOTIFY'
        self.codehead = ()
        self.codetail = ('aid', 'type', 'count', 'date', 'name', 'fid')
        self.coderep = ()


class SendmsgSuccessfulResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'SENDMSG_SUCCESSFUL'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class UserResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        uid	- user id

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'USER'
        self.codehead = ()
        self.codetail = ('uid',)
        self.coderep = ()


class PongResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'PONG'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class AuthpongResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'AUTHPONG'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class NoSuchResourceResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NO_SUCH_RESOURCE'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class ApiPasswordNotDefinedResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'API_PASSWORD_NOT_DEFINED'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class FileAlreadyInMylistResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'FILE_ALREADY_IN_MYLIST'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class MylistEntryEditedResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        entries	- number of entries edited

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'MYLIST_ENTRY_EDITED'
        self.codehead = ()
        self.codetail = ('entries',)
        self.coderep = ()


class MultipleMylistEntriesResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        name	   - anime title
        eps	   - episodes
        unknowneps - eps with state unknown
        hddeps	   - eps with state on hdd
        cdeps	   - eps with state on cd
        deletedeps - eps with state deleted
        watchedeps - watched eps
        gshortname - group short name
        geps	   - eps for group

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'MULTIPLE_MYLIST_ENTRIES'
        self.codehead = ()
        self.codetail = ('name', 'eps', 'unknowneps', 'hddeps', 'cdeps', 'deletedeps', 'watchedeps')
        self.coderep = ('gshortname', 'geps')


class SizeHashExistsResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'SIZE_HASH_EXISTS'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class InvalidDataResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'INVALID_DATA'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class StreamnoidUsedResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'STREAMNOID_USED'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class NoSuchFileResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NO_SUCH_FILE'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class NoSuchEntryResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NO_SUCH_ENTRY'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class MultipleFilesFoundResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        fid	- file id

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'MULTIPLE_FILES_FOUND'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ('fid',)


class NoSuchNotificationResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NO_SUCH_NOTIFICATION'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class NoGroupsFoundResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NO GROUPS FOUND'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class NoSuchAnimeResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NO_SUCH_ANIME'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class NoSuchEpisodeResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NO_SUCH_EPISODE'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class NoSuchProducerResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NO_SUCH_PRODUCER'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class NoSuchGroupResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NO_SUCH_GROUP'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class BuddyAlreadyAddedResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'BUDDY_ALREADY_ADDED'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class NoSuchBuddyResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NO_SUCH_BUDDY'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class BuddyAlreadyAcceptedResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'BUDDY_ALREADY_ACCEPTED'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class BuddyAlreadyDeniedResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'BUDDY_ALREADY_DENIED'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class NoSuchVoteResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NO_SUCH_VOTE'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class InvalidVoteTypeResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'INVALID_VOTE_TYPE'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class InvalidVoteValueResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'INVALID_VOTE_VALUE'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class PermvoteNotAllowedResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        aname	- name of the anime

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'PERMVOTE_NOT_ALLOWED'
        self.codehead = ()
        self.codetail = ('aname',)
        self.coderep = ()


class AlreadyPermvotedResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        name	- aname/ename/gname

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'ALREADY_PERMVOTED'
        self.codehead = ()
        self.codetail = ('name',)
        self.coderep = ()


class NotificationDisabledResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NOTIFICATION_DISABLED'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class NoSuchPacketPendingResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NO_SUCH_PACKET_PENDING'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class NoSuchEntryMResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NO_SUCH_ENTRY_M'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class NoSuchEntryNResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NO_SUCH_ENTRY_N'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class NoSuchMessageResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NO_SUCH_MESSAGE'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class NoSuchNotifyResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NO_SUCH_NOTIFY'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class NoSuchUserResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NO_SUCH_USER'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class NoChanges(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NO_CHANGES'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class NotLoggedInResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NOT_LOGGED_IN'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class NoSuchMylistFileResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NO_SUCH_MYLIST_FILE'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class NoSuchMylistEntryResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NO_SUCH_MYLIST_ENTRY'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class LoginFailedResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'LOGIN_FAILED'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class LoginFirstResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'LOGIN_FIRST'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class AccessDeniedResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'ACCESS_DENIED'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class ClientVersionOutdatedResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'CLIENT_VERSION_OUTDATED'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class ClientBannedResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'CLIENT_BANNED'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class IllegalInputOrAccessDeniedResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'ILLEGAL_INPUT_OR_ACCESS_DENIED'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class InvalidSessionResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'INVALID_SESSION'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class NoSuchEncryptionTypeResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'NO_SUCH_ENCRYPTION_TYPE'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class EncodingNotSupportedResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'ENCODING_NOT_SUPPORTED'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class BannedResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'BANNED'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class UnknownCommandResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'UNKNOWN_COMMAND'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class InternalServerErrorResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'INTERNAL_SERVER_ERROR'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class AnidbOutOfServiceResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'ANIDB_OUT_OF_SERVICE'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class ServerBusyResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'SERVER_BUSY'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class ApiViolationResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'API_VIOLATION'
        self.codehead = ()
        self.codetail = ()
        self.coderep = ()


class VersionResponse(Response):
    def __init__(self, cmd, restag, rescode, resstr, datalines):
        """
        attributes:

        data:
        version	- server version

        """
        Response.__init__(self, cmd, restag, rescode, resstr, datalines)
        self.codestr = 'VERSION'
        self.codehead = ()
        self.codetail = ('version',)
        self.coderep = ()


responses = {
    '200': LoginAcceptedResponse,
    '201': LoginAcceptedNewVerResponse,
    '203': LoggedOutResponse,
    '205': ResourceResponse,
    '206': StatsResponse,
    '207': TopResponse,
    '208': UptimeResponse,
    '209': EncryptionEnabledResponse,
    '210': MylistEntryAddedResponse,
    '211': MylistEntryDeletedResponse,
    '214': AddedFileResponse,
    '215': AddedStreamResponse,
    '219': EncodingChangedResponse,
    '220': FileResponse,
    '221': MylistResponse,
    '222': MylistStatsResponse,
    '224': NotificationResponse,
    '225': GroupstatusResponse,
    '230': AnimeResponse,
    '231': AnimeBestMatchResponse,
    '232': RandomanimeResponse,
    '240': EpisodeResponse,
    '245': ProducerResponse,
    '246': NotificationAddedResponse,
    '247': NotificationDeletedResponse,
    '248': NotificationUpdatedResponse,
    '249': MultipleNotificationResponse,
    '250': GroupResponse,
    '253': BuddyListResponse,
    '254': BuddyStateResponse,
    '255': BuddyAddedResponse,
    '256': BuddyDeletedResponse,
    '257': BuddyAcceptedResponse,
    '258': BuddyDeniedResponse,
    '260': VotedResponse,
    '261': VoteFoundResponse,
    '262': VoteUpdatedResponse,
    '263': VoteRevokedResponse,
    '270': NotificationEnabledResponse,
    '271': NotificationNotifyResponse,
    '272': NotificationMessageResponse,
    '273': NotificationBuddyResponse,
    '274': NotificationShutdownResponse,
    '280': PushackConfirmedResponse,
    '281': NotifyackSuccessfulMResponse,
    '282': NotifyackSuccessfulNResponse,
    '290': NotificationStateResponse,
    '291': NotifylistResponse,
    '292': NotifygetMessageResponse,
    '293': NotifygetNotifyResponse,
    '294': SendmsgSuccessfulResponse,
    '295': UserResponse,
    '300': PongResponse,
    '301': AuthpongResponse,
    '305': NoSuchResourceResponse,
    '309': ApiPasswordNotDefinedResponse,
    '310': FileAlreadyInMylistResponse,
    '311': MylistEntryEditedResponse,
    '312': MultipleMylistEntriesResponse,
    '314': SizeHashExistsResponse,
    '315': InvalidDataResponse,
    '316': StreamnoidUsedResponse,
    '320': NoSuchFileResponse,
    '321': NoSuchEntryResponse,
    '322': MultipleFilesFoundResponse,
    '324': NoSuchNotificationResponse,
    '325': NoGroupsFoundResponse,
    '330': NoSuchAnimeResponse,
    '340': NoSuchEpisodeResponse,
    '345': NoSuchProducerResponse,
    '350': NoSuchGroupResponse,
    '355': BuddyAlreadyAddedResponse,
    '356': NoSuchBuddyResponse,
    '357': BuddyAlreadyAcceptedResponse,
    '358': BuddyAlreadyDeniedResponse,
    '360': NoSuchVoteResponse,
    '361': InvalidVoteTypeResponse,
    '362': InvalidVoteValueResponse,
    '363': PermvoteNotAllowedResponse,
    '364': AlreadyPermvotedResponse,
    '370': NotificationDisabledResponse,
    '380': NoSuchPacketPendingResponse,
    '381': NoSuchEntryMResponse,
    '382': NoSuchEntryNResponse,
    '392': NoSuchMessageResponse,
    '393': NoSuchNotifyResponse,
    '394': NoSuchUserResponse,
    '399': NoChanges,
    '403': NotLoggedInResponse,
    '410': NoSuchMylistFileResponse,
    '411': NoSuchMylistEntryResponse,
    '500': LoginFailedResponse,
    '501': LoginFirstResponse,
    '502': AccessDeniedResponse,
    '503': ClientVersionOutdatedResponse,
    '504': ClientBannedResponse,
    '505': IllegalInputOrAccessDeniedResponse,
    '506': InvalidSessionResponse,
    '509': NoSuchEncryptionTypeResponse,
    '519': EncodingNotSupportedResponse,
    '555': BannedResponse,
    '598': UnknownCommandResponse,
    '600': InternalServerErrorResponse,
    '601': AnidbOutOfServiceResponse,
    '602': ServerBusyResponse,
    '666': ApiViolationResponse,
    '998': VersionResponse
}