%PDF- %PDF-
Direktori : /lib/python3/dist-packages/twisted/words/im/ |
Current File : //lib/python3/dist-packages/twisted/words/im/basechat.py |
# -*- test-case-name: twisted.words.test.test_basechat -*- # Copyright (c) Twisted Matrix Laboratories. # See LICENSE for details. """ Base classes for Instance Messenger clients. """ from twisted.words.im.locals import AWAY, OFFLINE, ONLINE class ContactsList: """ A GUI object that displays a contacts list. @ivar chatui: The GUI chat client associated with this contacts list. @type chatui: L{ChatUI} @ivar contacts: The contacts. @type contacts: C{dict} mapping C{str} to a L{IPerson<interfaces.IPerson>} provider @ivar onlineContacts: The contacts who are currently online (have a status that is not C{OFFLINE}). @type onlineContacts: C{dict} mapping C{str} to a L{IPerson<interfaces.IPerson>} provider @ivar clients: The signed-on clients. @type clients: C{list} of L{IClient<interfaces.IClient>} providers """ def __init__(self, chatui): """ @param chatui: The GUI chat client associated with this contacts list. @type chatui: L{ChatUI} """ self.chatui = chatui self.contacts = {} self.onlineContacts = {} self.clients = [] def setContactStatus(self, person): """ Inform the user that a person's status has changed. @param person: The person whose status has changed. @type person: L{IPerson<interfaces.IPerson>} provider """ if person.name not in self.contacts: self.contacts[person.name] = person if person.name not in self.onlineContacts and ( person.status == ONLINE or person.status == AWAY ): self.onlineContacts[person.name] = person if person.name in self.onlineContacts and person.status == OFFLINE: del self.onlineContacts[person.name] def registerAccountClient(self, client): """ Notify the user that an account client has been signed on to. @param client: The client being added to your list of account clients. @type client: L{IClient<interfaces.IClient>} provider """ if client not in self.clients: self.clients.append(client) def unregisterAccountClient(self, client): """ Notify the user that an account client has been signed off or disconnected from. @param client: The client being removed from the list of account clients. @type client: L{IClient<interfaces.IClient>} provider """ if client in self.clients: self.clients.remove(client) def contactChangedNick(self, person, newnick): """ Update your contact information to reflect a change to a contact's nickname. @param person: The person in your contacts list whose nickname is changing. @type person: L{IPerson<interfaces.IPerson>} provider @param newnick: The new nickname for this person. @type newnick: C{str} """ oldname = person.name if oldname in self.contacts: del self.contacts[oldname] person.name = newnick self.contacts[newnick] = person if oldname in self.onlineContacts: del self.onlineContacts[oldname] self.onlineContacts[newnick] = person class Conversation: """ A GUI window of a conversation with a specific person. @ivar person: The person who you're having this conversation with. @type person: L{IPerson<interfaces.IPerson>} provider @ivar chatui: The GUI chat client associated with this conversation. @type chatui: L{ChatUI} """ def __init__(self, person, chatui): """ @param person: The person who you're having this conversation with. @type person: L{IPerson<interfaces.IPerson>} provider @param chatui: The GUI chat client associated with this conversation. @type chatui: L{ChatUI} """ self.chatui = chatui self.person = person def show(self): """ Display the ConversationWindow. """ raise NotImplementedError("Subclasses must implement this method") def hide(self): """ Hide the ConversationWindow. """ raise NotImplementedError("Subclasses must implement this method") def sendText(self, text): """ Send text to the person with whom the user is conversing. @param text: The text to be sent. @type text: C{str} """ self.person.sendMessage(text, None) def showMessage(self, text, metadata=None): """ Display a message sent from the person with whom the user is conversing. @param text: The sent message. @type text: C{str} @param metadata: Metadata associated with this message. @type metadata: C{dict} """ raise NotImplementedError("Subclasses must implement this method") def contactChangedNick(self, person, newnick): """ Change a person's name. @param person: The person whose nickname is changing. @type person: L{IPerson<interfaces.IPerson>} provider @param newnick: The new nickname for this person. @type newnick: C{str} """ self.person.name = newnick class GroupConversation: """ A GUI window of a conversation with a group of people. @ivar chatui: The GUI chat client associated with this conversation. @type chatui: L{ChatUI} @ivar group: The group of people that are having this conversation. @type group: L{IGroup<interfaces.IGroup>} provider @ivar members: The names of the people in this conversation. @type members: C{list} of C{str} """ def __init__(self, group, chatui): """ @param chatui: The GUI chat client associated with this conversation. @type chatui: L{ChatUI} @param group: The group of people that are having this conversation. @type group: L{IGroup<interfaces.IGroup>} provider """ self.chatui = chatui self.group = group self.members = [] def show(self): """ Display the GroupConversationWindow. """ raise NotImplementedError("Subclasses must implement this method") def hide(self): """ Hide the GroupConversationWindow. """ raise NotImplementedError("Subclasses must implement this method") def sendText(self, text): """ Send text to the group. @param text: The text to be sent. @type text: C{str} """ self.group.sendGroupMessage(text, None) def showGroupMessage(self, sender, text, metadata=None): """ Display to the user a message sent to this group from the given sender. @param sender: The person sending the message. @type sender: C{str} @param text: The sent message. @type text: C{str} @param metadata: Metadata associated with this message. @type metadata: C{dict} """ raise NotImplementedError("Subclasses must implement this method") def setGroupMembers(self, members): """ Set the list of members in the group. @param members: The names of the people that will be in this group. @type members: C{list} of C{str} """ self.members = members def setTopic(self, topic, author): """ Change the topic for the group conversation window and display this change to the user. @param topic: This group's topic. @type topic: C{str} @param author: The person changing the topic. @type author: C{str} """ raise NotImplementedError("Subclasses must implement this method") def memberJoined(self, member): """ Add the given member to the list of members in the group conversation and displays this to the user. @param member: The person joining the group conversation. @type member: C{str} """ if member not in self.members: self.members.append(member) def memberChangedNick(self, oldnick, newnick): """ Change the nickname for a member of the group conversation and displays this change to the user. @param oldnick: The old nickname. @type oldnick: C{str} @param newnick: The new nickname. @type newnick: C{str} """ if oldnick in self.members: self.members.remove(oldnick) self.members.append(newnick) def memberLeft(self, member): """ Delete the given member from the list of members in the group conversation and displays the change to the user. @param member: The person leaving the group conversation. @type member: C{str} """ if member in self.members: self.members.remove(member) class ChatUI: """ A GUI chat client. @type conversations: C{dict} of L{Conversation} @ivar conversations: A cache of all the direct windows. @type groupConversations: C{dict} of L{GroupConversation} @ivar groupConversations: A cache of all the group windows. @type persons: C{dict} with keys that are a C{tuple} of (C{str}, L{IAccount<interfaces.IAccount>} provider) and values that are L{IPerson<interfaces.IPerson>} provider @ivar persons: A cache of all the users associated with this client. @type groups: C{dict} with keys that are a C{tuple} of (C{str}, L{IAccount<interfaces.IAccount>} provider) and values that are L{IGroup<interfaces.IGroup>} provider @ivar groups: A cache of all the groups associated with this client. @type onlineClients: C{list} of L{IClient<interfaces.IClient>} providers @ivar onlineClients: A list of message sources currently online. @type contactsList: L{ContactsList} @ivar contactsList: A contacts list. """ def __init__(self): self.conversations = {} self.groupConversations = {} self.persons = {} self.groups = {} self.onlineClients = [] self.contactsList = ContactsList(self) def registerAccountClient(self, client): """ Notify the user that an account has been signed on to. @type client: L{IClient<interfaces.IClient>} provider @param client: The client account for the person who has just signed on. @rtype: L{IClient<interfaces.IClient>} provider @return: The client, so that it may be used in a callback chain. """ self.onlineClients.append(client) self.contactsList.registerAccountClient(client) return client def unregisterAccountClient(self, client): """ Notify the user that an account has been signed off or disconnected. @type client: L{IClient<interfaces.IClient>} provider @param client: The client account for the person who has just signed off. """ self.onlineClients.remove(client) self.contactsList.unregisterAccountClient(client) def getContactsList(self): """ Get the contacts list associated with this chat window. @rtype: L{ContactsList} @return: The contacts list associated with this chat window. """ return self.contactsList def getConversation(self, person, Class=Conversation, stayHidden=False): """ For the given person object, return the conversation window or create and return a new conversation window if one does not exist. @type person: L{IPerson<interfaces.IPerson>} provider @param person: The person whose conversation window we want to get. @type Class: L{IConversation<interfaces.IConversation>} implementor @param Class: The kind of conversation window we want. If the conversation window for this person didn't already exist, create one of this type. @type stayHidden: C{bool} @param stayHidden: Whether or not the conversation window should stay hidden. @rtype: L{IConversation<interfaces.IConversation>} provider @return: The conversation window. """ conv = self.conversations.get(person) if not conv: conv = Class(person, self) self.conversations[person] = conv if stayHidden: conv.hide() else: conv.show() return conv def getGroupConversation(self, group, Class=GroupConversation, stayHidden=False): """ For the given group object, return the group conversation window or create and return a new group conversation window if it doesn't exist. @type group: L{IGroup<interfaces.IGroup>} provider @param group: The group whose conversation window we want to get. @type Class: L{IConversation<interfaces.IConversation>} implementor @param Class: The kind of conversation window we want. If the conversation window for this person didn't already exist, create one of this type. @type stayHidden: C{bool} @param stayHidden: Whether or not the conversation window should stay hidden. @rtype: L{IGroupConversation<interfaces.IGroupConversation>} provider @return: The group conversation window. """ conv = self.groupConversations.get(group) if not conv: conv = Class(group, self) self.groupConversations[group] = conv if stayHidden: conv.hide() else: conv.show() return conv def getPerson(self, name, client): """ For the given name and account client, return an instance of a L{IGroup<interfaces.IPerson>} provider or create and return a new instance of a L{IGroup<interfaces.IPerson>} provider. @type name: C{str} @param name: The name of the person of interest. @type client: L{IClient<interfaces.IClient>} provider @param client: The client account of interest. @rtype: L{IPerson<interfaces.IPerson>} provider @return: The person with that C{name}. """ account = client.account p = self.persons.get((name, account)) if not p: p = account.getPerson(name) self.persons[name, account] = p return p def getGroup(self, name, client): """ For the given name and account client, return an instance of a L{IGroup<interfaces.IGroup>} provider or create and return a new instance of a L{IGroup<interfaces.IGroup>} provider. @type name: C{str} @param name: The name of the group of interest. @type client: L{IClient<interfaces.IClient>} provider @param client: The client account of interest. @rtype: L{IGroup<interfaces.IGroup>} provider @return: The group with that C{name}. """ # I accept 'client' instead of 'account' in my signature for # backwards compatibility. (Groups changed to be Account-oriented # in CVS revision 1.8.) account = client.account g = self.groups.get((name, account)) if not g: g = account.getGroup(name) self.groups[name, account] = g return g def contactChangedNick(self, person, newnick): """ For the given C{person}, change the C{person}'s C{name} to C{newnick} and tell the contact list and any conversation windows with that C{person} to change as well. @type person: L{IPerson<interfaces.IPerson>} provider @param person: The person whose nickname will get changed. @type newnick: C{str} @param newnick: The new C{name} C{person} will take. """ oldnick = person.name if (oldnick, person.account) in self.persons: conv = self.conversations.get(person) if conv: conv.contactChangedNick(person, newnick) self.contactsList.contactChangedNick(person, newnick) del self.persons[oldnick, person.account] person.name = newnick self.persons[person.name, person.account] = person