From 96a0d9d783fed6a0d6ba2a2323fd453bddb02f38 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 7bb65b698..4cd6bae40 100644 --- a/src/Content/Text/BBCode.php +++ b/src/Content/Text/BBCode.php @@ -2179,6 +2179,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 array The list of spoiler headings + */ + public static function getSpoilerHeadings(string $text): array + { + 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 $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 93204e81d..01600c48b 100644 --- a/src/Protocol/ActivityPub.php +++ b/src/Protocol/ActivityPub.php @@ -76,6 +76,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 b1ed57b26..583059b79 100644 --- a/src/Protocol/ActivityPub/Receiver.php +++ b/src/Protocol/ActivityPub/Receiver.php @@ -1835,6 +1835,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 ecd184318..05599c7cc 100644 --- a/src/Protocol/ActivityPub/Transmitter.php +++ b/src/Protocol/ActivityPub/Transmitter.php @@ -1599,7 +1599,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'] = implode(', ', $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 80e92fa15..3d5e83f7b 100644 --- a/src/Protocol/DFRN.php +++ b/src/Protocol/DFRN.php @@ -780,7 +780,7 @@ class DFRN } // Remove the abstract element. It is only locally important. - $body = BBCode::stripAbstract($body); + // $body = BBCode::stripAbstract($body); $htmlbody = ''; if ($type == 'html') {