Merge pull request #265 from pfefferle/optimize-publish
optimize publishing
This commit is contained in:
commit
cf426ab8ab
9 changed files with 115 additions and 73 deletions
|
@ -13,7 +13,10 @@ class Activity_Dispatcher {
|
||||||
* Initialize the class, registering WordPress hooks.
|
* Initialize the class, registering WordPress hooks.
|
||||||
*/
|
*/
|
||||||
public static function init() {
|
public static function init() {
|
||||||
\add_action( 'activitypub_send_post_activity', array( '\Activitypub\Activity_Dispatcher', 'send_post_activity' ) );
|
// legacy
|
||||||
|
\add_action( 'activitypub_send_post_activity', array( '\Activitypub\Activity_Dispatcher', 'send_create_activity' ) );
|
||||||
|
|
||||||
|
\add_action( 'activitypub_send_create_activity', array( '\Activitypub\Activity_Dispatcher', 'send_create_activity' ) );
|
||||||
\add_action( 'activitypub_send_update_activity', array( '\Activitypub\Activity_Dispatcher', 'send_update_activity' ) );
|
\add_action( 'activitypub_send_update_activity', array( '\Activitypub\Activity_Dispatcher', 'send_update_activity' ) );
|
||||||
\add_action( 'activitypub_send_delete_activity', array( '\Activitypub\Activity_Dispatcher', 'send_delete_activity' ) );
|
\add_action( 'activitypub_send_delete_activity', array( '\Activitypub\Activity_Dispatcher', 'send_delete_activity' ) );
|
||||||
}
|
}
|
||||||
|
@ -23,38 +26,8 @@ class Activity_Dispatcher {
|
||||||
*
|
*
|
||||||
* @param \Activitypub\Model\Post $activitypub_post
|
* @param \Activitypub\Model\Post $activitypub_post
|
||||||
*/
|
*/
|
||||||
public static function send_post_activity( Model\Post $activitypub_post ) {
|
public static function send_create_activity( Model\Post $activitypub_post ) {
|
||||||
// get latest version of post
|
self::send_activity( $activitypub_post, 'Create' );
|
||||||
$user_id = $activitypub_post->get_post_author();
|
|
||||||
|
|
||||||
$activitypub_activity = new \Activitypub\Model\Activity( 'Create', \Activitypub\Model\Activity::TYPE_FULL );
|
|
||||||
$activitypub_activity->from_post( $activitypub_post );
|
|
||||||
|
|
||||||
$inboxes = \Activitypub\get_follower_inboxes( $user_id );
|
|
||||||
|
|
||||||
$followers_url = \get_rest_url( null, '/activitypub/1.0/users/' . intval( $user_id ) . '/followers' );
|
|
||||||
foreach ( $activitypub_activity->get_cc() as $cc ) {
|
|
||||||
if ( $cc === $followers_url ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$inbox = \Activitypub\get_inbox_by_actor( $cc );
|
|
||||||
if ( ! $inbox || \is_wp_error( $inbox ) ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// init array if empty
|
|
||||||
if ( ! isset( $inboxes[ $inbox ] ) ) {
|
|
||||||
$inboxes[ $inbox ] = array();
|
|
||||||
}
|
|
||||||
$inboxes[ $inbox ][] = $cc;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ( $inboxes as $inbox => $to ) {
|
|
||||||
$to = array_values( array_unique( $to ) );
|
|
||||||
$activitypub_activity->set_to( $to );
|
|
||||||
$activity = $activitypub_activity->to_json();
|
|
||||||
|
|
||||||
\Activitypub\safe_remote_post( $inbox, $activity, $user_id );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -62,19 +35,8 @@ class Activity_Dispatcher {
|
||||||
*
|
*
|
||||||
* @param \Activitypub\Model\Post $activitypub_post
|
* @param \Activitypub\Model\Post $activitypub_post
|
||||||
*/
|
*/
|
||||||
public static function send_update_activity( $activitypub_post ) {
|
public static function send_update_activity( Model\Post $activitypub_post ) {
|
||||||
// get latest version of post
|
self::send_activity( $activitypub_post, 'Update' );
|
||||||
$user_id = $activitypub_post->get_post_author();
|
|
||||||
|
|
||||||
$activitypub_activity = new \Activitypub\Model\Activity( 'Update', \Activitypub\Model\Activity::TYPE_FULL );
|
|
||||||
$activitypub_activity->from_post( $activitypub_post );
|
|
||||||
|
|
||||||
foreach ( \Activitypub\get_follower_inboxes( $user_id ) as $inbox => $to ) {
|
|
||||||
$activitypub_activity->set_to( $to );
|
|
||||||
$activity = $activitypub_activity->to_json(); // phpcs:ignore
|
|
||||||
|
|
||||||
\Activitypub\safe_remote_post( $inbox, $activity, $user_id );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -82,16 +44,30 @@ class Activity_Dispatcher {
|
||||||
*
|
*
|
||||||
* @param \Activitypub\Model\Post $activitypub_post
|
* @param \Activitypub\Model\Post $activitypub_post
|
||||||
*/
|
*/
|
||||||
public static function send_delete_activity( $activitypub_post ) {
|
public static function send_delete_activity( Model\Post $activitypub_post ) {
|
||||||
|
self::send_activity( $activitypub_post, 'Delete' );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @param [type] $activitypub_post
|
||||||
|
* @param [type] $activity_type
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function send_activity( Model\Post $activitypub_post, $activity_type ) {
|
||||||
// get latest version of post
|
// get latest version of post
|
||||||
$user_id = $activitypub_post->get_post_author();
|
$user_id = $activitypub_post->get_post_author();
|
||||||
|
|
||||||
$activitypub_activity = new \Activitypub\Model\Activity( 'Delete', \Activitypub\Model\Activity::TYPE_FULL );
|
$activitypub_activity = new \Activitypub\Model\Activity( $activity_type );
|
||||||
$activitypub_activity->from_post( $activitypub_post );
|
$activitypub_activity->from_post( $activitypub_post );
|
||||||
|
|
||||||
foreach ( \Activitypub\get_follower_inboxes( $user_id ) as $inbox => $to ) {
|
$inboxes = \Activitypub\get_follower_inboxes( $user_id, $activitypub_activity->get_cc() );
|
||||||
$activitypub_activity->set_to( $to );
|
|
||||||
$activity = $activitypub_activity->to_json(); // phpcs:ignore
|
foreach ( $inboxes as $inbox => $cc ) {
|
||||||
|
$cc = array_values( array_unique( $cc ) );
|
||||||
|
$activitypub_activity->add_cc( $cc );
|
||||||
|
$activity = $activitypub_activity->to_json();
|
||||||
|
|
||||||
\Activitypub\safe_remote_post( $inbox, $activity, $user_id );
|
\Activitypub\safe_remote_post( $inbox, $activity, $user_id );
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,7 +117,7 @@ class Activitypub {
|
||||||
$activitypub_post = new \Activitypub\Model\Post( $post );
|
$activitypub_post = new \Activitypub\Model\Post( $post );
|
||||||
|
|
||||||
if ( 'publish' === $new_status && 'publish' !== $old_status ) {
|
if ( 'publish' === $new_status && 'publish' !== $old_status ) {
|
||||||
\wp_schedule_single_event( \time(), 'activitypub_send_post_activity', array( $activitypub_post ) );
|
\wp_schedule_single_event( \time(), 'activitypub_send_create_activity', array( $activitypub_post ) );
|
||||||
} elseif ( 'publish' === $new_status ) {
|
} elseif ( 'publish' === $new_status ) {
|
||||||
\wp_schedule_single_event( \time(), 'activitypub_send_update_activity', array( $activitypub_post ) );
|
\wp_schedule_single_event( \time(), 'activitypub_send_update_activity', array( $activitypub_post ) );
|
||||||
} elseif ( 'trash' === $new_status ) {
|
} elseif ( 'trash' === $new_status ) {
|
||||||
|
|
|
@ -219,8 +219,11 @@ function get_publickey_by_actor( $actor, $key_id ) {
|
||||||
return new \WP_Error( 'activitypub_no_public_key', \__( 'No "Public-Key" found', 'activitypub' ), $metadata );
|
return new \WP_Error( 'activitypub_no_public_key', \__( 'No "Public-Key" found', 'activitypub' ), $metadata );
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_follower_inboxes( $user_id ) {
|
function get_follower_inboxes( $user_id, $cc = array() ) {
|
||||||
$followers = \Activitypub\Peer\Followers::get_followers( $user_id );
|
$followers = \Activitypub\Peer\Followers::get_followers( $user_id );
|
||||||
|
$followers = array_merge( $followers, $cc );
|
||||||
|
$followers = array_unique( $followers );
|
||||||
|
|
||||||
$inboxes = array();
|
$inboxes = array();
|
||||||
|
|
||||||
foreach ( $followers as $follower ) {
|
foreach ( $followers as $follower ) {
|
||||||
|
|
|
@ -9,24 +9,38 @@ namespace Activitypub\Model;
|
||||||
* @see https://www.w3.org/TR/activitypub/
|
* @see https://www.w3.org/TR/activitypub/
|
||||||
*/
|
*/
|
||||||
class Activity {
|
class Activity {
|
||||||
private $context = array( 'https://www.w3.org/ns/activitystreams' );
|
private $context = array(
|
||||||
|
'https://www.w3.org/ns/activitystreams',
|
||||||
|
'https://w3id.org/security/v1',
|
||||||
|
array(
|
||||||
|
'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers',
|
||||||
|
'PropertyValue' => 'schema:PropertyValue',
|
||||||
|
'schema' => 'http://schema.org#',
|
||||||
|
'pt' => 'https://joinpeertube.org/ns#',
|
||||||
|
'toot' => 'http://joinmastodon.org/ns#',
|
||||||
|
'value' => 'schema:value',
|
||||||
|
'Hashtag' => 'as:Hashtag',
|
||||||
|
'featured' => array(
|
||||||
|
'@id' => 'toot:featured',
|
||||||
|
'@type' => '@id',
|
||||||
|
),
|
||||||
|
'featuredTags' => array(
|
||||||
|
'@id' => 'toot:featuredTags',
|
||||||
|
'@type' => '@id',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
private $published = '';
|
private $published = '';
|
||||||
private $id = '';
|
private $id = '';
|
||||||
private $type = 'Create';
|
private $type = 'Create';
|
||||||
private $actor = '';
|
private $actor = '';
|
||||||
private $to = array( 'https://www.w3.org/ns/activitystreams#Public' );
|
private $to = array( 'https://www.w3.org/ns/activitystreams#Public' );
|
||||||
private $cc = array( 'https://www.w3.org/ns/activitystreams#Public' );
|
private $cc = array();
|
||||||
private $object = null;
|
private $object = null;
|
||||||
|
|
||||||
const TYPE_SIMPLE = 'simple';
|
public function __construct( $type = 'Create', $context = true ) {
|
||||||
const TYPE_FULL = 'full';
|
if ( true !== $context ) {
|
||||||
const TYPE_NONE = 'none';
|
|
||||||
|
|
||||||
public function __construct( $type = 'Create', $context = self::TYPE_SIMPLE ) {
|
|
||||||
if ( 'none' === $context ) {
|
|
||||||
$this->context = null;
|
$this->context = null;
|
||||||
} elseif ( 'full' === $context ) {
|
|
||||||
$this->context = \Activitypub\get_context();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->type = \ucfirst( $type );
|
$this->type = \ucfirst( $type );
|
||||||
|
@ -43,6 +57,20 @@ class Activity {
|
||||||
if ( \strncasecmp( $method, 'set', 3 ) === 0 ) {
|
if ( \strncasecmp( $method, 'set', 3 ) === 0 ) {
|
||||||
$this->$var = $params[0];
|
$this->$var = $params[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( \strncasecmp( $method, 'add', 3 ) === 0 ) {
|
||||||
|
if ( ! is_array( $this->$var ) ) {
|
||||||
|
$this->$var = $params[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( is_array( $params[0] ) ) {
|
||||||
|
$this->$var = array_merge( $this->$var, $params[0] );
|
||||||
|
} else {
|
||||||
|
array_push( $this->$var, $params[0] );
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->$var = array_unique( $this->$var );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function from_post( Post $post ) {
|
public function from_post( Post $post ) {
|
||||||
|
@ -51,7 +79,8 @@ class Activity {
|
||||||
if ( isset( $object['published'] ) ) {
|
if ( isset( $object['published'] ) ) {
|
||||||
$this->published = $object['published'];
|
$this->published = $object['published'];
|
||||||
}
|
}
|
||||||
$this->cc = array( \get_rest_url( null, '/activitypub/1.0/users/' . intval( $post->get_post_author() ) . '/followers' ) );
|
|
||||||
|
$this->add_to( \get_rest_url( null, '/activitypub/1.0/users/' . intval( $post->get_post_author() ) . '/followers' ) );
|
||||||
|
|
||||||
if ( isset( $this->object['attributedTo'] ) ) {
|
if ( isset( $this->object['attributedTo'] ) ) {
|
||||||
$this->actor = $this->object['attributedTo'];
|
$this->actor = $this->object['attributedTo'];
|
||||||
|
@ -59,7 +88,7 @@ class Activity {
|
||||||
|
|
||||||
foreach ( $post->get_tags() as $tag ) {
|
foreach ( $post->get_tags() as $tag ) {
|
||||||
if ( 'Mention' === $tag['type'] ) {
|
if ( 'Mention' === $tag['type'] ) {
|
||||||
$this->cc[] = $tag['href'];
|
$this->add_cc( $tag['href'] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -104,6 +104,24 @@ class Post {
|
||||||
'cite' => array(),
|
'cite' => array(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of audience
|
||||||
|
*
|
||||||
|
* Also used for visibility
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $to = array( 'https://www.w3.org/ns/activitystreams#Public' );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of audience
|
||||||
|
*
|
||||||
|
* Also used for visibility
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $cc = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
|
@ -111,6 +129,7 @@ class Post {
|
||||||
*/
|
*/
|
||||||
public function __construct( $post ) {
|
public function __construct( $post ) {
|
||||||
$this->post = \get_post( $post );
|
$this->post = \get_post( $post );
|
||||||
|
$this->add_to( \get_rest_url( null, '/activitypub/1.0/users/' . intval( $this->get_post_author() ) . '/followers' ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -134,6 +153,20 @@ class Post {
|
||||||
if ( \strncasecmp( $method, 'set', 3 ) === 0 ) {
|
if ( \strncasecmp( $method, 'set', 3 ) === 0 ) {
|
||||||
$this->$var = $params[0];
|
$this->$var = $params[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( \strncasecmp( $method, 'add', 3 ) === 0 ) {
|
||||||
|
if ( ! is_array( $this->$var ) ) {
|
||||||
|
$this->$var = $params[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( is_array( $params[0] ) ) {
|
||||||
|
$this->$var = array_merge( $this->$var, $params[0] );
|
||||||
|
} else {
|
||||||
|
array_push( $this->$var, $params[0] );
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->$var = array_unique( $this->$var );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -155,8 +188,8 @@ class Post {
|
||||||
'contentMap' => array(
|
'contentMap' => array(
|
||||||
\strstr( \get_locale(), '_', true ) => $this->get_content(),
|
\strstr( \get_locale(), '_', true ) => $this->get_content(),
|
||||||
),
|
),
|
||||||
'to' => array( 'https://www.w3.org/ns/activitystreams#Public' ),
|
'to' => $this->get_to(),
|
||||||
'cc' => array( 'https://www.w3.org/ns/activitystreams#Public' ),
|
'cc' => $this->get_cc(),
|
||||||
'attachment' => $this->get_attachments(),
|
'attachment' => $this->get_attachments(),
|
||||||
'tag' => $this->get_tags(),
|
'tag' => $this->get_tags(),
|
||||||
);
|
);
|
||||||
|
|
|
@ -356,7 +356,7 @@ class Inbox {
|
||||||
$inbox = \Activitypub\get_inbox_by_actor( $object['actor'] );
|
$inbox = \Activitypub\get_inbox_by_actor( $object['actor'] );
|
||||||
|
|
||||||
// send "Accept" activity
|
// send "Accept" activity
|
||||||
$activity = new \Activitypub\Model\Activity( 'Accept', \Activitypub\Model\Activity::TYPE_SIMPLE );
|
$activity = new \Activitypub\Model\Activity( 'Accept' );
|
||||||
$activity->set_object( $object );
|
$activity->set_object( $object );
|
||||||
$activity->set_actor( \get_author_posts_url( $user_id ) );
|
$activity->set_actor( \get_author_posts_url( $user_id ) );
|
||||||
$activity->set_to( $object['actor'] );
|
$activity->set_to( $object['actor'] );
|
||||||
|
|
|
@ -102,7 +102,8 @@ class Outbox {
|
||||||
|
|
||||||
foreach ( $posts as $post ) {
|
foreach ( $posts as $post ) {
|
||||||
$activitypub_post = new \Activitypub\Model\Post( $post );
|
$activitypub_post = new \Activitypub\Model\Post( $post );
|
||||||
$activitypub_activity = new \Activitypub\Model\Activity( 'Create', \Activitypub\Model\Activity::TYPE_NONE );
|
$activitypub_activity = new \Activitypub\Model\Activity( 'Create', false );
|
||||||
|
|
||||||
$activitypub_activity->from_post( $activitypub_post );
|
$activitypub_activity->from_post( $activitypub_post );
|
||||||
$json->orderedItems[] = $activitypub_activity->to_array(); // phpcs:ignore
|
$json->orderedItems[] = $activitypub_activity->to_array(); // phpcs:ignore
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ class Test_Activitypub_Activity_Dispatcher extends ActivityPub_TestCase_Cache_HT
|
||||||
add_filter( 'pre_http_request', array( $pre_http_request, 'filter' ), 10, 3 );
|
add_filter( 'pre_http_request', array( $pre_http_request, 'filter' ), 10, 3 );
|
||||||
|
|
||||||
$activitypub_post = new \Activitypub\Model\Post( $post );
|
$activitypub_post = new \Activitypub\Model\Post( $post );
|
||||||
\Activitypub\Activity_Dispatcher::send_post_activity( $activitypub_post );
|
\Activitypub\Activity_Dispatcher::send_create_activity( $activitypub_post );
|
||||||
|
|
||||||
$this->assertNotEmpty( $activitypub_post->get_content() );
|
$this->assertNotEmpty( $activitypub_post->get_content() );
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ class Test_Activitypub_Activity_Dispatcher extends ActivityPub_TestCase_Cache_HT
|
||||||
add_filter( 'pre_http_request', array( $pre_http_request, 'filter' ), 10, 3 );
|
add_filter( 'pre_http_request', array( $pre_http_request, 'filter' ), 10, 3 );
|
||||||
|
|
||||||
$activitypub_post = new \Activitypub\Model\Post( $post );
|
$activitypub_post = new \Activitypub\Model\Post( $post );
|
||||||
\Activitypub\Activity_Dispatcher::send_post_activity( $activitypub_post );
|
\Activitypub\Activity_Dispatcher::send_create_activity( $activitypub_post );
|
||||||
|
|
||||||
$this->assertNotEmpty( $activitypub_post->get_content() );
|
$this->assertNotEmpty( $activitypub_post->get_content() );
|
||||||
|
|
||||||
|
|
|
@ -19,10 +19,10 @@ class Test_Activitypub_Activity extends WP_UnitTestCase {
|
||||||
|
|
||||||
$activitypub_post = new \Activitypub\Model\Post( $post );
|
$activitypub_post = new \Activitypub\Model\Post( $post );
|
||||||
|
|
||||||
$activitypub_activity = new \Activitypub\Model\Activity( 'Create', \Activitypub\Model\Activity::TYPE_FULL );
|
$activitypub_activity = new \Activitypub\Model\Activity( 'Create' );
|
||||||
$activitypub_activity->from_post( $activitypub_post );
|
$activitypub_activity->from_post( $activitypub_post );
|
||||||
|
|
||||||
$this->assertContains( \get_rest_url( null, '/activitypub/1.0/users/1/followers' ), $activitypub_activity->get_cc() );
|
$this->assertContains( \get_rest_url( null, '/activitypub/1.0/users/1/followers' ), $activitypub_activity->get_to() );
|
||||||
$this->assertContains( 'https://example.com/alex', $activitypub_activity->get_cc() );
|
$this->assertContains( 'https://example.com/alex', $activitypub_activity->get_cc() );
|
||||||
|
|
||||||
remove_all_filters( 'activitypub_extract_mentions' );
|
remove_all_filters( 'activitypub_extract_mentions' );
|
||||||
|
|
Loading…
Reference in a new issue