component Email gateway: Convert mailing list to pubsub nodes:
- `Credentials` is now a Pydantic based model. - Mailing list related emails are now detected hand saved as pubsub items, using XEP-0277 blog items, and creating suitable nodes. The ID of the mailing list is used for root node. - Mailing list items are currently restricted to recipient associated JID. - Words in square bracket in title `[Like][That]` are removed and converted to blog categories. - Method to convert between MbData and email (in both directions) have been created. rel 462
This commit is contained in:
parent
26002870a8
commit
e1828b3672
2 changed files with 540 additions and 66 deletions
|
|
@ -33,6 +33,7 @@ from typing import (
|
|||
Set,
|
||||
Tuple,
|
||||
Union,
|
||||
cast,
|
||||
overload,
|
||||
)
|
||||
from urllib import parse
|
||||
|
|
@ -59,6 +60,7 @@ from libervia.backend.core.i18n import _
|
|||
from libervia.backend.core.log import getLogger
|
||||
from libervia.backend.memory import persistent
|
||||
from libervia.backend.memory.sqla_mapping import History, SubscriptionState
|
||||
from libervia.backend.plugins.plugin_xep_0277 import XEP_0277
|
||||
from libervia.backend.tools import utils
|
||||
from libervia.backend.tools.common import data_format, tls, uri
|
||||
from libervia.backend.tools.common.async_utils import async_lru
|
||||
|
|
@ -157,7 +159,7 @@ class APGateway:
|
|||
self._p = host.plugins["XEP-0060"]
|
||||
self._a = host.plugins["XEP-0084"]
|
||||
self._e = host.plugins["XEP-0106"]
|
||||
self._m = host.plugins["XEP-0277"]
|
||||
self._m = cast(XEP_0277, host.plugins["XEP-0277"])
|
||||
self._v = host.plugins["XEP-0292"]
|
||||
self._refs = host.plugins["XEP-0372"]
|
||||
self._r = host.plugins["XEP-0424"]
|
||||
|
|
@ -526,6 +528,7 @@ class APGateway:
|
|||
|
||||
for now, only handle XMPP items to convert to AP
|
||||
"""
|
||||
assert self.client is not None
|
||||
url_type, url_args = self.parse_apurl(url)
|
||||
if url_type == TYPE_ITEM:
|
||||
try:
|
||||
|
|
@ -2228,6 +2231,7 @@ class APGateway:
|
|||
@param public: if True, the activity will be addressed to public namespace
|
||||
@return: actor_id of the entity deleting the item, activity to send
|
||||
"""
|
||||
assert self.client is not None
|
||||
if node is None:
|
||||
node = self._m.namespace
|
||||
|
||||
|
|
@ -2763,7 +2767,7 @@ class APGateway:
|
|||
create_kwargs={"subscribed": True},
|
||||
)
|
||||
else:
|
||||
# it is a root item (i.e. not a reply to an other item)
|
||||
# it is a root item (i.e. not a reply to another item)
|
||||
create = node == self._events.namespace
|
||||
cached_node = await self.host.memory.storage.get_pubsub_node(
|
||||
client, service, node, with_subscriptions=True, create=create
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import Optional, Tuple, List, Dict, Any, Union
|
||||
from typing import Optional, Tuple, List, Dict, Any
|
||||
from urllib.parse import urlparse
|
||||
from pathlib import Path
|
||||
from base64 import b64encode
|
||||
|
|
@ -25,7 +25,7 @@ import tempfile
|
|||
from twisted.internet import defer, threads
|
||||
from twisted.words.protocols.jabber import jid, error
|
||||
from twisted.words.xish import domish
|
||||
from wokkel import rsm, pubsub, disco
|
||||
from wokkel import rsm, pubsub
|
||||
|
||||
from libervia.backend.core.i18n import _
|
||||
from libervia.backend.core import exceptions
|
||||
|
|
@ -265,7 +265,7 @@ class APPubsubService(rsm.PubSubService):
|
|||
avatar_data = await self.get_avatar_data(client, requestor_actor_id, ap_account)
|
||||
return self.apg._a.build_item_metadata_elt(avatar_data)
|
||||
|
||||
def _blocking_b_6_4_encode_avatar(self, avatar_data: Dict[str, Any]) -> None:
|
||||
def _blocking_b64encode_avatar(self, avatar_data: Dict[str, Any]) -> None:
|
||||
with avatar_data["path"].open("rb") as f:
|
||||
avatar_data["base64"] = b64encode(f.read()).decode()
|
||||
|
||||
|
|
@ -287,7 +287,7 @@ class APPubsubService(rsm.PubSubService):
|
|||
)
|
||||
if "base64" not in avatar_data:
|
||||
await threads.deferToThread(
|
||||
self._blocking_b_6_4_encode_avatar, avatar_data
|
||||
self._blocking_b64encode_avatar, avatar_data
|
||||
)
|
||||
else:
|
||||
if len(itemIdentifiers) > 1:
|
||||
|
|
@ -300,7 +300,7 @@ class APPubsubService(rsm.PubSubService):
|
|||
if cache_data is None:
|
||||
raise error.StanzaError("item-not-found")
|
||||
avatar_data = {"cache_uid": item_id, "path": cache_data["path"]}
|
||||
await threads.deferToThread(self._blocking_b_6_4_encode_avatar, avatar_data)
|
||||
await threads.deferToThread(self._blocking_b64encode_avatar, avatar_data)
|
||||
|
||||
return self.apg._a.build_item_data_elt(avatar_data)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue