Mercurial > libervia-backend
comparison sat/core/sat_main.py @ 3254:6cf4bd6972c2
core, frontends: avatar refactoring:
/!\ huge commit
Avatar logic has been reworked around the IDENTITY plugin: plugins able to handle avatar
or other identity related metadata (like nicknames) register to IDENTITY plugin in the
same way as for other features like download/upload. Once registered, IDENTITY plugin will
call them when suitable in order of priority, and handle caching.
Methods to manage those metadata from frontend now use serialised data.
For now `avatar` and `nicknames` are handled:
- `avatar` is now a dict with `path` + metadata like `media_type`, instead of just a string
path
- `nicknames` is now a list of nicknames in order of priority. This list is never empty,
and `nicknames[0]` should be the preferred nickname to use by frontends in most cases.
In addition to contact specified nicknames, user set nickname (the one set in roster) is
used in priority when available.
Among the side changes done with this commit, there are:
- a new `contactGet` bridge method to get roster metadata for a single contact
- SatPresenceProtocol.send returns a Deferred to check when it has actually been sent
- memory's methods to handle entities data now use `client` as first argument
- metadata filter can be specified with `getIdentity`
- `getAvatar` and `setAvatar` are now part of the IDENTITY plugin instead of XEP-0054 (and
there signature has changed)
- `isRoom` and `getBareOrFull` are now part of XEP-0045 plugin
- jp avatar/get command uses `xdg-open` first when available for `--show` flag
- `--no-cache` has been added to jp avatar/get and identity/get
- jp identity/set has been simplified, explicit options (`--nickname` only for now) are
used instead of `--field`. `--field` may come back in the future if necessary for extra
data.
- QuickContactList `SetContact` now handle None as a value, and doesn't use it to delete the
metadata anymore
- improved cache handling for `metadata` and `nicknames` in quick frontend
- new `default` argument in QuickContactList `getCache`
author | Goffi <goffi@goffi.org> |
---|---|
date | Tue, 14 Apr 2020 21:00:33 +0200 |
parents | b0c57c9a4bd8 |
children | f300d78f08f3 |
comparison
equal
deleted
inserted
replaced
3253:1af840e84af7 | 3254:6cf4bd6972c2 |
---|---|
100 self.bridge.register_method("getReady", lambda: self.initialised) | 100 self.bridge.register_method("getReady", lambda: self.initialised) |
101 self.bridge.register_method("getVersion", lambda: self.full_version) | 101 self.bridge.register_method("getVersion", lambda: self.full_version) |
102 self.bridge.register_method("getFeatures", self.getFeatures) | 102 self.bridge.register_method("getFeatures", self.getFeatures) |
103 self.bridge.register_method("profileNameGet", self.memory.getProfileName) | 103 self.bridge.register_method("profileNameGet", self.memory.getProfileName) |
104 self.bridge.register_method("profilesListGet", self.memory.getProfilesList) | 104 self.bridge.register_method("profilesListGet", self.memory.getProfilesList) |
105 self.bridge.register_method( | 105 self.bridge.register_method("getEntityData", self.memory._getEntityData) |
106 "getEntityData", | |
107 lambda jid_, keys, profile: self.memory.getEntityData( | |
108 jid.JID(jid_), keys, profile | |
109 ), | |
110 ) | |
111 self.bridge.register_method("getEntitiesData", self.memory._getEntitiesData) | 106 self.bridge.register_method("getEntitiesData", self.memory._getEntitiesData) |
112 self.bridge.register_method("profileCreate", self.memory.createProfile) | 107 self.bridge.register_method("profileCreate", self.memory.createProfile) |
113 self.bridge.register_method("asyncDeleteProfile", self.memory.asyncDeleteProfile) | 108 self.bridge.register_method("asyncDeleteProfile", self.memory.asyncDeleteProfile) |
114 self.bridge.register_method("profileStartSession", self.memory.startSession) | 109 self.bridge.register_method("profileStartSession", self.memory.startSession) |
115 self.bridge.register_method( | 110 self.bridge.register_method( |
116 "profileIsSessionStarted", self.memory._isSessionStarted | 111 "profileIsSessionStarted", self.memory._isSessionStarted |
117 ) | 112 ) |
118 self.bridge.register_method("profileSetDefault", self.memory.profileSetDefault) | 113 self.bridge.register_method("profileSetDefault", self.memory.profileSetDefault) |
119 self.bridge.register_method("connect", self._connect) | 114 self.bridge.register_method("connect", self._connect) |
120 self.bridge.register_method("disconnect", self.disconnect) | 115 self.bridge.register_method("disconnect", self.disconnect) |
116 self.bridge.register_method("contactGet", self._contactGet) | |
121 self.bridge.register_method("getContacts", self.getContacts) | 117 self.bridge.register_method("getContacts", self.getContacts) |
122 self.bridge.register_method("getContactsFromGroup", self.getContactsFromGroup) | 118 self.bridge.register_method("getContactsFromGroup", self.getContactsFromGroup) |
123 self.bridge.register_method("getMainResource", self.memory._getMainResource) | 119 self.bridge.register_method("getMainResource", self.memory._getMainResource) |
124 self.bridge.register_method( | 120 self.bridge.register_method( |
125 "getPresenceStatuses", self.memory._getPresenceStatuses | 121 "getPresenceStatuses", self.memory._getPresenceStatuses |
537 return ret | 533 return ret |
538 | 534 |
539 d_list.addCallback(buildFeatures, list(self.plugins.keys())) | 535 d_list.addCallback(buildFeatures, list(self.plugins.keys())) |
540 return d_list | 536 return d_list |
541 | 537 |
538 def _contactGet(self, entity_jid_s, profile_key): | |
539 client = self.getClient(profile_key) | |
540 entity_jid = jid.JID(entity_jid_s) | |
541 return defer.ensureDeferred(self.getContact(client, entity_jid)) | |
542 | |
543 async def getContact(self, client, entity_jid): | |
544 # we want to be sure that roster has been received | |
545 await client.roster.got_roster | |
546 item = client.roster.getItem(entity_jid) | |
547 if item is None: | |
548 raise exceptions.NotFound(f"{entity_jid} is not in roster!") | |
549 return (client.roster.getAttributes(item), list(item.groups)) | |
550 | |
542 def getContacts(self, profile_key): | 551 def getContacts(self, profile_key): |
543 client = self.getClient(profile_key) | 552 client = self.getClient(profile_key) |
544 | 553 |
545 def got_roster(__): | 554 def got_roster(__): |
546 ret = [] | 555 ret = [] |
706 resources.add(client.jid.resource) | 715 resources.add(client.jid.resource) |
707 ret_data = [] | 716 ret_data = [] |
708 for resource in resources: | 717 for resource in resources: |
709 res_jid = copy.copy(bare_jid) | 718 res_jid = copy.copy(bare_jid) |
710 res_jid.resource = resource | 719 res_jid.resource = resource |
711 cache_data = self.memory.getEntityData(res_jid, profile_key=client.profile) | 720 cache_data = self.memory.getEntityData(client, res_jid) |
712 res_data = { | 721 res_data = { |
713 "resource": resource, | 722 "resource": resource, |
714 } | 723 } |
715 try: | 724 try: |
716 presence = cache_data['presence'] | 725 presence = cache_data['presence'] |
955 # presence is sufficient, as a roster push will be sent according to | 964 # presence is sufficient, as a roster push will be sent according to |
956 # RFC 6121 §3.1.2 | 965 # RFC 6121 §3.1.2 |
957 self.profiles[profile].presence.subscribe(to_jid) | 966 self.profiles[profile].presence.subscribe(to_jid) |
958 | 967 |
959 def _updateContact(self, to_jid_s, name, groups, profile_key): | 968 def _updateContact(self, to_jid_s, name, groups, profile_key): |
960 return self.updateContact(jid.JID(to_jid_s), name, groups, profile_key) | 969 client = self.getClient(profile_key) |
961 | 970 return self.updateContact(client, jid.JID(to_jid_s), name, groups) |
962 def updateContact(self, to_jid, name, groups, profile_key): | 971 |
972 def updateContact(self, client, to_jid, name, groups): | |
963 """update a contact in roster list""" | 973 """update a contact in roster list""" |
964 profile = self.memory.getProfileName(profile_key) | |
965 assert profile | |
966 groups = set(groups) | |
967 roster_item = RosterItem(to_jid) | 974 roster_item = RosterItem(to_jid) |
968 roster_item.name = name or None | 975 roster_item.name = name or u'' |
969 roster_item.groups = set(groups) | 976 roster_item.groups = set(groups) |
970 return self.profiles[profile].roster.setItem(roster_item) | 977 if not self.trigger.point("roster_update", client, roster_item): |
978 return | |
979 return client.roster.setItem(roster_item) | |
971 | 980 |
972 def _delContact(self, to_jid_s, profile_key): | 981 def _delContact(self, to_jid_s, profile_key): |
973 return self.delContact(jid.JID(to_jid_s), profile_key) | 982 return self.delContact(jid.JID(to_jid_s), profile_key) |
974 | 983 |
975 def delContact(self, to_jid, profile_key): | 984 def delContact(self, to_jid, profile_key): |