<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
        <head>
                <title>Twisted IM</title>
        </head>
        <body>
                <h1>Twisted IM: An overview</h1>

                <p>Twisted IM is a multi-protocol chat framework, based on the
                Twisted framework we've all come to know and love. It's fairly
                simple and extensible in two directions - it's pretty easy to
                add new protocols, and it's also quite easy to add new
                front-ends.</p>

                <h2>Code flow</h2>
                <p>Twisted IM is usually started from the file
                <code>twisted/scripts/im.py</code> (maybe with a shell-script
                wrapper or similar). Twisted currently comes with two
                interfaces for Twisted IM - one written in GTK for Python
                under Linux, and one written in Swing for Jython.
                <code>im.py</code> picks an implementation and starts it - if
                you want to write your own interface, you can modify
                <code>im.py</code> to start it under appropriate
                conditions.</p>

                <p>Once started, both interfaces behave in a very similar
                fashion, so I won't be getting into differences here.</p>

                <h3>AccountManager</h3>
                <p>Control flow starts at the relevant subclass of <code
                        class="API"
                        base="twisted.im">baseaccount.AccountManager</code>.
                The AccountManager is responsible for, well, managing accounts
                - remembering what accounts are available, their
                settings, adding and removal of accounts, and making accounts
                log on at startup.</p>

                <p>This would be a good place to start your interface, load a
                list of accounts from disk and tell them to login. Most of the
                method names in <code class="API"
                        base="twisted.im.baseaccount">AccountManager</code>
                are pretty self-explanatory, and your subclass can override
                whatever it wants, but you <em>need</em> to override <code
                        class="python">__init__</code>. Something like
                this:</p>

                <pre class="python">
def __init__(self):
        self.chatui = (your subclass of basechat.ChatUI)
        self.accounts = (load account list)
        for a in self.accounts:
                a.logOn(self.chatui)
                </pre>
                
                <h3>ChatUI</h3>
                <p>Account objects talk to the user via a subclass of <code
                        class="API" base="twisted.im">basechat.ChatUI</code>.
                This class keeps track of all the various conversations that
                are currently active, so that when an account receives and
                incoming message, it can put that message in its correct
                context.</p>

                <p>How much of this class you need to override depends on what
                you need to do. You will need to override
                <code>getConversation</code> (a one-on-one conversation, like
                an IRC DCC chat) and <code>getGroupConversation</code> (a
                multiple user conversation, like an IRC channel). You might
                want to override <code>getGroup</code> and
                <code>getPerson</code>.</p>

                <p>The main problem with the default versions of the above
                routines is that they take a parameter, <code>Class</code>,
                which defaults to an abstract implementation of that class -
                for example, <code>getConversation</code> has a
                <code>Class</code> parameter that defaults to <code
                        class="API"
                        base="twisted.im">basechat.Conversation</code> which
                raises a lot of <code>NotImplementedError</code>s. In your
                subclass, override the method with a new method whose Class
                parameter defaults to your own implementation of
                <code>Conversation</code>, that simply calls the parent
                class' implementation.</p>

                <h3>Conversation and GroupConversation</h3>
                <p>These classes are where your interface meets the chat
                protocol. Chat protocols get a message, find the appropriate
                <code>Conversation</code> or <code>GroupConversation</code>
                object, and call its methods when various interesting things
                happen.</p>

                <p>Override whatever methods you want to get the information
                you want to display. You must override the <code>hide</code>
                and <code>show</code> methods, however - they are called
                frequently and the default implementation raises
                <code>NotImplementedError</code>.</p>

                <h3>Accounts</h3>
                <p>An account is an instance of a subclass of <code
                        class="API"
                        base="twisted.im">basesupport.AbstractAccount</code>.
                For more details and sample code, see the various
                <code>*support</code> files in <code>twisted.im</code>.</p>

        </body>
</html>