diff --git a/templates/utils.html b/templates/utils.html
index fce8184..b0bf6d9 100644
--- a/templates/utils.html
+++ b/templates/utils.html
@@ -245,7 +245,7 @@
Attachments
{% endif %}
- {% for a in obj.attachment %}
+ {% for a in (obj | iter_note_attachments) %}
{% if (a.mediaType and a.mediaType.startswith("image/")) or (a.type and a.type == 'Image') %}
diff --git a/utils/template_filters.py b/utils/template_filters.py
index 4220cb5..f3c225b 100644
--- a/utils/template_filters.py
+++ b/utils/template_filters.py
@@ -2,6 +2,7 @@ import logging
import urllib
from datetime import datetime
from datetime import timezone
+from functools import lru_cache
from urllib.parse import urlparse
import bleach
@@ -345,6 +346,7 @@ def get_attachment_url(url, size):
@filters.app_template_filter()
+@lru_cache(maxsize=256)
def update_inline_imgs(content):
soup = BeautifulSoup(content, "html5lib")
imgs = soup.find_all("img")
@@ -418,6 +420,28 @@ def has_actor_type(doc):
return False
+@lru_cache(maxsize=256)
+def _get_inlined_imgs(content):
+ imgs = []
+ if not content:
+ return imgs
+
+ soup = BeautifulSoup(content, "html5lib")
+ for img in soup.find_all("img"):
+ src = img.attrs.get("src")
+ if src:
+ imgs.append(src)
+
+ return imgs
+
+
+@filters.app_template_filter()
+def iter_note_attachments(note):
+ attachments = note.get("attachment", [])
+ imgs = _get_inlined_imgs(note.get("content"))
+ return [a for a in attachments if a.get("url") not in imgs]
+
+
@filters.app_template_filter()
def not_only_imgs(attachment):
for a in attachment: