massive refactoring to switch from camelCase to snake_case:

historically, Libervia (SàT before) was using camelCase as allowed by PEP8 when using a
pre-PEP8 code, to use the same coding style as in Twisted.

However, snake_case is more readable and it's better to follow PEP8 best practices, so it
has been decided to move on full snake_case. Because Libervia has a huge codebase, this
ended with a ugly mix of camelCase and snake_case.

To fix that, this patch does a big refactoring by renaming every function and method
(including bridge) that are not coming from Twisted or Wokkel, to use fully snake_case.

This is a massive change, and may result in some bugs.
This commit is contained in:
Goffi 2023-04-08 13:54:42 +02:00
commit 6a6f15707a
10 changed files with 9945 additions and 9945 deletions

View file

@ -45,9 +45,9 @@ class Cache(object):
if None, the cache will be common for all profiles
"""
self.profile = profile
path_elts = [host.memory.getConfig("", "local_dir"), C.CACHE_DIR]
path_elts = [host.memory.config_get("", "local_dir"), C.CACHE_DIR]
if profile:
path_elts.extend(["profiles", regex.pathEscape(profile)])
path_elts.extend(["profiles", regex.path_escape(profile)])
else:
path_elts.append("common")
self.cache_dir = Path(*path_elts)
@ -121,14 +121,14 @@ class Cache(object):
raise exceptions.DataError("Invalid char found")
return self.cache_dir / filename
def getMetadata(self, uid: str, update_eol: bool = True) -> Optional[Dict[str, Any]]:
def get_metadata(self, uid: str, update_eol: bool = True) -> Optional[Dict[str, Any]]:
"""Retrieve metadata for cached data
@param uid(unicode): unique identifier of file
@param update_eol(bool): True if eol must extended
if True, max_age will be added to eol (only if it is not already expired)
@return (dict, None): metadata with following keys:
see [cacheData] for data details, an additional "path" key is the full path to
see [cache_data] for data details, an additional "path" key is the full path to
cached file.
None if file is not in cache (or cache is invalid)
"""
@ -176,23 +176,23 @@ class Cache(object):
cache_data["path"] = self.getPath(cache_data["filename"])
return cache_data
def getFilePath(self, uid: str) -> Path:
def get_file_path(self, uid: str) -> Path:
"""Retrieve absolute path to file
@param uid(unicode): unique identifier of file
@return (unicode, None): absolute path to cached file
None if file is not in cache (or cache is invalid)
"""
metadata = self.getMetadata(uid)
metadata = self.get_metadata(uid)
if metadata is not None:
return metadata["path"]
def removeFromCache(self, uid, metadata=None):
def remove_from_cache(self, uid, metadata=None):
"""Remove data from cache
@param uid(unicode): unique identifier cache file
"""
cache_data = self.getMetadata(uid, update_eol=False)
cache_data = self.get_metadata(uid, update_eol=False)
if cache_data is None:
log.debug(f"cache with uid {uid!r} has already expired or been removed")
return
@ -215,7 +215,7 @@ class Cache(object):
cache_file.unlink()
log.debug(f"cache with uid {uid!r} has been removed")
def cacheData(
def cache_data(
self,
source: str,
uid: str,

View file

@ -47,7 +47,7 @@ class BlockCipher:
"""
if leave_empty and text == "":
return ""
iv = BlockCipher.getRandomKey()
iv = BlockCipher.get_random_key()
key = key.encode()
key = (
key[: BlockCipher.MAX_KEY_SIZE]
@ -91,7 +91,7 @@ class BlockCipher:
return BlockCipher.unpad(decrypted)
@staticmethod
def getRandomKey(size=None, base64=False):
def get_random_key(size=None, base64=False):
"""Return a random key suitable for block cipher encryption.
Note: a good value for the key length is to make it as long as the block size.

View file

@ -87,7 +87,7 @@ class HashManager(object):
return self.hashes.__contains__(hash_)
def load(self):
def fillHashes(hashes):
def fill_hashes(hashes):
for hash_, xml in hashes.items():
element = xml_tools.ElementParser()(xml)
disco_info = disco.DiscoInfo.fromElement(element)
@ -106,7 +106,7 @@ class HashManager(object):
log.info("Disco hashes loaded")
d = self.persistent.load()
d.addCallback(fillHashes)
d.addCallback(fill_hashes)
return d
@ -131,11 +131,11 @@ class Discovery(object):
@param node(unicode): optional node to use for disco request
@return: a Deferred which fire a boolean (True if feature is available)
"""
disco_infos = yield self.getInfos(client, jid_, node)
disco_infos = yield self.get_infos(client, jid_, node)
defer.returnValue(feature in disco_infos.features)
@defer.inlineCallbacks
def checkFeature(self, client, feature, jid_=None, node=""):
def check_feature(self, client, feature, jid_=None, node=""):
"""Like hasFeature, but raise an exception is feature is not Found
@param feature: feature namespace
@ -144,13 +144,13 @@ class Discovery(object):
@raise: exceptions.FeatureNotFound
"""
disco_infos = yield self.getInfos(client, jid_, node)
disco_infos = yield self.get_infos(client, jid_, node)
if not feature in disco_infos.features:
raise failure.Failure(exceptions.FeatureNotFound())
@defer.inlineCallbacks
def checkFeatures(self, client, features, jid_=None, identity=None, node=""):
"""Like checkFeature, but check several features at once, and check also identity
def check_features(self, client, features, jid_=None, identity=None, node=""):
"""Like check_feature, but check several features at once, and check also identity
@param features(iterable[unicode]): features to check
@param jid_(jid.JID): jid of the target, or None for profile's server
@ -159,14 +159,14 @@ class Discovery(object):
@raise: exceptions.FeatureNotFound
"""
disco_infos = yield self.getInfos(client, jid_, node)
disco_infos = yield self.get_infos(client, jid_, node)
if not set(features).issubset(disco_infos.features):
raise failure.Failure(exceptions.FeatureNotFound())
if identity is not None and identity not in disco_infos.identities:
raise failure.Failure(exceptions.FeatureNotFound())
async def hasIdentity(
async def has_identity(
self,
client: SatXMPPEntity,
category: str,
@ -182,10 +182,10 @@ class Discovery(object):
@param node(unicode): optional node to use for disco request
@return: True if the entity has the given identity
"""
disco_infos = await self.getInfos(client, jid_, node)
disco_infos = await self.get_infos(client, jid_, node)
return (category, type_) in disco_infos.identities
def getInfos(self, client, jid_=None, node="", use_cache=True):
def get_infos(self, client, jid_=None, node="", use_cache=True):
"""get disco infos from jid_, filling capability hash if needed
@param jid_: jid of the target, or None for profile's server
@ -199,13 +199,13 @@ class Discovery(object):
if not use_cache:
# we ignore cache, so we pretend we haven't found it
raise KeyError
cap_hash = self.host.memory.getEntityData(
cap_hash = self.host.memory.entity_data_get(
client, jid_, [C.ENTITY_CAP_HASH]
)[C.ENTITY_CAP_HASH]
except (KeyError, exceptions.UnknownEntityError):
# capability hash is not available, we'll compute one
def infosCb(disco_infos):
cap_hash = self.generateHash(disco_infos)
def infos_cb(disco_infos):
cap_hash = self.generate_hash(disco_infos)
for ext_form in disco_infos.extensions.values():
# wokkel doesn't call typeCheck on reception, so we do it here
# to avoid ending up with incorrect types. We have to do it after
@ -213,12 +213,12 @@ class Discovery(object):
# hash)
ext_form.typeCheck()
self.hashes[cap_hash] = disco_infos
self.host.memory.updateEntityData(
self.host.memory.update_entity_data(
client, jid_, C.ENTITY_CAP_HASH, cap_hash
)
return disco_infos
def infosEb(fail):
def infos_eb(fail):
if fail.check(defer.CancelledError):
reason = "request time-out"
fail = failure.Failure(exceptions.TimeOutError(str(fail.value)))
@ -236,21 +236,21 @@ class Discovery(object):
# XXX we set empty disco in cache, to avoid getting an error or waiting
# for a timeout again the next time
self.host.memory.updateEntityData(
self.host.memory.update_entity_data(
client, jid_, C.ENTITY_CAP_HASH, CAP_HASH_ERROR
)
raise fail
d = client.disco.requestInfo(jid_, nodeIdentifier=node)
d.addCallback(infosCb)
d.addErrback(infosEb)
d.addCallback(infos_cb)
d.addErrback(infos_eb)
return d
else:
disco_infos = self.hashes[cap_hash]
return defer.succeed(disco_infos)
@defer.inlineCallbacks
def getItems(self, client, jid_=None, node="", use_cache=True):
def get_items(self, client, jid_=None, node="", use_cache=True):
"""get disco items from jid_, cache them for our own server
@param jid_(jid.JID): jid of the target, or None for profile's server
@ -264,7 +264,7 @@ class Discovery(object):
if jid_ == client.server_jid and not node:
# we cache items only for our own server and if node is not set
try:
items = self.host.memory.getEntityData(
items = self.host.memory.entity_data_get(
client, jid_, ["DISCO_ITEMS"]
)["DISCO_ITEMS"]
log.debug("[%s] disco items are in cache" % jid_.full())
@ -274,7 +274,7 @@ class Discovery(object):
except (KeyError, exceptions.UnknownEntityError):
log.debug("Caching [%s] disco items" % jid_.full())
items = yield client.disco.requestItems(jid_, nodeIdentifier=node)
self.host.memory.updateEntityData(
self.host.memory.update_entity_data(
client, jid_, "DISCO_ITEMS", items
)
else:
@ -290,24 +290,24 @@ class Discovery(object):
defer.returnValue(items)
def _infosEb(self, failure_, entity_jid):
def _infos_eb(self, failure_, entity_jid):
failure_.trap(StanzaError)
log.warning(
_("Error while requesting [%(jid)s]: %(error)s")
% {"jid": entity_jid.full(), "error": failure_.getErrorMessage()}
)
def findServiceEntity(self, client, category, type_, jid_=None):
"""Helper method to find first available entity from findServiceEntities
def find_service_entity(self, client, category, type_, jid_=None):
"""Helper method to find first available entity from find_service_entities
args are the same as for [findServiceEntities]
args are the same as for [find_service_entities]
@return (jid.JID, None): found entity
"""
d = self.host.findServiceEntities(client, category, type_)
d = self.host.find_service_entities(client, category, type_)
d.addCallback(lambda entities: entities.pop() if entities else None)
return d
def findServiceEntities(self, client, category, type_, jid_=None):
def find_service_entities(self, client, category, type_, jid_=None):
"""Return all available items of an entity which correspond to (category, type_)
@param category: identity's category
@ -318,29 +318,29 @@ class Discovery(object):
"""
found_entities = set()
def infosCb(infos, entity_jid):
def infos_cb(infos, entity_jid):
if (category, type_) in infos.identities:
found_entities.add(entity_jid)
def gotItems(items):
def got_items(items):
defers_list = []
for item in items:
info_d = self.getInfos(client, item.entity)
info_d = self.get_infos(client, item.entity)
info_d.addCallbacks(
infosCb, self._infosEb, [item.entity], None, [item.entity]
infos_cb, self._infos_eb, [item.entity], None, [item.entity]
)
defers_list.append(info_d)
return defer.DeferredList(defers_list)
d = self.getItems(client, jid_)
d.addCallback(gotItems)
d = self.get_items(client, jid_)
d.addCallback(got_items)
d.addCallback(lambda __: found_entities)
reactor.callLater(
TIMEOUT, d.cancel
) # FIXME: one bad service make a general timeout
return d
def findFeaturesSet(self, client, features, identity=None, jid_=None):
def find_features_set(self, client, features, identity=None, jid_=None):
"""Return entities (including jid_ and its items) offering features
@param features: iterable of features which must be present
@ -355,7 +355,7 @@ class Discovery(object):
features = set(features)
found_entities = set()
def infosCb(infos, entity):
def infos_cb(infos, entity):
if entity is None:
log.warning(_("received an item without jid"))
return
@ -364,23 +364,23 @@ class Discovery(object):
if features.issubset(infos.features):
found_entities.add(entity)
def gotItems(items):
def got_items(items):
defer_list = []
for entity in [jid_] + [item.entity for item in items]:
infos_d = self.getInfos(client, entity)
infos_d.addCallbacks(infosCb, self._infosEb, [entity], None, [entity])
infos_d = self.get_infos(client, entity)
infos_d.addCallbacks(infos_cb, self._infos_eb, [entity], None, [entity])
defer_list.append(infos_d)
return defer.DeferredList(defer_list)
d = self.getItems(client, jid_)
d.addCallback(gotItems)
d = self.get_items(client, jid_)
d.addCallback(got_items)
d.addCallback(lambda __: found_entities)
reactor.callLater(
TIMEOUT, d.cancel
) # FIXME: one bad service make a general timeout
return d
def generateHash(self, services):
def generate_hash(self, services):
""" Generate a unique hash for given service
hash algorithm is the one described in XEP-0115
@ -433,7 +433,7 @@ class Discovery(object):
return cap_hash
@defer.inlineCallbacks
def _discoInfos(
def _disco_infos(
self, entity_jid_s, node="", use_cache=True, profile_key=C.PROF_KEY_NONE
):
"""Discovery method for the bridge
@ -443,9 +443,9 @@ class Discovery(object):
@return: list of tuples
"""
client = self.host.getClient(profile_key)
client = self.host.get_client(profile_key)
entity = jid.JID(entity_jid_s)
disco_infos = yield self.getInfos(client, entity, node, use_cache)
disco_infos = yield self.get_infos(client, entity, node, use_cache)
extensions = {}
# FIXME: should extensions be serialised using tools.common.data_format?
for form_type, form in list(disco_infos.extensions.items()):
@ -459,7 +459,7 @@ class Discovery(object):
values = [field.value] if field.value is not None else field.values
if field.fieldType == "boolean":
values = [C.boolConst(v) for v in values]
values = [C.bool_const(v) for v in values]
fields.append((data, values))
extensions[form_type or ""] = fields
@ -483,7 +483,7 @@ class Discovery(object):
yield (item.entity.full(), item.nodeIdentifier or "", item.name or "")
@defer.inlineCallbacks
def _discoItems(
def _disco_items(
self, entity_jid_s, node="", use_cache=True, profile_key=C.PROF_KEY_NONE
):
""" Discovery method for the bridge
@ -492,8 +492,8 @@ class Discovery(object):
@param node(unicode): optional node to use
@param use_cache(bool): if True, use cached data if available
@return: list of tuples"""
client = self.host.getClient(profile_key)
client = self.host.get_client(profile_key)
entity = jid.JID(entity_jid_s)
disco_items = yield self.getItems(client, entity, node, use_cache)
disco_items = yield self.get_items(client, entity, node, use_cache)
ret = list(self.items2tuples(disco_items))
defer.returnValue(ret)

View file

@ -50,7 +50,7 @@ class EncryptionHandler:
def host(self):
return self.client.host_app
async def loadSessions(self):
async def load_sessions(self):
"""Load persistent sessions"""
await self._stored_session.load()
start_d_list = []
@ -69,18 +69,18 @@ class EncryptionHandler:
log.info(_("encryption sessions restored"))
@classmethod
def registerPlugin(cls, plg_instance, name, namespace, priority=0, directed=False):
def register_plugin(cls, plg_instance, name, namespace, priority=0, directed=False):
"""Register a plugin handling an encryption algorithm
@param plg_instance(object): instance of the plugin
it must have the following methods:
- getTrustUI(entity): return a XMLUI for trust management
- get_trust_ui(entity): return a XMLUI for trust management
entity(jid.JID): entity to manage
The returned XMLUI must be a form
if may have the following methods:
- startEncryption(entity): start encrypted session
- start_encryption(entity): start encrypted session
entity(jid.JID): entity to start encrypted session with
- stopEncryption(entity): start encrypted session
- stop_encryption(entity): start encrypted session
entity(jid.JID): entity to stop encrypted session with
if they don't exists, those 2 methods will be ignored.
@ -115,7 +115,7 @@ class EncryptionHandler:
return cls.plugins
@classmethod
def getPlugin(cls, namespace):
def get_plugin(cls, namespace):
try:
return next(p for p in cls.plugins if p.namespace == namespace)
except StopIteration:
@ -124,12 +124,12 @@ class EncryptionHandler:
namespace=namespace))
@classmethod
def getNamespaces(cls):
def get_namespaces(cls):
"""Get available plugin namespaces"""
return {p.namespace for p in cls.getPlugins()}
@classmethod
def getNSFromName(cls, name):
def get_ns_from_name(cls, name):
"""Retrieve plugin namespace from its name
@param name(unicode): name of the plugin (case insensitive)
@ -143,7 +143,7 @@ class EncryptionHandler:
"Can't find a plugin with the name \"{name}\".".format(
name=name)))
def getBridgeData(self, session):
def get_bridge_data(self, session):
"""Retrieve session data serialized for bridge.
@param session(dict): encryption session
@ -159,7 +159,7 @@ class EncryptionHandler:
return data_format.serialise(bridge_data)
async def _startEncryption(self, plugin, entity):
async def _start_encryption(self, plugin, entity):
"""Start encryption with a plugin
This method must be called just before adding a plugin session.
@ -168,14 +168,14 @@ class EncryptionHandler:
if not plugin.directed:
await self._stored_session.aset(entity.userhost(), plugin.namespace)
try:
start_encryption = plugin.instance.startEncryption
start_encryption = plugin.instance.start_encryption
except AttributeError:
log.debug(f"No startEncryption method found for {plugin.namespace}")
log.debug(f"No start_encryption method found for {plugin.namespace}")
else:
# we copy entity to avoid having the resource changed by stop_encryption
await utils.asDeferred(start_encryption, self.client, copy.copy(entity))
await utils.as_deferred(start_encryption, self.client, copy.copy(entity))
async def _stopEncryption(self, plugin, entity):
async def _stop_encryption(self, plugin, entity):
"""Stop encryption with a plugin
This method must be called just before removing a plugin session.
@ -186,12 +186,12 @@ class EncryptionHandler:
except KeyError:
pass
try:
stop_encryption = plugin.instance.stopEncryption
stop_encryption = plugin.instance.stop_encryption
except AttributeError:
log.debug(f"No stopEncryption method found for {plugin.namespace}")
log.debug(f"No stop_encryption method found for {plugin.namespace}")
else:
# we copy entity to avoid having the resource changed by stop_encryption
return utils.asDeferred(stop_encryption, self.client, copy.copy(entity))
return utils.as_deferred(stop_encryption, self.client, copy.copy(entity))
async def start(self, entity, namespace=None, replace=False):
"""Start an encryption session with an entity
@ -211,7 +211,7 @@ class EncryptionHandler:
if namespace is None:
plugin = self.plugins[0]
else:
plugin = self.getPlugin(namespace)
plugin = self.get_plugin(namespace)
bare_jid = entity.userhostJID()
if bare_jid in self._sessions:
@ -227,7 +227,7 @@ class EncryptionHandler:
# there is a conflict, but replacement is requested
# so we stop previous encryption to use new one
del self._sessions[bare_jid]
await self._stopEncryption(former_plugin, entity)
await self._stop_encryption(former_plugin, entity)
else:
msg = (_("Session with {bare_jid} is already encrypted with {name}. "
"Please stop encryption session before changing algorithm.")
@ -238,7 +238,7 @@ class EncryptionHandler:
data = {"plugin": plugin}
if plugin.directed:
if not entity.resource:
entity.resource = self.host.memory.getMainResource(self.client, entity)
entity.resource = self.host.memory.main_resource_get(self.client, entity)
if not entity.resource:
raise exceptions.NotFound(
_("No resource found for {destinee}, can't encrypt with {name}")
@ -251,14 +251,14 @@ class EncryptionHandler:
elif entity.resource:
raise ValueError(_("{name} encryption must be used with bare jids."))
await self._startEncryption(plugin, entity)
await self._start_encryption(plugin, entity)
self._sessions[entity.userhostJID()] = data
log.info(_("Encryption session has been set for {entity_jid} with "
"{encryption_name}").format(
entity_jid=entity.full(), encryption_name=plugin.name))
self.host.bridge.messageEncryptionStarted(
self.host.bridge.message_encryption_started(
entity.full(),
self.getBridgeData(data),
self.get_bridge_data(data),
self.client.profile)
msg = D_("Encryption session started: your messages with {destinee} are "
"now end to end encrypted using {name} algorithm.").format(
@ -312,16 +312,16 @@ class EncryptionHandler:
# we stop the whole session
# see comment below for deleting session before stopping encryption
del self._sessions[entity.userhostJID()]
await self._stopEncryption(plugin, entity)
await self._stop_encryption(plugin, entity)
else:
# plugin's stopEncryption may call stop again (that's the case with OTR)
# so we need to remove plugin from session before calling self._stopEncryption
# plugin's stop_encryption may call stop again (that's the case with OTR)
# so we need to remove plugin from session before calling self._stop_encryption
del self._sessions[entity.userhostJID()]
await self._stopEncryption(plugin, entity)
await self._stop_encryption(plugin, entity)
log.info(_("encryption session stopped with entity {entity}").format(
entity=entity.full()))
self.host.bridge.messageEncryptionStopped(
self.host.bridge.message_encryption_stopped(
entity.full(),
{'name': plugin.name,
'namespace': plugin.namespace,
@ -358,7 +358,7 @@ class EncryptionHandler:
return None
return session["plugin"].namespace
def getTrustUI(self, entity_jid, namespace=None):
def get_trust_ui(self, entity_jid, namespace=None):
"""Retrieve encryption UI
@param entity_jid(jid.JID): get the UI for this entity
@ -379,53 +379,53 @@ class EncryptionHandler:
.format(entity_jid=entity_jid.full()))
plugin = session['plugin']
else:
plugin = self.getPlugin(namespace)
plugin = self.get_plugin(namespace)
try:
get_trust_ui = plugin.instance.getTrustUI
get_trust_ui = plugin.instance.get_trust_ui
except AttributeError:
raise NotImplementedError(
"Encryption plugin doesn't handle trust management UI")
else:
return utils.asDeferred(get_trust_ui, self.client, entity_jid)
return utils.as_deferred(get_trust_ui, self.client, entity_jid)
## Menus ##
@classmethod
def _importMenus(cls, host):
host.importMenu(
def _import_menus(cls, host):
host.import_menu(
(D_("Encryption"), D_("unencrypted (plain text)")),
partial(cls._onMenuUnencrypted, host=host),
partial(cls._on_menu_unencrypted, host=host),
security_limit=0,
help_string=D_("End encrypted session"),
type_=C.MENU_SINGLE,
)
for plg in cls.getPlugins():
host.importMenu(
host.import_menu(
(D_("Encryption"), plg.name),
partial(cls._onMenuName, host=host, plg=plg),
partial(cls._on_menu_name, host=host, plg=plg),
security_limit=0,
help_string=D_("Start {name} session").format(name=plg.name),
type_=C.MENU_SINGLE,
)
host.importMenu(
host.import_menu(
(D_("Encryption"), D_("⛨ {name} trust").format(name=plg.name)),
partial(cls._onMenuTrust, host=host, plg=plg),
partial(cls._on_menu_trust, host=host, plg=plg),
security_limit=0,
help_string=D_("Manage {name} trust").format(name=plg.name),
type_=C.MENU_SINGLE,
)
@classmethod
def _onMenuUnencrypted(cls, data, host, profile):
client = host.getClient(profile)
def _on_menu_unencrypted(cls, data, host, profile):
client = host.get_client(profile)
peer_jid = jid.JID(data['jid']).userhostJID()
d = defer.ensureDeferred(client.encryption.stop(peer_jid))
d.addCallback(lambda __: {})
return d
@classmethod
def _onMenuName(cls, data, host, plg, profile):
client = host.getClient(profile)
def _on_menu_name(cls, data, host, plg, profile):
client = host.get_client(profile)
peer_jid = jid.JID(data['jid'])
if not plg.directed:
peer_jid = peer_jid.userhostJID()
@ -436,15 +436,15 @@ class EncryptionHandler:
@classmethod
@defer.inlineCallbacks
def _onMenuTrust(cls, data, host, plg, profile):
client = host.getClient(profile)
def _on_menu_trust(cls, data, host, plg, profile):
client = host.get_client(profile)
peer_jid = jid.JID(data['jid']).userhostJID()
ui = yield client.encryption.getTrustUI(peer_jid, plg.namespace)
ui = yield client.encryption.get_trust_ui(peer_jid, plg.namespace)
defer.returnValue({'xmlui': ui.toXml()})
## Triggers ##
def setEncryptionFlag(self, mess_data):
def set_encryption_flag(self, mess_data):
"""Set "encryption" key in mess_data if session with destinee is encrypted"""
to_jid = mess_data['to']
encryption = self._sessions.get(to_jid.userhostJID())
@ -455,11 +455,11 @@ class EncryptionHandler:
f"encryption flag must not be set for groupchat if encryption algorithm "
f"({encryption['plugin'].name}) is directed!")
mess_data[C.MESS_KEY_ENCRYPTION] = encryption
self.markAsEncrypted(mess_data, plugin.namespace)
self.mark_as_encrypted(mess_data, plugin.namespace)
## Misc ##
def markAsEncrypted(self, mess_data, namespace):
def mark_as_encrypted(self, mess_data, namespace):
"""Helper method to mark a message as having been e2e encrypted.
This should be used in the post_treat workflow of messageReceived trigger of
@ -483,7 +483,7 @@ class EncryptionHandler:
return mess_data
def isEncryptionRequested(
def is_encryption_requested(
self,
mess_data: MessageData,
namespace: Optional[str] = None
@ -513,7 +513,7 @@ class EncryptionHandler:
return mess_data['extra'].get(C.MESS_KEY_ENCRYPTED, False)
def markAsTrusted(self, mess_data):
def mark_as_trusted(self, mess_data):
"""Helper methor to mark a message as sent from a trusted entity.
This should be used in the post_treat workflow of messageReceived trigger of
@ -523,7 +523,7 @@ class EncryptionHandler:
mess_data[C.MESS_KEY_TRUSTED] = True
return mess_data
def markAsUntrusted(self, mess_data):
def mark_as_untrusted(self, mess_data):
"""Helper methor to mark a message as sent from an untrusted entity.
This should be used in the post_treat workflow of messageReceived trigger of

File diff suppressed because it is too large Load diff

View file

@ -38,7 +38,7 @@ def run_migrations_offline():
script output.
"""
db_config = sqla_config.getDbConfig()
db_config = sqla_config.get_db_config()
context.configure(
url=db_config["url"],
target_metadata=target_metadata,
@ -76,7 +76,7 @@ async def run_migrations_online():
and associate a connection with the context.
"""
db_config = sqla_config.getDbConfig()
db_config = sqla_config.get_db_config()
engine = create_async_engine(
db_config["url"],
poolclass=pool.NullPool,

View file

@ -29,7 +29,7 @@ from twisted.internet import defer
from twisted.python.failure import Failure
from twisted.words.xish import domish
from twisted.words.protocols.jabber import jid
from sat.tools.xml_tools import paramsXML2XMLUI, getText
from sat.tools.xml_tools import params_xml_2_xmlui, get_text
from sat.tools.common import data_format
from xml.sax.saxutils import quoteattr
@ -38,7 +38,7 @@ from xml.sax.saxutils import quoteattr
# this need an overall simplification to make maintenance easier
def createJidElts(jids):
def create_jid_elts(jids):
"""Generator which return <jid/> elements from jids
@param jids(iterable[id.jID]): jids to use
@ -101,18 +101,18 @@ class Params(object):
def load_default_params(self):
self.dom = minidom.parseString(Params.default_xml.encode("utf-8"))
def _mergeParams(self, source_node, dest_node):
def _merge_params(self, source_node, dest_node):
"""Look for every node in source_node and recursively copy them to dest if they don't exists"""
def getNodesMap(children):
def get_nodes_map(children):
ret = {}
for child in children:
if child.nodeType == child.ELEMENT_NODE:
ret[(child.tagName, child.getAttribute("name"))] = child
return ret
source_map = getNodesMap(source_node.childNodes)
dest_map = getNodesMap(dest_node.childNodes)
source_map = get_nodes_map(source_node.childNodes)
dest_map = get_nodes_map(dest_node.childNodes)
source_set = set(source_map.keys())
dest_set = set(dest_map.keys())
to_add = source_set.difference(dest_set)
@ -122,22 +122,22 @@ class Params(object):
to_recurse = source_set - to_add
for node_key in to_recurse:
self._mergeParams(source_map[node_key], dest_map[node_key])
self._merge_params(source_map[node_key], dest_map[node_key])
def load_xml(self, xml_file):
"""Load parameters template from xml file"""
self.dom = minidom.parse(xml_file)
default_dom = minidom.parseString(Params.default_xml.encode("utf-8"))
self._mergeParams(default_dom.documentElement, self.dom.documentElement)
self._merge_params(default_dom.documentElement, self.dom.documentElement)
def loadGenParams(self):
def load_gen_params(self):
"""Load general parameters data from storage
@return: deferred triggered once params are loaded
"""
return self.storage.loadGenParams(self.params_gen)
return self.storage.load_gen_params(self.params_gen)
def loadIndParams(self, profile, cache=None):
def load_ind_params(self, profile, cache=None):
"""Load individual parameters
set self.params cache or a temporary cache
@ -147,11 +147,11 @@ class Params(object):
"""
if cache is None:
self.params[profile] = {}
return self.storage.loadIndParams(
return self.storage.load_ind_params(
self.params[profile] if cache is None else cache, profile
)
def purgeProfile(self, profile):
def purge_profile(self, profile):
"""Remove cache data of a profile
@param profile: %(doc_profile)s
@ -176,7 +176,7 @@ class Params(object):
self.params = {}
self.params_gen = {}
def createProfile(self, profile, component):
def create_profile(self, profile, component):
"""Create a new profile
@param profile(unicode): name of the profile
@ -184,14 +184,14 @@ class Params(object):
@param callback: called when the profile actually exists in database and memory
@return: a Deferred instance
"""
if self.storage.hasProfile(profile):
if self.storage.has_profile(profile):
log.info(_("The profile name already exists"))
return defer.fail(exceptions.ConflictError())
if not self.host.trigger.point("ProfileCreation", profile):
return defer.fail(exceptions.CancelError())
return self.storage.createProfile(profile, component or None)
return self.storage.create_profile(profile, component or None)
def asyncDeleteProfile(self, profile, force=False):
def profile_delete_async(self, profile, force=False):
"""Delete an existing profile
@param profile: name of the profile
@ -199,18 +199,18 @@ class Params(object):
To be used for direct calls only (not through the bridge).
@return: a Deferred instance
"""
if not self.storage.hasProfile(profile):
if not self.storage.has_profile(profile):
log.info(_("Trying to delete an unknown profile"))
return defer.fail(Failure(exceptions.ProfileUnknownError(profile)))
if self.host.isConnected(profile):
if self.host.is_connected(profile):
if force:
self.host.disconnect(profile)
else:
log.info(_("Trying to delete a connected profile"))
return defer.fail(Failure(exceptions.ProfileConnected))
return self.storage.deleteProfile(profile)
return self.storage.delete_profile(profile)
def getProfileName(self, profile_key, return_profile_keys=False):
def get_profile_name(self, profile_key, return_profile_keys=False):
"""return profile according to profile_key
@param profile_key: profile name or key which can be
@ -229,7 +229,7 @@ class Params(object):
try:
default = self.host.memory.memory_data[
"Profile_default"
] = self.storage.getProfilesList()[0]
] = self.storage.get_profiles_list()[0]
except IndexError:
log.info(_("No profile exist yet"))
raise exceptions.ProfileUnknownError(profile_key)
@ -240,7 +240,7 @@ class Params(object):
raise exceptions.ProfileNotSetError
elif return_profile_keys and profile_key in [C.PROF_KEY_ALL]:
return profile_key # this value must be managed by the caller
if not self.storage.hasProfile(profile_key):
if not self.storage.has_profile(profile_key):
log.error(_("Trying to access an unknown profile (%s)") % profile_key)
raise exceptions.ProfileUnknownError(profile_key)
return profile_key
@ -260,7 +260,7 @@ class Params(object):
# the node is new
return None
def updateParams(self, xml, security_limit=C.NO_SECURITY_LIMIT, app=""):
def update_params(self, xml, security_limit=C.NO_SECURITY_LIMIT, app=""):
"""import xml in parameters, update if the param already exists
If security_limit is specified and greater than -1, the parameters
@ -287,7 +287,7 @@ class Params(object):
0
) # count the params to be removed from current category
for node in cat_node.childNodes:
if node.nodeName != "param" or not self.checkSecurityLimit(
if node.nodeName != "param" or not self.check_security_limit(
node, security_limit
):
to_remove.append(node)
@ -324,7 +324,7 @@ class Params(object):
pre_process_app_node(src_parent, security_limit, app)
import_node(self.dom.documentElement, src_parent)
def paramsRegisterApp(self, xml, security_limit, app):
def params_register_app(self, xml, security_limit, app):
"""Register frontend's specific parameters
If security_limit is specified and greater than -1, the parameters
@ -351,12 +351,12 @@ class Params(object):
)
return
self.frontends_cache.append(app)
self.updateParams(xml, security_limit, app)
self.update_params(xml, security_limit, app)
log.debug("Frontends parameters registered for %(app)s" % {"app": app})
def __default_ok(self, value, name, category):
# FIXME: will not work with individual parameters
self.setParam(name, value, category)
self.param_set(name, value, category)
def __default_ko(self, failure, name, category):
log.error(
@ -364,7 +364,7 @@ class Params(object):
% {"category": category, "name": name, "reason": str(failure.value)}
)
def setDefault(self, name, category, callback, errback=None):
def set_default(self, name, category, callback, errback=None):
"""Set default value of parameter
'default_cb' attibute of parameter must be set to 'yes'
@ -376,10 +376,10 @@ class Params(object):
# TODO: send signal param update if value changed
# TODO: manage individual paramaters
log.debug(
"setDefault called for %(category)s/%(name)s"
"set_default called for %(category)s/%(name)s"
% {"category": category, "name": name}
)
node = self._getParamNode(name, category, "@ALL@")
node = self._get_param_node(name, category, "@ALL@")
if not node:
log.error(
_(
@ -390,15 +390,15 @@ class Params(object):
return
if node[1].getAttribute("default_cb") == "yes":
# del node[1].attributes['default_cb'] # default_cb is not used anymore as a flag to know if we have to set the default value,
# and we can still use it later e.g. to call a generic setDefault method
value = self._getParam(category, name, C.GENERAL)
# and we can still use it later e.g. to call a generic set_default method
value = self._get_param(category, name, C.GENERAL)
if value is None: # no value set by the user: we have the default value
log.debug("Default value to set, using callback")
d = defer.maybeDeferred(callback)
d.addCallback(self.__default_ok, name, category)
d.addErrback(errback or self.__default_ko, name, category)
def _getAttr_internal(self, node, attr, value):
def _get_attr_internal(self, node, attr, value):
"""Get attribute value.
/!\ This method would return encrypted password values.
@ -464,7 +464,7 @@ class Params(object):
"\t"
) # FIXME: it's not good to use tabs as separator !
else: # no user defined value, take default value from the XML
jids = [getText(jid_) for jid_ in node.getElementsByTagName("jid")]
jids = [get_text(jid_) for jid_ in node.getElementsByTagName("jid")]
to_delete = []
for idx, value in enumerate(jids):
try:
@ -480,7 +480,7 @@ class Params(object):
return value_to_use
return node.getAttribute(attr)
def _getAttr(self, node, attr, value):
def _get_attr(self, node, attr, value):
"""Get attribute value (synchronous).
/!\ This method can not be used to retrieve password values.
@ -491,11 +491,11 @@ class Params(object):
"""
if attr == "value" and node.getAttribute("type") == "password":
raise exceptions.InternalError(
"To retrieve password values, use _asyncGetAttr instead of _getAttr"
"To retrieve password values, use _async_get_attr instead of _get_attr"
)
return self._getAttr_internal(node, attr, value)
return self._get_attr_internal(node, attr, value)
def _asyncGetAttr(self, node, attr, value, profile=None):
def _async_get_attr(self, node, attr, value, profile=None):
"""Get attribute value.
Profile passwords are returned hashed (if not empty),
@ -506,7 +506,7 @@ class Params(object):
@param profile: %(doc_profile)s
@return (unicode, bool, int, list): Deferred value to retrieve
"""
value = self._getAttr_internal(node, attr, value)
value = self._get_attr_internal(node, attr, value)
if attr != "value" or node.getAttribute("type") != "password":
return defer.succeed(value)
param_cat = node.parentNode.getAttribute("name")
@ -519,7 +519,7 @@ class Params(object):
raise exceptions.ProfileNotSetError(
"The profile is needed to decrypt a password"
)
password = self.host.memory.decryptValue(value, profile)
password = self.host.memory.decrypt_value(value, profile)
if password is None:
raise exceptions.InternalError("password should never be None")
@ -528,25 +528,25 @@ class Params(object):
def _type_to_str(self, result):
"""Convert result to string, according to its type """
if isinstance(result, bool):
return C.boolConst(result)
return C.bool_const(result)
elif isinstance(result, (list, set, tuple)):
return ', '.join(self._type_to_str(r) for r in result)
else:
return str(result)
def getStringParamA(self, name, category, attr="value", profile_key=C.PROF_KEY_NONE):
""" Same as getParamA but for bridge: convert non string value to string """
def get_string_param_a(self, name, category, attr="value", profile_key=C.PROF_KEY_NONE):
""" Same as param_get_a but for bridge: convert non string value to string """
return self._type_to_str(
self.getParamA(name, category, attr, profile_key=profile_key)
self.param_get_a(name, category, attr, profile_key=profile_key)
)
def getParamA(
def param_get_a(
self, name, category, attr="value", use_default=True, profile_key=C.PROF_KEY_NONE
):
"""Helper method to get a specific attribute.
/!\ This method would return encrypted password values,
to get the plain values you have to use asyncGetParamA.
to get the plain values you have to use param_get_a_async.
@param name: name of the parameter
@param category: category of the parameter
@param attr: name of the attribute (default: "value")
@ -557,7 +557,7 @@ class Params(object):
"""
# FIXME: looks really dirty and buggy, need to be reviewed/refactored
# FIXME: security_limit is not managed here !
node = self._getParamNode(name, category)
node = self._get_param_node(name, category)
if not node:
log.error(
_(
@ -569,18 +569,18 @@ class Params(object):
if attr == "value" and node[1].getAttribute("type") == "password":
raise exceptions.InternalError(
"To retrieve password values, use asyncGetParamA instead of getParamA"
"To retrieve password values, use param_get_a_async instead of param_get_a"
)
if node[0] == C.GENERAL:
value = self._getParam(category, name, C.GENERAL)
value = self._get_param(category, name, C.GENERAL)
if value is None and attr == "value" and not use_default:
return value
return self._getAttr(node[1], attr, value)
return self._get_attr(node[1], attr, value)
assert node[0] == C.INDIVIDUAL
profile = self.getProfileName(profile_key)
profile = self.get_profile_name(profile_key)
if not profile:
log.error(_("Requesting a param for an non-existant profile"))
raise exceptions.ProfileUnknownError(profile_key)
@ -590,19 +590,19 @@ class Params(object):
raise exceptions.ProfileNotConnected(profile)
if attr == "value":
value = self._getParam(category, name, profile=profile)
value = self._get_param(category, name, profile=profile)
if value is None and attr == "value" and not use_default:
return value
return self._getAttr(node[1], attr, value)
return self._get_attr(node[1], attr, value)
async def asyncGetStringParamA(
async def async_get_string_param_a(
self, name, category, attr="value", security_limit=C.NO_SECURITY_LIMIT,
profile=C.PROF_KEY_NONE):
value = await self.asyncGetParamA(
value = await self.param_get_a_async(
name, category, attr, security_limit, profile_key=profile)
return self._type_to_str(value)
def asyncGetParamA(
def param_get_a_async(
self,
name,
category,
@ -618,7 +618,7 @@ class Params(object):
@param profile: owner of the param (@ALL@ for everyone)
@return (defer.Deferred): parameter value, with corresponding type (bool, int, list, etc)
"""
node = self._getParamNode(name, category)
node = self._get_param_node(name, category)
if not node:
log.error(
_(
@ -628,7 +628,7 @@ class Params(object):
)
raise ValueError("Requested param doesn't exist")
if not self.checkSecurityLimit(node[1], security_limit):
if not self.check_security_limit(node[1], security_limit):
log.warning(
_(
"Trying to get parameter '%(param)s' in category '%(cat)s' without authorization!!!"
@ -638,12 +638,12 @@ class Params(object):
raise exceptions.PermissionError
if node[0] == C.GENERAL:
value = self._getParam(category, name, C.GENERAL)
return self._asyncGetAttr(node[1], attr, value)
value = self._get_param(category, name, C.GENERAL)
return self._async_get_attr(node[1], attr, value)
assert node[0] == C.INDIVIDUAL
profile = self.getProfileName(profile_key)
profile = self.get_profile_name(profile_key)
if not profile:
raise exceptions.InternalError(
_("Requesting a param for a non-existant profile")
@ -652,23 +652,23 @@ class Params(object):
if attr != "value":
return defer.succeed(node[1].getAttribute(attr))
try:
value = self._getParam(category, name, profile=profile)
return self._asyncGetAttr(node[1], attr, value, profile)
value = self._get_param(category, name, profile=profile)
return self._async_get_attr(node[1], attr, value, profile)
except exceptions.ProfileNotInCacheError:
# We have to ask data to the storage manager
d = self.storage.getIndParam(category, name, profile)
d = self.storage.get_ind_param(category, name, profile)
return d.addCallback(
lambda value: self._asyncGetAttr(node[1], attr, value, profile)
lambda value: self._async_get_attr(node[1], attr, value, profile)
)
def _getParamsValuesFromCategory(
def _get_params_values_from_category(
self, category, security_limit, app, extra_s, profile_key):
client = self.host.getClient(profile_key)
client = self.host.get_client(profile_key)
extra = data_format.deserialise(extra_s)
return defer.ensureDeferred(self.getParamsValuesFromCategory(
return defer.ensureDeferred(self.get_params_values_from_category(
client, category, security_limit, app, extra))
async def getParamsValuesFromCategory(
async def get_params_values_from_category(
self, client, category, security_limit, app='', extra=None):
"""Get all parameters "attribute" for a category
@ -676,14 +676,14 @@ class Params(object):
@param security_limit(int): NO_SECURITY_LIMIT (-1) to return all the params.
Otherwise sole the params which have a security level defined *and*
lower or equal to the specified value are returned.
@param app(str): see [getParams]
@param extra(dict): see [getParams]
@param app(str): see [get_params]
@param extra(dict): see [get_params]
@return (dict): key: param name, value: param value (converted to string if needed)
"""
# TODO: manage category of general type (without existant profile)
if extra is None:
extra = {}
prof_xml = await self._constructProfileXml(client, security_limit, app, extra)
prof_xml = await self._construct_profile_xml(client, security_limit, app, extra)
ret = {}
for category_node in prof_xml.getElementsByTagName("category"):
if category_node.getAttribute("name") == category:
@ -696,7 +696,7 @@ class Params(object):
)
)
continue
value = await self.asyncGetStringParamA(
value = await self.async_get_string_param_a(
name, category, security_limit=security_limit,
profile=client.profile)
@ -706,7 +706,7 @@ class Params(object):
prof_xml.unlink()
return ret
def _getParam(
def _get_param(
self, category, name, type_=C.INDIVIDUAL, cache=None, profile=C.PROF_KEY_NONE
):
"""Return the param, or None if it doesn't exist
@ -736,7 +736,7 @@ class Params(object):
return None
return cache[(category, name)]
async def _constructProfileXml(self, client, security_limit, app, extra):
async def _construct_profile_xml(self, client, security_limit, app, extra):
"""Construct xml for asked profile, filling values when needed
/!\ as noticed in doc, don't forget to unlink the minidom.Document
@ -749,18 +749,18 @@ class Params(object):
"""
profile = client.profile
def checkNode(node):
def check_node(node):
"""Check the node against security_limit, app and extra"""
return (self.checkSecurityLimit(node, security_limit)
and self.checkApp(node, app)
and self.checkExtra(node, extra))
return (self.check_security_limit(node, security_limit)
and self.check_app(node, app)
and self.check_extra(node, extra))
if profile in self.params:
profile_cache = self.params[profile]
else:
# profile is not in cache, we load values in a short time cache
profile_cache = {}
await self.loadIndParams(profile, profile_cache)
await self.load_ind_params(profile, profile_cache)
# init the result document
prof_xml = minidom.parseString("<params/>")
@ -782,7 +782,7 @@ class Params(object):
for node in dest_cat.childNodes:
if node.nodeName != "param":
continue
if not checkNode(node):
if not check_node(node):
to_remove.append(node)
continue
dest_params[node.getAttribute("name")] = node
@ -799,14 +799,14 @@ class Params(object):
# we have to merge new params (we are parsing individual parameters, we have to add them
# to the previously parsed general ones)
name = param_node.getAttribute("name")
if not checkNode(param_node):
if not check_node(param_node):
continue
if name not in dest_params:
# this is reached when a previous category exists
dest_params[name] = param_node.cloneNode(True)
dest_cat.appendChild(dest_params[name])
profile_value = self._getParam(
profile_value = self._get_param(
category,
name,
type_node.nodeName,
@ -867,12 +867,12 @@ class Params(object):
return prof_xml
def _getParamsUI(self, security_limit, app, extra_s, profile_key):
client = self.host.getClient(profile_key)
def _get_params_ui(self, security_limit, app, extra_s, profile_key):
client = self.host.get_client(profile_key)
extra = data_format.deserialise(extra_s)
return defer.ensureDeferred(self.getParamsUI(client, security_limit, app, extra))
return defer.ensureDeferred(self.param_ui_get(client, security_limit, app, extra))
async def getParamsUI(self, client, security_limit, app, extra=None):
async def param_ui_get(self, client, security_limit, app, extra=None):
"""Get XMLUI to handle parameters
@param security_limit: NO_SECURITY_LIMIT (-1) to return all the params.
@ -883,10 +883,10 @@ class Params(object):
- ignore: list of (category/name) values to remove from parameters
@return(str): a SàT XMLUI for parameters
"""
param_xml = await self.getParams(client, security_limit, app, extra)
return paramsXML2XMLUI(param_xml)
param_xml = await self.get_params(client, security_limit, app, extra)
return params_xml_2_xmlui(param_xml)
async def getParams(self, client, security_limit, app, extra=None):
async def get_params(self, client, security_limit, app, extra=None):
"""Construct xml for asked profile, take params xml as skeleton
@param security_limit: NO_SECURITY_LIMIT (-1) to return all the params.
@ -900,12 +900,12 @@ class Params(object):
"""
if extra is None:
extra = {}
prof_xml = await self._constructProfileXml(client, security_limit, app, extra)
prof_xml = await self._construct_profile_xml(client, security_limit, app, extra)
return_xml = prof_xml.toxml()
prof_xml.unlink()
return "\n".join((line for line in return_xml.split("\n") if line))
def _getParamNode(self, name, category, type_="@ALL@"): # FIXME: is type_ useful ?
def _get_param_node(self, name, category, type_="@ALL@"): # FIXME: is type_ useful ?
"""Return a node from the param_xml
@param name: name of the node
@param category: category of the node
@ -931,7 +931,7 @@ class Params(object):
return (type_node.nodeName, param)
return None
def getParamsCategories(self):
def params_categories_get(self):
"""return the categories availables"""
categories = []
for cat in self.dom.getElementsByTagName("category"):
@ -940,7 +940,7 @@ class Params(object):
categories.append(cat.getAttribute("name"))
return categories
def setParam(self, name, value, category, security_limit=C.NO_SECURITY_LIMIT,
def param_set(self, name, value, category, security_limit=C.NO_SECURITY_LIMIT,
profile_key=C.PROF_KEY_NONE):
"""Set a parameter, return None if the parameter is not in param xml.
@ -955,14 +955,14 @@ class Params(object):
@param profile_key (str): %(doc_profile_key)s
@return: a deferred None value when everything is done
"""
# FIXME: setParam should accept the right type for value, not only str !
# FIXME: param_set should accept the right type for value, not only str !
if profile_key != C.PROF_KEY_NONE:
profile = self.getProfileName(profile_key)
profile = self.get_profile_name(profile_key)
if not profile:
log.error(_("Trying to set parameter for an unknown profile"))
raise exceptions.ProfileUnknownError(profile_key)
node = self._getParamNode(name, category, "@ALL@")
node = self._get_param_node(name, category, "@ALL@")
if not node:
log.error(
_("Requesting an unknown parameter (%(category)s/%(name)s)")
@ -970,7 +970,7 @@ class Params(object):
)
return defer.succeed(None)
if not self.checkSecurityLimit(node[1], security_limit):
if not self.check_security_limit(node[1], security_limit):
msg = _(
"{profile!r} is trying to set parameter {name!r} in category "
"{category!r} without authorization!!!").format(
@ -1018,12 +1018,12 @@ class Params(object):
if node[0] == C.GENERAL:
self.params_gen[(category, name)] = value
self.storage.setGenParam(category, name, value)
for profile in self.storage.getProfilesList():
if self.host.memory.isSessionStarted(profile):
self.host.bridge.paramUpdate(name, value, category, profile)
self.storage.set_gen_param(category, name, value)
for profile in self.storage.get_profiles_list():
if self.host.memory.is_session_started(profile):
self.host.bridge.param_update(name, value, category, profile)
self.host.trigger.point(
"paramUpdateTrigger", name, value, category, node[0], profile
"param_update_trigger", name, value, category, node[0], profile
)
return defer.succeed(None)
@ -1035,7 +1035,7 @@ class Params(object):
return defer.succeed(None)
elif type_ == "password":
try:
personal_key = self.host.memory.auth_sessions.profileGetUnique(profile)[
personal_key = self.host.memory.auth_sessions.profile_get_unique(profile)[
C.MEMORY_CRYPTO_KEY
]
except TypeError:
@ -1044,7 +1044,7 @@ class Params(object):
)
if (category, name) == C.PROFILE_PASS_PATH:
# using 'value' as the encryption key to encrypt another encryption key... could be confusing!
d = self.host.memory.encryptPersonalData(
d = self.host.memory.encrypt_personal_data(
data_key=C.MEMORY_CRYPTO_KEY,
data_value=personal_key,
crypto_key=value,
@ -1060,21 +1060,21 @@ class Params(object):
else:
d = defer.succeed(value)
def gotFinalValue(value):
if self.host.memory.isSessionStarted(profile):
def got_final_value(value):
if self.host.memory.is_session_started(profile):
self.params[profile][(category, name)] = value
self.host.bridge.paramUpdate(name, value, category, profile)
self.host.bridge.param_update(name, value, category, profile)
self.host.trigger.point(
"paramUpdateTrigger", name, value, category, node[0], profile
"param_update_trigger", name, value, category, node[0], profile
)
return self.storage.setIndParam(category, name, value, profile)
return self.storage.set_ind_param(category, name, value, profile)
else:
raise exceptions.ProfileNotConnected
d.addCallback(gotFinalValue)
d.addCallback(got_final_value)
return d
def _getNodesOfTypes(self, attr_type, node_type="@ALL@"):
def _get_nodes_of_types(self, attr_type, node_type="@ALL@"):
"""Return all the nodes matching the given types.
TODO: using during the dev but not anymore... remove if not needed
@ -1105,7 +1105,7 @@ class Params(object):
ret[(cat, param.getAttribute("name"))] = param
return ret
def checkSecurityLimit(self, node, security_limit):
def check_security_limit(self, node, security_limit):
"""Check the given node against the given security limit.
The value NO_SECURITY_LIMIT (-1) means that everything is allowed.
@return: True if this node can be accessed with the given security limit.
@ -1117,7 +1117,7 @@ class Params(object):
return True
return False
def checkApp(self, node, app):
def check_app(self, node, app):
"""Check the given node against the given app.
@param node: parameter node
@ -1128,7 +1128,7 @@ class Params(object):
return True
return node.getAttribute("app") == app
def checkExtra(self, node, extra):
def check_extra(self, node, extra):
"""Check the given node against the extra filters.
@param node: parameter node
@ -1147,7 +1147,7 @@ class Params(object):
return True
def makeOptions(options, selected=None):
def make_options(options, selected=None):
"""Create option XML form dictionary
@param options(dict): option's name => option's label map

View file

@ -51,7 +51,7 @@ class PersistentDict:
self.namespace = namespace
self.profile = profile
def _setCache(self, data):
def _set_cache(self, data):
self._cache = data
def load(self):
@ -60,10 +60,10 @@ class PersistentDict:
need to be called before any other operation
@return: defers the PersistentDict instance itself
"""
d = defer.ensureDeferred(self.storage.getPrivates(
d = defer.ensureDeferred(self.storage.get_privates(
self.namespace, binary=self.binary, profile=self.profile
))
d.addCallback(self._setCache)
d.addCallback(self._set_cache)
d.addCallback(lambda __: self)
return d
@ -117,20 +117,20 @@ class PersistentDict:
def __setitem__(self, key, value):
defer.ensureDeferred(
self.storage.setPrivateValue(
self.storage.set_private_value(
self.namespace, key, value, self.binary, self.profile
)
)
return self._cache.__setitem__(key, value)
def __delitem__(self, key):
self.storage.delPrivateValue(self.namespace, key, self.binary, self.profile)
self.storage.del_private_value(self.namespace, key, self.binary, self.profile)
return self._cache.__delitem__(key)
def clear(self):
"""Delete all values from this namespace"""
self._cache.clear()
return self.storage.delPrivateNamespace(self.namespace, self.binary, self.profile)
return self.storage.del_private_namespace(self.namespace, self.binary, self.profile)
def get(self, key, default=None):
return self._cache.get(key, default)
@ -139,7 +139,7 @@ class PersistentDict:
"""Async set, return a Deferred fired when value is actually stored"""
self._cache.__setitem__(key, value)
return defer.ensureDeferred(
self.storage.setPrivateValue(
self.storage.set_private_value(
self.namespace, key, value, self.binary, self.profile
)
)
@ -147,7 +147,7 @@ class PersistentDict:
def adel(self, key):
"""Async del, return a Deferred fired when value is actually deleted"""
self._cache.__delitem__(key)
return self.storage.delPrivateValue(
return self.storage.del_private_value(
self.namespace, key, self.binary, self.profile)
def setdefault(self, key, default):
@ -163,7 +163,7 @@ class PersistentDict:
@return: deferred fired when data is actually saved
"""
return defer.ensureDeferred(
self.storage.setPrivateValue(
self.storage.set_private_value(
self.namespace, name, self._cache[name], self.binary, self.profile
)
)
@ -192,14 +192,14 @@ class LazyPersistentBinaryDict(PersistentBinaryDict):
raise NotImplementedError
def items(self):
d = defer.ensureDeferred(self.storage.getPrivates(
d = defer.ensureDeferred(self.storage.get_privates(
self.namespace, binary=self.binary, profile=self.profile
))
d.addCallback(lambda data_dict: data_dict.items())
return d
def all(self):
return defer.ensureDeferred(self.storage.getPrivates(
return defer.ensureDeferred(self.storage.get_privates(
self.namespace, binary=self.binary, profile=self.profile
))
@ -252,7 +252,7 @@ class LazyPersistentBinaryDict(PersistentBinaryDict):
def __getitem__(self, key):
"""get the value as a Deferred"""
d = defer.ensureDeferred(self.storage.getPrivates(
d = defer.ensureDeferred(self.storage.get_privates(
self.namespace, keys=[key], binary=self.binary, profile=self.profile
))
d.addCallback(self._data2value, key)
@ -260,21 +260,21 @@ class LazyPersistentBinaryDict(PersistentBinaryDict):
def __setitem__(self, key, value):
defer.ensureDeferred(
self.storage.setPrivateValue(
self.storage.set_private_value(
self.namespace, key, value, self.binary, self.profile
)
)
def __delitem__(self, key):
self.storage.delPrivateValue(self.namespace, key, self.binary, self.profile)
self.storage.del_private_value(self.namespace, key, self.binary, self.profile)
def _defaultOrException(self, failure_, default):
def _default_or_exception(self, failure_, default):
failure_.trap(KeyError)
return default
def get(self, key, default=None):
d = self.__getitem__(key)
d.addErrback(self._defaultOrException, default=default)
d.addErrback(self._default_or_exception, default=default)
return d
def aset(self, key, value):
@ -282,7 +282,7 @@ class LazyPersistentBinaryDict(PersistentBinaryDict):
# FIXME: redundant with force, force must be removed
# XXX: similar as PersistentDict.aset, but doesn't use cache
return defer.ensureDeferred(
self.storage.setPrivateValue(
self.storage.set_private_value(
self.namespace, key, value, self.binary, self.profile
)
)
@ -290,7 +290,7 @@ class LazyPersistentBinaryDict(PersistentBinaryDict):
def adel(self, key):
"""Async del, return a Deferred fired when value is actually deleted"""
# XXX: similar as PersistentDict.adel, but doesn't use cache
return self.storage.delPrivateValue(
return self.storage.del_private_value(
self.namespace, key, self.binary, self.profile)
def setdefault(self, key, default):
@ -303,7 +303,7 @@ class LazyPersistentBinaryDict(PersistentBinaryDict):
@return: deferred fired when data is actually saved
"""
return defer.ensureDeferred(
self.storage.setPrivateValue(
self.storage.set_private_value(
self.namespace, name, value, self.binary, self.profile
)
)
@ -314,4 +314,4 @@ class LazyPersistentBinaryDict(PersistentBinaryDict):
@param key(unicode): key to delete
@return (D): A deferred fired when delete is done
"""
return self.storage.delPrivateValue(self.namespace, key, self.binary, self.profile)
return self.storage.del_private_value(self.namespace, key, self.binary, self.profile)

View file

@ -122,10 +122,10 @@ class Storage:
# profile id to component entry point
self.components: Dict[int, str] = {}
def getProfileById(self, profile_id):
def get_profile_by_id(self, profile_id):
return self.profiles.get(profile_id)
async def migrateApply(self, *args: str, log_output: bool = False) -> None:
async def migrate_apply(self, *args: str, log_output: bool = False) -> None:
"""Do a migration command
Commands are applied by running Alembic in a subprocess.
@ -167,7 +167,7 @@ class Storage:
await conn.run_sync(Base.metadata.create_all)
log.debug("stamping the database")
await self.migrateApply("stamp", "head")
await self.migrate_apply("stamp", "head")
log.debug("stamping done")
def _check_db_is_up_to_date(self, conn: Connection) -> bool:
@ -193,14 +193,14 @@ class Storage:
else:
log.info("Database needs to be updated")
log.info("updating…")
await self.migrateApply("upgrade", "head", log_output=True)
await self.migrate_apply("upgrade", "head", log_output=True)
log.info("Database is now up-to-date")
@aio
async def initialise(self) -> None:
log.info(_("Connecting database"))
db_config = sqla_config.getDbConfig()
db_config = sqla_config.get_db_config()
engine = create_async_engine(
db_config["url"],
future=True,
@ -288,31 +288,31 @@ class Storage:
## Profiles
def getProfilesList(self) -> List[str]:
def get_profiles_list(self) -> List[str]:
""""Return list of all registered profiles"""
return list(self.profiles.keys())
def hasProfile(self, profile_name: str) -> bool:
def has_profile(self, profile_name: str) -> bool:
"""return True if profile_name exists
@param profile_name: name of the profile to check
"""
return profile_name in self.profiles
def profileIsComponent(self, profile_name: str) -> bool:
def profile_is_component(self, profile_name: str) -> bool:
try:
return self.profiles[profile_name] in self.components
except KeyError:
raise exceptions.NotFound("the requested profile doesn't exists")
def getEntryPoint(self, profile_name: str) -> str:
def get_entry_point(self, profile_name: str) -> str:
try:
return self.components[self.profiles[profile_name]]
except KeyError:
raise exceptions.NotFound("the requested profile doesn't exists or is not a component")
@aio
async def createProfile(self, name: str, component_ep: Optional[str] = None) -> None:
async def create_profile(self, name: str, component_ep: Optional[str] = None) -> None:
"""Create a new profile
@param name: name of the profile
@ -331,7 +331,7 @@ class Storage:
return profile
@aio
async def deleteProfile(self, name: str) -> None:
async def delete_profile(self, name: str) -> None:
"""Delete profile
@param name: name of the profile
@ -349,7 +349,7 @@ class Storage:
## Params
@aio
async def loadGenParams(self, params_gen: dict) -> None:
async def load_gen_params(self, params_gen: dict) -> None:
"""Load general parameters
@param params_gen: dictionary to fill
@ -361,7 +361,7 @@ class Storage:
params_gen[(p.category, p.name)] = p.value
@aio
async def loadIndParams(self, params_ind: dict, profile: str) -> None:
async def load_ind_params(self, params_ind: dict, profile: str) -> None:
"""Load individual parameters
@param params_ind: dictionary to fill
@ -376,7 +376,7 @@ class Storage:
params_ind[(p.category, p.name)] = p.value
@aio
async def getIndParam(self, category: str, name: str, profile: str) -> Optional[str]:
async def get_ind_param(self, category: str, name: str, profile: str) -> Optional[str]:
"""Ask database for the value of one specific individual parameter
@param category: category of the parameter
@ -395,7 +395,7 @@ class Storage:
return result.scalar_one_or_none()
@aio
async def getIndParamValues(self, category: str, name: str) -> Dict[str, str]:
async def get_ind_param_values(self, category: str, name: str) -> Dict[str, str]:
"""Ask database for the individual values of a parameter for all profiles
@param category: category of the parameter
@ -414,7 +414,7 @@ class Storage:
return {param.profile.name: param.value for param in result.scalars()}
@aio
async def setGenParam(self, category: str, name: str, value: Optional[str]) -> None:
async def set_gen_param(self, category: str, name: str, value: Optional[str]) -> None:
"""Save the general parameters in database
@param category: category of the parameter
@ -436,7 +436,7 @@ class Storage:
await session.commit()
@aio
async def setIndParam(
async def set_ind_param(
self,
category:str,
name: str,
@ -489,7 +489,7 @@ class Storage:
return History.source == jid_.userhost()
@aio
async def historyGet(
async def history_get(
self,
from_jid: Optional[jid.JID],
to_jid: Optional[jid.JID],
@ -509,7 +509,7 @@ class Storage:
- None for unlimited
@param between: confound source and dest (ignore the direction)
@param filters: pattern to filter the history results
@return: list of messages as in [messageNew], minus the profile which is already
@return: list of messages as in [message_new], minus the profile which is already
known.
"""
# we have to set a default value to profile because it's last argument
@ -634,7 +634,7 @@ class Storage:
return [h.as_tuple() for h in result]
@aio
async def addToHistory(self, data: dict, profile: str) -> None:
async def add_to_history(self, data: dict, profile: str) -> None:
"""Store a new message in history
@param data: message data as build by SatMessageProtocol.onMessage
@ -682,7 +682,7 @@ class Storage:
## Private values
def _getPrivateClass(self, binary, profile):
def _get_private_class(self, binary, profile):
"""Get ORM class to use for private values"""
if profile is None:
return PrivateGenBin if binary else PrivateGen
@ -691,7 +691,7 @@ class Storage:
@aio
async def getPrivates(
async def get_privates(
self,
namespace:str,
keys: Optional[Iterable[str]] = None,
@ -714,7 +714,7 @@ class Storage:
f"{' binary' if binary else ''} private values from database for namespace "
f"{namespace}{f' with keys {keys!r}' if keys is not None else ''}"
)
cls = self._getPrivateClass(binary, profile)
cls = self._get_private_class(binary, profile)
stmt = select(cls).filter_by(namespace=namespace)
if keys:
stmt = stmt.where(cls.key.in_(list(keys)))
@ -725,7 +725,7 @@ class Storage:
return {p.key: p.value for p in result.scalars()}
@aio
async def setPrivateValue(
async def set_private_value(
self,
namespace: str,
key:str,
@ -743,7 +743,7 @@ class Storage:
@param profile: profile to use for individual value
if None, it's a general value
"""
cls = self._getPrivateClass(binary, profile)
cls = self._get_private_class(binary, profile)
values = {
"namespace": namespace,
@ -768,7 +768,7 @@ class Storage:
await session.commit()
@aio
async def delPrivateValue(
async def del_private_value(
self,
namespace: str,
key: str,
@ -783,7 +783,7 @@ class Storage:
@param profile: profile to use for individual value
if None, it's a general value
"""
cls = self._getPrivateClass(binary, profile)
cls = self._get_private_class(binary, profile)
stmt = delete(cls).filter_by(namespace=namespace, key=key)
@ -795,7 +795,7 @@ class Storage:
await session.commit()
@aio
async def delPrivateNamespace(
async def del_private_namespace(
self,
namespace: str,
binary: bool = False,
@ -805,9 +805,9 @@ class Storage:
Be really cautious when you use this method, as all data with given namespace are
removed.
Params are the same as for delPrivateValue
Params are the same as for del_private_value
"""
cls = self._getPrivateClass(binary, profile)
cls = self._get_private_class(binary, profile)
stmt = delete(cls).filter_by(namespace=namespace)
@ -821,7 +821,7 @@ class Storage:
## Files
@aio
async def getFiles(
async def get_files(
self,
client: Optional[SatXMPPEntity],
file_id: Optional[str] = None,
@ -852,7 +852,7 @@ class Storage:
@param projection: name of columns to retrieve
None to retrieve all
@param unique: if True will remove duplicates
other params are the same as for [setFile]
other params are the same as for [set_file]
@return: files corresponding to filters
"""
if projection is None:
@ -910,7 +910,7 @@ class Storage:
return [dict(r) for r in result]
@aio
async def setFile(
async def set_file(
self,
client: SatXMPPEntity,
name: str,
@ -987,7 +987,7 @@ class Storage:
))
@aio
async def fileGetUsedSpace(self, client: SatXMPPEntity, owner: jid.JID) -> int:
async def file_get_used_space(self, client: SatXMPPEntity, owner: jid.JID) -> int:
async with self.session() as session:
result = await session.execute(
select(sum_(File.size)).filter_by(
@ -998,7 +998,7 @@ class Storage:
return result.scalar_one_or_none() or 0
@aio
async def fileDelete(self, file_id: str) -> None:
async def file_delete(self, file_id: str) -> None:
"""Delete file metadata from the database
@param file_id: id of the file to delete
@ -1010,7 +1010,7 @@ class Storage:
await session.commit()
@aio
async def fileUpdate(
async def file_update(
self,
file_id: str,
column: str,
@ -1068,7 +1068,7 @@ class Storage:
)
@aio
async def getPubsubNode(
async def get_pubsub_node(
self,
client: SatXMPPEntity,
service: jid.JID,
@ -1085,7 +1085,7 @@ class Storage:
@param with_items: retrieve items in the same query
@param with_subscriptions: retrieve subscriptions in the same query
@param create: if the node doesn't exist in DB, create it
@param create_kwargs: keyword arguments to use with ``setPubsubNode`` if the node
@param create_kwargs: keyword arguments to use with ``set_pubsub_node`` if the node
needs to be created.
"""
async with self.session() as session:
@ -1112,15 +1112,15 @@ class Storage:
if create_kwargs is None:
create_kwargs = {}
try:
return await as_future(self.setPubsubNode(
return await as_future(self.set_pubsub_node(
client, service, name, **create_kwargs
))
except IntegrityError as e:
if "unique" in str(e.orig).lower():
# the node may already exist, if it has been created just after
# getPubsubNode above
# get_pubsub_node above
log.debug("ignoring UNIQUE constraint error")
cached_node = await as_future(self.getPubsubNode(
cached_node = await as_future(self.get_pubsub_node(
client,
service,
name,
@ -1133,7 +1133,7 @@ class Storage:
return ret
@aio
async def setPubsubNode(
async def set_pubsub_node(
self,
client: SatXMPPEntity,
service: jid.JID,
@ -1159,7 +1159,7 @@ class Storage:
return node
@aio
async def updatePubsubNodeSyncState(
async def update_pubsub_node_sync_state(
self,
node: PubsubNode,
state: SyncState
@ -1176,7 +1176,7 @@ class Storage:
)
@aio
async def deletePubsubNode(
async def delete_pubsub_node(
self,
profiles: Optional[List[str]],
services: Optional[List[jid.JID]],
@ -1207,7 +1207,7 @@ class Storage:
await session.commit()
@aio
async def cachePubsubItems(
async def cache_pubsub_items(
self,
client: SatXMPPEntity,
node: PubsubNode,
@ -1240,7 +1240,7 @@ class Storage:
await session.commit()
@aio
async def deletePubsubItems(
async def delete_pubsub_items(
self,
node: PubsubNode,
items_names: Optional[List[str]] = None
@ -1264,7 +1264,7 @@ class Storage:
await session.commit()
@aio
async def purgePubsubItems(
async def purge_pubsub_items(
self,
services: Optional[List[jid.JID]] = None,
names: Optional[List[str]] = None,
@ -1313,7 +1313,7 @@ class Storage:
await session.commit()
@aio
async def getItems(
async def get_items(
self,
node: PubsubNode,
max_items: Optional[int] = None,
@ -1352,7 +1352,7 @@ class Storage:
metadata = {
"service": node.service,
"node": node.name,
"uri": uri.buildXMPPUri(
"uri": uri.build_xmpp_uri(
"pubsub",
path=node.service.full(),
node=node.name,
@ -1487,7 +1487,7 @@ class Storage:
result.reverse()
return result, metadata
def _getSqlitePath(
def _get_sqlite_path(
self,
path: List[Union[str, int]]
) -> str:
@ -1495,7 +1495,7 @@ class Storage:
return f"${''.join(f'[{p}]' if isinstance(p, int) else f'.{p}' for p in path)}"
@aio
async def searchPubsubItems(
async def search_pubsub_items(
self,
query: dict,
) -> Tuple[List[PubsubItem]]:
@ -1626,7 +1626,7 @@ class Storage:
op_attr = OP_MAP[operator]
except KeyError:
raise ValueError(f"invalid operator: {operator!r}")
sqlite_path = self._getSqlitePath(path)
sqlite_path = self._get_sqlite_path(path)
if operator in ("overlap", "ioverlap", "disjoint", "idisjoint"):
col = literal_column("json_each.value")
if operator[0] == "i":
@ -1683,7 +1683,7 @@ class Storage:
raise NotImplementedError(f"Unknown {order!r} order")
else:
# we have a JSON path
# sqlite_path = self._getSqlitePath(path)
# sqlite_path = self._get_sqlite_path(path)
col = PubsubItem.parsed[path]
direction = order_data.get("direction", "ASC").lower()
if not direction in ("asc", "desc"):

View file

@ -22,15 +22,15 @@ from sat.core.constants import Const as C
from sat.tools import config
def getDbConfig() -> dict:
def get_db_config() -> dict:
"""Get configuration for database
@return: dict with following keys:
- type: only "sqlite" for now
- path: path to the sqlite DB
"""
main_conf = config.parseMainConf()
local_dir = Path(config.getConfig(main_conf, "", "local_dir"))
main_conf = config.parse_main_conf()
local_dir = Path(config.config_get(main_conf, "", "local_dir"))
database_path = (local_dir / C.SAVEFILE_DATABASE).expanduser()
url = f"sqlite+aiosqlite:///{quote(str(database_path))}?timeout=30"
return {