Use channels for non public content
This commit is contained in:
parent
a1f6e6e871
commit
b00c2070d7
9 changed files with 67 additions and 58 deletions
|
@ -1,6 +1,6 @@
|
||||||
-- ------------------------------------------
|
-- ------------------------------------------
|
||||||
-- Friendica 2023.09-dev (Giant Rhubarb)
|
-- Friendica 2023.09-dev (Giant Rhubarb)
|
||||||
-- DB_UPDATE_VERSION 1533
|
-- DB_UPDATE_VERSION 1534
|
||||||
-- ------------------------------------------
|
-- ------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
@ -1310,6 +1310,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',
|
`media-type` tinyint NOT NULL DEFAULT 0 COMMENT 'Type of media in a bit array (1 = image, 2 = video, 4 = audio',
|
||||||
`language` varbinary(128) COMMENT 'Language information about this post',
|
`language` varbinary(128) COMMENT 'Language information about this post',
|
||||||
`created` datetime COMMENT '',
|
`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',
|
`comments` mediumint unsigned COMMENT 'Number of comments',
|
||||||
`activities` mediumint unsigned COMMENT 'Number of activities (like, dislike, ...)',
|
`activities` mediumint unsigned COMMENT 'Number of activities (like, dislike, ...)',
|
||||||
PRIMARY KEY(`uri-id`),
|
PRIMARY KEY(`uri-id`),
|
||||||
|
|
|
@ -6,16 +6,17 @@ Engagement data per post
|
||||||
Fields
|
Fields
|
||||||
------
|
------
|
||||||
|
|
||||||
| Field | Description | Type | Null | Key | Default | Extra |
|
| Field | Description | Type | Null | Key | Default | Extra |
|
||||||
| ------------ | ------------------------------------------------------------- | ------------------ | ---- | --- | ------- | ----- |
|
| ------------ | --------------------------------------------------------------------- | ------------------ | ---- | --- | ------- | ----- |
|
||||||
| uri-id | Id of the item-uri table entry that contains the item uri | int unsigned | NO | PRI | NULL | |
|
| uri-id | Id of the item-uri table entry that contains the item uri | int unsigned | NO | PRI | NULL | |
|
||||||
| owner-id | Item owner | int unsigned | NO | | 0 | |
|
| owner-id | Item owner | int unsigned | NO | | 0 | |
|
||||||
| contact-type | Person, organisation, news, community, relay | tinyint | NO | | 0 | |
|
| contact-type | Person, organisation, news, community, relay | tinyint | NO | | 0 | |
|
||||||
| media-type | Type of media in a bit array (1 = image, 2 = video, 4 = audio | tinyint | NO | | 0 | |
|
| media-type | Type of media in a bit array (1 = image, 2 = video, 4 = audio | tinyint | NO | | 0 | |
|
||||||
| language | Language information about this post | varbinary(128) | YES | | NULL | |
|
| language | Language information about this post | varbinary(128) | YES | | NULL | |
|
||||||
| created | | datetime | YES | | NULL | |
|
| created | | datetime | YES | | NULL | |
|
||||||
| comments | Number of comments | mediumint unsigned | YES | | NULL | |
|
| restricted | If true, this post is either unlisted or not from a federated network | boolean | NO | | 0 | |
|
||||||
| activities | Number of activities (like, dislike, ...) | mediumint unsigned | YES | | NULL | |
|
| comments | Number of comments | mediumint unsigned | YES | | NULL | |
|
||||||
|
| activities | Number of activities (like, dislike, ...) | mediumint unsigned | YES | | NULL | |
|
||||||
|
|
||||||
Indexes
|
Indexes
|
||||||
------------
|
------------
|
||||||
|
|
|
@ -1250,7 +1250,7 @@ class Item
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Post::insert($item['uri-id'], $item);
|
$inserted = Post::insert($item['uri-id'], $item);
|
||||||
|
|
||||||
if ($item['gravity'] == self::GRAVITY_PARENT) {
|
if ($item['gravity'] == self::GRAVITY_PARENT) {
|
||||||
Post\Thread::insert($item['uri-id'], $item);
|
Post\Thread::insert($item['uri-id'], $item);
|
||||||
|
@ -1405,7 +1405,9 @@ class Item
|
||||||
self::updateDisplayCache($posted_item['uri-id']);
|
self::updateDisplayCache($posted_item['uri-id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
Post\Engagement::storeFromItem($posted_item);
|
if ($inserted) {
|
||||||
|
Post\Engagement::storeFromItem($posted_item);
|
||||||
|
}
|
||||||
|
|
||||||
return $post_user_id;
|
return $post_user_id;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,10 +36,10 @@ class Post
|
||||||
*
|
*
|
||||||
* @param integer $uri_id
|
* @param integer $uri_id
|
||||||
* @param array $fields
|
* @param array $fields
|
||||||
* @return int ID of inserted post
|
* @return bool Success of the insert process
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public static function insert(int $uri_id, array $data = []): int
|
public static function insert(int $uri_id, array $data = []): bool
|
||||||
{
|
{
|
||||||
if (empty($uri_id)) {
|
if (empty($uri_id)) {
|
||||||
throw new BadMethodCallException('Empty URI_id');
|
throw new BadMethodCallException('Empty URI_id');
|
||||||
|
@ -50,11 +50,7 @@ class Post
|
||||||
// Additionally assign the key fields
|
// Additionally assign the key fields
|
||||||
$fields['uri-id'] = $uri_id;
|
$fields['uri-id'] = $uri_id;
|
||||||
|
|
||||||
if (!DBA::insert('post', $fields, Database::INSERT_IGNORE)) {
|
return DBA::insert('post', $fields, Database::INSERT_IGNORE);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return DBA::lastInsertId();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -29,8 +29,10 @@ use Friendica\DI;
|
||||||
use Friendica\Model\Contact;
|
use Friendica\Model\Contact;
|
||||||
use Friendica\Model\Item;
|
use Friendica\Model\Item;
|
||||||
use Friendica\Model\Post;
|
use Friendica\Model\Post;
|
||||||
|
use Friendica\Model\Tag;
|
||||||
use Friendica\Model\Verb;
|
use Friendica\Model\Verb;
|
||||||
use Friendica\Protocol\Activity;
|
use Friendica\Protocol\Activity;
|
||||||
|
use Friendica\Protocol\Relay;
|
||||||
use Friendica\Util\DateTimeFormat;
|
use Friendica\Util\DateTimeFormat;
|
||||||
|
|
||||||
// Channel
|
// Channel
|
||||||
|
@ -45,26 +47,12 @@ class Engagement
|
||||||
*/
|
*/
|
||||||
public static function storeFromItem(array $item)
|
public static function storeFromItem(array $item)
|
||||||
{
|
{
|
||||||
if (!in_array($item['network'], Protocol::FEDERATED)) {
|
|
||||||
Logger::debug('No federated network', ['uri-id' => $item['uri-id'], 'parent-uri-id' => $item['parent-uri-id'], 'network' => $item['network']]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (($item['uid'] != 0) && ($item['gravity'] == Item::GRAVITY_COMMENT)) {
|
|
||||||
Logger::debug('Non public comments are not stored', ['uri-id' => $item['uri-id'], 'parent-uri-id' => $item['parent-uri-id'], 'uid' => $item['uid']]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in_array($item['verb'], [Activity::FOLLOW, Activity::VIEW, Activity::READ])) {
|
if (in_array($item['verb'], [Activity::FOLLOW, Activity::VIEW, Activity::READ])) {
|
||||||
Logger::debug('Technical activities are not stored', ['uri-id' => $item['uri-id'], 'parent-uri-id' => $item['parent-uri-id'], 'verb' => $item['verb']]);
|
Logger::debug('Technical activities are not stored', ['uri-id' => $item['uri-id'], 'parent-uri-id' => $item['parent-uri-id'], 'verb' => $item['verb']]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$parent = Post::selectFirst(['created', 'owner-id', 'uid', 'private', 'contact-contact-type', 'language'], ['uri-id' => $item['parent-uri-id']]);
|
$parent = Post::selectFirst(['created', 'owner-id', 'uid', 'private', 'contact-contact-type', 'language'], ['uri-id' => $item['parent-uri-id']]);
|
||||||
if ($parent['private'] != Item::PUBLIC) {
|
|
||||||
Logger::debug('Non public posts are not stored', ['uri-id' => $item['uri-id'], 'parent-uri-id' => $item['parent-uri-id'], 'uid' => $parent['uid'], 'private' => $parent['private']]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($parent['created'] < DateTimeFormat::utc('now - ' . DI::config()->get('channel', 'engagement_hours') . ' hour')) {
|
if ($parent['created'] < DateTimeFormat::utc('now - ' . DI::config()->get('channel', 'engagement_hours') . ' hour')) {
|
||||||
Logger::debug('Post is too old', ['uri-id' => $item['uri-id'], 'parent-uri-id' => $item['parent-uri-id'], 'created' => $parent['created']]);
|
Logger::debug('Post is too old', ['uri-id' => $item['uri-id'], 'parent-uri-id' => $item['parent-uri-id'], 'created' => $parent['created']]);
|
||||||
|
@ -77,6 +65,15 @@ class Engagement
|
||||||
$store = Contact::hasFollowers($parent['owner-id']);
|
$store = Contact::hasFollowers($parent['owner-id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!$store) {
|
||||||
|
$tagList = Relay::getSubscribedTags();
|
||||||
|
foreach (array_column(Tag::getByURIId($item['parent-uri-id'], [Tag::HASHTAG]), 'name') as $tag) {
|
||||||
|
if (in_array($tag, $tagList)) {
|
||||||
|
$store = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$mediatype = self::getMediaType($item['parent-uri-id']);
|
$mediatype = self::getMediaType($item['parent-uri-id']);
|
||||||
|
|
||||||
if (!$store) {
|
if (!$store) {
|
||||||
|
@ -90,6 +87,7 @@ class Engagement
|
||||||
'media-type' => $mediatype,
|
'media-type' => $mediatype,
|
||||||
'language' => $parent['language'],
|
'language' => $parent['language'],
|
||||||
'created' => $parent['created'],
|
'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]),
|
'comments' => DBA::count('post', ['parent-uri-id' => $item['parent-uri-id'], 'gravity' => Item::GRAVITY_COMMENT]),
|
||||||
'activities' => DBA::count('post', [
|
'activities' => DBA::count('post', [
|
||||||
"`parent-uri-id` = ? AND `gravity` = ? AND NOT `vid` IN (?, ?, ?)",
|
"`parent-uri-id` = ? AND `gravity` = ? AND NOT `vid` IN (?, ?, ?)",
|
||||||
|
@ -98,7 +96,7 @@ class Engagement
|
||||||
])
|
])
|
||||||
];
|
];
|
||||||
if (!$store && ($engagement['comments'] == 0) && ($engagement['activities'] == 0)) {
|
if (!$store && ($engagement['comments'] == 0) && ($engagement['activities'] == 0)) {
|
||||||
Logger::debug('No media, follower, comments or activities. Engagement not stored', ['fields' => $engagement]);
|
Logger::debug('No media, follower, subscribed tags, comments or activities. Engagement not stored', ['fields' => $engagement]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$ret = DBA::insert('post-engagement', $engagement, Database::INSERT_UPDATE);
|
$ret = DBA::insert('post-engagement', $engagement, Database::INSERT_UPDATE);
|
||||||
|
|
|
@ -340,13 +340,8 @@ class Profile extends BaseModule
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_array($contact['network'], Protocol::FEDERATED)) {
|
$channel_settings_label = $this->t('Channel Settings');
|
||||||
$channel_settings_label = $this->t('Channel Settings');
|
$channel_frequency = Contact\User::getChannelFrequency($contact['id'], $this->session->getLocalUserId());
|
||||||
$channel_frequency = Contact\User::getChannelFrequency($contact['id'], $this->session->getLocalUserId());
|
|
||||||
} else {
|
|
||||||
$channel_settings_label = null;
|
|
||||||
$channel_frequency = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$poll_interval = null;
|
$poll_interval = null;
|
||||||
if ((($contact['network'] == Protocol::FEED) && !$this->config->get('system', 'adjust_poll_frequency')) || ($contact['network'] == Protocol::MAIL)) {
|
if ((($contact['network'] == Protocol::FEED) && !$this->config->get('system', 'adjust_poll_frequency')) || ($contact['network'] == Protocol::MAIL)) {
|
||||||
|
|
|
@ -306,6 +306,8 @@ class Timeline extends BaseModule
|
||||||
$condition = $this->addLanguageCondition($uid, $condition);
|
$condition = $this->addLanguageCondition($uid, $condition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$condition = DBA::mergeConditions($condition, ["(NOT `restricted` OR EXISTS(SELECT `id` FROM `post-user` WHERE `uid` = ? AND `uri-id` = `post-engagement`.`uri-id`))", $uid]);
|
||||||
|
|
||||||
$condition = DBA::mergeConditions($condition, ["NOT EXISTS(SELECT `cid` FROM `user-contact` WHERE `uid` = ? AND `cid` = `post-engagement`.`owner-id` AND (`ignored` OR `blocked` OR `collapsed` OR `is-blocked` OR `channel-frequency` = ?))", $uid, Contact\User::FREQUENCY_NEVER]);
|
$condition = DBA::mergeConditions($condition, ["NOT EXISTS(SELECT `cid` FROM `user-contact` WHERE `uid` = ? AND `cid` = `post-engagement`.`owner-id` AND (`ignored` OR `blocked` OR `collapsed` OR `is-blocked` OR `channel-frequency` = ?))", $uid, Contact\User::FREQUENCY_NEVER]);
|
||||||
|
|
||||||
if (($this->selectedTab != TimelineEntity::WHATSHOT) && !is_null($this->accountType)) {
|
if (($this->selectedTab != TimelineEntity::WHATSHOT) && !is_null($this->accountType)) {
|
||||||
|
@ -381,7 +383,7 @@ class Timeline extends BaseModule
|
||||||
return $comments;
|
return $comments;
|
||||||
}
|
}
|
||||||
|
|
||||||
$condition = ["`contact-type` != ? AND `comments` > ?", Contact::TYPE_COMMUNITY, 0];
|
$condition = ["`contact-type` != ? AND `comments` > ? AND NOT `restricted`", Contact::TYPE_COMMUNITY, 0];
|
||||||
$condition = $this->addLanguageCondition($uid, $condition);
|
$condition = $this->addLanguageCondition($uid, $condition);
|
||||||
|
|
||||||
$limit = $this->database->count('post-engagement', $condition) / $divider;
|
$limit = $this->database->count('post-engagement', $condition) / $divider;
|
||||||
|
@ -405,7 +407,7 @@ class Timeline extends BaseModule
|
||||||
return $activities;
|
return $activities;
|
||||||
}
|
}
|
||||||
|
|
||||||
$condition = ["`contact-type` != ? AND `activities` > ?", Contact::TYPE_COMMUNITY, 0];
|
$condition = ["`contact-type` != ? AND `activities` > ? AND NOT `restricted`", Contact::TYPE_COMMUNITY, 0];
|
||||||
$condition = $this->addLanguageCondition($uid, $condition);
|
$condition = $this->addLanguageCondition($uid, $condition);
|
||||||
|
|
||||||
$limit = $this->database->count('post-engagement', $condition) / $divider;
|
$limit = $this->database->count('post-engagement', $condition) / $divider;
|
||||||
|
|
|
@ -86,24 +86,14 @@ class Relay
|
||||||
|
|
||||||
$body = ActivityPub\Processor::normalizeMentionLinks($body);
|
$body = ActivityPub\Processor::normalizeMentionLinks($body);
|
||||||
|
|
||||||
$systemTags = [];
|
|
||||||
$userTags = [];
|
|
||||||
$denyTags = [];
|
$denyTags = [];
|
||||||
|
|
||||||
if ($scope == self::SCOPE_TAGS) {
|
if ($scope == self::SCOPE_TAGS) {
|
||||||
$server_tags = $config->get('system', 'relay_server_tags');
|
$tagList = self::getSubscribedTags();
|
||||||
$tagitems = explode(',', mb_strtolower($server_tags));
|
} else {
|
||||||
foreach ($tagitems as $tag) {
|
$tagList = [];
|
||||||
$systemTags[] = trim($tag, '# ');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($config->get('system', 'relay_user_tags')) {
|
|
||||||
$userTags = Search::getUserTags();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$tagList = array_unique(array_merge($systemTags, $userTags));
|
|
||||||
|
|
||||||
$deny_tags = $config->get('system', 'relay_deny_tags');
|
$deny_tags = $config->get('system', 'relay_deny_tags');
|
||||||
$tagitems = explode(',', mb_strtolower($deny_tags));
|
$tagitems = explode(',', mb_strtolower($deny_tags));
|
||||||
foreach ($tagitems as $tag) {
|
foreach ($tagitems as $tag) {
|
||||||
|
@ -149,6 +139,29 @@ class Relay
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of subscribed tags by both the users and the tags that are defined by the admin
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getSubscribedTags(): array
|
||||||
|
{
|
||||||
|
$systemTags = [];
|
||||||
|
$server_tags = DI::config()->get('system', 'relay_server_tags');
|
||||||
|
|
||||||
|
foreach (explode(',', mb_strtolower($server_tags)) as $tag) {
|
||||||
|
$systemTags[] = trim($tag, '# ');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DI::config()->get('system', 'relay_user_tags')) {
|
||||||
|
$userTags = Search::getUserTags();
|
||||||
|
} else {
|
||||||
|
$userTags = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_unique(array_merge($systemTags, $userTags));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Detect the language of a post and decide if the post should be accepted
|
* Detect the language of a post and decide if the post should be accepted
|
||||||
*
|
*
|
||||||
|
|
|
@ -56,7 +56,7 @@ use Friendica\Database\DBA;
|
||||||
|
|
||||||
// This file is required several times during the test in DbaDefinition which justifies this condition
|
// This file is required several times during the test in DbaDefinition which justifies this condition
|
||||||
if (!defined('DB_UPDATE_VERSION')) {
|
if (!defined('DB_UPDATE_VERSION')) {
|
||||||
define('DB_UPDATE_VERSION', 1533);
|
define('DB_UPDATE_VERSION', 1534);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
@ -1333,6 +1333,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"],
|
"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" => "varbinary(128)", "comment" => "Language information about this post"],
|
"language" => ["type" => "varbinary(128)", "comment" => "Language information about this post"],
|
||||||
"created" => ["type" => "datetime", "comment" => ""],
|
"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"],
|
"comments" => ["type" => "mediumint unsigned", "comment" => "Number of comments"],
|
||||||
"activities" => ["type" => "mediumint unsigned", "comment" => "Number of activities (like, dislike, ...)"],
|
"activities" => ["type" => "mediumint unsigned", "comment" => "Number of activities (like, dislike, ...)"],
|
||||||
],
|
],
|
||||||
|
|
Loading…
Reference in a new issue