2 # Copyright (c) Twisted Matrix Laboratories.
3 # See LICENSE for details.
6 Pan-protocol chat client.
9 from zope.interface import Interface, Attribute
11 from twisted.words.im import locals
13 # (Random musings, may not reflect on current state of code:)
15 # Accounts have Protocol components (clients)
16 # Persons have Conversation components
17 # Groups have GroupConversation components
18 # Persons and Groups are associated with specific Accounts
19 # At run-time, Clients/Accounts are slaved to a User Interface
20 # (Note: User may be a bot, so don't assume all UIs are built on gui toolkits)
23 class IAccount(Interface):
25 I represent a user's account with a chat service.
28 client = Attribute('The L{IClient} currently connecting to this account, if any.')
29 gatewayType = Attribute('A C{str} that identifies the protocol used by this account.')
31 def __init__(accountName, autoLogin, username, password, host, port):
33 @type accountName: string
34 @param accountName: A name to refer to the account by locally.
35 @type autoLogin: boolean
36 @type username: string
37 @type password: string
53 @type chatui: Implementor of C{IChatUI}
55 @rtype: L{Deferred} L{Client}
63 def getGroup(groupName):
65 @rtype: L{Group<IGroup>}
68 def getPerson(personName):
70 @rtype: L{Person<IPerson>}
73 class IClient(Interface):
75 account = Attribute('The L{IAccount} I am a Client for')
77 def __init__(account, chatui, logonDeferred):
79 @type account: L{IAccount}
80 @type chatui: L{IChatUI}
81 @param logonDeferred: Will be called back once I am logged on.
82 @type logonDeferred: L{Deferred<twisted.internet.defer.Deferred>}
85 def joinGroup(groupName):
87 @param groupName: The name of the group to join.
88 @type groupName: string
91 def leaveGroup(groupName):
93 @param groupName: The name of the group to leave.
94 @type groupName: string
97 def getGroupConversation(name, hide=0):
104 class IPerson(Interface):
106 def __init__(name, account):
110 @param name: My name, as the server knows me.
112 @param account: The account I am accessed through.
113 @type account: I{Account}
118 Am I online right now?
125 What is my on-line status?
127 @return: L{locals.StatusEnum}
132 @rtype: string (XXX: How about a scalar?)
135 def sendMessage(text, metadata=None):
137 Send a message to this person.
144 class IGroup(Interface):
146 A group which you may have a conversation with.
148 Groups generally have a loosely-defined set of members, who may
149 leave and join at any time.
152 name = Attribute('My C{str} name, as the server knows me.')
153 account = Attribute('The L{Account<IAccount>} I am accessed through.')
155 def __init__(name, account):
159 @param name: My name, as the server knows me.
161 @param account: The account I am accessed through.
162 @type account: L{Account<IAccount>}
167 Set this Groups topic on the server.
172 def sendGroupMessage(text, metadata=None):
174 Send a message to this group.
179 @param metadata: Valid keys for this dictionary include:
181 - C{'style'}: associated with one of:
182 - C{'emote'}: indicates this is an action
196 class IConversation(Interface):
198 A conversation with a specific person.
201 def __init__(person, chatui):
203 @type person: L{IPerson}
208 doesn't seem like it belongs in this interface.
216 def sendText(text, metadata):
219 def showMessage(text, metadata):
222 def changedNick(person, newnick):
224 @param person: XXX Shouldn't this always be Conversation.person?
227 class IGroupConversation(Interface):
231 doesn't seem like it belongs in this interface.
239 def sendText(text, metadata):
242 def showGroupMessage(sender, text, metadata):
245 def setGroupMembers(members):
247 Sets the list of members in the group and displays it to the user.
250 def setTopic(topic, author):
252 Displays the topic (from the server) for the group conversation window.
255 @type author: string (XXX: Not Person?)
258 def memberJoined(member):
260 Adds the given member to the list of members in the group conversation
261 and displays this to the user,
263 @type member: string (XXX: Not Person?)
266 def memberChangedNick(oldnick, newnick):
268 Changes the oldnick in the list of members to C{newnick} and displays this
271 @type oldnick: string (XXX: Not Person?)
272 @type newnick: string
275 def memberLeft(member):
277 Deletes the given member from the list of members in the group
278 conversation and displays the change to the user.
280 @type member: string (XXX: Not Person?)
284 class IChatUI(Interface):
286 def registerAccountClient(client):
288 Notifies user that an account has been signed on to.
290 @type client: L{Client<IClient>}
293 def unregisterAccountClient(client):
295 Notifies user that an account has been signed off or disconnected.
297 @type client: L{Client<IClient>}
300 def getContactsList():
302 @rtype: L{ContactsList}
305 # WARNING: You'll want to be polymorphed into something with
306 # intrinsic stoning resistance before continuing.
308 def getConversation(person, Class, stayHidden=0):
310 For the given person object, returns the conversation window
311 or creates and returns a new conversation window if one does not exist.
313 @type person: L{Person<IPerson>}
314 @type Class: L{Conversation<IConversation>} class
315 @type stayHidden: boolean
317 @rtype: L{Conversation<IConversation>}
320 def getGroupConversation(group, Class, stayHidden=0):
322 For the given group object, returns the group conversation window or
323 creates and returns a new group conversation window if it doesn't exist.
325 @type group: L{Group<interfaces.IGroup>}
326 @type Class: L{Conversation<interfaces.IConversation>} class
327 @type stayHidden: boolean
329 @rtype: L{GroupConversation<interfaces.IGroupConversation>}
332 def getPerson(name, client):
334 Get a Person for a client.
336 Duplicates L{IAccount.getPerson}.
339 @type client: L{Client<IClient>}
341 @rtype: L{Person<IPerson>}
344 def getGroup(name, client):
346 Get a Group for a client.
348 Duplicates L{IAccount.getGroup}.
351 @type client: L{Client<IClient>}
353 @rtype: L{Group<IGroup>}
356 def contactChangedNick(oldnick, newnick):
358 For the given person, changes the person's name to newnick, and
359 tells the contact list and any conversation windows with that person
362 @type oldnick: string
363 @type newnick: string