From 836ec2f20dcd6ed0cded2fec41e2df0938dce319 Mon Sep 17 00:00:00 2001 From: ~keith Date: Sat, 13 Aug 2022 02:06:01 +0000 Subject: [PATCH] Generate ActivityPub content warnings from [spoiler] elements --- src/Content/Text/BBCode.php | 24 ++++++++++++++++++++++++ src/Protocol/ActivityPub.php | 1 + src/Protocol/ActivityPub/Receiver.php | 6 ++++++ src/Protocol/ActivityPub/Transmitter.php | 11 ++++++++++- src/Protocol/DFRN.php | 2 +- 5 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/Content/Text/BBCode.php b/src/Content/Text/BBCode.php index e8a396a35..b292f48cd 100644 --- a/src/Content/Text/BBCode.php +++ b/src/Content/Text/BBCode.php @@ -2211,6 +2211,30 @@ class BBCode DI::profiler()->stopRecording(); return $abstract; } + + /** + * Returns a list of the headings of "spoiler" elements + * + * @param string $text The text containing spoiler elements + * @return string The list of spoiler headings + */ + public static function getSpoilerHeadings(string $text): string + { + DI::profiler()->startRecording('rendering'); + + $headings = BBCode::performWithEscapedTags($text, ['code', 'noparse', 'nobb', 'pre'], function ($text) { + $headings = []; + if (preg_match_all('/\[spoiler=[\"\']*(.*?)[\"\']*\]/ism', $text, $matches)) { + foreach ($matches[1] as $item) { + $headings[] = BBCode::toPlaintext($item); + } + } + return implode(', ', $headings); + }); + + DI::profiler()->stopRecording(); + return $headings; + } /** * Callback function to replace a Friendica style mention in a mention for Diaspora diff --git a/src/Protocol/ActivityPub.php b/src/Protocol/ActivityPub.php index 603416a5d..ee84d18a6 100644 --- a/src/Protocol/ActivityPub.php +++ b/src/Protocol/ActivityPub.php @@ -78,6 +78,7 @@ class ActivityPub 'discoverable' => 'toot:discoverable', 'PropertyValue' => 'schema:PropertyValue', 'value' => 'schema:value', + 'keithext' => 'http://bytes.keithhacks.cyou/keith/friendica/', ]]; const ACCOUNT_TYPES = ['Person', 'Organization', 'Service', 'Group', 'Application', 'Tombstone']; /** diff --git a/src/Protocol/ActivityPub/Receiver.php b/src/Protocol/ActivityPub/Receiver.php index 80eb602a0..313903692 100644 --- a/src/Protocol/ActivityPub/Receiver.php +++ b/src/Protocol/ActivityPub/Receiver.php @@ -1894,6 +1894,12 @@ class Receiver $object_data['sensitive'] = JsonLD::fetchElement($object, 'as:sensitive'); $object_data['name'] = JsonLD::fetchElement($object, 'as:name', '@value'); $object_data['summary'] = JsonLD::fetchElement($object, 'as:summary', '@value'); + // HACK Don't know exactly where I should be checking keithext:summaryFromSpoilers to prevent + // auto-generated spoiler CWs from showing up on Friendica, but it's definitely not here. + // However, this should work for now. + // TODO @keith clean this up or else + if (JsonLD::fetchElement($object, 'keithext:summaryFromSpoilers', '@value')) + $object_data['summary'] = null; $object_data['content'] = JsonLD::fetchElement($object, 'as:content', '@value'); $object_data['mediatype'] = JsonLD::fetchElement($object, 'as:mediaType', '@value'); $object_data = self::getSource($object, $object_data); diff --git a/src/Protocol/ActivityPub/Transmitter.php b/src/Protocol/ActivityPub/Transmitter.php index 6a601b6f9..156f0a3c4 100644 --- a/src/Protocol/ActivityPub/Transmitter.php +++ b/src/Protocol/ActivityPub/Transmitter.php @@ -1594,7 +1594,16 @@ class Transmitter return $data; } - $data['summary'] = BBCode::toPlaintext(BBCode::getAbstract($item['body'], Protocol::ACTIVITYPUB)); + $abstract = BBCode::getAbstract($item['body'], Protocol::ACTIVITYPUB); + if (!empty($abstract)) { + $data['summary'] = BBCode::toPlaintext($abstract); + } else { + $warnings = BBCode::getSpoilerHeadings($item['body']); + if ($warnings) { + $data['summary'] = $warnings; + $data['keithext:summaryFromSpoilers'] = true; + } + } if ($item['uri'] != $item['thr-parent']) { $data['inReplyTo'] = $item['thr-parent']; diff --git a/src/Protocol/DFRN.php b/src/Protocol/DFRN.php index da4db5d9a..6bf905c58 100644 --- a/src/Protocol/DFRN.php +++ b/src/Protocol/DFRN.php @@ -781,7 +781,7 @@ class DFRN } // Remove the abstract element. It is only locally important. - $body = BBCode::stripAbstract($body); + // $body = BBCode::stripAbstract($body); $htmlbody = ''; if ($type == 'html') {