From 0d2ea97eb18dfe0269cade524f73cafb34e798a3 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 17 Feb 2024 21:32:17 +0000 Subject: [PATCH] Fix comtact-relation follower calculation --- database.sql | 3 +- doc/database/db_contact-relation.md | 23 +++++++-------- src/Content/Widget.php | 1 + src/Model/Contact/Relation.php | 43 ++++++++++++++++++++++------- static/dbstructure.config.php | 3 +- 5 files changed, 50 insertions(+), 23 deletions(-) diff --git a/database.sql b/database.sql index f1966a15e7..41ce810cf5 100644 --- a/database.sql +++ b/database.sql @@ -1,6 +1,6 @@ -- ------------------------------------------ -- Friendica 2024.03-rc (Yellow Archangel) --- DB_UPDATE_VERSION 1552 +-- DB_UPDATE_VERSION 1553 -- ------------------------------------------ @@ -539,6 +539,7 @@ CREATE TABLE IF NOT EXISTS `contact-relation` ( `relation-score` smallint unsigned COMMENT 'score for interactions of relation-cid on cid', `thread-score` smallint unsigned COMMENT 'score for interactions of cid on threads of relation-cid', `relation-thread-score` smallint unsigned COMMENT 'score for interactions of relation-cid on threads of cid', + `post-score` smallint unsigned COMMENT 'score for the amount of posts from cid that can be seen by relation-cid', PRIMARY KEY(`cid`,`relation-cid`), INDEX `relation-cid` (`relation-cid`), FOREIGN KEY (`cid`) REFERENCES `contact` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE, diff --git a/doc/database/db_contact-relation.md b/doc/database/db_contact-relation.md index f11fd95a0f..c83c9b8326 100644 --- a/doc/database/db_contact-relation.md +++ b/doc/database/db_contact-relation.md @@ -6,17 +6,18 @@ Contact relations Fields ------ -| Field | Description | Type | Null | Key | Default | Extra | -| --------------------- | -------------------------------------------------------- | ----------------- | ---- | --- | ------------------- | ----- | -| cid | contact the related contact had interacted with | int unsigned | NO | PRI | 0 | | -| relation-cid | related contact who had interacted with the contact | int unsigned | NO | PRI | 0 | | -| last-interaction | Date of the last interaction by relation-cid on cid | datetime | NO | | 0001-01-01 00:00:00 | | -| follow-updated | Date of the last update of the contact relationship | datetime | NO | | 0001-01-01 00:00:00 | | -| follows | if true, relation-cid follows cid | boolean | NO | | 0 | | -| score | score for interactions of cid on relation-cid | smallint unsigned | YES | | NULL | | -| relation-score | score for interactions of relation-cid on cid | smallint unsigned | YES | | NULL | | -| thread-score | score for interactions of cid on threads of relation-cid | smallint unsigned | YES | | NULL | | -| relation-thread-score | score for interactions of relation-cid on threads of cid | smallint unsigned | YES | | NULL | | +| Field | Description | Type | Null | Key | Default | Extra | +| --------------------- | ----------------------------------------------------------------------- | ----------------- | ---- | --- | ------------------- | ----- | +| cid | contact the related contact had interacted with | int unsigned | NO | PRI | 0 | | +| relation-cid | related contact who had interacted with the contact | int unsigned | NO | PRI | 0 | | +| last-interaction | Date of the last interaction by relation-cid on cid | datetime | NO | | 0001-01-01 00:00:00 | | +| follow-updated | Date of the last update of the contact relationship | datetime | NO | | 0001-01-01 00:00:00 | | +| follows | if true, relation-cid follows cid | boolean | NO | | 0 | | +| score | score for interactions of cid on relation-cid | smallint unsigned | YES | | NULL | | +| relation-score | score for interactions of relation-cid on cid | smallint unsigned | YES | | NULL | | +| thread-score | score for interactions of cid on threads of relation-cid | smallint unsigned | YES | | NULL | | +| relation-thread-score | score for interactions of relation-cid on threads of cid | smallint unsigned | YES | | NULL | | +| post-score | score for the amount of posts from cid that can be seen by relation-cid | smallint unsigned | YES | | NULL | | Indexes ------------ diff --git a/src/Content/Widget.php b/src/Content/Widget.php index 20d82cbe4c..1bb2ec2b61 100644 --- a/src/Content/Widget.php +++ b/src/Content/Widget.php @@ -103,6 +103,7 @@ class Widget { // Always hide content from these networks $networks = [Protocol::PHANTOM, Protocol::FACEBOOK, Protocol::APPNET, Protocol::TWITTER, Protocol::ZOT]; + Addon::loadAddons(); if (!Addon::isEnabled("discourse")) { $networks[] = Protocol::DISCOURSE; diff --git a/src/Model/Contact/Relation.php b/src/Model/Contact/Relation.php index 217b5a896e..1fd250b310 100644 --- a/src/Model/Contact/Relation.php +++ b/src/Model/Contact/Relation.php @@ -22,6 +22,7 @@ namespace Friendica\Model\Contact; use Exception; +use Friendica\Content\Widget; use Friendica\Core\Logger; use Friendica\Core\Protocol; use Friendica\Database\Database; @@ -78,14 +79,14 @@ class Relation */ public static function discoverByUser(int $uid) { - $contact = Contact::selectFirst(['id', 'url', 'network'], ['uid' => $uid, 'self' => true]); + $contact = Contact::selectFirst(['id', 'url', 'network'], ['id' => Contact::getPublicIdByUserId($uid)]); if (empty($contact)) { Logger::warning('Self contact for user not found', ['uid' => $uid]); return; } - $followers = self::getContacts($uid, [Contact::FOLLOWER, Contact::FRIEND]); - $followings = self::getContacts($uid, [Contact::SHARING, Contact::FRIEND]); + $followers = self::getContacts($uid, [Contact::FOLLOWER, Contact::FRIEND], false); + $followings = self::getContacts($uid, [Contact::SHARING, Contact::FRIEND], false); self::updateFollowersFollowings($contact, $followers, $followings); } @@ -207,10 +208,11 @@ class Relation * Fetch contact url list from the given local user * * @param integer $uid - * @param array $rel + * @param array $rel + * @param bool $only_ap * @return array contact list */ - private static function getContacts(int $uid, array $rel): array + private static function getContacts(int $uid, array $rel, bool $only_ap = true): array { $list = []; $profile = Profile::getByUID($uid); @@ -219,15 +221,22 @@ class Relation } $condition = [ - 'rel' => $rel, - 'uid' => $uid, - 'self' => false, + 'rel' => $rel, + 'uid' => $uid, + 'self' => false, 'deleted' => false, - 'hidden' => false, + 'hidden' => false, 'archive' => false, 'pending' => false, + 'blocked' => false, + 'failed' => false, ]; - $condition = DBA::mergeConditions($condition, ["`url` IN (SELECT `url` FROM `apcontact`)"]); + if ($only_ap) { + $condition = DBA::mergeConditions($condition, ["`url` IN (SELECT `url` FROM `apcontact`)"]); + } else { + $networks = Widget::unavailableNetworks(); + $condition = DBA::mergeConditions($condition, array_merge(["NOT `network` IN (" . substr(str_repeat("?, ", count($networks)), 0, -2) . ")"], $networks)); + } $contacts = DBA::select('contact', ['url'], $condition); while ($contact = DBA::fetch($contacts)) { $list[] = $contact['url']; @@ -870,6 +879,20 @@ class Relation DBA::update('contact-relation', ['thread-score' => $score], ['relation-cid' => $contact_id, 'cid' => $interaction['author-id']]); } DBA::close($interactions); + + $total = DBA::fetchFirst("SELECT count(*) AS `posts` FROM `post-thread-user` WHERE EXISTS(SELECT `cid` FROM `contact-relation` WHERE `cid` = `post-thread-user`.`author-id` AND `relation-cid` = ? AND `follows`) AND `uid` = ? AND `created` > ?", + $contact_id, $uid, DateTimeFormat::utc('now - ' . $days . ' day')); + + Logger::debug('Calculate post-score', ['uid' => $uid, 'total' => $total['posts']]); + + $posts = DBA::p("SELECT `author-id`, count(*) AS `posts` FROM `post-thread-user` WHERE EXISTS(SELECT `cid` FROM `contact-relation` WHERE `cid` = `post-thread-user`.`author-id` AND `relation-cid` = ? AND `follows`) AND `uid` = ? AND `created` > ? GROUP BY `author-id`", + $contact_id, $uid, DateTimeFormat::utc('now - ' . $days . ' day')); + while ($post = DBA::fetch($posts)) { + $score = min((int)(($post['posts'] / $total['posts']) * 65535), 65535); + DBA::update('contact-relation', ['post-score' => $score], ['relation-cid' => $contact_id, 'cid' => $post['author-id']]); + } + DBA::close($posts); + Logger::debug('Calculation - end', ['uid' => $uid]); } } diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php index 1b7f7a40de..7606d7b65f 100644 --- a/static/dbstructure.config.php +++ b/static/dbstructure.config.php @@ -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', 1552); + define('DB_UPDATE_VERSION', 1553); } return [ @@ -598,6 +598,7 @@ return [ "relation-score" => ["type" => "smallint unsigned", "comment" => "score for interactions of relation-cid on cid"], "thread-score" => ["type" => "smallint unsigned", "comment" => "score for interactions of cid on threads of relation-cid"], "relation-thread-score" => ["type" => "smallint unsigned", "comment" => "score for interactions of relation-cid on threads of cid"], + "post-score" => ["type" => "smallint unsigned", "comment" => "score for the amount of posts from cid that can be seen by relation-cid"], ], "indexes" => [ "PRIMARY" => ["cid", "relation-cid"],