-
Notifications
You must be signed in to change notification settings - Fork 5
/
Contacts.py
245 lines (226 loc) · 8.42 KB
/
Contacts.py
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
#(C) Marek Chrusciel,
# Jakub Kosinski,
# Marcin Krupowicz,
# Mateusz Strycharski
#
# $Id$
from GGConstans import *
from Exceptions import *
import types
class Contact(object):
"""
Klasa reprezentujaca pojedynczy kontakt. Zawiera nastepujace pola (wszystkie publiczne):
* uin - numer uzytkownika
* name - imie uzytkownika
* surname - nazwisko uzytkownika
* shown_name - nazwa wyswietlana
* nick - pseudonim uzytkownika
* mobilephone - numer telefonu komorkowego
* group - nazwa grupy
* email - adres email uzytkownika
* available - okresla dzwieki zwiazane z pojawieniem sie danej osoby i przyjmuje wartosci 0 (uzyte zostana ustawienia globalne),
1 (dzwiek powiadomienia wylaczony) lub 2 (zostanie odtworzony plik okreslony w polu available_source)
* available_source - sciezka do pliku opisanego wyzej
* message - dziala podobnie do available, z tym, ze okresla dzwiek przychodzacej wiadomosci
* message_source - sciezka do dzwieku odgrywanego przy otrzymaniu wiadomosci (opis powyzej)
* hidden - okresla, czy bedziemy dostepni (0) czy niedostepni (1) dla danej osoby w trybie 'tylko dla znajomych'
* telephone - numer telefonu
Powyzsze pola mozemy przekazac w konstruktorze klase w formie slownika na dwa sposoby. Pierwszy z nich podaje slownik z kluczami
o nazwach wlasciwosci (jedynym wymaganym kluczem jest 'uin') badz w formacie z slownika z kluczem 'request_string' o wartosci postaci:
name;surname;nick;shown_name;mobilephone;group;uin;email;available;available_source;message;message_source;hidden;telephone
Oprocz powyzszych pol, klasa posiada jeszcze pola modyfikowane przez klasy GGNotifyReply oraz GGStatus:
* status - status uzytkownika
* ip - adres IP uzytkownika do bezposrednich polaczen
* port - port do bezposrednich polaczen
* version - wersja klienta
* image_size - maksymalny rozmiar przyjmowanej grafiki
* description - opis (moze byc pusty)
* return_time - data powrotu uzytkownika (jesli nie ma, to = 0)
* user_type - typ uzytkownika (z klasy GGUserTypes)
Przyklady uzycia:
1. Contact({'uin':12345, 'name':'Tola', 'shown_name':'Tola', 'hidden':1, 'message':2, 'message_source':'/home/user/message.wav'})
Utworzy kontakt o numerze 12345, nazwie 'Tola', wyswietlanej nazwie 'Tola', ukryty w trybie 'tylko dla znajomych' oraz ze zdefiniowanym
dzwiekiem odgrywanym podczas przychodzacej wiadomosci
2. Contact({'request_string':'Tola;;;Tola;;;12345;;0;1;/home/user/message.wav;1;'})
Utworzy kontakt jak wyzej.
"""
status = GGStatuses.NotAvail
ip = 0
port = 0
version = 0 #zera sa po to, zeby sie nie odwolywac do None, jesli pola nie zostaly jeszcze wypelnione
image_size = 0
description = ""
return_time = 0
user_type = GGUserTypes.Normal
def __init__(self, params):
assert type(params) == types.DictType
if params.has_key('request_string'):
self.name, self.surname, self.nick, self.shown_name, self.mobilephone, self.group, self.uin, self.email, self.available, self.available_source, self.message, self.message_source, self.hidden, self.telephone = params['request_string'].split(";")
self.uin = int(self.uin)
if self.shown_name == "":
self.shown_name = str(self.uin)
if self.available == "":
self.available = 0
else:
self.available = int(self.available)
if self.message == "":
self.message = 0
else:
self.message = int(self.message)
if self.hidden == "":
self.hidden = 0
else:
self.hidden = int(self.hidden)
else: #konstruktor nie jest slownikiem z jedynym kluczem 'request_string', zawiera pola takie jak uin, surname, itp.
self.uin = int(params['uin'])
if params.has_key('name'):
self.name = params['name']
else:
self.name = ""
if params.has_key('surname'):
self.surname = params['surname']
else:
self.surname = ""
if params.has_key('nick'):
self.nick = params['nick']
else:
self.nick = ""
if params.has_key('shown_name'):
self.shown_name = params['shown_name']
else:
self.shown_name = str(repr(params['uin']))
if params.has_key('mobilephone'):
self.mobilephone = str(params['mobilephone'])
else:
self.mobilephone = ""
if params.has_key('group'):
self.group = params['group']
else:
self.group = ""
if params.has_key('email'):
self.email = params['email']
else:
self.email = ""
if params.has_key('available'):
self.available = int(params['available'])
else:
self.available = 0
if params.has_key('available_source'):
self.available_source = params['available_source']
else:
self.available_source = ""
if params.has_key('message'):
self.message = int(params['message'])
else:
self.message = 0
if params.has_key('message_source'):
self.message_source = params['message_source']
else:
self.message_source = ""
if params.has_key('hidden'):
self.hidden = int(params['hidden'])
else:
self.hidden = 0
if params.has_key('telephone'):
self.telephone = str(params['telephone'])
else:
self.telephone = ""
def request_string(self):
return ";".join([self.name, self.surname, self.nick, self.shown_name, self.mobilephone, self.group, str(self.uin), self.email, str(self.available), self.available_source, str(self.message), self.message_source, str(self.hidden), self.telephone])
class ContactsList(list):
"""
Klasa reprezentujaca liste kontaktow GG. Wpisy sa obiektami klast Contact. Konstruktor przyjmuje dwa rodzaje parametrow.
Pierwszy z nich to lista obiektow typu Contact, drugi to zawartosc pliku z kontaktami (wartosci oddzielone srednikami, opis w klasie Contact)
Dostep do kontaktow realizowany jest za pomoca uin, np. list['12345'] zwroci obiekt Contact o uin=12345 lub None w przypadku, gdy kontaktu
nie ma na liscie.
"""
def __init__(self, contacts = []):
assert type(contacts) == types.ListType or types.StringType
if type(contacts) == types.ListType:
for c in contacts:
assert type(c) == Contact
self.data = contacts
else:
list = contacts.split("\n")
tmp = []
for c in list:
if c != "" and c != "GG70ExportString,;":
tmp.append({'request_string':c})
clist = []
for c in tmp:
clist.append(Contact(c))
self.data = clist
def add_contact(self, contact):
"""
Metoda dodajaca kontakt. Jako parametr przyjmuje obiekt klasy Contact lub napis w formacie pliku kontaktow Gadu-Gadu.
"""
if type(contact) == types.StringType:
c = Contact(contact)
elif type(contact) == Contact:
c = contact
else:
raise AssertionError
if self[c.uin] != None: #jest juz kontakt o takim numerku
x = self[c.uin]
self.data.remove(x) #usuwamy go wiec
self.add_contact(c) #.. i tworzymy nowy :]
else:
self.data.append(c)
def remove_contact(self, uin):
"""
Metoda usuwajaca kontakt o numerze uin z listy. W przypadku, gdy na liscie nie ma kontaktu o podanym uin wyrzucany jest wyjatek KeyError.
"""
contact = self[uin]
if contact == None:
raise GGNotInContactsList(uin)
else:
self.data.remove(contact)
def __index_by_uin(self, uin):
"""
Znajduje miejsce w liscie kontaktow kontaktu u numerku 'uin'
Zwraca:
* miejsce w liscie kontaktow (jesli znaleziono)
* -1 (jesli nie znaleziono)
"""
i = 0
for c in self.data:
if int(c.uin) == int(uin):
return i
i += 1
return -1
def __getitem__(self, uin):
"""
Zwraca:
* kontakt o numerze uin, jesli taki jest na liscie kontaktow
* None gdy nie ma takiego kontaktu na liscie
"""
index = self.__index_by_uin(uin)
if index == -1:
return None
else:
return self.data[index]
def __len__(self):
return len(self.data)
def __contains__(self, contact):
"""
Sprawdza czy dany kontakt jest na liscie kontaktow
parametr:
* contact (typu Contact lub integer)
uzycie:
* if 3932154 in contacts_list:
pass
* c = Contact({"uin":423543, "shown_name":"Juzefina})
if c in contacts_list:
pass
"""
if type(contact) == types.IntType:
return self[contact] != None
elif type(contact) == Contact:
return self.data.__contains__(contact)
else:
raise AssertionError
def export_request_string(self):
"""
Metoda zwracajaca cala liste kontaktow w formacie pliku kontaktow Gadu-Gadu. Kazda linia reprezentuje jeden kontakt.
"""
return "\n".join(map(Contact.request_string, self.data))