diff --git a/catalog/templates/_item_user_pieces.html b/catalog/templates/_item_user_pieces.html
index e961789d..4e03832d 100644
--- a/catalog/templates/_item_user_pieces.html
+++ b/catalog/templates/_item_user_pieces.html
@@ -92,6 +92,16 @@
{{ note.title|default:'' }}
{{ note.content|linebreaks }}
+
+ {% for attachment in note.attachments %}
+ {% if attachment.type == 'image' %}
+

+ {% endif %}
+ {% endfor %}
+
{% endfor %}
diff --git a/journal/migrations/0002_note.py b/journal/migrations/0002_note.py
index ef33ee41..da630bf7 100644
--- a/journal/migrations/0002_note.py
+++ b/journal/migrations/0002_note.py
@@ -41,7 +41,7 @@ class Migration(migrations.Migration):
("title", models.TextField(blank=True, default=None, null=True)),
("content", models.TextField()),
("sensitive", models.BooleanField(default=False)),
- ("attachements", models.JSONField(default=list)),
+ ("attachments", models.JSONField(default=list)),
(
"item",
models.ForeignKey(
diff --git a/journal/models/common.py b/journal/models/common.py
index 2e2cde5e..375198c6 100644
--- a/journal/models/common.py
+++ b/journal/models/common.py
@@ -228,7 +228,7 @@ class Piece(PolymorphicModel, UserOwnedObjectMixin):
return pp.post_id if pp else None
@cached_property
- def latest_post(self):
+ def latest_post(self) -> "Post | None":
pk = self.latest_post_id
return Takahe.get_post(pk) if pk else None
diff --git a/journal/models/note.py b/journal/models/note.py
index 671e9059..cf84837b 100644
--- a/journal/models/note.py
+++ b/journal/models/note.py
@@ -16,7 +16,7 @@ class Note(Content):
title = models.TextField(blank=True, null=True, default=None)
content = models.TextField(blank=False, null=False)
sensitive = models.BooleanField(default=False, null=False)
- attachements = models.JSONField(default=list)
+ attachments = models.JSONField(default=list)
@property
def html(self):
@@ -41,12 +41,23 @@ class Note(Content):
@override
@classmethod
def params_from_ap_object(cls, post, obj, piece):
- return {
+ params = {
"title": obj.get("title", post.summary),
"content": obj.get("content", "").strip(),
"sensitive": obj.get("sensitive", post.sensitive),
- # "attachements": obj.get("attachements", []),
+ "attachments": [],
}
+ if post:
+ for atta in post.attachments.all():
+ params["attachments"].append(
+ {
+ "type": (atta.mimetype or "unknown").split("/")[0],
+ "mimetype": atta.mimetype,
+ "url": atta.full_url().absolute,
+ "preview_url": atta.thumbnail_url().absolute,
+ }
+ )
+ return params
@override
@classmethod
@@ -66,15 +77,21 @@ class Note(Content):
return ShelfMember.objects.filter(item=self.item, owner=self.owner).first()
def to_mastodon_params(self):
- return {
+ params = {
"spoiler_text": self.title,
"content": self.content,
"sensitive": self.sensitive,
- # "attachements": self.attachements,
"reply_to_toot_url": (
self.shelfmember.get_mastodon_repost_url() if self.shelfmember else None
),
}
+ if self.latest_post:
+ attachments = []
+ for atta in self.latest_post.attachments.all():
+ attachments.append((atta.file_display_name, atta.file, atta.mimetype))
+ if attachments:
+ params["attachments"] = attachments
+ return params
def to_post_params(self):
return {
@@ -84,4 +101,5 @@ class Note(Content):
"reply_to_pk": (
self.shelfmember.latest_post_id if self.shelfmember else None
),
+ # not passing "attachments" so it won't change
}
diff --git a/journal/models/renderers.py b/journal/models/renderers.py
index d6beffbb..f708432a 100644
--- a/journal/models/renderers.py
+++ b/journal/models/renderers.py
@@ -1,9 +1,13 @@
import re
-from typing import cast
+from typing import TYPE_CHECKING, cast
import mistune
from django.utils.html import escape
+if TYPE_CHECKING:
+ from catalog.models import Item
+ from users.models import User
+
_mistune_plugins = [
"url",
"strikethrough",
@@ -50,3 +54,11 @@ def _spolier(s: str) -> str:
def render_text(s: str) -> str:
return _spolier(s).strip().replace("\n", "
")
+
+
+def render_post_with_macro(txt: str, item: "Item") -> str:
+ return (
+ txt.replace("[category]", item.category.name)
+ .replace("[title]", item.display_title)
+ .replace("[url]", item.absolute_url)
+ )
diff --git a/mastodon/api.py b/mastodon/api.py
index 4fdede0a..c72d3cd4 100644
--- a/mastodon/api.py
+++ b/mastodon/api.py
@@ -262,14 +262,16 @@ def post_toot2(
reply_to_toot_url: str | None = None,
sensitive: bool = False,
spoiler_text: str | None = None,
+ attachments: list = [],
):
headers = {
"User-Agent": USER_AGENT,
"Authorization": f"Bearer {user.mastodon_token}",
"Idempotency-Key": random_string_generator(16),
}
+ base_url = "https://" + get_api_domain(user.mastodon_site)
response = None
- url = "https://" + get_api_domain(user.mastodon_site) + API_PUBLISH_TOOT
+ url = base_url + API_PUBLISH_TOOT
payload = {
"status": content,
"visibility": get_toot_visibility(visibility, user),
@@ -278,12 +280,29 @@ def post_toot2(
reply_to_id = get_status_id_by_url(reply_to_toot_url)
if reply_to_id:
payload["in_reply_to_id"] = reply_to_id
- # if media_id:
- # payload["media_ids[]"] = [media_id]
if spoiler_text:
payload["spoiler_text"] = spoiler_text
if sensitive:
payload["sensitive"] = True
+ media_ids = []
+ for atta in attachments:
+ try:
+ media_id = (
+ requests.post(
+ base_url + "/api/v1/media",
+ headers=headers,
+ data={},
+ files={"file": atta},
+ )
+ .json()
+ .get("id")
+ )
+ media_ids.append(media_id)
+ except Exception as e:
+ logger.warning(f"Error uploading image {e}")
+ headers["Idempotency-Key"] = random_string_generator(16)
+ if media_ids:
+ payload["media_ids[]"] = media_ids
try:
if update_id:
response = put(url + "/" + update_id, headers=headers, data=payload)