2 """Pan-protocol chat client.
4 Stability: incendiary, work in progress.
6 from zope.interface import Interface
10 #from twisted.words.im import locals
12 # (Random musings, may not reflect on current state of code:)
14 # Accounts have Protocol components (clients)
15 # Persons have Conversation components
16 # Groups have GroupConversation components
17 # Persons and Groups are associated with specific Accounts
18 # At run-time, Clients/Accounts are slaved to a User Interface
19 # (Note: User may be a bot, so don't assume all UIs are built on gui toolkits)
22 class IAccount(Interface):
23 """I represent a user's account with a chat service.
25 @cvar gatewayType: Identifies the protocol used by this account.
26 @type gatewayType: string
28 @ivar client: The Client currently connecting to this account, if any.
29 @type client: L{IClient}
32 def __init__(accountName, autoLogin, username, password, host, port):
34 @type accountName: string
35 @param accountName: A name to refer to the account by locally.
36 @type autoLogin: boolean
37 @type username: string
38 @type password: string
52 @type chatui: Implementor of C{IChatUI}
54 @returntype: Deferred L{Client}
61 def getGroup(groupName):
63 @returntype: L{Group<IGroup>}
66 def getPerson(personName):
68 @returntype: L{Person<IPerson>}
71 class IClient(Interface):
73 @ivar account: The Account I am a Client for.
74 @type account: L{IAccount}
76 def __init__(account, chatui, logonDeferred):
78 @type account: L{IAccount}
79 @type chatui: L{IChatUI}
80 @param logonDeferred: Will be called back once I am logged on.
81 @type logonDeferred: L{Deferred<twisted.internet.defer.Deferred>}
84 def joinGroup(groupName):
86 @param groupName: The name of the group to join.
87 @type groupName: string
90 def leaveGroup(groupName):
92 @param groupName: The name of the group to leave.
93 @type groupName: string
96 def getGroupConversation(name,hide=0):
103 class IPerson(Interface):
104 def __init__(name, account):
107 @param name: My name, as the server knows me.
109 @param account: The account I am accessed through.
110 @type account: I{Account}
114 """Am I online right now?
120 """What is my on-line status?
122 @returns: L{locals.StatusEnum}
127 @returntype: string (XXX: How about a scalar?)
130 def sendMessage(text, metadata=None):
131 """Send a message to this person.
138 class IGroup(Interface):
139 """A group which you may have a conversation with.
141 Groups generally have a loosely-defined set of members, who may
142 leave and join at any time.
144 @ivar name: My name, as the server knows me.
146 @ivar account: The account I am accessed through.
147 @type account: I{Account<IAccount>}
150 def __init__(name, account):
153 @param name: My name, as the server knows me.
155 @param account: The account I am accessed through.
156 @type account: I{Account<IAccount>}
160 """Set this Groups topic on the server.
165 def sendGroupMessage(text, metadata=None):
166 """Send a message to this group.
171 @param metadata: Valid keys for this dictionary include:
173 - C{'style'}: associated with one of:
174 - C{'emote'}: indicates this is an action
181 """Depart this group"""
184 class IConversation(Interface):
185 """A conversation with a specific person."""
186 def __init__(person, chatui):
188 @type person: L{IPerson}
192 """doesn't seem like it belongs in this interface."""
195 """nor this neither."""
197 def sendText(text, metadata):
200 def showMessage(text, metadata):
203 def changedNick(person, newnick):
205 @param person: XXX Shouldn't this always be Conversation.person?
208 class IGroupConversation(Interface):
210 """doesn't seem like it belongs in this interface."""
213 """nor this neither."""
215 def sendText(text, metadata):
218 def showGroupMessage(sender, text, metadata):
221 def setGroupMembers(members):
222 """Sets the list of members in the group and displays it to the user
225 def setTopic(topic, author):
226 """Displays the topic (from the server) for the group conversation window
229 @type author: string (XXX: Not Person?)
232 def memberJoined(member):
233 """Adds the given member to the list of members in the group conversation
234 and displays this to the user
236 @type member: string (XXX: Not Person?)
239 def memberChangedNick(oldnick, newnick):
240 """Changes the oldnick in the list of members to newnick and displays this
243 @type oldnick: string (XXX: Not Person?)
244 @type newnick: string
247 def memberLeft(member):
248 """Deletes the given member from the list of members in the group
249 conversation and displays the change to the user
251 @type member: string (XXX: Not Person?)
255 class IChatUI(Interface):
256 def registerAccountClient(client):
257 """Notifies user that an account has been signed on to.
259 @type client: L{Client<IClient>}
262 def unregisterAccountClient(client):
263 """Notifies user that an account has been signed off or disconnected
265 @type client: L{Client<IClient>}
268 def getContactsList():
270 @returntype: L{ContactsList}
273 # WARNING: You'll want to be polymorphed into something with
274 # intrinsic stoning resistance before continuing.
276 def getConversation(person, Class, stayHidden=0):
277 """For the given person object, returns the conversation window
278 or creates and returns a new conversation window if one does not exist.
280 @type person: L{Person<IPerson>}
281 @type Class: L{Conversation<IConversation>} class
282 @type stayHidden: boolean
284 @returntype: L{Conversation<IConversation>}
287 def getGroupConversation(group,Class,stayHidden=0):
288 """For the given group object, returns the group conversation window or
289 creates and returns a new group conversation window if it doesn't exist.
291 @type group: L{Group<interfaces.IGroup>}
292 @type Class: L{Conversation<interfaces.IConversation>} class
293 @type stayHidden: boolean
295 @returntype: L{GroupConversation<interfaces.IGroupConversation>}
298 def getPerson(name, client):
299 """Get a Person for a client.
301 Duplicates L{IAccount.getPerson}.
304 @type client: L{Client<IClient>}
306 @returntype: L{Person<IPerson>}
309 def getGroup(name, client):
310 """Get a Group for a client.
312 Duplicates L{IAccount.getGroup}.
315 @type client: L{Client<IClient>}
317 @returntype: L{Group<IGroup>}
320 def contactChangedNick(oldnick, newnick):
321 """For the given person, changes the person's name to newnick, and
322 tells the contact list and any conversation windows with that person
325 @type oldnick: string
326 @type newnick: string