]> git.mxchange.org Git - friendica.git/commitdiff
Filter user defined channels by size
authorMichael <heluecht@pirati.ca>
Tue, 30 Jan 2024 10:05:05 +0000 (10:05 +0000)
committerMichael <heluecht@pirati.ca>
Tue, 30 Jan 2024 10:05:05 +0000 (10:05 +0000)
12 files changed:
database.sql
doc/database/db_channel.md
doc/database/db_post-engagement.md
src/Content/Conversation/Entity/Timeline.php
src/Content/Conversation/Factory/UserDefinedChannel.php
src/Content/Conversation/Repository/UserDefinedChannel.php
src/Model/Post/Engagement.php
src/Module/Conversation/Timeline.php
src/Module/Settings/Channels.php
static/dbstructure.config.php
view/templates/settings/channels.tpl
view/theme/frio/templates/settings/channels.tpl

index 3e74e28dcbd8f0be2047cedf212728a2131a7acc..da167e2c41daa44ab9c7e7b141b0fe58f32b20a8 100644 (file)
@@ -1,6 +1,6 @@
 -- ------------------------------------------
 -- Friendica 2024.03-dev (Yellow Archangel)
--- DB_UPDATE_VERSION 1548
+-- DB_UPDATE_VERSION 1549
 -- ------------------------------------------
 
 
