forked from forks/microblog.pub
Allow to interact with objects via lookup
This commit is contained in:
parent
d381bb3fec
commit
c711096262
4 changed files with 90 additions and 11 deletions
22
app/admin.py
22
app/admin.py
|
@ -116,6 +116,16 @@ async def get_lookup(
|
|||
db_session, [ap_object] # type: ignore
|
||||
)
|
||||
else:
|
||||
# Check if the object is in the inbox
|
||||
requested_object = await boxes.get_anybox_object_by_ap_id(
|
||||
db_session, ap_object.ap_id
|
||||
)
|
||||
if requested_object:
|
||||
return RedirectResponse(
|
||||
request.url_for("admin_object") + f"?ap_id={ap_object.ap_id}",
|
||||
status_code=302,
|
||||
)
|
||||
|
||||
actors_metadata = await get_actors_metadata(
|
||||
db_session, [ap_object.actor] # type: ignore
|
||||
)
|
||||
|
@ -148,6 +158,14 @@ async def admin_new(
|
|||
in_reply_to_object = await boxes.get_anybox_object_by_ap_id(
|
||||
db_session, in_reply_to
|
||||
)
|
||||
if not in_reply_to_object:
|
||||
logger.info(f"Saving unknwown object {in_reply_to}")
|
||||
raw_object = await ap.fetch(in_reply_to)
|
||||
await boxes.save_object_to_inbox(db_session, raw_object)
|
||||
await db_session.commit()
|
||||
in_reply_to_object = await boxes.get_anybox_object_by_ap_id(
|
||||
db_session, in_reply_to
|
||||
)
|
||||
|
||||
# Add mentions to the initial note content
|
||||
if not in_reply_to_object:
|
||||
|
@ -891,7 +909,9 @@ async def admin_actions_bookmark(
|
|||
) -> RedirectResponse:
|
||||
inbox_object = await get_inbox_object_by_ap_id(db_session, ap_object_id)
|
||||
if not inbox_object:
|
||||
raise ValueError("Should never happen")
|
||||
logger.info(f"Saving unknwown object {ap_object_id}")
|
||||
raw_object = await ap.fetch(ap_object_id)
|
||||
inbox_object = await boxes.save_object_to_inbox(db_session, raw_object)
|
||||
inbox_object.is_bookmarked = True
|
||||
await db_session.commit()
|
||||
return RedirectResponse(redirect_url, status_code=302)
|
||||
|
|
61
app/boxes.py
61
app/boxes.py
|
@ -128,7 +128,13 @@ async def send_delete(db_session: AsyncSession, ap_object_id: str) -> None:
|
|||
async def send_like(db_session: AsyncSession, ap_object_id: str) -> None:
|
||||
inbox_object = await get_inbox_object_by_ap_id(db_session, ap_object_id)
|
||||
if not inbox_object:
|
||||
raise ValueError(f"{ap_object_id} not found in the inbox")
|
||||
logger.info(f"Saving unknwown object {ap_object_id}")
|
||||
raw_object = await ap.fetch(ap.get_id(ap_object_id))
|
||||
await save_object_to_inbox(db_session, raw_object)
|
||||
await db_session.commit()
|
||||
inbox_object = await get_inbox_object_by_ap_id(db_session, ap_object_id)
|
||||
if not inbox_object:
|
||||
raise ValueError("Should never happen")
|
||||
|
||||
like_id = allocate_outbox_id()
|
||||
like = {
|
||||
|
@ -155,7 +161,13 @@ async def send_like(db_session: AsyncSession, ap_object_id: str) -> None:
|
|||
async def send_announce(db_session: AsyncSession, ap_object_id: str) -> None:
|
||||
inbox_object = await get_inbox_object_by_ap_id(db_session, ap_object_id)
|
||||
if not inbox_object:
|
||||
raise ValueError(f"{ap_object_id} not found in the inbox")
|
||||
logger.info(f"Saving unknwown object {ap_object_id}")
|
||||
raw_object = await ap.fetch(ap.get_id(ap_object_id))
|
||||
await save_object_to_inbox(db_session, raw_object)
|
||||
await db_session.commit()
|
||||
inbox_object = await get_inbox_object_by_ap_id(db_session, ap_object_id)
|
||||
if not inbox_object:
|
||||
raise ValueError("Should never happen")
|
||||
|
||||
if inbox_object.visibility not in [
|
||||
ap.VisibilityEnum.PUBLIC,
|
||||
|
@ -183,12 +195,13 @@ async def send_announce(db_session: AsyncSession, ap_object_id: str) -> None:
|
|||
raise ValueError("Should never happen")
|
||||
|
||||
inbox_object.announced_via_outbox_object_ap_id = outbox_object.ap_id
|
||||
await db_session.commit()
|
||||
|
||||
recipients = await _compute_recipients(db_session, announce)
|
||||
for rcp in recipients:
|
||||
await new_outgoing_activity(db_session, rcp, outbox_object.id)
|
||||
|
||||
await db_session.commit()
|
||||
|
||||
|
||||
async def send_follow(db_session: AsyncSession, ap_actor_id: str) -> None:
|
||||
actor = await fetch_actor(db_session, ap_actor_id)
|
||||
|
@ -300,6 +313,12 @@ async def fetch_conversation_root(
|
|||
obj: AnyboxObject | RemoteObject,
|
||||
is_root: bool = False,
|
||||
) -> str:
|
||||
"""Some softwares do not set the context/conversation field (like Misskey).
|
||||
This means we have to track conversation ourselves. To do set, we fetch
|
||||
the root of the conversation and either:
|
||||
- use the context field if set
|
||||
- or build a custom conversation ID
|
||||
"""
|
||||
if not obj.in_reply_to or is_root:
|
||||
if obj.ap_context:
|
||||
return obj.ap_context
|
||||
|
@ -1731,6 +1750,42 @@ async def save_to_inbox(
|
|||
await db_session.commit()
|
||||
|
||||
|
||||
async def save_object_to_inbox(
|
||||
db_session: AsyncSession,
|
||||
raw_object: ap.RawObject,
|
||||
) -> models.InboxObject:
|
||||
obj_actor = await fetch_actor(db_session, ap.get_actor_id(raw_object))
|
||||
|
||||
ro = RemoteObject(raw_object, actor=obj_actor)
|
||||
|
||||
ap_published_at = now()
|
||||
if "published" in ro.ap_object:
|
||||
ap_published_at = parse_isoformat(ro.ap_object["published"])
|
||||
|
||||
inbox_object = models.InboxObject(
|
||||
server=urlparse(ro.ap_id).hostname,
|
||||
actor_id=obj_actor.id,
|
||||
ap_actor_id=obj_actor.ap_id,
|
||||
ap_type=ro.ap_type,
|
||||
ap_id=ro.ap_id,
|
||||
ap_context=ro.ap_context,
|
||||
conversation=await fetch_conversation_root(db_session, ro),
|
||||
ap_published_at=ap_published_at,
|
||||
ap_object=ro.ap_object,
|
||||
visibility=ro.visibility,
|
||||
relates_to_inbox_object_id=None,
|
||||
relates_to_outbox_object_id=None,
|
||||
activity_object_ap_id=ro.activity_object_ap_id,
|
||||
og_meta=await opengraph.og_meta_from_note(db_session, ro),
|
||||
is_hidden_from_stream=True,
|
||||
)
|
||||
|
||||
db_session.add(inbox_object)
|
||||
await db_session.flush()
|
||||
await db_session.refresh(inbox_object)
|
||||
return inbox_object
|
||||
|
||||
|
||||
async def public_outbox_objects_count(db_session: AsyncSession) -> int:
|
||||
return await db_session.scalar(
|
||||
select(func.count(models.OutboxObject.id)).where(
|
||||
|
|
|
@ -76,12 +76,12 @@ _RESIZED_CACHE: MutableMapping[tuple[str, int], tuple[bytes, str, Any]] = LFUCac
|
|||
# TODO(ts):
|
||||
#
|
||||
# Next:
|
||||
# - empty recipients for Share on "was not in the inbox" object
|
||||
# - support Move
|
||||
# - support actor delete
|
||||
# - allow to share old notes
|
||||
# - allow to interact with object not in anybox (i.e. like from a lookup)
|
||||
# - only show 10 most recent threads in DMs
|
||||
# - custom CSS for disabled button (e.g. sharing on a direct post)
|
||||
# - prevent double accept/double follow
|
||||
# - UI support for updating posts
|
||||
# - indieauth tweaks
|
||||
|
|
|
@ -503,7 +503,7 @@
|
|||
</ul>
|
||||
</nav>
|
||||
|
||||
{% if is_admin and (object.is_from_outbox or object.is_from_inbox) %}
|
||||
{% if is_admin %}
|
||||
<nav class="flexbox activity-bar">
|
||||
<ul>
|
||||
{% if object.is_from_outbox %}
|
||||
|
@ -524,7 +524,7 @@
|
|||
{{ admin_reply_button(object.ap_id) }}
|
||||
</li>
|
||||
|
||||
{% if object.is_from_inbox %}
|
||||
{% if not object.is_from_outbox %}
|
||||
<li>
|
||||
{% if object.liked_via_outbox_object_ap_id %}
|
||||
{{ admin_undo_button(object.liked_via_outbox_object_ap_id, "unlike", object.permalink_id) }}
|
||||
|
@ -551,13 +551,17 @@
|
|||
</li>
|
||||
{% endif %}
|
||||
|
||||
{% if object.is_from_inbox %}
|
||||
<li>
|
||||
{{ admin_profile_button(object.actor.ap_id) }}
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if object.is_from_inbox or object.is_from_outbox %}
|
||||
<li>
|
||||
{{ admin_expand_button(object.ap_id) }}
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</nav>
|
||||
{% endif %}
|
||||
|
|
Loading…
Reference in a new issue