Mercurial > libervia-desktop
annotate cagou/plugins/plugin_wid_contact_list.py @ 233:ba8f3a4a5ac7
plugin chat: e2e encryption improvments:
OTR buttons has been replaced with a more generic one, which use new encryption mechanisms
to retrieve all current encryption algorithms (+ a button for plain text).
"refresh" and "authentify" buttons for OTR are temporarily removed.
Encryption state is checked on chat widget startup, and current encryption method is
selected (it will appear with a different background in encryption menu).
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 11 Aug 2018 18:34:16 +0200 |
parents | 9e5f9f0cee48 |
children | ff1efdeff53f |
rev | line source |
---|---|
9 | 1 #!/usr/bin/python |
2 # -*- coding: utf-8 -*- | |
3 | |
4 # Cagou: desktop/mobile frontend for Salut à Toi XMPP client | |
126 | 5 # Copyright (C) 2016-2018 Jérôme Poisson (goffi@goffi.org) |
9 | 6 |
7 # This program is free software: you can redistribute it and/or modify | |
8 # it under the terms of the GNU Affero General Public License as published by | |
9 # the Free Software Foundation, either version 3 of the License, or | |
10 # (at your option) any later version. | |
11 | |
12 # This program is distributed in the hope that it will be useful, | |
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 # GNU Affero General Public License for more details. | |
16 | |
17 # You should have received a copy of the GNU Affero General Public License | |
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 | |
20 | |
21 from sat.core import log as logging | |
22 log = logging.getLogger(__name__) | |
219 | 23 from cagou.core.constants import Const as C |
14 | 24 from sat.core.i18n import _ |
9 | 25 from sat_frontends.quick_frontend.quick_contact_list import QuickContactList |
22 | 26 from sat_frontends.tools import jid |
9 | 27 from kivy.uix.boxlayout import BoxLayout |
219 | 28 from cagou.core.utils import FilterBehavior |
223
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
29 from cagou.core.menu import SideMenu, TouchMenuBehaviour, TouchMenuItemBehaviour |
110
34dfe0e32064
contact list: text entered in header input do filtering in shown contacts
Goffi <goffi@goffi.org>
parents:
90
diff
changeset
|
30 from kivy.metrics import dp |
9 | 31 from kivy import properties |
15
56838ad5c84b
files reorganisation, cagou is now launched with python2 cagou.py in src/
Goffi <goffi@goffi.org>
parents:
14
diff
changeset
|
32 from cagou.core import cagou_widget |
56838ad5c84b
files reorganisation, cagou is now launched with python2 cagou.py in src/
Goffi <goffi@goffi.org>
parents:
14
diff
changeset
|
33 from cagou.core import image |
16
ba14b596b90e
host can now be get as a global value:
Goffi <goffi@goffi.org>
parents:
15
diff
changeset
|
34 from cagou import G |
221
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
35 from functools import partial |
219 | 36 import bisect |
221
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
37 import re |
9 | 38 |
39 | |
14 | 40 PLUGIN_INFO = { |
41 "name": _(u"contacts"), | |
42 "main": "ContactList", | |
43 "description": _(u"list of contacts"), | |
180
0ddd2b20cc6b
plugins chat, contact_list, settings, widget_selector: changed icons theme
Goffi <goffi@goffi.org>
parents:
126
diff
changeset
|
44 "icon_medium": u"{media}/icons/muchoslava/png/contact_list_no_border_blue_44.png" |
14 | 45 } |
46 | |
47 | |
221
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
48 class AddContactMenu(SideMenu): |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
49 profile = properties.StringProperty() |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
50 size_hint_close = (1, 0) |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
51 size_hint_open = (1, 0.5) |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
52 |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
53 def __init__(self, **kwargs): |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
54 super(AddContactMenu, self).__init__(**kwargs) |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
55 if self.profile is None: |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
56 log.warning(_(u"profile not set in AddContactMenu")) |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
57 self.profile = next(iter(G.host.profiles)) |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
58 |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
59 def addContact(self, contact_jid): |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
60 """Actually add the contact |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
61 |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
62 @param contact_jid(unicode): jid of the contact to add |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
63 """ |
223
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
64 self.hide() |
221
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
65 contact_jid = contact_jid.strip() |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
66 # FIXME: trivial jid verification |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
67 if not contact_jid or not re.match(r"[^@ ]+@[^@ ]+", contact_jid): |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
68 return |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
69 contact_jid = jid.JID(contact_jid).bare |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
70 G.host.bridge.addContact(contact_jid, |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
71 self.profile, |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
72 callback=lambda: G.host.addNote( |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
73 _(u"contact request"), |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
74 _(u"a contact request has been sent to {contact_jid}").format( |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
75 contact_jid=contact_jid)), |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
76 errback=partial(G.host.errback, |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
77 title=_(u"can't add contact"), |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
78 message=_(u"error while trying to add contact: {msg}"))) |
223
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
79 |
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
80 |
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
81 class DelContactMenu(SideMenu): |
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
82 size_hint_close = (1, 0) |
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
83 size_hint_open = (1, 0.5) |
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
84 |
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
85 def __init__(self, contact_item, **kwargs): |
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
86 self.contact_item = contact_item |
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
87 super(DelContactMenu, self).__init__(**kwargs) |
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
88 |
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
89 def do_delete_contact(self): |
221
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
90 self.hide() |
223
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
91 G.host.bridge.delContact(self.contact_item.jid.bare, |
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
92 self.contact_item.profile, |
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
93 callback=lambda: G.host.addNote( |
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
94 _(u"contact removed"), |
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
95 _(u"{contact_jid} has been removed from your contacts list").format( |
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
96 contact_jid=self.contact_item.jid.bare)), |
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
97 errback=partial(G.host.errback, |
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
98 title=_(u"can't remove contact"), |
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
99 message=_(u"error while trying to remove contact: {msg}"))) |
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
100 |
221
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
101 |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
102 |
9 | 103 class Avatar(image.Image): |
104 pass | |
105 | |
106 | |
223
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
107 class ContactItem(TouchMenuItemBehaviour, BoxLayout): |
219 | 108 base_width = dp(150) |
221
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
109 profile = properties.StringProperty() |
9 | 110 data = properties.DictProperty() |
111 jid = properties.StringProperty('') | |
112 | |
113 def __init__(self, **kwargs): | |
50
c45d6e9ec731
contact list: fixed contact list display
Goffi <goffi@goffi.org>
parents:
39
diff
changeset
|
114 super(ContactItem, self).__init__(**kwargs) |
9 | 115 |
223
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
116 def do_item_action(self, touch): |
221
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
117 assert self.profile |
219 | 118 # XXX: for now clicking on an item launch the corresponding Chat widget |
119 # behaviour should change in the future | |
120 try: | |
121 # FIXME: Q&D way to get chat plugin, should be replaced by a clean method | |
122 # in host | |
123 plg_infos = [p for p in G.host.getPluggedWidgets() | |
124 if 'chat' in p['import_name']][0] | |
125 except IndexError: | |
126 log.warning(u"No plugin widget found to display chat") | |
127 else: | |
128 factory = plg_infos['factory'] | |
129 G.host.switchWidget(self, factory(plg_infos, | |
130 jid.JID(self.jid), | |
221
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
131 profiles=[self.profile])) |
22 | 132 |
223
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
133 def getMenuChoices(self): |
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
134 choices = [] |
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
135 choices.append(dict(text=_(u'delete'), |
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
136 index=len(choices)+1, |
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
137 callback=self.main_wid.removeContact)) |
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
138 return choices |
22 | 139 |
223
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
140 |
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
141 class ContactList(QuickContactList, cagou_widget.CagouWidget, FilterBehavior, |
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
142 TouchMenuBehaviour): |
219 | 143 float_layout = properties.ObjectProperty() |
144 layout = properties.ObjectProperty() | |
9 | 145 |
146 def __init__(self, host, target, profiles): | |
16
ba14b596b90e
host can now be get as a global value:
Goffi <goffi@goffi.org>
parents:
15
diff
changeset
|
147 QuickContactList.__init__(self, G.host, profiles) |
ba14b596b90e
host can now be get as a global value:
Goffi <goffi@goffi.org>
parents:
15
diff
changeset
|
148 cagou_widget.CagouWidget.__init__(self) |
219 | 149 FilterBehavior.__init__(self) |
150 self._wid_map = {} # (profile, bare_jid) to widget map | |
17
5c9feaa060a5
contact list: added call to the new postInit method
Goffi <goffi@goffi.org>
parents:
16
diff
changeset
|
151 self.postInit() |
219 | 152 if len(self.profiles) != 1: |
153 raise NotImplementedError('multi profiles is not implemented yet') | |
154 self.update(profile=next(iter(self.profiles))) | |
9 | 155 |
221
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
156 def addContactMenu(self): |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
157 """Show the "add a contact" menu""" |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
158 # FIXME: for now we add contact to the first profile we find |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
159 profile = next(iter(self.profiles)) |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
160 AddContactMenu(profile=profile).show() |
e1a385a791cc
plugin contact list: implemented contact addition
Goffi <goffi@goffi.org>
parents:
219
diff
changeset
|
161 |
223
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
162 def removeContact(self, menu_label): |
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
163 item = self.menu_item |
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
164 self.clear_menu() |
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
165 DelContactMenu(contact_item=item).show() |
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
166 |
110
34dfe0e32064
contact list: text entered in header input do filtering in shown contacts
Goffi <goffi@goffi.org>
parents:
90
diff
changeset
|
167 def onHeaderInputComplete(self, wid, text): |
219 | 168 self.do_filter(self.layout.children, |
169 text, | |
170 lambda c: c.jid, | |
171 width_cb=lambda c: c.base_width, | |
172 height_cb=lambda c: c.minimum_height, | |
173 ) | |
174 | |
175 def _addContactItem(self, bare_jid, profile): | |
176 """Create a new ContactItem instance, and add it | |
110
34dfe0e32064
contact list: text entered in header input do filtering in shown contacts
Goffi <goffi@goffi.org>
parents:
90
diff
changeset
|
177 |
219 | 178 item will be added in a sorted position |
179 @param bare_jid(jid.JID): entity bare JID | |
180 @param profile(unicode): profile where the contact is | |
181 """ | |
182 data = G.host.contact_lists[profile].getItem(bare_jid) | |
223
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
183 wid = ContactItem(profile=profile, data=data, jid=bare_jid, main_wid=self) |
219 | 184 child_jids = [c.jid for c in reversed(self.layout.children)] |
185 idx = bisect.bisect_right(child_jids, bare_jid) | |
186 self.layout.add_widget(wid, -idx) | |
187 self._wid_map[(profile, bare_jid)] = wid | |
9 | 188 |
189 def update(self, entities=None, type_=None, profile=None): | |
50
c45d6e9ec731
contact list: fixed contact list display
Goffi <goffi@goffi.org>
parents:
39
diff
changeset
|
190 log.debug("update: %s %s %s" % (entities, type_, profile)) |
219 | 191 if type_ == None or type_ == C.UPDATE_STRUCTURE: |
192 log.debug("full contact list update") | |
193 self.layout.clear_widgets() | |
194 for bare_jid, data in self.items_sorted.iteritems(): | |
223
9e5f9f0cee48
plugin contact list: use new TouchMenuBehaviour to implement contact deletion
Goffi <goffi@goffi.org>
parents:
221
diff
changeset
|
195 wid = ContactItem(profile=profile, data=data, jid=bare_jid, main_wid=self) |
219 | 196 self.layout.add_widget(wid) |
197 self._wid_map[(profile, bare_jid)] = wid | |
198 elif type_ == C.UPDATE_MODIFY: | |
199 for entity in entities: | |
200 entity_bare = entity.bare | |
201 wid = self._wid_map[(profile, entity_bare)] | |
202 wid.data = G.host.contact_lists[profile].getItem(entity_bare) | |
203 elif type_ == C.UPDATE_ADD: | |
204 for entity in entities: | |
205 self._addContactItem(entity.bare, profile) | |
206 elif type_ == C.UPDATE_DELETE: | |
207 for entity in entities: | |
208 try: | |
209 self.layout.remove_widget(self._wid_map.pop((profile, entity.bare))) | |
210 except KeyError: | |
211 log.debug("entity not found: {entity}".format(entity=entity.bare)) | |
212 else: | |
213 log.debug("update type not handled: {update_type}".format(update_type=type_)) |