~vpzom/lotide

59a21be8fa10c770a44df2b68ad4856126079753 — Colin Reeder a month ago 00e0b3d
Fix targeting for replies
2 files changed, 104 insertions(+), 52 deletions(-)

M src/apub_util.rs
M src/main.rs
M src/apub_util.rs => src/apub_util.rs +29 -11
@@ 2,6 2,7 @@ use crate::{BaseURL, CommentLocalID, CommunityLocalID, PostLocalID, ThingLocalRe
use activitystreams::prelude::*;
use serde::{Deserialize, Serialize};
use std::borrow::Cow;
use std::collections::HashSet;
use std::convert::TryFrom;
use std::ops::Deref;
use std::sync::Arc;


@@ 1175,7 1176,7 @@ pub fn local_comment_to_create_ap(
    comment: &crate::CommentInfo,
    post_ap_id: &url::Url,
    parent_ap_id: Option<url::Url>,
    post_or_parent_author_ap_id: Option<url::Url>,
    parent_or_post_author_ap_id: Option<url::Url>,
    community_ap_id: url::Url,
    host_url_apub: &BaseURL,
) -> Result<activitystreams::activity::Create, crate::Error> {


@@ 1183,8 1184,8 @@ pub fn local_comment_to_create_ap(
        &comment,
        post_ap_id,
        parent_ap_id,
        post_or_parent_author_ap_id,
        community_ap_id,
        parent_or_post_author_ap_id.clone(),
        community_ap_id.clone(),
        &host_url_apub,
    )?;



@@ 1200,6 1201,16 @@ pub fn local_comment_to_create_ap(
        res.into()
    });

    if let Some(parent_or_post_author_ap_id) = parent_or_post_author_ap_id {
        create
            .set_to(parent_or_post_author_ap_id)
            .set_many_ccs(vec![activitystreams::public(), community_ap_id]);
    } else {
        create
            .set_to(community_ap_id)
            .set_cc(activitystreams::public());
    }

    Ok(create)
}



@@ 1279,15 1290,19 @@ pub fn local_comment_like_undo_to_ap(
    Ok(undo)
}

