This file is indexed.

/usr/share/pyshared/twisted/words/im/basechat.py is in python-twisted-words 11.1.0-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
# -*- 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 OFFLINE, ONLINE, AWAY


class ContactsList:
    """A GUI object that displays a contacts list"""
    def __init__(self, chatui):
        """
        @param chatui: ???
        @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.

        @type person: L{Person<interfaces.IPerson>}
        """
        if not self.contacts.has_key(person.name):
            self.contacts[person.name] = person
        if not self.onlineContacts.has_key(person.name) and \
            (person.status == ONLINE or person.status == AWAY):
            self.onlineContacts[person.name] = person
        if self.onlineContacts.has_key(person.name) 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.

        @type client: L{Client<interfaces.IClient>}
        """
        if not client 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.

        @type client: L{Client<interfaces.IClient>}
        """
        if client in self.clients:
            self.clients.remove(client)

    def contactChangedNick(self, person, newnick):
        oldname = person.name
        if self.contacts.has_key(oldname):
            del self.contacts[oldname]
            person.name = newnick
            self.contacts[newnick] = person
            if self.onlineContacts.has_key(oldname):
                del self.onlineContacts[oldname]
                self.onlineContacts[newnick] = person


class Conversation:
    """A GUI window of a conversation with a specific person"""
    def __init__(self, person, chatui):
        """
        @type person: L{Person<interfaces.IPerson>}
        @type chatui: L{ChatUI}
        """
        self.chatui = chatui
        self.person = person

    def show(self):
        """Displays the ConversationWindow"""
        raise NotImplementedError("Subclasses must implement this method")

    def hide(self):
        """Hides the ConversationWindow"""
        raise NotImplementedError("Subclasses must implement this method")

    def sendText(self, text):
        """Sends text to the person with whom the user is conversing.

        @returntype: L{Deferred<twisted.internet.defer.Deferred>}
        """
        self.person.sendMessage(text, None)

    def showMessage(self, text, metadata=None):
        """Display a message sent from the person with whom she is conversing

        @type text: string
        @type metadata: dict
        """
        raise NotImplementedError("Subclasses must implement this method")

    def contactChangedNick(self, person, newnick):
        """Change a person's name.

        @type person: L{Person<interfaces.IPerson>}
        @type newnick: string
        """
        self.person.name = newnick



class GroupConversation:
    """A conversation with a group of people."""
    def __init__(self, group, chatui):
        """
        @type group: L{Group<interfaces.IGroup>}
        @param chatui: ???
        @type chatui: L{ChatUI}
        """
        self.chatui = chatui
        self.group = group
        self.members = []

    def show(self):
        """Displays the GroupConversationWindow."""
        raise NotImplementedError("Subclasses must implement this method")

    def hide(self):
        """Hides the GroupConversationWindow."""
        raise NotImplementedError("Subclasses must implement this method")

    def sendText(self, text):
        """Sends text to the group.

        @type text: string
        @returntype: L{Deferred<twisted.internet.defer.Deferred>}
        """
        self.group.sendGroupMessage(text, None)

    def showGroupMessage(self, sender, text, metadata=None):
        """Displays to the user a message sent to this group from the given sender
        @type sender: string (XXX: Not Person?)
        @type text: string
        @type metadata: dict
        """
        raise NotImplementedError("Subclasses must implement this method")

    def setGroupMembers(self, members):
        """Sets the list of members in the group and displays it to the user
        """
        self.members = members

    def setTopic(self, topic, author):
        """Displays the topic (from the server) for the group conversation window

        @type topic: string
        @type author: string (XXX: Not Person?)
        """
        raise NotImplementedError("Subclasses must implement this method")

    def memberJoined(self, member):
        """Adds the given member to the list of members in the group conversation
        and displays this to the user

        @type member: string (XXX: Not Person?)
        """
        if not member in self.members:
            self.members.append(member)

    def memberChangedNick(self, oldnick, newnick):
        """Changes the oldnick in the list of members to newnick and displays this
        change to the user

        @type oldnick: string
        @type newnick: string
        """
        if oldnick in self.members:
            self.members.remove(oldnick)
            self.members.append(newnick)
            #self.chatui.contactChangedNick(oldnick, newnick)

    def memberLeft(self, member):
        """Deletes the given member from the list of members in the group
        conversation and displays the change to the user

        @type member: string
        """
        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{basesupport.AbstractAccount}) and values that are
        L{Person<interfaces.IPerson>}.
    @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{basesupport.AbstractAccount}) and values that are
        L{Group<interfaces.IGroup>}
    @ivar groups: A cache of all the user groups associated with this client.

    @type onlineClients: C{list} of L{Client<interfaces.IClient>}
    @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):
        """
        Notifies user that an account has been signed on to.

        @type client: L{Client<interfaces.IClient>}
        @returns: client, so that I may be used in a callback chain
        """
        print "signing onto", client.accountName
        self.onlineClients.append(client)
        self.contactsList.registerAccountClient(client)
        return client


    def unregisterAccountClient(self, client):
        """
        Notifies user that an account has been signed off or disconnected

        @type client: L{Client<interfaces.IClient>}
        """
        print "signing off from", client.accountName
        self.onlineClients.remove(client)
        self.contactsList.unregisterAccountClient(client)


    def getContactsList(self):
        """
        @returntype: L{ContactsList}
        """
        return self.contactsList


    def getConversation(self, person, Class=Conversation, stayHidden=0):
        """
        For the given person object, returns the conversation window
        or creates and returns a new conversation window if one does not exist.

        @type person: L{Person<interfaces.IPerson>}
        @type Class: L{Conversation<interfaces.IConversation>} class
        @type stayHidden: boolean

        @returntype: L{Conversation<interfaces.IConversation>}
        """
        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=0):
        """
        For the given group object, returns the group conversation window or
        creates and returns a new group conversation window if it doesn't exist

        @type group: L{Group<interfaces.IGroup>}
        @type Class: L{Conversation<interfaces.IConversation>} class
        @type stayHidden: boolean

        @returntype: L{GroupConversation<interfaces.IGroupConversation>}
        """
        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, returns the instance of the
        AbstractPerson subclass, or creates and returns a new AbstractPerson
        subclass of the type Class

        @type name: string
        @type client: L{Client<interfaces.IClient>}

        @returntype: L{Person<interfaces.IPerson>}
        """
        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, returns the instance of the
        AbstractGroup subclass, or creates and returns a new AbstractGroup
        subclass of the type Class

        @type name: string
        @type client: L{Client<interfaces.IClient>}

        @returntype: L{Group<interfaces.IGroup>}
        """
        # 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{Person<interfaces.IPerson>}
        @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 self.persons.has_key((oldnick, person.account)):
            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