diff --git a/sat/plugins/plugin_xep_0277.py b/sat/plugins/plugin_xep_0277.py
index 7e0ae0a2..c10ac7b8 100644
--- a/sat/plugins/plugin_xep_0277.py
+++ b/sat/plugins/plugin_xep_0277.py
@@ -19,8 +19,9 @@
import time
import dateutil
import calendar
+from mimetypes import guess_type
from secrets import token_urlsafe
-from typing import List, Optional, Dict, Tuple, Union, Any, Dict
+from typing import List, Optional, Dict, Tuple, Any, Dict
from functools import partial
import shortuuid
@@ -452,9 +453,15 @@ class XEP_0277(object):
# links
comments = microblog_data['comments'] = []
for link_elt in entry_elt.elements(NS_ATOM, "link"):
+ href = link_elt.getAttribute("href")
+ if not href:
+ log.warning(
+ f'missing href in element: {link_elt.toXml()}'
+ )
+ continue
rel = link_elt.getAttribute("rel")
if (rel == "replies" and link_elt.getAttribute("title") == "comments"):
- uri = link_elt["href"]
+ uri = href
comments_data = {
"uri": uri,
}
@@ -468,12 +475,6 @@ class XEP_0277(object):
comments_data["node"] = comment_node
comments.append(comments_data)
elif rel == "via":
- href = link_elt.getAttribute("href")
- if not href:
- log.warning(
- f'missing href in "via" element: {link_elt.toXml()}'
- )
- continue
try:
repeater_jid = jid.JID(item_elt["publisher"])
except (KeyError, RuntimeError):
@@ -496,13 +497,33 @@ class XEP_0277(object):
"by": repeater_jid.full(),
"uri": href
}
+ elif rel in ("related", "enclosure"):
+ attachment: Dict[str, Any] = {
+ "sources": [{"url": href}]
+ }
+ if rel == "related":
+ attachment["external"] = True
+ for attr, key in (
+ ("type", "media_type"),
+ ("title", "desc"),
+ ):
+ value = link_elt.getAttribute(attr)
+ if value:
+ attachment[key] = value
+ try:
+ attachment["size"] = int(link_elt.attributes["lenght"])
+ except (KeyError, ValueError):
+ pass
+ if "media_type" not in attachment:
+ media_type = guess_type(href, False)[0]
+ if media_type is not None:
+ attachment["media_type"] = media_type
+
+ attachments = extra.setdefault("attachments", [])
+ attachments.append(attachment)
else:
- title = link_elt.getAttribute("title", "")
- href = link_elt.getAttribute("href", "")
log.warning(
- "Unmanaged link element: rel={rel} title={title} href={href}".format(
- rel=rel, title=title, href=href
- )
+ f"Unmanaged link element: {link_elt.toXml()}"
)
# author
@@ -606,6 +627,7 @@ class XEP_0277(object):
@return: deferred which fire domish.Element
"""
entry_elt = domish.Element((NS_ATOM, "entry"))
+ extra = mb_data.get("extra", {})
## language ##
if "language" in mb_data:
@@ -616,7 +638,7 @@ class XEP_0277(object):
for elem_name in ("title", "content"):
for type_ in ["", "_rich", "_xhtml"]:
- attr = "{}{}".format(elem_name, type_)
+ attr = f"{elem_name}{type_}"
if attr in mb_data:
elem = entry_elt.addElement(elem_name)
if type_:
@@ -624,7 +646,7 @@ class XEP_0277(object):
xml_content = await synt.convert(
mb_data[attr], synt.getCurrentSyntax(client.profile), "XHTML"
)
- if "{}_xhtml".format(elem_name) in mb_data:
+ if f"{elem_name}_xhtml" in mb_data:
raise failure.Failure(
exceptions.DataError(
_(
@@ -681,6 +703,44 @@ class XEP_0277(object):
for elem in elems:
elem.name = "title"
+ ## attachments ##
+ attachments = extra.get(C.KEY_ATTACHMENTS)
+ if attachments:
+ for attachment in attachments:
+ try:
+ url = attachment["url"]
+ except KeyError:
+ try:
+ url = next(
+ s['url'] for s in attachment["sources"] if 'url' in s
+ )
+ except (StopIteration, KeyError):
+ log.warning(
+ f'"url" missing in attachment, ignoring: {attachment}'
+ )
+ continue
+
+ if not url.startswith("http"):
+ log.warning(f"non HTTP URL in attachment, ignoring: {attachment}")
+ continue
+ link_elt = entry_elt.addElement("link")
+ # XXX: "uri" is set in self._manageComments if not already existing
+ link_elt["href"] = url
+ if attachment.get("external", False):
+ # this is a link to an external data such as a website
+ link_elt["rel"] = "related"
+ else:
+ # this is an attached file
+ link_elt["rel"] = "enclosure"
+ for key, attr in (
+ ("media_type", "type"),
+ ("desc", "title"),
+ ("size", "lenght")
+ ):
+ value = attachment.get(key)
+ if value:
+ link_elt[attr] = str(value)
+
## author ##
author_elt = entry_elt.addElement("author")
try:
@@ -736,7 +796,6 @@ class XEP_0277(object):
link_elt["rel"] = "replies"
link_elt["title"] = "comments"
- extra = mb_data.get("extra", {})
if "repeated" in extra:
try:
repeated = extra["repeated"]