@@ -502,6 +502,8 @@ CREATE TABLE IF NOT EXISTS `channel` (
        `access-key` varchar(1) COMMENT 'Access key',
        `include-tags` varchar(1023) COMMENT 'Comma separated list of tags that will be included in the channel',
        `exclude-tags` varchar(1023) COMMENT 'Comma separated list of tags that aren\'t allowed in the channel',
+       `min-size` int unsigned COMMENT 'Minimum post size',
+       `max-size` int unsigned COMMENT 'Maximum post size',
        `full-text-search` varchar(1023) COMMENT 'Full text search pattern, see https://mariadb.com/kb/en/full-text-index-overview/#in-boolean-mode',
        `media-type` smallint unsigned COMMENT 'Filtered media types',
        `languages` mediumtext COMMENT 'Desired languages',
@@ -1346,6 +1348,7 @@ CREATE TABLE IF NOT EXISTS `post-engagement` (
        `media-type` tinyint NOT NULL DEFAULT 0 COMMENT 'Type of media in a bit array (1 = image, 2 = video, 4 = audio',
        `language` varchar(128) COMMENT 'Language information about this post',
        `searchtext` mediumtext COMMENT 'Simplified text for the full text search',
+       `size` int unsigned COMMENT 'Body size',
        `created` datetime COMMENT '',
        `restricted` boolean NOT NULL DEFAULT '0' COMMENT 'If true, this post is either unlisted or not from a federated network',
        `comments` mediumint unsigned COMMENT 'Number of comments',
index 5b0636dc802464a3fe62f804f0d9bb23d694abbc..4a469b4ee3e51e3e1a25b122f1d01e9d4e093633 100644 (file)
@@ -16,6 +16,8 @@ Fields
 | access-key       | Access key                                                                                        | varchar(1)         | YES  |     | NULL    |                |
 | include-tags     | Comma separated list of tags that will be included in the channel                                 | varchar(1023)      | YES  |     | NULL    |                |
 | exclude-tags     | Comma separated list of tags that aren't allowed in the channel                                   | varchar(1023)      | YES  |     | NULL    |                |
+| min-size         | Minimum post size                                                                                 | int unsigned       | YES  |     | NULL    |                |
+| max-size         | Maximum post size                                                                                 | int unsigned       | YES  |     | NULL    |                |
 | full-text-search | Full text search pattern, see https://mariadb.com/kb/en/full-text-index-overview/#in-boolean-mode | varchar(1023)      | YES  |     | NULL    |                |
 | media-type       | Filtered media types                                                                              | smallint unsigned  | YES  |     | NULL    |                |
 | languages        | Desired languages                                                                                 | mediumtext         | YES  |     | NULL    |                |
index e63f170b76c771091748471593e87b2290574828..027ae56a7980ca1043c014b80529cb071ae3eedf 100644 (file)
@@ -14,6 +14,7 @@ Fields
 | media-type   | Type of media in a bit array (1 = image, 2 = video, 4 = audio         | tinyint            | NO   |     | 0       |       |
 | language     | Language information about this post                                  | varchar(128)       | YES  |     | NULL    |       |
 | searchtext   | Simplified text for the full text search                              | mediumtext         | YES  |     | NULL    |       |
+| size         | Body size                                                             | int unsigned       | YES  |     | NULL    |       |
 | created      |                                                                       | datetime           | YES  |     | NULL    |       |
 | restricted   | If true, this post is either unlisted or not from a federated network | boolean            | NO   |     | 0       |       |
 | comments     | Number of comments                                                    | mediumint unsigned | YES  |     | NULL    |       |
index a27d9fb98f3076d10ecc9a904d9a7627d395f629..47d6e8db47fe197543f243b89f69ab6e0a51e884 100644 (file)
@@ -30,6 +30,8 @@ namespace Friendica\Content\Conversation\Entity;
  * @property-read int    $uid            User of the channel
  * @property-read string $includeTags    The tags to include in the channel
  * @property-read string $excludeTags    The tags to exclude in the channel
+ * @property-read int    $minSize        Minimum content size
+ * @property-read int    $maxSize        Maximum content size
  * @property-read string $fullTextSearch full text search pattern
  * @property-read int    $mediaType      Media types that are included in the channel
  * @property-read array  $languages      Channel languages
@@ -57,6 +59,10 @@ class Timeline extends \Friendica\BaseEntity
        protected $includeTags;
        /** @var string */
        protected $excludeTags;
+       /** @var int */
+       protected $minSize;
+       /** @var int */
+       protected $maxSize;
        /** @var string */
        protected $fullTextSearch;
        /** @var int */
@@ -68,7 +74,7 @@ class Timeline extends \Friendica\BaseEntity
        /** @var bool */
        protected $valid;
 
-       public function __construct(string $code = null, string $label = null, string $description = null, string $accessKey = null, string $path = null, int $uid = null, string $includeTags = null, string $excludeTags = null, string $fullTextSearch = null, int $mediaType = null, int $circle = null, array $languages = null, bool $publish = null, bool $valid = null)
+       public function __construct(string $code = null, string $label = null, string $description = null, string $accessKey = null, string $path = null, int $uid = null, string $includeTags = null, string $excludeTags = null, string $fullTextSearch = null, int $mediaType = null, int $circle = null, array $languages = null, bool $publish = null, bool $valid = null, int $minSize = null, int $maxSize = null)
        {
                $this->code           = $code;
                $this->label          = $label;
@@ -78,6 +84,8 @@ class Timeline extends \Friendica\BaseEntity
                $this->uid            = $uid;
                $this->includeTags    = $includeTags;
                $this->excludeTags    = $excludeTags;
+               $this->minSize        = $minSize;
+               $this->maxSize        = $maxSize;
                $this->fullTextSearch = $fullTextSearch;
                $this->mediaType      = $mediaType;
                $this->circle         = $circle;
index 08a092205c4c2b2bbc7436e6eec2140cf1adb69b..f3b5f65a1435e563901529847988042c45cdfc1d 100644 (file)
@@ -52,6 +52,8 @@ final class UserDefinedChannel extends Timeline implements ICanCreateFromTableRo
                        $row['languages'] ?? null,
                        $row['publish'] ?? null,
                        $row['valid'] ?? null,
+                       $row['min-size'] ?? null,
+                       $row['max-size'] ?? null,
                );
        }
 }
index c47991ac4eedced3efddb8579fdd0057c90b675a..6515bc71967ba9826eb5f8cad7837c9f20331f1e 100644 (file)
@@ -130,6 +130,8 @@ class UserDefinedChannel extends \Friendica\BaseRepository
                        'circle'           => $Channel->circle,
                        'include-tags'     => $Channel->includeTags,
                        'exclude-tags'     => $Channel->excludeTags,
+                       'min-size'         => $Channel->minSize,
+                       'max-size'         => $Channel->maxSize,
                        'full-text-search' => $Channel->fullTextSearch,
                        'media-type'       => $Channel->mediaType,
                        'languages'        => serialize($Channel->languages),
index 64f796ccc71c355e1ce8397d37a8157eae7dcf58..e787aec408707a6f94ce169216ad7e1d1bf018cc 100644 (file)
@@ -38,7 +38,8 @@ use Friendica\Util\DateTimeFormat;
 
 class Engagement
 {
-       const KEYWORDS = ['source', 'server', 'from', 'to', 'group', 'application', 'tag', 'network', 'platform', 'visibility', 'language'];
+       const KEYWORDS  = ['source', 'server', 'from', 'to', 'group', 'application', 'tag', 'network', 'platform', 'visibility', 'language'];
+       const SHORTCUTS = ['lang' => 'language', 'net' => 'network', 'relay' => 'application'];
 
        /**
         * Store engagement data from an item array
@@ -101,6 +102,7 @@ class Engagement
                        'media-type'   => $mediatype,
                        'language'     => $parent['language'],
                        'searchtext'   => $searchtext,
+                       'size'         => self::getContentSize($parent),
                        'created'      => $parent['created'],
                        'restricted'   => !in_array($item['network'], Protocol::FEDERATED) || ($parent['private'] != Item::PUBLIC),
                        'comments'     => DBA::count('post', ['parent-uri-id' => $item['parent-uri-id'], 'gravity' => Item::GRAVITY_COMMENT]),
@@ -125,6 +127,18 @@ class Engagement
                return ($ret && !$exists) ? $engagement['uri-id'] : 0;
        }
 
+       private static function getContentSize(array $item): int 
+       {
+               $body = ' ' . $item['title'] . ' ' . $item['content-warning'] . ' ' . $item['body'];
+               $body = BBCode::removeAttachment($body);
+               $body = BBCode::removeSharedData($body);
+               $body = preg_replace('/[^@!#]\[url\=.*?\].*?\[\/url\]/ism', '', $body);
+               $body = BBCode::removeLinks($body);
+               $msg = BBCode::toPlaintext($body, false);
+
+               return mb_strlen($msg);
+       }
+
        public static function getSearchTextForActivity(string $content, int $author_id, array $tags, array $receivers): string
        {
                $author = Contact::getById($author_id);
@@ -347,7 +361,11 @@ class Engagement
 
        public static function escapeKeywords(string $fullTextSearch): string
        {
-               foreach (Engagement::KEYWORDS as $keyword) {
+               foreach (SELF::SHORTCUTS as $search => $replace) {
+                       $fullTextSearch = preg_replace('~' . $search . ':(.[\w\*@\.-]+)~', $replace . ':$1', $fullTextSearch);
+               }
+
+               foreach (self::KEYWORDS as $keyword) {
                        $fullTextSearch = preg_replace('~(' . $keyword . '):(.[\w\*@\.-]+)~', '"$1_$2"', $fullTextSearch);
                }
                return $fullTextSearch;
index 1b375d099dbd9cb2255c24774ef7f780470ed862..d0f8f0973613af5eb954ca2aff2a5b1a8989c649 100644 (file)
@@ -427,6 +427,14 @@ class Timeline extends BaseModule
                        $condition    = DBA::mergeConditions($condition, array_merge(["NOT `uri-id` IN (SELECT `uri-id` FROM `post-tag` INNER JOIN `tag` ON `tag`.`id` = `post-tag`.`tid` WHERE `post-tag`.`type` = 1 AND `name` IN (" . $placeholders . "))"], $search));
                }
 
+               if (!is_null($channel->minSize)) {
+                       $condition = DBA::mergeConditions($condition, ["`size` >= ?", $channel->minSize]);
+               }
+
+               if (!is_null($channel->maxSize)) {
+                       $condition = DBA::mergeConditions($condition, ["`size` <= ?", $channel->maxSize]);
+               }
+
                if (!empty($channel->mediaType)) {
                        $condition = DBA::mergeConditions($condition, ["`media-type` & ?", $channel->mediaType]);
                }
index 34ba0d1d80efe79034b0a576225854399aa01777..a1b5949edefcc69c6e5c42bcad2e5385a51a407c 100644 (file)
@@ -83,6 +83,8 @@ class Channels extends BaseSettings
                                'circle'           => (int)$request['new_circle'],
                                'include-tags'     => Strings::cleanTags($request['new_include_tags']),
                                'exclude-tags'     => Strings::cleanTags($request['new_exclude_tags']),
+                               'min-size'         => $request['new_min_size'] != '' ? (int)$request['new_min_size'] : null,
+                               'max-size'         => $request['new_max_size'] != '' ? (int)$request['new_max_size'] : null,
                                'full-text-search' => $request['new_text_search'],
                                'media-type'       => ($request['new_image'] ? 1 : 0) | ($request['new_video'] ? 2 : 0) | ($request['new_audio'] ? 4 : 0),
                                'languages'        => $request['new_languages'],
@@ -112,6 +114,8 @@ class Channels extends BaseSettings
                                'circle'           => (int)$request['circle'][$id],
                                'include-tags'     => Strings::cleanTags($request['include_tags'][$id]),
                                'exclude-tags'     => Strings::cleanTags($request['exclude_tags'][$id]),
+                               'min-size'         => $request['min_size'][$id] != '' ? (int)$request['min_size'][$id] : null,
+                               'max-size'         => $request['max_size'][$id] != '' ? (int)$request['max_size'][$id] : null,
                                'full-text-search' => $request['text_search'][$id],
                                'media-type'       => ($request['image'][$id] ? 1 : 0) | ($request['video'][$id] ? 2 : 0) | ($request['audio'][$id] ? 4 : 0),
                                'languages'        => $request['languages'][$id],
@@ -181,6 +185,8 @@ class Channels extends BaseSettings
                                'circle'       => ["circle[$channel->code]", $this->t('Circle/Channel'), $channel->circle, '', $circles],
                                'include_tags' => ["include_tags[$channel->code]", $this->t("Include Tags"), str_replace(',', ', ', $channel->includeTags)],
                                'exclude_tags' => ["exclude_tags[$channel->code]", $this->t("Exclude Tags"), str_replace(',', ', ', $channel->excludeTags)],
+                               'min_size'     => ["min_size[$channel->code]", $this->t("Minimum Size"), $channel->minSize],
+                               'max_size'     => ["max_size[$channel->code]", $this->t("Maximum Size"), $channel->maxSize],
                                'text_search'  => ["text_search[$channel->code]", $this->t("Full Text Search"), $channel->fullTextSearch],
                                'image'        => ["image[$channel->code]", $this->t("Images"), $channel->mediaType & 1],
                                'video'        => ["video[$channel->code]", $this->t("Videos"), $channel->mediaType & 2],
@@ -200,6 +206,8 @@ class Channels extends BaseSettings
                        'circle'       => ['new_circle', $this->t('Circle/Channel'), 0, $this->t('Select a circle or channel, that your channel should be based on.'), $circles],
                        'include_tags' => ["new_include_tags", $this->t("Include Tags"), '', $this->t('Comma separated list of tags. A post will be used when it contains any of the listed tags.')],
                        'exclude_tags' => ["new_exclude_tags", $this->t("Exclude Tags"), '', $this->t('Comma separated list of tags. If a post contain any of these tags, then it will not be part of nthis channel.')],
+                       'min_size'     => ["new_min_size", $this->t("Minimum Size"), '', $this->t('Minimum post size. Leave empty for no minimum size. The size is calculated without links, attached posts, mentions or hashtags.')],
+                       'max_size'     => ["new_max_size", $this->t("Maximum Size"), '', $this->t('Maximum post size. Leave empty for no maximum size. The size is calculated without links, attached posts, mentions or hashtags.')],
                        'text_search'  => ["new_text_search", $this->t("Full Text Search"), '', $this->t('Search terms for the body, supports the "boolean mode" operators from MariaDB. See the help for a complete list of operators and additional keywords: %s', '<a href="help/Channels">help/Channels</a>')],
                        'image'        => ['new_image', $this->t("Images"), false, $this->t("Check to display images in the channel.")],
                        'video'        => ["new_video", $this->t("Videos"), false, $this->t("Check to display videos in the channel.")],
index 5595a752b2c440e1a11197beaab438cecffa4422..a75403fcd9abcf9b134846dd6465c1e0b3aa75c4 100644 (file)
@@ -56,7 +56,7 @@ use Friendica\Database\DBA;
 
 // This file is required several times during the test in DbaDefinition which justifies this condition
 if (!defined('DB_UPDATE_VERSION')) {
-       define('DB_UPDATE_VERSION', 1548);
+       define('DB_UPDATE_VERSION', 1549);
 }
 
 return [
@@ -560,6 +560,8 @@ return [
                        "access-key" => ["type" => "varchar(1)", "comment" => "Access key"],
                        "include-tags" => ["type" => "varchar(1023)", "comment" => "Comma separated list of tags that will be included in the channel"],
                        "exclude-tags" => ["type" => "varchar(1023)", "comment" => "Comma separated list of tags that aren't allowed in the channel"],
+                       "min-size" => ["type" => "int unsigned", "comment" => "Minimum post size"],
+                       "max-size" => ["type" => "int unsigned", "comment" => "Maximum post size"],
                        "full-text-search" => ["type" => "varchar(1023)", "comment" => "Full text search pattern, see https://mariadb.com/kb/en/full-text-index-overview/#in-boolean-mode"],
                        "media-type" => ["type" => "smallint unsigned", "comment" => "Filtered media types"],
                        "languages" => ["type" => "mediumtext", "comment" => "Desired languages"],
@@ -1367,6 +1369,7 @@ return [
                        "media-type" => ["type" => "tinyint", "not null" => "1", "default" => "0", "comment" => "Type of media in a bit array (1 = image, 2 = video, 4 = audio"],
                        "language" => ["type" => "varchar(128)", "comment" => "Language information about this post"],
                        "searchtext" => ["type" => "mediumtext", "comment" => "Simplified text for the full text search"],
+                       "size" => ["type" => "int unsigned", "comment" => "Body size"],
                        "created" => ["type" => "datetime", "comment" => ""],
                        "restricted" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "If true, this post is either unlisted or not from a federated network"],
                        "comments" => ["type" => "mediumint unsigned", "comment" => "Number of comments"],
index 44260a2336960227ea911912e3724262bb45a1a7..903989cff6e8ca5c31a5dfa02f6b861795fd6e7b 100644 (file)
@@ -11,6 +11,8 @@
        {{include file="field_textarea.tpl" field=$include_tags}}
        {{include file="field_textarea.tpl" field=$exclude_tags}}
        {{include file="field_textarea.tpl" field=$text_search}}
+       {{include file="field_input.tpl" field=$min_size}}
+       {{include file="field_input.tpl" field=$max_size}}
        {{include file="field_checkbox.tpl" field=$image}}
        {{include file="field_checkbox.tpl" field=$video}}
        {{include file="field_checkbox.tpl" field=$audio}}
@@ -31,6 +33,8 @@
                        {{include file="field_select.tpl" field=$e.circle}}
                        {{include file="field_textarea.tpl" field=$e.include_tags}}
                        {{include file="field_textarea.tpl" field=$e.exclude_tags}}
+                       {{include file="field_input.tpl" field=$e.min_size}}
+                       {{include file="field_input.tpl" field=$e.max_size}}
                        {{include file="field_textarea.tpl" field=$e.text_search}}
                        {{include file="field_checkbox.tpl" field=$e.image}}
                        {{include file="field_checkbox.tpl" field=$e.video}}
index 932783e1dc71e11db799949c445d8825fc77784d..1ec246978c4bcad76e3bc2b982ce54b7ffcb5064 100644 (file)
@@ -18,6 +18,8 @@
                                {{include file="field_select.tpl" field=$circle}}
                                {{include file="field_textarea.tpl" field=$include_tags}}
                                {{include file="field_textarea.tpl" field=$exclude_tags}}
+                               {{include file="field_input.tpl" field=$min_size}}
+                               {{include file="field_input.tpl" field=$max_size}}
                                {{include file="field_textarea.tpl" field=$text_search}}
                                {{include file="field_checkbox.tpl" field=$image}}
                                {{include file="field_checkbox.tpl" field=$video}}
@@ -48,6 +50,8 @@
                                                {{include file="field_select.tpl" field=$e.circle}}
                                                {{include file="field_textarea.tpl" field=$e.include_tags}}
                                                {{include file="field_textarea.tpl" field=$e.exclude_tags}}
+                                               {{include file="field_input.tpl" field=$e.min_size}}
+                                               {{include file="field_input.tpl" field=$e.max_size}}
                                                {{include file="field_textarea.tpl" field=$e.text_search}}
                                                {{include file="field_checkbox.tpl" field=$e.image}}
                                                {{include file="field_checkbox.tpl" field=$e.video}}