X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FProtocol%2FActivityPub%2FReceiver.php;h=4504cee4c49367b7e587d0b2d767ba21a0e55aff;hb=3d8e82d95d9cc76b45a8db301b22c4111f335e1c;hp=7669934a650b288b97e2952a0527f73e325e678a;hpb=f6df07ec86d1da7c5d3212a3bf745f770c33bf0d;p=friendica.git diff --git a/src/Protocol/ActivityPub/Receiver.php b/src/Protocol/ActivityPub/Receiver.php index 7669934a65..4504cee4c4 100644 --- a/src/Protocol/ActivityPub/Receiver.php +++ b/src/Protocol/ActivityPub/Receiver.php @@ -1,6 +1,6 @@ $object_data['object_id'], 'type' => $type, 'signer' => $signer, 'actor' => $actor, 'attributedTo' => $attributed_to]); return; @@ -617,7 +635,7 @@ class Receiver break; default: - Logger::log('Unknown activity: ' . $type . ' ' . $object_data['object_type'], Logger::DEBUG); + Logger::info('Unknown activity: ' . $type . ' ' . $object_data['object_type']); break; } } @@ -932,16 +950,16 @@ class Receiver $data = ActivityPub::fetchContent($object_id, $uid); if (!empty($data)) { $object = JsonLD::compact($data); - Logger::log('Fetched content for ' . $object_id, Logger::DEBUG); + Logger::info('Fetched content for ' . $object_id); } else { - Logger::log('Empty content for ' . $object_id . ', check if content is available locally.', Logger::DEBUG); + Logger::info('Empty content for ' . $object_id . ', check if content is available locally.'); $item = Post::selectFirst(Item::DELIVER_FIELDLIST, ['uri' => $object_id]); if (!DBA::isResult($item)) { - Logger::log('Object with url ' . $object_id . ' was not found locally.', Logger::DEBUG); + Logger::info('Object with url ' . $object_id . ' was not found locally.'); return false; } - Logger::log('Using already stored item for url ' . $object_id, Logger::DEBUG); + Logger::info('Using already stored item for url ' . $object_id); $data = ActivityPub\Transmitter::createNote($item); $object = JsonLD::compact($data); } @@ -957,7 +975,7 @@ class Receiver return false; } } else { - Logger::log('Using original object for url ' . $object_id, Logger::DEBUG); + Logger::info('Using original object for url ' . $object_id); } $type = JsonLD::fetchElement($object, '@type'); @@ -966,6 +984,18 @@ class Receiver return false; } + // Lemmy is resharing "create" activities instead of content + // We fetch the content from the activity. + if (in_array($type, ['as:Create'])) { + $object = $object['as:object']; + $type = JsonLD::fetchElement($object, '@type'); + if (empty($type)) { + Logger::info('Empty type'); + return false; + } + $object_data = self::processObject($object); + } + // We currently don't handle 'pt:CacheFile', but with this step we avoid logging if (in_array($type, self::CONTENT_TYPES) || ($type == 'pt:CacheFile')) { $object_data = self::processObject($object); @@ -984,7 +1014,7 @@ class Receiver return self::fetchObject($object_id, [], false, $uid); } - Logger::log('Unhandled object type: ' . $type, Logger::DEBUG); + Logger::info('Unhandled object type: ' . $type); return false; } @@ -1220,29 +1250,59 @@ class Receiver } /** - * Check if the "as:url" element is an array with multiple links - * This is the case with audio and video posts. - * Then the links are added as attachments + * Extracts a potential alternate URL from a list of additional URL elements * - * @param array $object The raw object - * @param array $object_data The parsed object data for later processing - * @return array the object data + * @param array $urls + * @return string */ - private static function processAttachmentUrls(array $object, array $object_data) { - // Check if this is some url with multiple links - if (empty($object['as:url'])) { - return $object_data; - } + private static function extractAlternateUrl(array $urls): string + { + $alternateUrl = ''; + foreach ($urls as $key => $url) { + // Not a list but a single URL element + if (!is_numeric($key)) { + continue; + } - $urls = $object['as:url']; - $keys = array_keys($urls); - if (!is_numeric(array_pop($keys))) { - return $object_data; + if (empty($url['@type']) || ($url['@type'] != 'as:Link')) { + continue; + } + + $href = JsonLD::fetchElement($url, 'as:href', '@id'); + if (empty($href)) { + continue; + } + + $mediatype = JsonLD::fetchElement($url, 'as:mediaType'); + if (empty($mediatype)) { + continue; + } + + if ($mediatype == 'text/html') { + $alternateUrl = $href; + } } + return $alternateUrl; + } + + /** + * Check if the "as:url" element is an array with multiple links + * This is the case with audio and video posts. + * Then the links are added as attachments + * + * @param array $urls The object URL list + * @return array an array of attachments + */ + private static function processAttachmentUrls(array $urls): array + { $attachments = []; + foreach ($urls as $key => $url) { + // Not a list but a single URL element + if (!is_numeric($key)) { + continue; + } - foreach ($urls as $url) { if (empty($url['@type']) || ($url['@type'] != 'as:Link')) { continue; } @@ -1257,18 +1317,19 @@ class Receiver continue; } - if ($mediatype == 'text/html') { - $object_data['alternate-url'] = $href; - } - $filetype = strtolower(substr($mediatype, 0, strpos($mediatype, '/'))); if ($filetype == 'audio') { - $attachments[$filetype] = ['type' => $mediatype, 'url' => $href, 'height' => null, 'size' => null]; + $attachments[] = ['type' => $filetype, 'mediaType' => $mediatype, 'url' => $href, 'height' => null, 'size' => null, 'name' => '']; } elseif ($filetype == 'video') { $height = (int)JsonLD::fetchElement($url, 'as:height', '@value'); + // PeerTube audio-only track + if ($height === 0) { + continue; + } + $size = (int)JsonLD::fetchElement($url, 'pt:size', '@value'); - $attachments[$filetype] = ['type' => $mediatype, 'url' => $href, 'height' => $height, 'size' => $size]; + $attachments[] = ['type' => $filetype, 'mediaType' => $mediatype, 'url' => $href, 'height' => $height, 'size' => $size, 'name' => '']; } elseif (in_array($mediatype, ['application/x-bittorrent', 'application/x-bittorrent;x-scheme-handler/magnet'])) { $height = (int)JsonLD::fetchElement($url, 'as:height', '@value'); @@ -1277,19 +1338,14 @@ class Receiver continue; } - $attachments[$mediatype] = ['type' => $mediatype, 'url' => $href, 'height' => $height, 'size' => null]; + $attachments[$mediatype] = ['type' => $mediatype, 'mediaType' => $mediatype, 'url' => $href, 'height' => $height, 'size' => null, 'name' => '']; + } elseif ($mediatype == 'application/x-mpegURL') { + // PeerTube exception, actual video link is in the tags of this URL element + $attachments = array_merge($attachments, self::processAttachmentUrls($url['as:tag'])); } } - foreach ($attachments as $type => $attachment) { - $object_data['attachments'][] = ['type' => $type, - 'mediaType' => $attachment['type'], - 'height' => $attachment['height'], - 'size' => $attachment['size'], - 'name' => '', - 'url' => $attachment['url']]; - } - return $object_data; + return array_values($attachments); } /** @@ -1314,6 +1370,14 @@ class Receiver // An empty "id" field is translated to "./" by the compactor, so we have to check for this content if (empty($object_data['reply-to-id']) || ($object_data['reply-to-id'] == './')) { $object_data['reply-to-id'] = $object_data['id']; + + // On activities the "reply to" is the id of the object it refers to + if (in_array($object_data['object_type'], self::ACTIVITY_TYPES)) { + $object_id = JsonLD::fetchElement($object, 'as:object', '@id'); + if (!empty($object_id)) { + $object_data['reply-to-id'] = $object_id; + } + } } else { // Some systems (e.g. GNU Social) don't reply to the "id" field but the "uri" field. $replyToId = Item::getURIByLink($object_data['reply-to-id']); @@ -1363,7 +1427,6 @@ class Receiver $object_data = self::getSource($object, $object_data); $object_data['start-time'] = JsonLD::fetchElement($object, 'as:startTime', '@value'); $object_data['end-time'] = JsonLD::fetchElement($object, 'as:endTime', '@value'); - $object_data['adjust'] = JsonLD::fetchElement($object, 'dfrn:adjust', '@value'); $object_data['location'] = $location; $object_data['latitude'] = JsonLD::fetchElement($object, 'as:location', 'as:latitude', '@type', 'as:Place'); $object_data['latitude'] = JsonLD::fetchElement($object_data, 'latitude', '@value'); @@ -1387,7 +1450,8 @@ class Receiver } if (in_array($object_data['object_type'], ['as:Audio', 'as:Video'])) { - $object_data = self::processAttachmentUrls($object, $object_data); + $object_data['alternate-url'] = self::extractAlternateUrl($object['as:url'] ?? []) ?: $object_data['alternate-url']; + $object_data['attachments'] = array_merge($object_data['attachments'], self::processAttachmentUrls($object['as:url'] ?? [])); } $receiverdata = self::getReceivers($object, $object_data['actor'], $object_data['tags'], true);