Mercurial > libervia-backend
diff sat/plugins/plugin_comp_ap_gateway/__init__.py @ 4037:524856bd7b19
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.
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 08 Apr 2023 13:54:42 +0200 |
parents | 26c3e1bc7fb7 |
children | c23cad65ae99 |
line wrap: on
line diff
--- a/sat/plugins/plugin_comp_ap_gateway/__init__.py Fri Apr 07 15:18:39 2023 +0200 +++ b/sat/plugins/plugin_comp_ap_gateway/__init__.py Sat Apr 08 13:54:42 2023 +0200 @@ -151,9 +151,9 @@ self._t = host.plugins["TEXT_SYNTAXES"] self._i = host.plugins["IDENTITY"] self._events = host.plugins["XEP-0471"] - self._p.addManagedNode( + self._p.add_managed_node( "", - items_cb=self._itemsReceived, + items_cb=self._items_received, # we want to be sure that the callbacks are launched before pubsub cache's # one, as we need to inspect items before they are actually removed from cache # or updated @@ -162,20 +162,20 @@ self.pubsub_service = APPubsubService(self) self.ad_hoc = APAdHocService(self) self.ap_events = APEvents(self) - host.trigger.add("messageReceived", self._messageReceivedTrigger, priority=-1000) - host.trigger.add("XEP-0424_retractReceived", self._onMessageRetract) - host.trigger.add("XEP-0372_ref_received", self._onReferenceReceived) + host.trigger.add("messageReceived", self._message_received_trigger, priority=-1000) + host.trigger.add("XEP-0424_retractReceived", self._on_message_retract) + host.trigger.add("XEP-0372_ref_received", self._on_reference_received) - host.bridge.addMethod( - "APSend", + host.bridge.add_method( + "ap_send", ".plugin", in_sign="sss", out_sign="", - method=self._publishMessage, + method=self._publish_message, async_=True, ) - def getHandler(self, __): + def get_handler(self, __): return self.pubsub_service async def init(self, client): @@ -186,7 +186,7 @@ log.info(_("ActivityPub Gateway initialization")) # RSA keys - stored_data = await self.host.memory.storage.getPrivates( + stored_data = await self.host.memory.storage.get_privates( IMPORT_NAME, ["rsa_key"], profile=client.profile ) private_key_pem = stored_data.get("rsa_key") @@ -201,7 +201,7 @@ format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption() ).decode() - await self.host.memory.storage.setPrivateValue( + await self.host.memory.storage.set_private_value( IMPORT_NAME, "rsa_key", private_key_pem, profile=client.profile ) else: @@ -217,9 +217,9 @@ # params # URL and port - self.public_url = self.host.memory.getConfig( + self.public_url = self.host.memory.config_get( CONF_SECTION, "public_url" - ) or self.host.memory.getConfig( + ) or self.host.memory.config_get( CONF_SECTION, "xmpp_domain" ) if self.public_url is None: @@ -235,37 +235,37 @@ "\"public_url\" configuration option. ActivityPub Gateway won't be run." ) return - self.http_port = int(self.host.memory.getConfig( + self.http_port = int(self.host.memory.config_get( CONF_SECTION, 'http_port', 8123)) - connection_type = self.host.memory.getConfig( + connection_type = self.host.memory.config_get( CONF_SECTION, 'http_connection_type', 'https') if connection_type not in ('http', 'https'): raise exceptions.ConfigError( 'bad ap-gateay http_connection_type, you must use one of "http" or ' '"https"' ) - self.max_items = int(self.host.memory.getConfig( + self.max_items = int(self.host.memory.config_get( CONF_SECTION, 'new_node_max_items', 50 )) - self.comments_max_depth = int(self.host.memory.getConfig( + self.comments_max_depth = int(self.host.memory.config_get( CONF_SECTION, 'comments_max_depth', 0 )) - self.ap_path = self.host.memory.getConfig(CONF_SECTION, 'ap_path', '_ap') + self.ap_path = self.host.memory.config_get(CONF_SECTION, 'ap_path', '_ap') self.base_ap_url = parse.urljoin(f"https://{self.public_url}", f"{self.ap_path}/") # True (default) if we provide gateway only to entities/services from our server self.local_only = C.bool( - self.host.memory.getConfig(CONF_SECTION, 'local_only', C.BOOL_TRUE) + self.host.memory.config_get(CONF_SECTION, 'local_only', C.BOOL_TRUE) ) # if True (default), mention will be parsed in non-private content coming from # XMPP. This is necessary as XEP-0372 are coming separately from item where the # mention is done, which is hard to impossible to translate to ActivityPub (where # mention specified inside the item directly). See documentation for details. self.auto_mentions = C.bool( - self.host.memory.getConfig(CONF_SECTION, "auto_mentions", C.BOOL_TRUE) + self.host.memory.config_get(CONF_SECTION, "auto_mentions", C.BOOL_TRUE) ) - html_redirect: Dict[str, Union[str, dict]] = self.host.memory.getConfig( + html_redirect: Dict[str, Union[str, dict]] = self.host.memory.config_get( CONF_SECTION, 'html_redirect_dict', {} ) self.html_redirect: Dict[str, List[dict]] = {} @@ -291,13 +291,13 @@ if connection_type == 'http': reactor.listenTCP(self.http_port, self.server) else: - options = tls.getOptionsFromConfig( + options = tls.get_options_from_config( self.host.memory.config, CONF_SECTION) - tls.TLSOptionsCheck(options) - context_factory = tls.getTLSContextFactory(options) + tls.tls_options_check(options) + context_factory = tls.get_tls_context_factory(options) reactor.listenSSL(self.http_port, self.server, context_factory) - async def profileConnecting(self, client): + async def profile_connecting(self, client): self.client = client client.sendHistory = True client._ap_storage = persistent.LazyPersistentBinaryDict( @@ -306,10 +306,10 @@ ) await self.init(client) - def profileConnected(self, client): + def profile_connected(self, client): self.ad_hoc.init(client) - async def _itemsReceived( + async def _items_received( self, client: SatXMPPEntity, itemsEvent: pubsub.ItemsEvent @@ -326,7 +326,7 @@ return # we need recipient as JID and not gateway own JID to be able to use methods such # as "subscribe" - client = self.client.getVirtualClient(itemsEvent.sender) + client = self.client.get_virtual_client(itemsEvent.sender) recipient = itemsEvent.recipient if not recipient.user: log.debug("ignoring items event without local part specified") @@ -334,18 +334,18 @@ ap_account = self._e.unescape(recipient.user) - if self._pa.isAttachmentNode(itemsEvent.nodeIdentifier): - await self.convertAndPostAttachments( + if self._pa.is_attachment_node(itemsEvent.nodeIdentifier): + await self.convert_and_post_attachments( client, ap_account, itemsEvent.sender, itemsEvent.nodeIdentifier, itemsEvent.items ) else: - await self.convertAndPostItems( + await self.convert_and_post_items( client, ap_account, itemsEvent.sender, itemsEvent.nodeIdentifier, itemsEvent.items ) - async def getVirtualClient(self, actor_id: str) -> SatXMPPEntity: + async def get_virtual_client(self, actor_id: str) -> SatXMPPEntity: """Get client for this component with a specified jid This is needed to perform operations with the virtual JID corresponding to the AP @@ -353,8 +353,8 @@ @param actor_id: ID of the actor @return: virtual client """ - local_jid = await self.getJIDFromId(actor_id) - return self.client.getVirtualClient(local_jid) + local_jid = await self.get_jid_from_id(actor_id) + return self.client.get_virtual_client(local_jid) def is_activity(self, data: dict) -> bool: """Return True if the data has an activity type""" @@ -363,7 +363,7 @@ except (KeyError, TypeError): return False - async def apGet(self, url: str) -> dict: + async def ap_get(self, url: str) -> dict: """Retrieve AP JSON from given URL @raise error.StanzaError: "service-unavailable" is sent when something went wrong @@ -392,16 +392,16 @@ ) @overload - async def apGetObject(self, data: dict, key: str) -> Optional[dict]: + async def ap_get_object(self, data: dict, key: str) -> Optional[dict]: ... @overload - async def apGetObject( + async def ap_get_object( self, data: Union[str, dict], key: None = None ) -> dict: ... - async def apGetObject(self, data, key = None): + async def ap_get_object(self, data, key = None): """Retrieve an AP object, dereferencing when necessary This method is to be used with attributes marked as "Functional" in @@ -416,21 +416,21 @@ value = data if value is None: if key is None: - raise ValueError("None can't be used with apGetObject is key is None") + raise ValueError("None can't be used with ap_get_object is key is None") return None elif isinstance(value, dict): return value elif isinstance(value, str): - if self.isLocalURL(value): - return await self.apGetLocalObject(value) + if self.is_local_url(value): + return await self.ap_get_local_object(value) else: - return await self.apGet(value) + return await self.ap_get(value) else: raise NotImplementedError( "was expecting a string or a dict, got {type(value)}: {value!r}}" ) - async def apGetLocalObject( + async def ap_get_local_object( self, url: str ) -> dict: @@ -438,23 +438,23 @@ for now, only handle XMPP items to convert to AP """ - url_type, url_args = self.parseAPURL(url) + url_type, url_args = self.parse_apurl(url) if url_type == TYPE_ITEM: try: account, item_id = url_args except ValueError: raise ValueError(f"invalid URL: {url}") - author_jid, node = await self.getJIDAndNode(account) + author_jid, node = await self.get_jid_and_node(account) if node is None: node = self._m.namespace - cached_node = await self.host.memory.storage.getPubsubNode( + cached_node = await self.host.memory.storage.get_pubsub_node( self.client, author_jid, node ) if not cached_node: log.debug(f"node {node!r} at {author_jid} is not found in cache") found_item = None else: - cached_items, __ = await self.host.memory.storage.getItems( + cached_items, __ = await self.host.memory.storage.get_items( cached_node, item_ids=[item_id] ) if not cached_items: @@ -468,8 +468,8 @@ if found_item is None: # the node is not in cache, we have to make a request to retrieve the item - # If the node doesn't exist, getItems will raise a NotFound exception - found_items, __ = await self._p.getItems( + # If the node doesn't exist, get_items will raise a NotFound exception + found_items, __ = await self._p.get_items( self.client, author_jid, node, item_ids=[item_id] ) try: @@ -499,7 +499,7 @@ 'only object from "item" URLs can be retrieved for now' ) - async def apGetList( + async def ap_get_list( self, data: dict, key: str, @@ -507,7 +507,7 @@ ) -> Optional[List[Dict[str, Any]]]: """Retrieve a list of objects from AP data, dereferencing when necessary - This method is to be used with non functional vocabularies. Use ``apGetObject`` + This method is to be used with non functional vocabularies. Use ``ap_get_object`` otherwise. If the value is a dictionary, it will be wrapped in a list @param data: AP object where a list of objects is looked for @@ -519,10 +519,10 @@ if value is None: return None elif isinstance(value, str): - if self.isLocalURL(value): - value = await self.apGetLocalObject(value) + if self.is_local_url(value): + value = await self.ap_get_local_object(value) else: - value = await self.apGet(value) + value = await self.ap_get(value) if isinstance(value, dict): return [value] if not isinstance(value, list): @@ -533,9 +533,9 @@ for v in value ] else: - return [await self.apGetObject(i) for i in value] + return [await self.ap_get_object(i) for i in value] - async def apGetActors( + async def ap_get_actors( self, data: dict, key: str, @@ -575,11 +575,11 @@ f"list of actors is empty" ) if as_account: - return [await self.getAPAccountFromId(actor_id) for actor_id in value] + return [await self.get_ap_account_from_id(actor_id) for actor_id in value] else: return value - async def apGetSenderActor( + async def ap_get_sender_actor( self, data: dict, ) -> str: @@ -592,12 +592,12 @@ @raise exceptions.NotFound: no actor has been found in data """ try: - actors = await self.apGetActors(data, "actor", as_account=False) + actors = await self.ap_get_actors(data, "actor", as_account=False) except exceptions.DataError: actors = None if not actors: try: - actors = await self.apGetActors(data, "attributedTo", as_account=False) + actors = await self.ap_get_actors(data, "attributedTo", as_account=False) except exceptions.DataError: raise exceptions.NotFound( 'actor not specified in "actor" or "attributedTo"' @@ -607,7 +607,7 @@ except IndexError: raise exceptions.NotFound("list of actors is empty") - def mustEncode(self, text: str) -> bool: + def must_encode(self, text: str) -> bool: """Indicate if a text must be period encoded""" return ( not RE_ALLOWED_UNQUOTED.match(text) @@ -615,10 +615,10 @@ or "---" in text ) - def periodEncode(self, text: str) -> str: + def period_encode(self, text: str) -> str: """Period encode a text - see [getJIDAndNode] for reasons of period encoding + see [get_jid_and_node] for reasons of period encoding """ return ( parse.quote(text, safe="") @@ -629,7 +629,7 @@ .replace("%", ".") ) - async def getAPAccountFromJidAndNode( + async def get_ap_account_from_jid_and_node( self, jid_: jid.JID, node: Optional[str] @@ -644,28 +644,28 @@ if self.client is None: raise exceptions.InternalError("Client is not set yet") - if self.isVirtualJID(jid_): + if self.is_virtual_jid(jid_): # this is an proxy JID to an AP Actor return self._e.unescape(jid_.user) - if node and not jid_.user and not self.mustEncode(node): - is_pubsub = await self.isPubsub(jid_) + if node and not jid_.user and not self.must_encode(node): + is_pubsub = await self.is_pubsub(jid_) # when we have a pubsub service, the user part can be used to set the node # this produces more user-friendly AP accounts if is_pubsub: jid_.user = node node = None - is_local = self.isLocal(jid_) + is_local = self.is_local(jid_) user = jid_.user if is_local else jid_.userhost() if user is None: user = "" account_elts = [] - if node and self.mustEncode(node) or self.mustEncode(user): + if node and self.must_encode(node) or self.must_encode(user): account_elts = ["___"] if node: - node = self.periodEncode(node) - user = self.periodEncode(user) + node = self.period_encode(node) + user = self.period_encode(user) if not user: raise exceptions.InternalError("there should be a user part") @@ -678,21 +678,21 @@ )) return "".join(account_elts) - def isLocal(self, jid_: jid.JID) -> bool: + def is_local(self, jid_: jid.JID) -> bool: """Returns True if jid_ use a domain or subdomain of gateway's host""" local_host = self.client.host.split(".") assert local_host return jid_.host.split(".")[-len(local_host):] == local_host - async def isPubsub(self, jid_: jid.JID) -> bool: + async def is_pubsub(self, jid_: jid.JID) -> bool: """Indicate if a JID is a Pubsub service""" - host_disco = await self.host.getDiscoInfos(self.client, jid_) + host_disco = await self.host.get_disco_infos(self.client, jid_) return ( ("pubsub", "service") in host_disco.identities and not ("pubsub", "pep") in host_disco.identities ) - async def getJIDAndNode(self, ap_account: str) -> Tuple[jid.JID, Optional[str]]: + async def get_jid_and_node(self, ap_account: str) -> Tuple[jid.JID, Optional[str]]: """Decode raw AP account handle to get XMPP JID and Pubsub Node Username are case insensitive. @@ -767,7 +767,7 @@ # we need to check host disco, because disco request to user may be # blocked for privacy reason (see # https://xmpp.org/extensions/xep-0030.html#security) - is_pubsub = await self.isPubsub(jid.JID(domain)) + is_pubsub = await self.is_pubsub(jid.JID(domain)) if is_pubsub: # if the host is a pubsub service and not a PEP, we consider that username @@ -781,14 +781,14 @@ except RuntimeError: raise ValueError(f"Invalid jid: {jid_s!r}") - if self.local_only and not self.isLocal(jid_): + if self.local_only and not self.is_local(jid_): raise exceptions.PermissionError( "This gateway is configured to map only local entities and services" ) return jid_, node - def getLocalJIDFromAccount(self, account: str) -> jid.JID: + def get_local_jid_from_account(self, account: str) -> jid.JID: """Compute JID linking to an AP account The local jid is computer by escaping AP actor handle and using it as local part @@ -803,7 +803,7 @@ ) ) - async def getJIDFromId(self, actor_id: str) -> jid.JID: + async def get_jid_from_id(self, actor_id: str) -> jid.JID: """Compute JID linking to an AP Actor ID The local jid is computer by escaping AP actor handle and using it as local part @@ -811,17 +811,17 @@ If the actor_id comes from local server (checked with self.public_url), it means that we have an XMPP entity, and the original JID is returned """ - if self.isLocalURL(actor_id): - request_type, extra_args = self.parseAPURL(actor_id) + if self.is_local_url(actor_id): + request_type, extra_args = self.parse_apurl(actor_id) if request_type != TYPE_ACTOR or len(extra_args) != 1: raise ValueError(f"invalid actor id: {actor_id!r}") - actor_jid, __ = await self.getJIDAndNode(extra_args[0]) + actor_jid, __ = await self.get_jid_and_node(extra_args[0]) return actor_jid - account = await self.getAPAccountFromId(actor_id) - return self.getLocalJIDFromAccount(account) + account = await self.get_ap_account_from_id(actor_id) + return self.get_local_jid_from_account(account) - def parseAPURL(self, url: str) -> Tuple[str, List[str]]: + def parse_apurl(self, url: str) -> Tuple[str, List[str]]: """Parse an URL leading to an AP endpoint @param url: URL to parse (schema is not mandatory) @@ -831,7 +831,7 @@ type_, *extra_args = path[len(self.ap_path):].lstrip("/").split("/") return type_, [parse.unquote(a) for a in extra_args] - def buildAPURL(self, type_:str , *args: str) -> str: + def build_apurl(self, type_:str , *args: str) -> str: """Build an AP endpoint URL @param type_: type of AP endpoing @@ -842,18 +842,18 @@ str(Path(type_).joinpath(*(parse.quote_plus(a, safe="@") for a in args))) ) - def isLocalURL(self, url: str) -> bool: + def is_local_url(self, url: str) -> bool: """Tells if an URL link to this component ``public_url`` and ``ap_path`` are used to check the URL """ return url.startswith(self.base_ap_url) - def isVirtualJID(self, jid_: jid.JID) -> bool: + def is_virtual_jid(self, jid_: jid.JID) -> bool: """Tell if a JID is an AP actor mapped through this gateway""" return jid_.host == self.client.jid.userhost() - def buildSignatureHeader(self, values: Dict[str, str]) -> str: + def build_signature_header(self, values: Dict[str, str]) -> str: """Build key="<value>" signature header from signature data""" fields = [] for key, value in values.items(): @@ -868,7 +868,7 @@ return ",".join(fields) - def getDigest(self, body: bytes, algo="SHA-256") -> Tuple[str, str]: + def get_digest(self, body: bytes, algo="SHA-256") -> Tuple[str, str]: """Get digest data to use in header and signature @param body: body of the request @@ -879,12 +879,12 @@ return algo, base64.b64encode(hashlib.sha256(body).digest()).decode() @async_lru(maxsize=LRU_MAX_SIZE) - async def getActorData(self, actor_id) -> dict: + async def get_actor_data(self, actor_id) -> dict: """Retrieve actor data with LRU cache""" - return await self.apGet(actor_id) + return await self.ap_get(actor_id) @async_lru(maxsize=LRU_MAX_SIZE) - async def getActorPubKeyData( + async def get_actor_pub_key_data( self, actor_id: str ) -> Tuple[str, str, rsa.RSAPublicKey]: @@ -894,7 +894,7 @@ @return: key_id, owner and public_key @raise KeyError: publicKey is missing from actor data """ - actor_data = await self.getActorData(actor_id) + actor_data = await self.get_actor_data(actor_id) pub_key_data = actor_data["publicKey"] key_id = pub_key_data["id"] owner = pub_key_data["owner"] @@ -947,11 +947,11 @@ return data - def getKeyId(self, actor_id: str) -> str: + def get_key_id(self, actor_id: str) -> str: """Get local key ID from actor ID""" return f"{actor_id}#main-key" - async def checkSignature( + async def check_signature( self, signature: str, key_id: str, @@ -971,11 +971,11 @@ to_sign = "\n".join(f"{k.lower()}: {v}" for k,v in headers.items()) if key_id.startswith("acct:"): actor = key_id[5:] - actor_id = await self.getAPActorIdFromAccount(actor) + actor_id = await self.get_ap_actor_id_from_account(actor) else: actor_id = key_id.split("#", 1)[0] - pub_key_id, pub_key_owner, pub_key = await self.getActorPubKeyData(actor_id) + pub_key_id, pub_key_owner, pub_key = await self.get_actor_pub_key_data(actor_id) if pub_key_id != key_id or pub_key_owner != actor_id: raise exceptions.EncryptionError("Public Key mismatch") @@ -994,7 +994,7 @@ return actor_id - def getSignatureData( + def get_signature_data( self, key_id: str, headers: Dict[str, str] @@ -1028,10 +1028,10 @@ "signature": signature } new_headers = {k: v for k,v in headers.items() if not k.startswith("(")} - new_headers["Signature"] = self.buildSignatureHeader(sign_data) + new_headers["Signature"] = self.build_signature_header(sign_data) return new_headers, sign_data - async def convertAndPostItems( + async def convert_and_post_items( self, client: SatXMPPEntity, ap_account: str, @@ -1049,11 +1049,11 @@ @param subscribe_extra_nodes: if True, extra data nodes will be automatically subscribed, that is comment nodes if present and attachments nodes. """ - actor_id = await self.getAPActorIdFromAccount(ap_account) - inbox = await self.getAPInboxFromId(actor_id) + actor_id = await self.get_ap_actor_id_from_account(ap_account) + inbox = await self.get_ap_inbox_from_id(actor_id) for item in items: if item.name == "item": - cached_item = await self.host.memory.storage.searchPubsubItems({ + cached_item = await self.host.memory.storage.search_pubsub_items({ "profiles": [self.client.profile], "services": [service], "nodes": [node], @@ -1070,10 +1070,10 @@ while root_elt.parent is not None: root_elt = root_elt.parent author_jid = jid.JID(root_elt["from"]).userhostJID() - if subscribe_extra_nodes and not self.isVirtualJID(author_jid): + if subscribe_extra_nodes and not self.is_virtual_jid(author_jid): # we subscribe automatically to comment nodes if any - recipient_jid = self.getLocalJIDFromAccount(ap_account) - recipient_client = self.client.getVirtualClient(recipient_jid) + recipient_jid = self.get_local_jid_from_account(ap_account) + recipient_client = self.client.get_virtual_client(recipient_jid) comments_data = event_data.get("comments") if comments_data: comment_service = jid.JID(comments_data["jid"]) @@ -1097,13 +1097,13 @@ # blog item mb_data = await self._m.item_2_mb_data(client, item, service, node) author_jid = jid.JID(mb_data["author_jid"]) - if subscribe_extra_nodes and not self.isVirtualJID(author_jid): + if subscribe_extra_nodes and not self.is_virtual_jid(author_jid): # we subscribe automatically to comment nodes if any - recipient_jid = self.getLocalJIDFromAccount(ap_account) - recipient_client = self.client.getVirtualClient(recipient_jid) + recipient_jid = self.get_local_jid_from_account(ap_account) + recipient_client = self.client.get_virtual_client(recipient_jid) for comment_data in mb_data.get("comments", []): comment_service = jid.JID(comment_data["service"]) - if self.isVirtualJID(comment_service): + if self.is_virtual_jid(comment_service): log.debug( f"ignoring virtual comment service: {comment_data}" ) @@ -1125,14 +1125,14 @@ url_actor = ap_item["actor"] elif item.name == "retract": - url_actor, ap_item = await self.apDeleteItem( + url_actor, ap_item = await self.ap_delete_item( client.jid, node, item["id"] ) else: raise exceptions.InternalError(f"unexpected element: {item.toXml()}") - await self.signAndPost(inbox, url_actor, ap_item) + await self.sign_and_post(inbox, url_actor, ap_item) - async def convertAndPostAttachments( + async def convert_and_post_attachments( self, client: SatXMPPEntity, ap_account: str, @@ -1162,8 +1162,8 @@ f"{len(items)})" ) - actor_id = await self.getAPActorIdFromAccount(ap_account) - inbox = await self.getAPInboxFromId(actor_id) + actor_id = await self.get_ap_actor_id_from_account(ap_account) + inbox = await self.get_ap_inbox_from_id(actor_id) item_elt = items[0] item_id = item_elt["id"] @@ -1179,16 +1179,16 @@ ) return - if self.isVirtualJID(publisher): + if self.is_virtual_jid(publisher): log.debug(f"ignoring item coming from local virtual JID {publisher}") return if publisher is not None: item_elt["publisher"] = publisher.userhost() - item_service, item_node, item_id = self._pa.attachmentNode2Item(node) - item_account = await self.getAPAccountFromJidAndNode(item_service, item_node) - if self.isVirtualJID(item_service): + item_service, item_node, item_id = self._pa.attachment_node_2_item(node) + item_account = await self.get_ap_account_from_jid_and_node(item_service, item_node) + if self.is_virtual_jid(item_service): # it's a virtual JID mapping to an external AP actor, we can use the # item_id directly item_url = item_id @@ -1199,9 +1199,9 @@ ) return else: - item_url = self.buildAPURL(TYPE_ITEM, item_account, item_id) + item_url = self.build_apurl(TYPE_ITEM, item_account, item_id) - old_attachment_pubsub_items = await self.host.memory.storage.searchPubsubItems({ + old_attachment_pubsub_items = await self.host.memory.storage.search_pubsub_items({ "profiles": [self.client.profile], "services": [service], "nodes": [node], @@ -1211,19 +1211,19 @@ old_attachment = {} else: old_attachment_items = [i.data for i in old_attachment_pubsub_items] - old_attachments = self._pa.items2attachmentData(client, old_attachment_items) + old_attachments = self._pa.items_2_attachment_data(client, old_attachment_items) try: old_attachment = old_attachments[0] except IndexError: # no known element was present in attachments old_attachment = {} - publisher_account = await self.getAPAccountFromJidAndNode( + publisher_account = await self.get_ap_account_from_jid_and_node( publisher, None ) - publisher_actor_id = self.buildAPURL(TYPE_ACTOR, publisher_account) + publisher_actor_id = self.build_apurl(TYPE_ACTOR, publisher_account) try: - attachments = self._pa.items2attachmentData(client, [item_elt])[0] + attachments = self._pa.items_2_attachment_data(client, [item_elt])[0] except IndexError: # no known element was present in attachments attachments = {} @@ -1232,24 +1232,24 @@ if "noticed" in attachments: if not "noticed" in old_attachment: # new "noticed" attachment, we translate to "Like" activity - activity_id = self.buildAPURL("like", item_account, item_id) + activity_id = self.build_apurl("like", item_account, item_id) activity = self.create_activity( TYPE_LIKE, publisher_actor_id, item_url, activity_id=activity_id ) activity["to"] = [ap_account] activity["cc"] = [NS_AP_PUBLIC] - await self.signAndPost(inbox, publisher_actor_id, activity) + await self.sign_and_post(inbox, publisher_actor_id, activity) else: if "noticed" in old_attachment: # "noticed" attachment has been removed, we undo the "Like" activity - activity_id = self.buildAPURL("like", item_account, item_id) + activity_id = self.build_apurl("like", item_account, item_id) activity = self.create_activity( TYPE_LIKE, publisher_actor_id, item_url, activity_id=activity_id ) activity["to"] = [ap_account] activity["cc"] = [NS_AP_PUBLIC] undo = self.create_activity("Undo", publisher_actor_id, activity) - await self.signAndPost(inbox, publisher_actor_id, undo) + await self.sign_and_post(inbox, publisher_actor_id, undo) # reactions new_reactions = set(attachments.get("reactions", {}).get("reactions", [])) @@ -1258,7 +1258,7 @@ reactions_add = new_reactions - old_reactions for reactions, undo in ((reactions_remove, True), (reactions_add, False)): for reaction in reactions: - activity_id = self.buildAPURL( + activity_id = self.build_apurl( "reaction", item_account, item_id, reaction.encode().hex() ) reaction_activity = self.create_activity( @@ -1274,7 +1274,7 @@ ) else: activy = reaction_activity - await self.signAndPost(inbox, publisher_actor_id, activy) + await self.sign_and_post(inbox, publisher_actor_id, activy) # RSVP if "rsvp" in attachments: @@ -1282,39 +1282,39 @@ old_attending = old_attachment.get("rsvp", {}).get("attending", "no") if attending != old_attending: activity_type = TYPE_JOIN if attending == "yes" else TYPE_LEAVE - activity_id = self.buildAPURL(activity_type.lower(), item_account, item_id) + activity_id = self.build_apurl(activity_type.lower(), item_account, item_id) activity = self.create_activity( activity_type, publisher_actor_id, item_url, activity_id=activity_id ) activity["to"] = [ap_account] activity["cc"] = [NS_AP_PUBLIC] - await self.signAndPost(inbox, publisher_actor_id, activity) + await self.sign_and_post(inbox, publisher_actor_id, activity) else: if "rsvp" in old_attachment: old_attending = old_attachment.get("rsvp", {}).get("attending", "no") if old_attending == "yes": - activity_id = self.buildAPURL(TYPE_LEAVE.lower(), item_account, item_id) + activity_id = self.build_apurl(TYPE_LEAVE.lower(), item_account, item_id) activity = self.create_activity( TYPE_LEAVE, publisher_actor_id, item_url, activity_id=activity_id ) activity["to"] = [ap_account] activity["cc"] = [NS_AP_PUBLIC] - await self.signAndPost(inbox, publisher_actor_id, activity) + await self.sign_and_post(inbox, publisher_actor_id, activity) - if service.user and self.isVirtualJID(service): + if service.user and self.is_virtual_jid(service): # the item is on a virtual service, we need to store it in cache log.debug("storing attachments item in cache") - cached_node = await self.host.memory.storage.getPubsubNode( + cached_node = await self.host.memory.storage.get_pubsub_node( client, service, node, with_subscriptions=True, create=True ) - await self.host.memory.storage.cachePubsubItems( + await self.host.memory.storage.cache_pubsub_items( self.client, cached_node, [item_elt], [attachments] ) - async def signAndPost(self, url: str, actor_id: str, doc: dict) -> TReqResponse: + async def sign_and_post(self, url: str, actor_id: str, doc: dict) -> TReqResponse: """Sign a documentent and post it to AP server @param url: AP server endpoint @@ -1322,7 +1322,7 @@ @param doc: document to send """ if self.verbose: - __, actor_args = self.parseAPURL(actor_id) + __, actor_args = self.parse_apurl(actor_id) actor_account = actor_args[0] to_log = [ "", @@ -1331,7 +1331,7 @@ p_url = parse.urlparse(url) body = json.dumps(doc).encode() - digest_algo, digest_hash = self.getDigest(body) + digest_algo, digest_hash = self.get_digest(body) digest = f"{digest_algo}={digest_hash}" headers = { @@ -1343,7 +1343,7 @@ headers["Content-Type"] = ( 'application/activity+json' ) - headers, __ = self.getSignatureData(self.getKeyId(actor_id), headers) + headers, __ = self.get_signature_data(self.get_key_id(actor_id), headers) if self.verbose: if self.verbose>=3: @@ -1364,19 +1364,19 @@ log.info(f"==> response code: {resp.code}") return resp - def _publishMessage(self, mess_data_s: str, service_s: str, profile: str): + def _publish_message(self, mess_data_s: str, service_s: str, profile: str): mess_data: dict = data_format.deserialise(mess_data_s) # type: ignore service = jid.JID(service_s) - client = self.host.getClient(profile) - return defer.ensureDeferred(self.publishMessage(client, mess_data, service)) + client = self.host.get_client(profile) + return defer.ensureDeferred(self.publish_message(client, mess_data, service)) @async_lru(maxsize=LRU_MAX_SIZE) - async def getAPActorIdFromAccount(self, account: str) -> str: + async def get_ap_actor_id_from_account(self, account: str) -> str: """Retrieve account ID from it's handle using WebFinger Don't use this method to get local actor id from a local account derivated for JID: in this case, the actor ID is retrieve with - ``self.buildAPURL(TYPE_ACTOR, ap_account)`` + ``self.build_apurl(TYPE_ACTOR, ap_account)`` @param account: AP handle (user@domain.tld) @return: Actor ID (which is an URL) @@ -1408,21 +1408,21 @@ ) return href - async def getAPActorDataFromAccount(self, account: str) -> dict: + async def get_ap_actor_data_from_account(self, account: str) -> dict: """Retrieve ActivityPub Actor data @param account: ActivityPub Actor identifier """ - href = await self.getAPActorIdFromAccount(account) - return await self.apGet(href) + href = await self.get_ap_actor_id_from_account(account) + return await self.ap_get(href) - async def getAPInboxFromId(self, actor_id: str, use_shared: bool = True) -> str: + async def get_ap_inbox_from_id(self, actor_id: str, use_shared: bool = True) -> str: """Retrieve inbox of an actor_id @param use_shared: if True, and a shared inbox exists, it will be used instead of the user inbox """ - data = await self.getActorData(actor_id) + data = await self.get_actor_data(actor_id) if use_shared: try: return data["endpoints"]["sharedInbox"] @@ -1431,15 +1431,15 @@ return data["inbox"] @async_lru(maxsize=LRU_MAX_SIZE) - async def getAPAccountFromId(self, actor_id: str) -> str: + async def get_ap_account_from_id(self, actor_id: str) -> str: """Retrieve AP account from the ID URL Works with external or local actor IDs. @param actor_id: AP ID of the actor (URL to the actor data) @return: AP handle """ - if self.isLocalURL(actor_id): - url_type, url_args = self.parseAPURL(actor_id) + if self.is_local_url(actor_id): + url_type, url_args = self.parse_apurl(actor_id) if url_type != "actor" or not url_args: raise exceptions.DataError( f"invalid local actor ID: {actor_id}" @@ -1458,7 +1458,7 @@ return account url_parsed = parse.urlparse(actor_id) - actor_data = await self.getActorData(actor_id) + actor_data = await self.get_actor_data(actor_id) username = actor_data.get("preferredUsername") if not username: raise exceptions.DataError( @@ -1466,7 +1466,7 @@ ) account = f"{username}@{url_parsed.hostname}" # we try to retrieve the actor ID from the account to check it - found_id = await self.getAPActorIdFromAccount(account) + found_id = await self.get_ap_actor_id_from_account(account) if found_id != actor_id: # cf. https://socialhub.activitypub.rocks/t/how-to-retrieve-user-server-tld-handle-from-actors-url/2196 msg = ( @@ -1478,7 +1478,7 @@ raise exceptions.DataError(msg) return account - async def getAPItems( + async def get_ap_items( self, collection: dict, max_items: Optional[int] = None, @@ -1552,7 +1552,7 @@ retrieved_items = 0 current_page = collection["last"] while retrieved_items < count: - page_data, items = await self.parseAPPage( + page_data, items = await self.parse_ap_page( current_page, parser, only_ids ) if not items: @@ -1588,7 +1588,7 @@ found_after_id = False while retrieved_items < count: - __, page_items = await self.parseAPPage(page, parser, only_ids) + __, page_items = await self.parse_ap_page(page, parser, only_ids) if not page_items: break retrieved_items += len(page_items) @@ -1661,7 +1661,7 @@ __, item_elt = await self.ap_item_2_mb_data_and_elt(ap_item) return item_elt - async def parseAPPage( + async def parse_ap_page( self, page: Union[str, dict], parser: Callable[[dict], Awaitable[domish.Element]], @@ -1674,13 +1674,13 @@ @param only_ids: if True, only retrieve items IDs @return: page data, pubsub items """ - page_data = await self.apGetObject(page) + page_data = await self.ap_get_object(page) if page_data is None: log.warning('No data found in collection') return {}, [] - ap_items = await self.apGetList(page_data, "orderedItems", only_ids=only_ids) + ap_items = await self.ap_get_list(page_data, "orderedItems", only_ids=only_ids) if ap_items is None: - ap_items = await self.apGetList(page_data, "items", only_ids=only_ids) + ap_items = await self.ap_get_list(page_data, "items", only_ids=only_ids) if not ap_items: log.warning(f'No item field found in collection: {page_data!r}') return page_data, [] @@ -1699,7 +1699,7 @@ return page_data, items - async def getCommentsNodes( + async def get_comments_nodes( self, item_id: str, parent_id: Optional[str] @@ -1719,13 +1719,13 @@ """ if parent_id is None or not self.comments_max_depth: return ( - self._m.getCommentsNode(parent_id) if parent_id is not None else None, - self._m.getCommentsNode(item_id) + self._m.get_comments_node(parent_id) if parent_id is not None else None, + self._m.get_comments_node(item_id) ) parent_url = parent_id parents = [] for __ in range(COMMENTS_MAX_PARENTS): - parent_item = await self.apGet(parent_url) + parent_item = await self.ap_get(parent_url) parents.insert(0, parent_item) parent_url = parent_item.get("inReplyTo") if parent_url is None: @@ -1733,13 +1733,13 @@ parent_limit = self.comments_max_depth-1 if len(parents) <= parent_limit: return ( - self._m.getCommentsNode(parents[-1]["id"]), - self._m.getCommentsNode(item_id) + self._m.get_comments_node(parents[-1]["id"]), + self._m.get_comments_node(item_id) ) else: last_level_item = parents[parent_limit] return ( - self._m.getCommentsNode(last_level_item["id"]), + self._m.get_comments_node(last_level_item["id"]), None ) @@ -1755,7 +1755,7 @@ """ is_activity = self.is_activity(ap_item) if is_activity: - ap_object = await self.apGetObject(ap_item, "object") + ap_object = await self.ap_get_object(ap_item, "object") if not ap_object: log.warning(f'No "object" found in AP item {ap_item!r}') raise exceptions.DataError @@ -1815,16 +1815,16 @@ # author if is_activity: - authors = await self.apGetActors(ap_item, "actor") + authors = await self.ap_get_actors(ap_item, "actor") else: - authors = await self.apGetActors(ap_object, "attributedTo") + authors = await self.ap_get_actors(ap_object, "attributedTo") if len(authors) > 1: # we only keep first item as author # TODO: handle multiple actors log.warning("multiple actors are not managed") account = authors[0] - author_jid = self.getLocalJIDFromAccount(account).full() + author_jid = self.get_local_jid_from_account(account).full() mb_data["author"] = account.split("@", 1)[0] mb_data["author_jid"] = author_jid @@ -1848,12 +1848,12 @@ # comments in_reply_to = ap_object.get("inReplyTo") - __, comments_node = await self.getCommentsNodes(item_id, in_reply_to) + __, comments_node = await self.get_comments_nodes(item_id, in_reply_to) if comments_node is not None: comments_data = { "service": author_jid, "node": comments_node, - "uri": uri.buildXMPPUri( + "uri": uri.build_xmpp_uri( "pubsub", path=author_jid, node=comments_node @@ -1863,7 +1863,7 @@ return mb_data - async def getReplyToIdFromXMPPNode( + async def get_reply_to_id_from_xmpp_node( self, client: SatXMPPEntity, ap_account: str, @@ -1885,7 +1885,7 @@ """ # FIXME: propose a protoXEP to properly get parent item, node and service - found_items = await self.host.memory.storage.searchPubsubItems({ + found_items = await self.host.memory.storage.search_pubsub_items({ "profiles": [client.profile], "names": [parent_item] }) @@ -1894,7 +1894,7 @@ parent_ap_account = ap_account elif len(found_items) == 1: cached_node = found_items[0].node - parent_ap_account = await self.getAPAccountFromJidAndNode( + parent_ap_account = await self.get_ap_account_from_jid_and_node( cached_node.service, cached_node.name ) @@ -1917,12 +1917,12 @@ parent_ap_account = ap_account else: cached_node = cached_item.node - parent_ap_account = await self.getAPAccountFromJidAndNode( + parent_ap_account = await self.get_ap_account_from_jid_and_node( cached_node.service, cached_node.name ) - return self.buildAPURL( + return self.build_apurl( TYPE_ITEM, parent_ap_account, parent_item ) @@ -1937,11 +1937,11 @@ """ repeated = mb_data["extra"]["repeated"] repeater = jid.JID(repeated["by"]) - repeater_account = await self.getAPAccountFromJidAndNode( + repeater_account = await self.get_ap_account_from_jid_and_node( repeater, None ) - repeater_id = self.buildAPURL(TYPE_ACTOR, repeater_account) + repeater_id = self.build_apurl(TYPE_ACTOR, repeater_account) repeated_uri = repeated["uri"] if not repeated_uri.startswith("xmpp:"): @@ -1950,7 +1950,7 @@ f"item {mb_data}" ) raise NotImplementedError - parsed_url = uri.parseXMPPUri(repeated_uri) + parsed_url = uri.parse_xmpp_uri(repeated_uri) if parsed_url["type"] != "pubsub": log.warning( "Only pubsub URL are handled for repeated item at the moment, ignoring " @@ -1959,9 +1959,9 @@ raise NotImplementedError rep_service = jid.JID(parsed_url["path"]) rep_item = parsed_url["item"] - activity_id = self.buildAPURL("item", repeater.userhost(), mb_data["id"]) + activity_id = self.build_apurl("item", repeater.userhost(), mb_data["id"]) - if self.isVirtualJID(rep_service): + if self.is_virtual_jid(rep_service): # it's an AP actor linked through this gateway # in this case we can simply use the item ID if not rep_item.startswith("https:"): @@ -1974,18 +1974,18 @@ else: # the repeated item is an XMPP publication, we build the corresponding ID rep_node = parsed_url["node"] - repeated_account = await self.getAPAccountFromJidAndNode( + repeated_account = await self.get_ap_account_from_jid_and_node( rep_service, rep_node ) - announced_uri = self.buildAPURL("item", repeated_account, rep_item) + announced_uri = self.build_apurl("item", repeated_account, rep_item) announce = self.create_activity( "Announce", repeater_id, announced_uri, activity_id=activity_id ) announce["to"] = [NS_AP_PUBLIC] announce["cc"] = [ - self.buildAPURL(TYPE_FOLLOWERS, repeater_account), - await self.getAPActorIdFromAccount(repeated_account) + self.build_apurl(TYPE_FOLLOWERS, repeater_account), + await self.get_ap_actor_id_from_account(repeated_account) ] return announce @@ -2020,12 +2020,12 @@ mb_data["id"] = shortuuid.uuid() if not mb_data.get("author_jid"): mb_data["author_jid"] = client.jid.userhost() - ap_account = await self.getAPAccountFromJidAndNode( + ap_account = await self.get_ap_account_from_jid_and_node( jid.JID(mb_data["author_jid"]), None ) - url_actor = self.buildAPURL(TYPE_ACTOR, ap_account) - url_item = self.buildAPURL(TYPE_ITEM, ap_account, mb_data["id"]) + url_actor = self.build_apurl(TYPE_ACTOR, ap_account) + url_item = self.build_apurl(TYPE_ITEM, ap_account, mb_data["id"]) ap_object = { "id": url_item, "type": "Note", @@ -2076,7 +2076,7 @@ # references continue try: - mentioned_id = await self.getAPActorIdFromAccount(mentioned) + mentioned_id = await self.get_ap_actor_id_from_account(mentioned) except Exception as e: log.warning(f"Can't add mention to {mentioned!r}: {e}") else: @@ -2094,27 +2094,27 @@ raise exceptions.InternalError( "node or service is missing in mb_data" ) - target_ap_account = await self.getAPAccountFromJidAndNode( + target_ap_account = await self.get_ap_account_from_jid_and_node( service, node ) - if self.isVirtualJID(service): + if self.is_virtual_jid(service): # service is a proxy JID for AP account - actor_data = await self.getAPActorDataFromAccount(target_ap_account) + actor_data = await self.get_ap_actor_data_from_account(target_ap_account) followers = actor_data.get("followers") else: # service is a real XMPP entity - followers = self.buildAPURL(TYPE_FOLLOWERS, target_ap_account) + followers = self.build_apurl(TYPE_FOLLOWERS, target_ap_account) if followers: ap_object["cc"] = [followers] - if self._m.isCommentNode(node): - parent_item = self._m.getParentItem(node) - if self.isVirtualJID(service): + if self._m.is_comment_node(node): + parent_item = self._m.get_parent_item(node) + if self.is_virtual_jid(service): # the publication is on a virtual node (i.e. an XMPP node managed by # this gateway and linking to an ActivityPub actor) ap_object["inReplyTo"] = parent_item else: # the publication is from a followed real XMPP node - ap_object["inReplyTo"] = await self.getReplyToIdFromXMPPNode( + ap_object["inReplyTo"] = await self.get_reply_to_id_from_xmpp_node( client, ap_account, parent_item, @@ -2125,7 +2125,7 @@ "Create" if is_new else "Update", url_actor, ap_object, activity_id=url_item ) - async def publishMessage( + async def publish_message( self, client: SatXMPPEntity, mess_data: dict, @@ -2151,7 +2151,7 @@ if not service.user: raise ValueError("service must have a local part") account = self._e.unescape(service.user) - ap_actor_data = await self.getAPActorDataFromAccount(account) + ap_actor_data = await self.get_ap_actor_data_from_account(account) try: inbox_url = ap_actor_data["endpoints"]["sharedInbox"] @@ -2160,9 +2160,9 @@ item_data = await self.mb_data_2_ap_item(client, mess_data) url_actor = item_data["actor"] - resp = await self.signAndPost(inbox_url, url_actor, item_data) + resp = await self.sign_and_post(inbox_url, url_actor, item_data) - async def apDeleteItem( + async def ap_delete_item( self, jid_: jid.JID, node: Optional[str], @@ -2182,10 +2182,10 @@ if node is None: node = self._m.namespace - author_account = await self.getAPAccountFromJidAndNode(jid_, node) - author_actor_id = self.buildAPURL(TYPE_ACTOR, author_account) + author_account = await self.get_ap_account_from_jid_and_node(jid_, node) + author_actor_id = self.build_apurl(TYPE_ACTOR, author_account) - items = await self.host.memory.storage.searchPubsubItems({ + items = await self.host.memory.storage.search_pubsub_items({ "profiles": [self.client.profile], "services": [jid_], "names": [item_id] @@ -2210,7 +2210,7 @@ f"{items[0].toXml()}" ) - url_item = self.buildAPURL(TYPE_ITEM, author_account, item_id) + url_item = self.build_apurl(TYPE_ITEM, author_account, item_id) ap_item = self.create_activity( "Delete", author_actor_id, @@ -2223,7 +2223,7 @@ ap_item["to"] = [NS_AP_PUBLIC] return author_actor_id, ap_item - def _messageReceivedTrigger( + def _message_received_trigger( self, client: SatXMPPEntity, message_elt: domish.Element, @@ -2248,7 +2248,7 @@ if mess_data["type"] not in ("chat", "normal"): log.warning(f"ignoring message with unexpected type: {mess_data}") return mess_data - if not self.isLocal(mess_data["from"]): + if not self.is_local(mess_data["from"]): log.warning(f"ignoring non local message: {mess_data}") return mess_data if not mess_data["to"].user: @@ -2258,8 +2258,8 @@ return mess_data actor_account = self._e.unescape(mess_data["to"].user) - actor_id = await self.getAPActorIdFromAccount(actor_account) - inbox = await self.getAPInboxFromId(actor_id, use_shared=False) + actor_id = await self.get_ap_actor_id_from_account(actor_account) + inbox = await self.get_ap_inbox_from_id(actor_id, use_shared=False) try: language, message = next(iter(mess_data["message"].items())) @@ -2282,7 +2282,7 @@ C.KEY_ATTACHMENTS: attachments } - client = self.client.getVirtualClient(mess_data["from"]) + client = self.client.get_virtual_client(mess_data["from"]) ap_item = await self.mb_data_2_ap_item(client, mb_data, public=False) ap_object = ap_item["object"] ap_object["to"] = ap_item["to"] = [actor_id] @@ -2294,10 +2294,10 @@ "name": f"@{actor_account}", }) - await self.signAndPost(inbox, ap_item["actor"], ap_item) + await self.sign_and_post(inbox, ap_item["actor"], ap_item) return mess_data - async def _onMessageRetract( + async def _on_message_retract( self, client: SatXMPPEntity, message_elt: domish.Element, @@ -2307,7 +2307,7 @@ if client != self.client: return True from_jid = jid.JID(message_elt["from"]) - if not self.isLocal(from_jid): + if not self.is_local(from_jid): log.debug( f"ignoring retract request from non local jid {from_jid}" ) @@ -2319,15 +2319,15 @@ f"Invalid destinee's JID: {to_jid.full()}" ) ap_account = self._e.unescape(to_jid.user) - actor_id = await self.getAPActorIdFromAccount(ap_account) - inbox = await self.getAPInboxFromId(actor_id, use_shared=False) - url_actor, ap_item = await self.apDeleteItem( + actor_id = await self.get_ap_actor_id_from_account(ap_account) + inbox = await self.get_ap_inbox_from_id(actor_id, use_shared=False) + url_actor, ap_item = await self.ap_delete_item( from_jid.userhostJID(), None, fastened_elts.id, public=False ) - resp = await self.signAndPost(inbox, url_actor, ap_item) + resp = await self.sign_and_post(inbox, url_actor, ap_item) return False - async def _onReferenceReceived( + async def _on_reference_received( self, client: SatXMPPEntity, message_elt: domish.Element, @@ -2352,7 +2352,7 @@ return False ap_account = self._e.unescape(mentioned.user) - actor_id = await self.getAPActorIdFromAccount(ap_account) + actor_id = await self.get_ap_actor_id_from_account(ap_account) parsed_anchor: dict = reference_data.get("parsed_anchor") if not parsed_anchor: @@ -2380,14 +2380,14 @@ log.warning(f"missing pubsub item in anchor: {reference_data['anchor']}") return False - cached_node = await self.host.memory.storage.getPubsubNode( + cached_node = await self.host.memory.storage.get_pubsub_node( client, pubsub_service, pubsub_node ) if not cached_node: log.warning(f"Anchored node not found in cache: {reference_data['anchor']}") return False - cached_items, __ = await self.host.memory.storage.getItems( + cached_items, __ = await self.host.memory.storage.get_items( cached_node, item_ids=[pubsub_item] ) if not cached_items: @@ -2410,13 +2410,13 @@ "name": ap_account, }) - inbox = await self.getAPInboxFromId(actor_id, use_shared=False) + inbox = await self.get_ap_inbox_from_id(actor_id, use_shared=False) - resp = await self.signAndPost(inbox, ap_item["actor"], ap_item) + resp = await self.sign_and_post(inbox, ap_item["actor"], ap_item) return False - async def newReplyToXMPPItem( + async def new_reply_to_xmpp_item( self, client: SatXMPPEntity, ap_item: dict, @@ -2425,7 +2425,7 @@ ) -> None: """We got an AP item which is a reply to an XMPP item""" in_reply_to = ap_item["inReplyTo"] - url_type, url_args = self.parseAPURL(in_reply_to) + url_type, url_args = self.parse_apurl(in_reply_to) if url_type != "item": log.warning( "Ignoring AP item replying to an XMPP item with an unexpected URL " @@ -2440,12 +2440,12 @@ f"({in_reply_to!r}):\n{pformat(ap_item)}" ) return - parent_item_service, parent_item_node = await self.getJIDAndNode( + parent_item_service, parent_item_node = await self.get_jid_and_node( parent_item_account ) if parent_item_node is None: parent_item_node = self._m.namespace - items, __ = await self._p.getItems( + items, __ = await self._p.get_items( client, parent_item_service, parent_item_node, item_ids=[parent_item_id] ) try: @@ -2463,17 +2463,17 @@ comment_node = parent_item_parsed["comments"][0]["node"] except (KeyError, IndexError): # we don't have a comment node set for this item - from sat.tools.xml_tools import ppElt - log.info(f"{ppElt(parent_item_elt.toXml())}") + from sat.tools.xml_tools import pp_elt + log.info(f"{pp_elt(parent_item_elt.toXml())}") raise NotImplementedError() else: __, item_elt = await self.ap_item_2_mb_data_and_elt(ap_item) await self._p.publish(client, comment_service, comment_node, [item_elt]) - await self.notifyMentions( + await self.notify_mentions( targets, mentions, comment_service, comment_node, item_elt["id"] ) - def getAPItemTargets( + def get_ap_item_targets( self, item: Dict[str, Any] ) -> Tuple[bool, Dict[str, Set[str]], List[Dict[str, str]]]: @@ -2499,9 +2499,9 @@ continue if not value: continue - if not self.isLocalURL(value): + if not self.is_local_url(value): continue - target_type = self.parseAPURL(value)[0] + target_type = self.parse_apurl(value)[0] if target_type != TYPE_ACTOR: log.debug(f"ignoring non actor type as a target: {href}") else: @@ -2517,9 +2517,9 @@ if not href: log.warning('Missing "href" field from mention object: {tag!r}') continue - if not self.isLocalURL(href): + if not self.is_local_url(href): continue - uri_type = self.parseAPURL(href)[0] + uri_type = self.parse_apurl(href)[0] if uri_type != TYPE_ACTOR: log.debug(f"ignoring non actor URI as a target: {href}") continue @@ -2531,7 +2531,7 @@ return is_public, targets, mentions - async def newAPItem( + async def new_ap_item( self, client: SatXMPPEntity, destinee: Optional[jid.JID], @@ -2544,14 +2544,14 @@ @param node: XMPP pubsub node @param item: AP object payload """ - is_public, targets, mentions = self.getAPItemTargets(item) + is_public, targets, mentions = self.get_ap_item_targets(item) if not is_public and targets.keys() == {TYPE_ACTOR}: # this is a direct message await self.handle_message_ap_item( client, targets, mentions, destinee, item ) else: - await self.handlePubsubAPItem( + await self.handle_pubsub_ap_item( client, targets, mentions, destinee, node, item, is_public ) @@ -2570,7 +2570,7 @@ @param item: AP object payload """ targets_jids = { - await self.getJIDFromId(t) + await self.get_jid_from_id(t) for t_set in targets.values() for t in t_set } @@ -2596,7 +2596,7 @@ ) await defer.DeferredList(defer_l) - async def notifyMentions( + async def notify_mentions( self, targets: Dict[str, Set[str]], mentions: List[Dict[str, str]], @@ -2612,14 +2612,14 @@ https://www.w3.org/TR/activitystreams-vocabulary/#microsyntaxes). """ - anchor = uri.buildXMPPUri("pubsub", path=service.full(), node=node, item=item_id) + anchor = uri.build_xmpp_uri("pubsub", path=service.full(), node=node, item=item_id) seen = set() # we start with explicit mentions because mentions' content will be used in the # future to fill "begin" and "end" reference attributes (we can't do it at the # moment as there is no way to specify the XML element to use in the blog item). for mention in mentions: - mentioned_jid = await self.getJIDFromId(mention["uri"]) - self._refs.sendReference( + mentioned_jid = await self.get_jid_from_id(mention["uri"]) + self._refs.send_reference( self.client, to_jid=mentioned_jid, anchor=anchor @@ -2627,18 +2627,18 @@ seen.add(mentioned_jid) remaining = { - await self.getJIDFromId(t) + await self.get_jid_from_id(t) for t_set in targets.values() for t in t_set } - seen for target in remaining: - self._refs.sendReference( + self._refs.send_reference( self.client, to_jid=target, anchor=anchor ) - async def handlePubsubAPItem( + async def handle_pubsub_ap_item( self, client: SatXMPPEntity, targets: Dict[str, Set[str]], @@ -2663,23 +2663,23 @@ if in_reply_to and isinstance(in_reply_to, list): in_reply_to = in_reply_to[0] if in_reply_to and isinstance(in_reply_to, str): - if self.isLocalURL(in_reply_to): + if self.is_local_url(in_reply_to): # this is a reply to an XMPP item - await self.newReplyToXMPPItem(client, item, targets, mentions) + await self.new_reply_to_xmpp_item(client, item, targets, mentions) return # this item is a reply to an AP item, we use or create a corresponding node # for comments - parent_node, __ = await self.getCommentsNodes(item["id"], in_reply_to) + parent_node, __ = await self.get_comments_nodes(item["id"], in_reply_to) node = parent_node or node - cached_node = await self.host.memory.storage.getPubsubNode( + cached_node = await self.host.memory.storage.get_pubsub_node( client, service, node, with_subscriptions=True, create=True, create_kwargs={"subscribed": True} ) else: # it is a root item (i.e. not a reply to an other item) create = node == self._events.namespace - cached_node = await self.host.memory.storage.getPubsubNode( + cached_node = await self.host.memory.storage.get_pubsub_node( client, service, node, with_subscriptions=True, create=create ) if cached_node is None: @@ -2693,7 +2693,7 @@ data, item_elt = await self.ap_events.ap_item_2_event_data_and_elt(item) else: data, item_elt = await self.ap_item_2_mb_data_and_elt(item) - await self.host.memory.storage.cachePubsubItems( + await self.host.memory.storage.cache_pubsub_items( client, cached_node, [item_elt], @@ -2709,9 +2709,9 @@ [(subscription.subscriber, None, [item_elt])] ) - await self.notifyMentions(targets, mentions, service, node, item_elt["id"]) + await self.notify_mentions(targets, mentions, service, node, item_elt["id"]) - async def newAPDeleteItem( + async def new_ap_delete_item( self, client: SatXMPPEntity, destinee: Optional[jid.JID], @@ -2731,7 +2731,7 @@ raise exceptions.DataError('"id" attribute is missing in item') if not item_id.startswith("http"): raise exceptions.DataError(f"invalid id: {item_id!r}") - if self.isLocalURL(item_id): + if self.is_local_url(item_id): raise ValueError("Local IDs should not be used") # we have no way to know if a deleted item is a direct one (thus a message) or one @@ -2755,10 +2755,10 @@ ) raise exceptions.PermissionError("forbidden") - await self._r.retractByHistory(client, history) + await self._r.retract_by_history(client, history) else: # no history in cache with this ID, it's probably a pubsub item - cached_node = await self.host.memory.storage.getPubsubNode( + cached_node = await self.host.memory.storage.get_pubsub_node( client, client.jid, node, with_subscriptions=True ) if cached_node is None: @@ -2767,7 +2767,7 @@ "which is not cached" ) raise exceptions.NotFound - await self.host.memory.storage.deletePubsubItems(cached_node, [item_id]) + await self.host.memory.storage.delete_pubsub_items(cached_node, [item_id]) # notifyRetract is expecting domish.Element instances item_elt = domish.Element((None, "item")) item_elt["id"] = item_id