Allow to interact with objects via lookup

This commit is contained in:
Thomas Sileo 2022-08-15 12:49:07 +02:00
parent d381bb3fec
commit c711096262
4 changed files with 90 additions and 11 deletions

View file

@ -116,6 +116,16 @@ async def get_lookup(
db_session, [ap_object] # type: ignore db_session, [ap_object] # type: ignore
) )
else: 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( actors_metadata = await get_actors_metadata(
db_session, [ap_object.actor] # type: ignore 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( in_reply_to_object = await boxes.get_anybox_object_by_ap_id(
db_session, in_reply_to 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 # Add mentions to the initial note content
if not in_reply_to_object: if not in_reply_to_object:
@ -891,7 +909,9 @@ async def admin_actions_bookmark(
) -> RedirectResponse: ) -> RedirectResponse:
inbox_object = await get_inbox_object_by_ap_id(db_session, ap_object_id) inbox_object = await get_inbox_object_by_ap_id(db_session, ap_object_id)
if not inbox_object: 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 inbox_object.is_bookmarked = True
await db_session.commit() await db_session.commit()
return RedirectResponse(redirect_url, status_code=302) return RedirectResponse(redirect_url, status_code=302)

View file

@ -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: 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) inbox_object = await get_inbox_object_by_ap_id(db_session, ap_object_id)
if not inbox_object: 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_id = allocate_outbox_id()
like = { 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: 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) inbox_object = await get_inbox_object_by_ap_id(db_session, ap_object_id)
if not inbox_object: 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 [ if inbox_object.visibility not in [
ap.VisibilityEnum.PUBLIC, ap.VisibilityEnum.PUBLIC,
@ -183,12 +195,13 @@ async def send_announce(db_session: AsyncSession, ap_object_id: str) -> None:
raise ValueError("Should never happen") raise ValueError("Should never happen")
inbox_object.announced_via_outbox_object_ap_id = outbox_object.ap_id inbox_object.announced_via_outbox_object_ap_id = outbox_object.ap_id
await db_session.commit()
recipients = await _compute_recipients(db_session, announce) recipients = await _compute_recipients(db_session, announce)
for rcp in recipients: for rcp in recipients:
await new_outgoing_activity(db_session, rcp, outbox_object.id) 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: async def send_follow(db_session: AsyncSession, ap_actor_id: str) -> None:
actor = await fetch_actor(db_session, ap_actor_id) actor = await fetch_actor(db_session, ap_actor_id)
@ -300,6 +313,12 @@ async def fetch_conversation_root(
obj: AnyboxObject | RemoteObject, obj: AnyboxObject | RemoteObject,
is_root: bool = False, is_root: bool = False,
) -> str: ) -> 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 not obj.in_reply_to or is_root:
if obj.ap_context: if obj.ap_context:
return obj.ap_context return obj.ap_context
@ -1731,6 +1750,42 @@ async def save_to_inbox(
await db_session.commit() 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: async def public_outbox_objects_count(db_session: AsyncSession) -> int:
return await db_session.scalar( return await db_session.scalar(
select(func.count(models.OutboxObject.id)).where( select(func.count(models.OutboxObject.id)).where(

View file

@ -76,12 +76,12 @@ _RESIZED_CACHE: MutableMapping[tuple[str, int], tuple[bytes, str, Any]] = LFUCac
# TODO(ts): # TODO(ts):
# #
# Next: # Next:
# - empty recipients for Share on "was not in the inbox" object
# - support Move # - support Move
# - support actor delete # - support actor delete
# - allow to share old notes # - allow to share old notes
# - allow to interact with object not in anybox (i.e. like from a lookup) # - allow to interact with object not in anybox (i.e. like from a lookup)
# - only show 10 most recent threads in DMs # - 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 # - prevent double accept/double follow
# - UI support for updating posts # - UI support for updating posts
# - indieauth tweaks # - indieauth tweaks

View file

@ -503,7 +503,7 @@
</ul> </ul>
</nav> </nav>
{% if is_admin and (object.is_from_outbox or object.is_from_inbox) %} {% if is_admin %}
<nav class="flexbox activity-bar"> <nav class="flexbox activity-bar">
<ul> <ul>
{% if object.is_from_outbox %} {% if object.is_from_outbox %}
@ -524,7 +524,7 @@
{{ admin_reply_button(object.ap_id) }} {{ admin_reply_button(object.ap_id) }}
</li> </li>
{% if object.is_from_inbox %} {% if not object.is_from_outbox %}
<li> <li>
{% if object.liked_via_outbox_object_ap_id %} {% if object.liked_via_outbox_object_ap_id %}
{{ admin_undo_button(object.liked_via_outbox_object_ap_id, "unlike", object.permalink_id) }} {{ admin_undo_button(object.liked_via_outbox_object_ap_id, "unlike", object.permalink_id) }}
@ -551,13 +551,17 @@
</li> </li>
{% endif %} {% 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> <li>
{{ admin_profile_button(object.actor.ap_id) }} {{ admin_expand_button(object.ap_id) }}
</li> </li>
{% endif %} {% endif %}
<li>
{{ admin_expand_button(object.ap_id) }}
</li>
</ul> </ul>
</nav> </nav>
{% endif %} {% endif %}