pub fn spawn_enqueue_send_comment_to_community(
pub fn spawn_enqueue_send_comment(
    inboxes: HashSet<url::Url>,
    comment: crate::CommentInfo,
    community_ap_id: url::Url,
    community_ap_inbox: url::Url,
    post_ap_id: url::Url,
    parent_ap_id: Option<url::Url>,
    post_or_parent_author_ap_id: Option<url::Url>,
    ctx: Arc<crate::RouteContext>,
) {
    if inboxes.is_empty() {
        return;
    }

    let create = local_comment_to_create_ap(
        &comment,
        &post_ap_id,


@@ 1302,12 1317,15 @@ pub fn spawn_enqueue_send_comment_to_community(
    crate::spawn_task(async move {
        let create = create?;

        ctx.enqueue_task(&crate::tasks::DeliverToInbox {
            inbox: Cow::Owned(community_ap_inbox),
            sign_as: Some(crate::ActorLocalRef::Person(author)),
            object: serde_json::to_string(&create)?,
        })
        .await?;
        // TODO maybe insert these at the same time
        for inbox in inboxes {
            ctx.enqueue_task(&crate::tasks::DeliverToInbox {
                inbox: Cow::Owned(inbox),
                sign_as: Some(crate::ActorLocalRef::Person(author)),
                object: serde_json::to_string(&create)?,
            })
            .await?;
        }

        Ok(())
    });

M src/main.rs => src/main.rs +75 -41
@@ 1,6 1,6 @@
use serde_derive::{Deserialize, Serialize};
use std::borrow::Cow;
use std::collections::HashMap;
use std::collections::{HashMap, HashSet};
use std::convert::TryInto;
use std::ops::Deref;
use std::sync::Arc;


@@ 560,7 560,7 @@ pub fn on_post_add_comment(comment: CommentInfo<'static>, ctx: Arc<crate::RouteC

        let res = futures::future::try_join(
            db.query_opt(
                "SELECT community.id, community.local, community.ap_id, community.ap_inbox, post.local, post.ap_id, person.id, person.ap_id FROM community, post LEFT OUTER JOIN person ON (person.id = post.author) WHERE post.id = $1 AND post.community = community.id",
                "SELECT community.id, community.local, community.ap_id, community.ap_inbox, post.local, post.ap_id, person.id, person.ap_id, COALESCE(person.ap_shared_inbox, person.ap_inbox) FROM community, post LEFT OUTER JOIN person ON (person.id = post.author) WHERE post.id = $1 AND post.community = community.id",
                &[&comment.post.raw()],
            )
            .map_err(crate::Error::from),


@@ 568,16 568,17 @@ pub fn on_post_add_comment(comment: CommentInfo<'static>, ctx: Arc<crate::RouteC
                match comment.parent {
                    Some(parent) => {
                        let row = db.query_one(
                            "SELECT reply.local, reply.ap_id, person.id, person.ap_id FROM reply LEFT OUTER JOIN person ON (person.id = reply.author) WHERE reply.id=$1",
                            "SELECT reply.local, reply.ap_id, person.id, person.ap_id, COALESCE(person.ap_shared_inbox, person.ap_inbox) FROM reply LEFT OUTER JOIN person ON (person.id = reply.author) WHERE reply.id=$1",
                            &[&parent],
                        ).await?;

                        let author_local_id = row.get::<_, Option<_>>(2).map(UserLocalID);

                        if row.get(0) {
                            Ok(Some((crate::apub_util::get_local_comment_apub_id(parent, &ctx.host_url_apub), Some(crate::apub_util::get_local_person_apub_id(UserLocalID(row.get(2)), &ctx.host_url_apub)), true, author_local_id)))
                            Ok(Some((crate::apub_util::get_local_comment_apub_id(parent, &ctx.host_url_apub), Some(crate::apub_util::get_local_person_apub_id(author_local_id.unwrap(), &ctx.host_url_apub)), true, author_local_id, None)))
                        } else {
                            row.get::<_, Option<&str>>(1).map(|x: &str| -> Result<(BaseURL, Option<BaseURL>, bool, Option<UserLocalID>), crate::Error> { Ok((x.parse()?, row.get::<_, Option<&str>>(3).map(std::str::FromStr::from_str).transpose()?, false, author_local_id)) }).transpose()
                            let author_ap_inbox: Option<url::Url> = row.get::<_, Option<_>>(4).map(|x: &str| std::str::FromStr::from_str(x)).transpose()?;
                            row.get::<_, Option<&str>>(1).map(|x: &str| -> Result<(BaseURL, Option<BaseURL>, bool, Option<UserLocalID>, Option<url::Url>), crate::Error> { Ok((x.parse()?, row.get::<_, Option<&str>>(3).map(std::str::FromStr::from_str).transpose()?, false, author_local_id, author_ap_inbox)) }).transpose()
                        }
                    },
                    None => Ok(None),


@@ 608,44 609,64 @@ pub fn on_post_add_comment(comment: CommentInfo<'static>, ctx: Arc<crate::RouteC
                }
            };

            let (parent_ap_id, post_or_parent_author_local_id, post_or_parent_author_ap_id) =
                match comment.parent {
                    None => {
                        let author_id = UserLocalID(row.get(6));
                        if post_local {
                            (
                                None,
                                Some(author_id),
                                Some(Cow::Owned(crate::apub_util::get_local_person_apub_id(
                                    author_id,
                                    &ctx.host_url_apub,
                                ))),
                            )
                        } else {
                            (
                                None,
                                Some(author_id),
                                row.get::<_, Option<_>>(7)
                                    .map(std::str::FromStr::from_str)
                                    .transpose()?
                                    .map(Cow::Owned),
                            )
                        }
            let (
                parent_ap_id,
                post_or_parent_author_local_id,
                post_or_parent_author_local,
                post_or_parent_author_ap_id,
                post_or_parent_author_ap_inbox,
            ) = match comment.parent {
                None => {
                    let author_id = UserLocalID(row.get(6));
                    if post_local {
                        (
                            None,
                            Some(author_id),
                            Some(true),
                            Some(Cow::Owned(crate::apub_util::get_local_person_apub_id(
                                author_id,
                                &ctx.host_url_apub,
                            ))),
                            None,
                        )
                    } else {
                        (
                            None,
                            Some(author_id),
                            Some(false),
                            row.get::<_, Option<_>>(7)
                                .map(std::str::FromStr::from_str)
                                .transpose()?
                                .map(Cow::Owned),
                            row.get::<_, Option<_>>(8)
                                .map(std::str::FromStr::from_str)
                                .transpose()?
                                .map(Cow::Owned),
                        )
                    }
                    Some(_) => match &res.1 {
                        None => (None, None, None),
                        Some((parent_ap_id, parent_author_ap_id, _, parent_author_local_id)) => (
                            Some(parent_ap_id),
                            *parent_author_local_id,
                            parent_author_ap_id.as_ref().map(Cow::Borrowed),
                        ),
                    },
                };
                }
                Some(_) => match &res.1 {
                    None => (None, None, None, None, None),
                    Some((
                        parent_ap_id,
                        parent_author_ap_id,
                        parent_local,
                        parent_author_local_id,
                        parent_author_ap_inbox,
                    )) => (
                        Some(parent_ap_id),
                        *parent_author_local_id,
                        Some(*parent_local),
                        parent_author_ap_id.as_ref().map(Cow::Borrowed),
                        parent_author_ap_inbox.as_ref().map(Cow::Borrowed),
                    ),
                },
            };

            // Generate notifications
            match comment.parent {
                Some(parent_id) => {
                    if let Some((_, _, parent_local, parent_author_id)) = res.1 {
                    if let Some((_, _, parent_local, parent_author_id, _)) = res.1 {
                        if parent_local && parent_author_id != comment.author {
                            if let Some(parent_author_id) = parent_author_id {
                                let ctx = ctx.clone();


@@ 689,10 710,23 @@ pub fn on_post_add_comment(comment: CommentInfo<'static>, ctx: Arc<crate::RouteC
                    let community = CommunityLocalID(row.get(0));
                    crate::on_community_add_comment(community, comment.id, comment_ap_id, ctx);
                } else if comment.ap_id == APIDOrLocal::Local {
                    crate::apub_util::spawn_enqueue_send_comment_to_community(
                    let community_ap_id = std::str::FromStr::from_str(row.get(2))?;
                    let community_inbox = std::str::FromStr::from_str(row.get(3))?;
                    let mut inboxes = HashSet::new();

                    inboxes.insert(community_inbox);

                    if post_or_parent_author_local == Some(true) {
                        if let Some(post_or_parent_author_ap_inbox) = post_or_parent_author_ap_inbox
                        {
                            inboxes.insert(post_or_parent_author_ap_inbox.into_owned());
                        }
                    }

                    crate::apub_util::spawn_enqueue_send_comment(
                        inboxes,
                        comment,
                        std::str::FromStr::from_str(row.get(2))?,
                        std::str::FromStr::from_str(row.get(3))?,
                        community_ap_id,
                        post_ap_id.into(),
                        parent_ap_id.map(|x| x.deref().clone()),
                        post_or_parent_author_ap_id.map(|x| x.into_owned().into()),