port some functions from osada
This commit is contained in:
parent
40bbdfdf6a
commit
5ccef18d4e
@ -1844,7 +1844,8 @@ class Activity {
|
||||
$s['item_private'] = 1;
|
||||
|
||||
set_iconfig($s,'activitypub','recips',$act->raw_recips);
|
||||
// @FIXME: $parent is not defined
|
||||
|
||||
$parent = (($s['parent_mid'] && $s['parent_mid'] === $s['mid']) ? true : false);
|
||||
if($parent) {
|
||||
set_iconfig($s,'activitypub','rawmsg',$act->raw,1);
|
||||
}
|
||||
@ -1853,6 +1854,266 @@ class Activity {
|
||||
|
||||
}
|
||||
|
||||
static function store($channel,$observer_hash,$act,$item,$fetch_parents = true) {
|
||||
|
||||
$is_sys_channel = is_sys_channel($channel['channel_id']);
|
||||
|
||||
// Mastodon only allows visibility in public timelines if the public inbox is listed in the 'to' field.
|
||||
// They are hidden in the public timeline if the public inbox is listed in the 'cc' field.
|
||||
// This is not part of the activitypub protocol - we might change this to show all public posts in pubstream at some point.
|
||||
|
||||
$pubstream = ((is_array($act->obj) && array_key_exists('to', $act->obj) && in_array(ACTIVITY_PUBLIC_INBOX, $act->obj['to'])) ? true : false);
|
||||
|
||||
if(! perm_is_allowed($channel['channel_id'],$observer_hash,'send_stream') && ! ($is_sys_channel && $pubstream)) {
|
||||
logger('no permission');
|
||||
return;
|
||||
}
|
||||
|
||||
if(is_array($act->obj)) {
|
||||
$content = self::get_content($act->obj);
|
||||
}
|
||||
if(! $content) {
|
||||
logger('no content');
|
||||
return;
|
||||
}
|
||||
|
||||
$item['aid'] = $channel['channel_account_id'];
|
||||
$item['uid'] = $channel['channel_id'];
|
||||
$s['uuid'] = '';
|
||||
|
||||
// Friendica sends the diaspora guid in a nonstandard field via AP
|
||||
if($act->obj['diaspora:guid'])
|
||||
$s['uuid'] = $act->obj['diaspora:guid'];
|
||||
|
||||
if(! ( $item['author_xchan'] && $item['owner_xchan'])) {
|
||||
logger('owner or author missing.');
|
||||
return;
|
||||
}
|
||||
|
||||
if($channel['channel_system']) {
|
||||
if(! MessageFilter::evaluate($item,get_config('system','pubstream_incl'),get_config('system','pubstream_excl'))) {
|
||||
logger('post is filtered');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$abook = q("select * from abook where abook_xchan = '%s' and abook_channel = %d limit 1",
|
||||
dbesc($observer_hash),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
|
||||
if($abook) {
|
||||
if(! post_is_importable($item,$abook[0])) {
|
||||
logger('post is filtered');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if($act->obj['conversation']) {
|
||||
set_iconfig($item,'ostatus','conversation',$act->obj['conversation'],1);
|
||||
}
|
||||
|
||||
// This isn't perfect but the best we can do for now.
|
||||
|
||||
$item['comment_policy'] = 'authenticated';
|
||||
|
||||
set_iconfig($item,'activitypub','recips',$act->raw_recips);
|
||||
|
||||
$parent = (($item['parent_mid'] && $item['parent_mid'] === $item['mid']) ? true : false);
|
||||
|
||||
if(! $parent) {
|
||||
$p = q("select parent_mid from item where mid = '%s' and uid = %d limit 1",
|
||||
dbesc($item['parent_mid']),
|
||||
intval($item['uid'])
|
||||
);
|
||||
if(! $p) {
|
||||
$a = (($fetch_parents) ? self::fetch_and_store_parents($channel,$act,$item) : false);
|
||||
if($a) {
|
||||
$p = q("select parent_mid from item where mid = '%s' and uid = %d limit 1",
|
||||
dbesc($item['parent_mid']),
|
||||
intval($item['uid'])
|
||||
);
|
||||
}
|
||||
else {
|
||||
logger('could not fetch parents');
|
||||
return;
|
||||
|
||||
// @TODO we maybe could accept these is we formatted the body correctly with share_bb()
|
||||
// or at least provided a link to the object
|
||||
// if(in_array($act->type,[ 'Like','Dislike' ])) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// @TODO do we actually want that?
|
||||
// if no parent was fetched, turn into a top-level post
|
||||
|
||||
// turn into a top level post
|
||||
// $s['parent_mid'] = $s['mid'];
|
||||
// $s['thr_parent'] = $s['mid'];
|
||||
}
|
||||
}
|
||||
if($p[0]['parent_mid'] !== $item['parent_mid']) {
|
||||
$item['thr_parent'] = $item['parent_mid'];
|
||||
}
|
||||
else {
|
||||
$item['thr_parent'] = $p[0]['parent_mid'];
|
||||
}
|
||||
$item['parent_mid'] = $p[0]['parent_mid'];
|
||||
}
|
||||
|
||||
$r = q("select id, created, edited from item where mid = '%s' and uid = %d limit 1",
|
||||
dbesc($item['mid']),
|
||||
intval($item['uid'])
|
||||
);
|
||||
if($r) {
|
||||
if($item['edited'] > $r[0]['edited']) {
|
||||
$item['id'] = $r[0]['id'];
|
||||
$x = item_store_update($item);
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$x = item_store($item);
|
||||
}
|
||||
|
||||
if(is_array($x) && $x['item_id']) {
|
||||
if($parent) {
|
||||
if($item['owner_xchan'] === $channel['channel_hash']) {
|
||||
// We are the owner of this conversation, so send all received comments back downstream
|
||||
Master::Summon(array('Notifier','comment-import',$x['item_id']));
|
||||
}
|
||||
$r = q("select * from item where id = %d limit 1",
|
||||
intval($x['item_id'])
|
||||
);
|
||||
if($r) {
|
||||
send_status_notifications($x['item_id'],$r[0]);
|
||||
}
|
||||
}
|
||||
sync_an_item($channel['channel_id'],$x['item_id']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static public function fetch_and_store_parents($channel,$act,$item) {
|
||||
|
||||
logger('fetching parents');
|
||||
|
||||
$p = [];
|
||||
|
||||
$current_act = $act;
|
||||
$current_item = $item;
|
||||
|
||||
while($current_item['parent_mid'] !== $current_item['mid']) {
|
||||
$n = ActivityStreams::fetch($current_item['parent_mid'], $channel);
|
||||
if(! $n) {
|
||||
break;
|
||||
}
|
||||
$a = new ActivityStreams($n);
|
||||
|
||||
logger($a->debug());
|
||||
|
||||
if(! $a->is_valid()) {
|
||||
break;
|
||||
}
|
||||
|
||||
$replies = null;
|
||||
if(isset($n['replies']['first']['items'])) {
|
||||
$replies = $n['replies']['first']['items'];
|
||||
// we already have this one
|
||||
array_diff($replies, [$current_item['mid']]);
|
||||
}
|
||||
|
||||
$item = null;
|
||||
|
||||
switch($a->type) {
|
||||
case 'Create':
|
||||
case 'Update':
|
||||
case 'Like':
|
||||
case 'Dislike':
|
||||
case 'Announce':
|
||||
$item = self::decode_note($a);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
if(! $item) {
|
||||
break;
|
||||
}
|
||||
|
||||
array_unshift($p,[ $a, $item, $replies]);
|
||||
|
||||
if($item['parent_mid'] === $item['mid'] || count($p) > 20) {
|
||||
break;
|
||||
}
|
||||
|
||||
$current_act = $a;
|
||||
$current_item = $item;
|
||||
}
|
||||
|
||||
if($p) {
|
||||
foreach($p as $pv) {
|
||||
self::store($channel,$pv[0]->actor['id'],$pv[0],$pv[1],false);
|
||||
if($pv[2])
|
||||
self::fetch_and_store_replies($channel, $pv[2]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static public function fetch_and_store_replies($channel, $arr) {
|
||||
|
||||
logger('fetching replies');
|
||||
|
||||
$p = [];
|
||||
|
||||
foreach($arr as $url) {
|
||||
|
||||
$n = ActivityStreams::fetch($url, $channel);
|
||||
if(! $n) {
|
||||
break;
|
||||
}
|
||||
|
||||
$a = new ActivityStreams($n);
|
||||
|
||||
if(! $a->is_valid()) {
|
||||
break;
|
||||
}
|
||||
|
||||
$item = null;
|
||||
|
||||
switch($a->type) {
|
||||
case 'Create':
|
||||
case 'Update':
|
||||
case 'Like':
|
||||
case 'Dislike':
|
||||
case 'Announce':
|
||||
$item = self::decode_note($a);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(! $item) {
|
||||
break;
|
||||
}
|
||||
|
||||
array_unshift($p,[ $a, $item ]);
|
||||
|
||||
}
|
||||
|
||||
if($p) {
|
||||
foreach($p as $pv) {
|
||||
self::store($channel,$pv[0]->actor['id'],$pv[0],$pv[1],false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static function announce_note($channel,$observer_hash,$act) {
|
||||
|
||||
$s = [];
|
||||
@ -1973,25 +2234,21 @@ class Activity {
|
||||
$x = item_store($s);
|
||||
}
|
||||
|
||||
|
||||
if(is_array($x) && $x['item_id']) {
|
||||
// @FIXME: $parent is not defined
|
||||
if($parent) {
|
||||
if($s['owner_xchan'] === $channel['channel_hash']) {
|
||||
// We are the owner of this conversation, so send all received comments back downstream
|
||||
Master::Summon(array('Notifier','comment-import',$x['item_id']));
|
||||
}
|
||||
$r = q("select * from item where id = %d limit 1",
|
||||
intval($x['item_id'])
|
||||
);
|
||||
if($r) {
|
||||
send_status_notifications($x['item_id'],$r[0]);
|
||||
}
|
||||
if($s['owner_xchan'] === $channel['channel_hash']) {
|
||||
// We are the owner of this conversation, so send all received comments back downstream
|
||||
Master::Summon(array('Notifier','comment-import',$x['item_id']));
|
||||
}
|
||||
$r = q("select * from item where id = %d limit 1",
|
||||
intval($x['item_id'])
|
||||
);
|
||||
if($r) {
|
||||
send_status_notifications($x['item_id'],$r[0]);
|
||||
}
|
||||
|
||||
sync_an_item($channel['channel_id'],$x['item_id']);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
static function like_note($channel,$observer_hash,$act) {
|
||||
|
Reference in New Issue
Block a user